As explained in the User's Guide page, a sequence is an unbounded array of eXtremeDB-supported scalar data elements. The C++ Sequence class is used together with the generated C API classname_fieldname_*()
functions in C++ applications to manage database fields of type sequence. As sequences are effectively vectors of values, they are accessed through iterators. Whereas the C type mco_seq_iterator_h
is used in C applications, the C++ class Sequence serves the equivalent role in C++ applications. The Sequence class provides a powerful set of Analytics Methods for performing mathematical and statistical operations on sequences.
Normally sequence data is inserted using the generated C API
classname_fieldname_append()
. For example consider the following schema definition:#define uint4 unsigned<4> class Quote { char<16> symbol; sequence<uint4 asc> day; sequence<float> price; tree<symbol> by_symbol; };With this class definition, the Quote sequence fields
day
andprice
can be populated with code like the following:#define N_ITEMS 4 uint4 days[N_ITEMS] = { 1, 2, 4, 5 }; float prices[N_ITEMS] = { 10, 20, 40 ,50 }; ... Quote q; q.create(t); q.symbol_put("IBM", (uint2)(strlen("IBM"))); q.day_append(days, N_ITEMS); ... q.price_append(prices, N_ITEMS);It may sometimes be necessary to insert values into an ordered time series. Values can be inserted into an existing sequence using the generated C API <classname>_<fieldname>_insert(). For example, the following code snippet searches for the Quote object with symbol "
IBM
", then insertsday
andprice
values:#define DAY_THREE 3 #define DAY_THREE_PRICE 30 uint4 day_to_insert[1] = { DAY_THREE }; float price_to_insert[1] = { DAY_THREE_PRICE }; ... mco_trans_h t; mco_cursor_t cur; ... mco_trans_start(db, MCO_READ_WRITE, MCO_TRANS_FOREGROUND, &t); mco_cursor_first(t, &cur); rc = Quote::by_symbol::cursor(t, &cur); if (MCO_S_OK == rc) { rc = Quote::by_symbol::search(t, &cur, MCO_GE, "IBM", (uint2)(sizeof("IBM"))); if (MCO_S_OK == rc) { //insert here Quote q; q.create(t); rc = q.from_cursor(t, &cur); Sequence<uint4> seq = q.day_iterator(); if (MCO_S_OK == rc) { rc = q.day_search(seq, DAY_THREE, MCO_SEQ_BOUNDARY_EXCLUSIVE, 0, MCO_SEQ_BOUNDARY_OPEN); mco_seq_no_t pos = seq.iter->first_seq_no; rc = q.day_insert(pos, day_to_insert, 1); ... rc = q.price_insert(pos, price_to_insert, 1); rc = mco_trans_commit(t); } } }Iterating Sequences
Normally sequence data is iterated using the Sequence method
next()
. For example, the Quote sequence fieldsday
andprice
can be iterated with code like the following:mco_trans_h trans; MCO_RET rc; ... mco_trans_start(db, MCO_READ_ONLY, MCO_TRANS_FOREGROUND, &trans); if ( MCO_S_OK == rc ) { Sequence<uint4> day_iterator; ... quote.day_search(day_iterator, DMY(1,1,2013), MCO_SEQ_BOUNDARY_INCLUSIVE, DMY(1,4,2013), MCO_SEQ_BOUNDARY_INCLUSIVE)); Sequence<float> price_iterator = quote.price_project(day_iterator); /* Iterate day and price sequences */ while (day_iterator.next(day)) { printf("%u: %f\n", day, ++price_iterator); } mco_trans_rollback(trans); }Note how the
next()
method is used to iterate through theday
sequence and the convenient ++ operator is used to iterate theprice
sequence.Using Analytics Methods
As mentione above, the Sequence class provides a number of Analytics Methods to efficiently manipulate sequence data and perform a variety of statistical operations. For example, the following code snippet demonstrates how to iterate a Grid Aggregate Maximum sequence of Quote
price
values using a generic sequence output functionprint_sequence()
(as demonstrated in SDK sample):
samples/native/sequences/api/cpp
mco_trans_h trans; MCO_RET rc; ... mco_trans_start(db, MCO_READ_ONLY, MCO_TRANS_FOREGROUND, &trans); if ( MCO_S_OK == rc ) { /* Iterate through all Quote objects */ Quote::by_sym::cursor(trans, "e_cursor); for (rc = mco_cursor_first(trans, "e_cursor); rc != MCO_S_CURSOR_END; rc = mco_cursor_next(trans, "e_cursor)) { /* Get current Quote object */ quote.from_cursor(trans, "e_cursor); /* Print the Grid Aggregate sequence for price */ print_sequence(quote, quote.price_iterator().gridAggMax(7)); } mco_trans_rollback(trans); }Note that the C type
returned by generated function
sequence_iterator
quote.price_iterator()
is converted to a C++ Sequence and its methodgridAggMax()
is invoked in the call to functionprint_sequence()
. This Sequence is then iterated and printed out inprint_sequence()
.