mco_seq_join_TYPE C
mco_seq_join_TYPE() 这个 C 函数接收一个元迭代器作为输入,并生成相同类型的输出序列。此函数不应与生成的 CLASS_FIELD_join() API 混淆!
输入的 metaiterator 参数是一个“迭代器的迭代器”,即一种特殊的迭代器,它提供了一种通过遍历其元素来连接多个序列的方法,直到到达序列的末尾,然后获取下一个迭代器并对其进行迭代,依此类推。 元迭代器结构具有以下形式:
typedef struct mco_seq_meta_iterator_t_
{
mco_seq_meta_iterator_next_t next;
mco_seq_meta_iterator_first_t first;
mco_seq_iterator_t iterator; /* 由对 next 的调用初始化的迭代器 */
void* user_data; /* 用户上下文可以通过此字段提供。 */
} mco_seq_meta_iterator_t, *mco_seq_meta_iterator_h;此函数的目的是将 SmartEDB 记录迭代器(或游标)与序列迭代器相结合,因为序列是 SmartEDB 的常规字段类型,即序列字段属于记录。例如,考虑以下模式:
#define uint4 unsigned<4>
#define MAX_SYMBOL_LEN 21
declare database stockdb;
class Quote
{
char<MAX_SYMBOL_LEN> symbol;
sequence<date asc> day;
sequence<float> price;
unique tree<symbol> by_sym;
};序列价格指定了特定股票报价的价格。报价表以字段 symbol 上的索引 by_sym 作为主键。如果要计算所有报价的总价,就需要遍历报价表中的所有记录,使用 mco_seq_agg_sum_float() 函数对每条记录的序列价格计算总价,然后将所有这些结果相加。
mco_seq_join_TYPE() API 允许构建一个元迭代器来更高效地执行此操作。该元迭代器遍历 Quote 表,并返回价格字段的序列迭代器。然后,可以将 mco_seq_agg_sum() 应用于 mco_seq_join_float() 的结果,以获取所需的总和。
显然,要实现这个功能需要编写一些程序来实现元迭代器。以下示例代码演示了如何使用 mco_seq_join_float() 和 mco_seq_agg_max_float() 来获取所有报价中的最低价最大值。我们将使用一个更真实的报价表:
#define uint4 unsigned<4>
#define MAX_SYMBOL_LEN 21
declare database stockdb;
class Quote
{
char<MAX_SYMBOL_LEN> symbol;
sequence<date asc> day;
sequence<float> low;
sequence<float> high;
sequence<float> open;
sequence<float> close;
sequence<uint4> volume;
sequence<char<15>> day_str;
unique tree<symbol> by_sym;
};应用程序特定的用户数据通过以下结构提供给元迭代器:
typedef struct quote_low_dsc_t
{
mco_trans_h trans; // 事务处理
mco_cursor_t quote_cursor; // 报价记录的游标
Quote quote; // 当前报价记录
} quote_low_dsc;The metaiterator's first and next functions are implemented as follows:
MCO_RET join_low_first(mco_seq_meta_iterator_h meta_iterator)
{
quote_low_dsc *ud = (quote_low_dsc *)meta_iterator->user_data;
MCO_RET rc = mco_cursor_first(ud->trans, &ud->quote_cursor);
if (rc != MCO_S_OK)
return rc;
CHECK(Quote_from_cursor(ud->trans, &ud->quote_cursor, &ud->quote));
CHECK(Quote_low_iterator(&ud->quote, &meta_iterator->iterator));
return MCO_S_OK;
}
MCO_RET join_low_next(mco_seq_meta_iterator_h meta_iterator)
{
quote_low_dsc *ud = (quote_low_dsc *)meta_iterator->user_data;
MCO_RET rc = mco_cursor_next(ud->trans, &ud->quote_cursor);
if (rc != MCO_S_OK)
return rc;
CHECK(Quote_from_cursor(ud->trans, &ud->quote_cursor, &ud->quote));
CHECK(Quote_low_iterator(&ud->quote, &meta_iterator->iterator));
return MCO_S_OK;
}现在,函数 join() 初始化元迭代器和 Quote 游标,然后调用 mco_seq_join_float() 以获取所有 Quote 记录的低序列元素的序列。接着,从调用 mco_seq_agg_max_float() 并传入合并后的低序列的结果中提取最大值:
void join(mco_db_h db)
{
mco_seq_iterator_t all_low_it;
mco_seq_iterator_t min_low_it;
mco_seq_iterator_t count_low_it;
mco_seq_meta_iterator_t low_meta_it;
MCO_RET rc;
float min_low;
quote_low_dsc muluser_data;
CHECK(mco_trans_start(db, MCO_READ_ONLY, MCO_TRANS_FOREGROUND, &user_data.trans));
printf("--- JOIN --------------------\n");
/* Initialize the metaiterator */
low_meta_it.next = join_low_next;
low_meta_it.first = join_low_first;
low_meta_it.user_data = &user_data;
/* Initialize the cursor over all Quote objects */
CHECK(Quote_by_sym_index_cursor(user_data.trans, &user_data.quote_cursor));
CHECK(mco_seq_join_float(&all_low_it, &low_meta_it));
/* now all_low_it is a sequence which consists of all low sequences
for all Quote objects */
CHECK(mco_seq_agg_max_float(&min_low_it, &all_low_it));
CHECK(mco_seq_next_float(&min_low_it, &min_low));
printf("Maximum of lows: %g\n", min_low);
CHECK(mco_trans_commit(user_data.trans));
}