RDM::TIME_SERIES::stats< N, STATS_T, NEXT > Class Template Reference

Template Class for doing statistics. More...

#include "rdm_time_series_stats.h"

Public Member Functions

uint8_t * serialize (uint8_t *buffer)
uint8_t * unserialize (uint8_t *buffer)
RDM_RETCODE init (RDM_DB p_db)
Initialize this object. More...
void reset (void)
Reset this object. More...
RDM_RETCODE flush_value (uint32_t threshold=1, RDM::DB::TRANSACTIONAL_T transactional=RDM::DB::NOT_TRANSACTIONAL)
Flush this object. More...
RDM_RETCODE flush_stats (uint32_t threshold=1, RDM::DB::TRANSACTIONAL_T transactional=RDM::DB::NOT_TRANSACTIONAL)
Flush this object. More...
template<class SOURCE_VALUE_T >
RDM_RETCODE put_value (SOURCE_VALUE_T *source_value, RDM::DB::TRANSACTIONAL_T transactional=RDM::DB::NOT_TRANSACTIONAL)
Template method for receiving a data value. More...
template<class SOURCE_STATS_T >
RDM_RETCODE put_stats (SOURCE_STATS_T *source_stats, RDM::DB::TRANSACTIONAL_T transactional=RDM::DB::NOT_TRANSACTIONAL)
Template method for receiving statistics. More...

Static Public Member Functions

constexpr static int get_serialize_size (void)
Get the size of a buffer for serialization to hold its state. More...

Friends

template<class ANY_NEXT >
class RDM::DB::transaction
template<class ANY_NEXT_1 , class ANY_NEXT_2 >
class split
template<uint32_t ANY_N, class ANY_RANGE_T , class ANY_NEXT >
class collect
template<uint32_t ANY_N, class ANY_RANGE_T , class ANY_INDATA_T , class ANY_NEXT >
class fft
template<uint32_t ANY_N, class ANY_AGGREGATE_T , class ANY_AGG_ELEMENT_T , class ANY_NEXT >
class mean
template<class ANY_RATIO , class ANY_NEXT >
class scale
template<uint32_t ANY_N, class ANY_STATS_T , class ANY_NEXT >
class stats
template<uint32_t ANY_N, class ANY_NEXT >
class downsample
template<class ANY_NEXT >
class custom

Detailed Description

template<uint32_t N, class STATS_T, class NEXT>
class RDM::TIME_SERIES::stats< N, STATS_T, NEXT >

Template Class for doing statistics.

Template class for doing statistics of data values or aggregating statistics. It is an error for this class to receive ranges. The sum of the data values (sum), the sum of the squared data values (sum2), and the total number of data values (n) will be computed or aggregated. The result of this will be forwarded to the next class in the chain.

We collect these values for easy calculation of the mean value and the standard deviation. These can be calculated as follows (we included the Bessel's correction here):

  • Mean value: sum / n
  • Standard deviation: sqrt ((sum2 - sum * sum / n) / (n - 1))

Upon destruction of this class, there might be incomplete aggregations that have not yet been passed to the next class in the chain. flush() can be called to force those incomplete aggregations to be sent to the next class. This approach may not always be desirable. Another approach is to restore the state of this class the next time this class is instantiated. See restore_aggregate for details.

Template Parameters
N The number of receved elements to average.
STATS_T The aggregate statistics class for which objects will be passed to the next class.
NEXT The class in the chain to receive statistics.
Examples
cpp70Example_main.cpp, time_series_custom.cpp, time_series_restore_aggregate.cpp, and time_series_stats.cpp.

Member Function Documentation

flush_stats()

template<uint32_t N, class STATS_T , class NEXT >
RDM_RETCODE RDM::TIME_SERIES::stats< N, STATS_T, NEXT >::flush_stats ( uint32_t threshold = 1,
RDM::DB::TRANSACTIONAL_T transactional = RDM::DB::NOT_TRANSACTIONAL
)
inline

Flush this object.

Call this method to flush what has been collected so far. A threshold can also be provided. All the data collected for those statistics will be kept as is. The same is the case where the threshold has not been reached.

This operation can be specified as being transactional. However, if the caller always rolls back the transaction in the case of a failure, there is no need to specify single operations to be transactional.

Return values
sOKAY Normal, successful return.
eNOSTARTUPDATE An update operation was attempted when no rdm_dbStartUpdate() is active.
eNOTLOCKED Attempt to access a table for reading or update without proper locks.
eCURSORDB Cursor is associated with a different database.
eDBNOTOPEN Database not open.
ePRECOMMITTED A precommitted transaction must be committed or rolled back before further operations on this database are allowed.
eDUPLICATE Attempt to insert a duplicate value as a unique/primary key.
eREADONLY Database is read-only and cannot be updated.
eREFINTEGRITY Integrity constraint violation.
eROWLIMIT Table row limit reached.
eINVARG Invalid argument.
Parameters
threshold [IN] Only flush objects where at least this many elements have been collected
transactional [IN] Is the flush required to be transactional
348 {
349RDM_RETCODE rc = sOKAY;
350
351if (n >= threshold && n > 0)
352 {
353RDM_TRANS trans{};
354
355if (transactional == RDM::DB::TRANSACTIONAL)
356 {
357 rc = rdm_dbStartUpdate (db, NULL, 0, NULL, 0, &trans);
358 }
359
360if (rc == sOKAY)
361 {
362 rc = next.put_stats (&aggregate_stats, transactional);
363if (rc == sOKAY)
364 {
365 n_just_before_last_flush = n;
366 rc = next.flush_stats (threshold, transactional);
367if (rc == sOKAY)
368 {
369 n = 0;
370 }
371else
372 {
373 next.unput ();
374 }
375 }
376if (transactional == RDM::DB::TRANSACTIONAL)
377 {
378if (rc == sOKAY)
379 {
380 rc = rdm_transEnd (trans);
381 }
382else
383 {
385 }
386 }
387 }
388 }
389else
390 {
391if (n == 0)
392 {
393 n_just_before_last_flush = 0;
394 }
395 rc = next.flush_stats (threshold, transactional);
396 }
397
398return rc;
399 }

References rdm_dbStartUpdate(), rdm_transEnd(), rdm_transEndRollback(), sOKAY, and RDM::DB::TRANSACTIONAL.

Here is the call graph for this function:

flush_value()

template<uint32_t N, class STATS_T , class NEXT >
RDM_RETCODE RDM::TIME_SERIES::stats< N, STATS_T, NEXT >::flush_value ( uint32_t threshold = 1,
RDM::DB::TRANSACTIONAL_T transactional = RDM::DB::NOT_TRANSACTIONAL
)
inline

Flush this object.

Call this method to flush what has been collected so far. A threshold can also be provided. All the data collected for those values will be kept as is. The same is the case where the threshold has not been reached.

This operation can be specified as being transactional. However, if the caller always rolls back the transaction in the case of a failure, there is no need to specify single operations to be transactional.

Return values
sOKAY Normal, successful return.
eNOSTARTUPDATE An update operation was attempted when no rdm_dbStartUpdate() is active.
eNOTLOCKED Attempt to access a table for reading or update without proper locks.
eCURSORDB Cursor is associated with a different database.
eDBNOTOPEN Database not open.
ePRECOMMITTED A precommitted transaction must be committed or rolled back before further operations on this database are allowed.
eDUPLICATE Attempt to insert a duplicate value as a unique/primary key.
eREADONLY Database is read-only and cannot be updated.
eREFINTEGRITY Integrity constraint violation.
eROWLIMIT Table row limit reached.
eINVARG Invalid argument.
Parameters
threshold [IN] Only flush objects where at least this many elements have been collected
transactional [IN] Is the flush required to be transactional
266 {
267RDM_RETCODE rc = sOKAY;
268
269if (n >= threshold && n > 0)
270 {
271
272RDM_TRANS trans{};
273
274if (transactional == RDM::DB::TRANSACTIONAL)
275 {
276 rc = rdm_dbStartUpdate (db, NULL, 0, NULL, 0, &trans);
277 }
278
279if (rc == sOKAY)
280 {
281 rc = next.put_stats (&aggregate_stats, RDM::DB::NOT_TRANSACTIONAL);
282if (rc == sOKAY)
283 {
284 n_just_before_last_flush = n;
285 rc = next.flush_stats (threshold, RDM::DB::NOT_TRANSACTIONAL);
286if (rc == sOKAY)
287 {
288 n = 0;
289 }
290else
291 {
292 next.unput ();
293 }
294 }
295if (transactional == RDM::DB::TRANSACTIONAL)
296 {
297if (rc == sOKAY)
298 {
299 rc = rdm_transEnd (trans);
300 }
301else
302 {
304 }
305 }
306 }
307 }
308else
309 {
310if (n == 0)
311 {
312 n_just_before_last_flush = 0;
313 }
314 rc = next.flush_stats (threshold, transactional);
315 }
316
317return rc;
318 }

References RDM::DB::NOT_TRANSACTIONAL, rdm_dbStartUpdate(), rdm_transEnd(), rdm_transEndRollback(), sOKAY, and RDM::DB::TRANSACTIONAL.

Here is the call graph for this function:

get_serialize_size()

template<uint32_t N, class STATS_T , class NEXT >
constexpr static int RDM::TIME_SERIES::stats< N, STATS_T, NEXT >::get_serialize_size ( void )
inlinestaticconstexpr

Get the size of a buffer for serialization to hold its state.

Get the size needed for a buffer to hold the state of this object.

160 {
161return sizeof(prev_aggregate_stats) + sizeof(aggregate_stats) + sizeof(n) + sizeof(n_just_before_last_put) + sizeof(n_just_before_last_flush) + NEXT::get_serialize_size ();
162 }

init()

template<uint32_t N, class STATS_T , class NEXT >
RDM_RETCODE RDM::TIME_SERIES::stats< N, STATS_T, NEXT >::init ( RDM_DB p_db )
inline

Initialize this object.

Call this method before sending it any data values or statistics.

Return values
sOKAY Normal, successful return.
eINVARG Invalid argument.
eDBNOTOPEN Database not open.
eCURSORDB Cursor is associated with a different database.
ePRECOMMITTED A precommitted transaction must be committed or rolled back before further operations on this database are allowed.
Parameters
p_db [IN] Use this database for chained classes that need to insert rows
Examples
time_series_custom.cpp.
219 {
220RDM_RETCODE rc = next.init (p_db);
221 n = 0;
222
223return rc;
224 }

put_stats()

template<uint32_t N, class STATS_T , class NEXT >
template<class SOURCE_STATS_T >
RDM_RETCODE RDM::TIME_SERIES::stats< N, STATS_T, NEXT >::put_stats ( SOURCE_STATS_T * source_stats,
RDM::DB::TRANSACTIONAL_T transactional = RDM::DB::NOT_TRANSACTIONAL
)
inline

Template method for receiving statistics.

Receive one statistic and process it accordingly.

The type for the value provided is required to have columns for 'time_stamp_first', 'time_stamp_last', 'n', 'value_sum', and 'value_sum2' with appropriate types. Such a type can be generated using rdm-compile with a schema including a table similar to this:

CREATE TABLE stats
(
time_stamp_first UINT64 NOT NULL,
time_stamp_last UINT64 PRIMARY KEY,
n UINT64 NOT NULL,
value_sum DOUBLE NOT NULL,
value_sum2 DOUBLE NOT NULL
);

This operation can be specified as being transactional. However, if the caller always rolls back the transaction in the case of a failure, there is no need to specify single operations to be transactional.

Template Parameters
SOURCE_STATS_T The actual type of the statistic received.
Return values
sOKAY Normal, successful return.
eNOSTARTUPDATE An update operation was attempted when no rdm_dbStartUpdate() is active.
eNOTLOCKED Attempt to access a table for reading or update without proper locks.
eCURSORDB Cursor is associated with a different database.
eDBNOTOPEN Database not open.
ePRECOMMITTED A precommitted transaction must be committed or rolled back before further operations on this database are allowed.
eDUPLICATE Attempt to insert a duplicate value as a unique/primary key.
eREADONLY Database is read-only and cannot be updated.
eREFINTEGRITY Integrity constraint violation.
eROWLIMIT Table row limit reached.
eINVARG Invalid argument.
Parameters
[in] source_stats The source statistics sent to this class
transactional [IN] Is the put required to be transactional
535 {
536RDM_RETCODE rc = sOKAY;
537
538 prev_aggregate_stats = aggregate_stats;
539
540if (n == 0)
541 {
542 aggregate_stats.time_stamp_first =
543 source_stats->time_stamp_first;
544 aggregate_stats.n = source_stats->n;
545 aggregate_stats.value_sum = source_stats->value_sum;
546 aggregate_stats.value_sum2 = source_stats->value_sum2;
547 }
548else
549 {
550 aggregate_stats.n += source_stats->n;
551 aggregate_stats.value_sum = aggregate_stats.value_sum + source_stats->value_sum;
552 aggregate_stats.value_sum2 = aggregate_stats.value_sum2 + source_stats->value_sum2;
553 }
554 aggregate_stats.time_stamp_last =
555 source_stats->time_stamp_last;
556
557if (n == N - 1)
558 {
559 rc = next.put_stats (&aggregate_stats, transactional);
560if (rc == sOKAY)
561 {
562 n_just_before_last_put = n;
563 n = 0;
564 }
565else
566 {
567 aggregate_stats = prev_aggregate_stats;
568 }
569 }
570else
571 {
572 n++;
573 }
574
575return rc;
576 }

References sOKAY.

put_value()

template<uint32_t N, class STATS_T , class NEXT >
template<class SOURCE_VALUE_T >
RDM_RETCODE RDM::TIME_SERIES::stats< N, STATS_T, NEXT >::put_value ( SOURCE_VALUE_T * source_value,
RDM::DB::TRANSACTIONAL_T transactional = RDM::DB::NOT_TRANSACTIONAL
)
inline

Template method for receiving a data value.

Receive one data value and process it accordingly.

The type for the value provided is required to have columns for 'time_stamp_current' and 'value_current' with appropriate types. Such a type can be generated using rdm-compile with a schema including a table similar to this:

CREATE TABLE measurement
(
time_stamp_current UINT64 PRIMARY KEY,
value_current DOUBLE NOT NULL
);

This operation can be specified as being transactional. However, if the caller always rolls back the transaction in the case of a failure, there is no need to specify single operations to be transactional.

Template Parameters
SOURCE_VALUE_T The actual type of the source values received
Return values
sOKAY Normal, successful return.
eNOSTARTUPDATE An update operation was attempted when no rdm_dbStartUpdate() is active.
eNOTLOCKED Attempt to access a table for reading or update without proper locks.
eCURSORDB Cursor is associated with a different database.
eDBNOTOPEN Database not open.
ePRECOMMITTED A precommitted transaction must be committed or rolled back before further operations on this database are allowed.
eDUPLICATE Attempt to insert a duplicate value as a unique/primary key.
eREADONLY Database is read-only and cannot be updated.
eREFINTEGRITY Integrity constraint violation.
eROWLIMIT Table row limit reached.
eINVARG Invalid argument.
Parameters
[in] source_value The source value sent to this class
transactional [IN] Is the put required to be transactional
443 {
444RDM_RETCODE rc = sOKAY;
445
446 prev_aggregate_stats = aggregate_stats;
447
448if (n == 0)
449 {
450 aggregate_stats.time_stamp_first =
451 source_value->time_stamp_current;
452 aggregate_stats.n = 1;
453 aggregate_stats.value_sum = source_value->value_current;
454 aggregate_stats.value_sum2 = source_value->value_current *
455 source_value->value_current;
456 }
457else
458 {
459 aggregate_stats.n++;
460 aggregate_stats.value_sum = aggregate_stats.value_sum + source_value->value_current;
461 aggregate_stats.value_sum2 = aggregate_stats.value_sum2 + source_value->value_current *
462 source_value->value_current;
463 }
464
465 aggregate_stats.time_stamp_last =
466 source_value->time_stamp_current;
467
468if (n == N - 1)
469 {
470 rc = next.put_stats (&aggregate_stats, transactional);
471if (rc == sOKAY)
472 {
473 n_just_before_last_put = n;
474 n = 0;
475 }
476else
477 {
478 aggregate_stats = prev_aggregate_stats;
479 }
480 }
481else
482 {
483 n++;
484 }
485
486
487return rc;
488 }

References sOKAY.

reset()

template<uint32_t N, class STATS_T , class NEXT >
void RDM::TIME_SERIES::stats< N, STATS_T, NEXT >::reset ( void )
inline

Reset this object.

Call this method to discard all internally kept data values, ranges, and statistics that have not yet been persisted and start over from scratch.

233 {
234 next.reset ();
235 n = 0;
236 }

serialize()

template<uint32_t N, class STATS_T , class NEXT >
uint8_t* RDM::TIME_SERIES::stats< N, STATS_T, NEXT >::serialize ( uint8_t * buffer )
inline
171 {
172 memcpy (buffer, &prev_aggregate_stats, sizeof (prev_aggregate_stats));
173 buffer += sizeof (prev_aggregate_stats);
174 memcpy (buffer, &aggregate_stats, sizeof (aggregate_stats));
175 buffer += sizeof (aggregate_stats);
176 memcpy (buffer, &n, sizeof (n));
177 buffer += sizeof (n);
178 memcpy (buffer, &n_just_before_last_put, sizeof (n_just_before_last_put));
179 buffer += sizeof (n_just_before_last_put);
180 memcpy (buffer, &n_just_before_last_flush, sizeof (n_just_before_last_flush));
181 buffer += sizeof (n_just_before_last_flush);
182return next.serialize (buffer);
183 }

unserialize()

template<uint32_t N, class STATS_T , class NEXT >
uint8_t* RDM::TIME_SERIES::stats< N, STATS_T, NEXT >::unserialize ( uint8_t * buffer )
inline
192 {
193 memcpy (&prev_aggregate_stats, buffer, sizeof (prev_aggregate_stats));
194 buffer += sizeof (prev_aggregate_stats);
195 memcpy (&aggregate_stats, buffer, sizeof (aggregate_stats));
196 buffer += sizeof (aggregate_stats);
197 memcpy (&n, buffer, sizeof (n));
198 buffer += sizeof (n);
199 memcpy (&n_just_before_last_put, buffer, sizeof (n_just_before_last_put));
200 buffer += sizeof (n_just_before_last_put);
201 memcpy (&n_just_before_last_flush, buffer, sizeof (n_just_before_last_flush));
202 buffer += sizeof (n_just_before_last_flush);
203return next.unserialize (buffer);
204 }

Friends And Related Function Documentation

collect

template<uint32_t N, class STATS_T , class NEXT >
template<uint32_t ANY_N, class ANY_RANGE_T , class ANY_NEXT >
friend class collect
friend

custom

template<uint32_t N, class STATS_T , class NEXT >
template<class ANY_NEXT >
friend class custom
friend

downsample

template<uint32_t N, class STATS_T , class NEXT >
template<uint32_t ANY_N, class ANY_NEXT >
friend class downsample
friend

fft

template<uint32_t N, class STATS_T , class NEXT >
template<uint32_t ANY_N, class ANY_RANGE_T , class ANY_INDATA_T , class ANY_NEXT >
friend class fft
friend

mean

template<uint32_t N, class STATS_T , class NEXT >
template<uint32_t ANY_N, class ANY_AGGREGATE_T , class ANY_AGG_ELEMENT_T , class ANY_NEXT >
friend class mean
friend

RDM::DB::transaction

template<uint32_t N, class STATS_T , class NEXT >
template<class ANY_NEXT >
friend class RDM::DB::transaction
friend

scale

template<uint32_t N, class STATS_T , class NEXT >
template<class ANY_RATIO , class ANY_NEXT >
friend class scale
friend

split

template<uint32_t N, class STATS_T , class NEXT >
template<class ANY_NEXT_1 , class ANY_NEXT_2 >
friend class split
friend

stats

template<uint32_t N, class STATS_T , class NEXT >
template<uint32_t ANY_N, class ANY_STATS_T , class ANY_NEXT >
friend class stats
friend

The documentation for this class was generated from the following files:
RDM_RETCODE rdm_transEnd(RDM_TRANS trans)
End a transactional operation.
@ NOT_TRANSACTIONAL
Definition: rdm_db_transaction.h:36
RDM_RETCODE rdm_transEndRollback(RDM_TRANS trans)
End a transactional operation with a rollback.
@ sOKAY
Definition: rdmretcodetypes.h:100
struct RDM_TRANS_S * RDM_TRANS
Definition: rdmtypes.h:328
enum RDM_RETCODE_E RDM_RETCODE
RaimaDB status and error return codes.
RDM_RETCODE rdm_dbStartUpdate(RDM_DB db, const RDM_TABLE_ID *writeTableIds, uint32_t numWriteTableIds, const RDM_TABLE_ID *readTableIds, uint32_t numReadTableIds, RDM_TRANS *pTrans)
Get write locks.
@ TRANSACTIONAL
Definition: rdm_db_transaction.h:35