Example #1
0
int main(int argc, char *argv[])
{
  if (argc != 2) {
    exit(1);
  }
  char db_name[32] = "cstore";
  char *table_name = argv[1];
  char full_table_name[32];
  if (!init_db()) {
    exit(1);
  }
  if (!create_db(db_name)) {
    std::cerr << "create_db failed" << std::endl;
    exit(1);
  }

  sprintf(full_table_name, "%s/%s", db_name, table_name);
  if (!create_schema(full_table_name)) {
    std::cerr << "create_schema failed" << std::endl;
    exit(1);
  }

  ib_crsr_t ib_crsr;

  std::string line;
  int i = 0;
  ib_trx_t ib_trx = ib_trx_begin(IB_TRX_REPEATABLE_READ);
  ib_cursor_open_table(full_table_name, ib_trx, &ib_crsr);
  while (getline(std::cin, line)) {
    std::vector<std::string> strs;
    boost::split(strs, line, boost::is_any_of(" ") );
    ib_tpl_t tpl = ib_clust_read_tuple_create(ib_crsr);
    ib_tuple_write_u32(tpl, 0, atoi(strs[0].c_str()));
    ib_tuple_write_u32(tpl, 1, atoi(strs[1].c_str()));
    ib_tuple_write_u32(tpl, 2, atoi(strs[2].c_str()));
    ib_err_t err = ib_cursor_insert_row(ib_crsr, tpl);
    if (err != DB_SUCCESS) {
      std::cerr << "insert_row failed" << std::endl;
    }
    ib_tuple_delete(tpl);
    if (++i % 10000 == 0) {
      std::cout << i << std::endl;
      ib_cursor_close(ib_crsr); 
      ib_trx_commit(ib_trx);
      ib_trx = ib_trx_begin(IB_TRX_REPEATABLE_READ);
      ib_cursor_open_table(full_table_name, ib_trx, &ib_crsr);
    }
  }
  ib_cursor_close(ib_crsr); 
  ib_trx_commit(ib_trx);
  fin_db();

  return 0;
}
/**
 * Flush the entire cache
 * @param when when the cache should be flushed (0 == immediately)
 */
void flush(uint32_t when __attribute__((unused))) 
{
  /* @TODO implement support for when != 0 */
  ib_trx_t transaction= ib_trx_begin(IB_TRX_REPEATABLE_READ);
  ib_crsr_t cursor= NULL;
	ib_err_t err= DB_SUCCESS;

  checked(ib_cursor_open_table(tablename, transaction, &cursor));
  checked(ib_cursor_first(cursor));
  checked(ib_cursor_lock(cursor, IB_LOCK_X));

  do 
  {
    checked(ib_cursor_delete_row(cursor));
  } while ((err= ib_cursor_next(cursor)) == DB_SUCCESS);

  if (err != DB_END_OF_INDEX)
  {
    fprintf(stderr, "Failed to flush the cache: %s\n", ib_strerror(err));
    goto error_exit;
  }
  ib_cursor_close(cursor);
  cursor= NULL;
  checked(ib_trx_commit(transaction));
  return;

 error_exit:
  if (cursor != NULL)
    ib_cursor_close(cursor);

  ib_err_t error= ib_trx_rollback(transaction);
  if (error != DB_SUCCESS)
    fprintf(stderr, "Failed to roll back the transaction:\n\t%s\n",
            ib_strerror(error));
}
/**
 * Store an item into the database. Update the CAS id on the item before
 * storing it in the database.
 *
 * @param trx the transaction to use
 * @param item the item to store
 * @return true if we can go ahead and commit the transaction, false otherwise
 */
static bool do_put_item(ib_trx_t trx, struct item* item) 
{
  update_cas(item);

  ib_crsr_t cursor= NULL;
  ib_tpl_t tuple= NULL;
  bool retval= false;

  checked(ib_cursor_open_table(tablename, trx, &cursor));
  checked(ib_cursor_lock(cursor, IB_LOCK_X));
  tuple= ib_clust_read_tuple_create(cursor);

  checked(ib_col_set_value(tuple, key_col_idx, item->key, item->nkey));
  checked(ib_col_set_value(tuple, data_col_idx, item->data, item->size));
  checked(ib_tuple_write_u32(tuple, flags_col_idx, item->flags));
  checked(ib_tuple_write_u64(tuple, cas_col_idx, item->cas));
  checked(ib_tuple_write_u32(tuple, exp_col_idx, (ib_u32_t)item->exp));
  checked(ib_cursor_insert_row(cursor, tuple));

  retval= true;
  /* Release resources: */
  /* FALLTHROUGH */

 error_exit:
  if (tuple != NULL)
    ib_tuple_delete(tuple);

  if (cursor != NULL)
    ib_cursor_close(cursor);

  return retval;
}
Example #4
0
/*********************************************************************
Open the secondary indexes on T(C1), T(C2), T(C3). */
static
ib_err_t
open_sec_index_1(
/*=============*/
	const char*	dbname,		/*!< in: database name */
	const char* 	name)		/*!< in: table name */
{
	ib_crsr_t	crsr;
	ib_trx_t	ib_trx;
	ib_err_t	err = DB_SUCCESS;
	char		index_name[IB_MAX_TABLE_NAME_LEN];
	char		table_name[IB_MAX_TABLE_NAME_LEN];

#ifdef __WIN__
	sprintf(table_name, "%s/%s", dbname, name);
#else
	snprintf(table_name, sizeof(table_name), "%s/%s", dbname, name);
#endif

	ib_trx = ib_trx_begin(IB_TRX_REPEATABLE_READ);

	err = ib_cursor_open_table(table_name, ib_trx, &crsr);
	assert(err == DB_SUCCESS);

#ifdef __WIN__
	sprintf(index_name, "%s_%s", table_name, "c1");
#else
	snprintf(index_name, sizeof(index_name), "%s_%s", table_name, "c1");
#endif
	err = open_sec_index(crsr, index_name);
	assert(err == DB_SUCCESS);

#ifdef __WIN__
	sprintf(index_name, "%s_%s", table_name, "c2");
#else
	snprintf(index_name, sizeof(index_name), "%s_%s", table_name, "c2");
#endif
	err = open_sec_index(crsr, index_name);
	assert(err == DB_SUCCESS);

#ifdef __WIN__
	sprintf(index_name, "%s_%s", table_name, "c3");
#else
	snprintf(index_name, sizeof(index_name), "%s_%s", table_name, "c3");
#endif
	err = open_sec_index(crsr, index_name);
	assert(err == DB_SUCCESS);

	err = ib_cursor_close(crsr);
	assert(err == DB_SUCCESS);

	err = ib_trx_commit(ib_trx);
	assert(err == DB_SUCCESS);

	return(err);
}
/**
 * Try to locate an item in the database. Return a cursor and the tuple to
 * the item if I found it in the database.
 *
 * @param trx the transaction to use
 * @param key the key of the item to look up
 * @param nkey the size of the key
 * @param cursor where to store the cursor (OUT)
 * @param tuple where to store the tuple (OUT)
 * @return true if I found the object, false otherwise
 */
static bool do_locate_item(ib_trx_t trx,
                           const void* key,
                           size_t nkey,
                           ib_crsr_t *cursor)
{
  int res;
  ib_tpl_t tuple= NULL;

  *cursor= NULL;

  checked(ib_cursor_open_table(tablename, trx, cursor));
  tuple= ib_clust_search_tuple_create(*cursor);
  if (tuple == NULL)
  {
    fprintf(stderr, "Failed to allocate tuple object\n");
    goto error_exit;
  }

  checked(ib_col_set_value(tuple, key_col_idx, key, nkey));
  ib_err_t err= ib_cursor_moveto(*cursor, tuple, IB_CUR_GE, &res);

  if (err == DB_SUCCESS && res == 0)
  {
    ib_tuple_delete(tuple);
    return true;
  }
  else if (err != DB_SUCCESS &&
           err != DB_RECORD_NOT_FOUND &&
           err != DB_END_OF_INDEX)
  {
    fprintf(stderr, "ERROR: ib_cursor_moveto(): %s\n", ib_strerror(err));
  }
  /* FALLTHROUGH */
 error_exit:
  if (tuple != NULL)
    ib_tuple_delete(tuple);

  if (*cursor != NULL)
  {
    ib_err_t cursor_error;
    cursor_error= ib_cursor_close(*cursor);
    (void) cursor_error;
  }

  *cursor= NULL;

  return false;
}
Example #6
0
int main(int argc, char *argv[])
{
  if (!init_db()) { exit(1); }

  ib_crsr_t crsr, index_crsr;
  ib_tpl_t tpl;
  ib_err_t err;
  char *l6_orderkey_rle = "l5_customer_key_rle";
  char cstore_l6_orderkey_rle[64];
  sprintf(cstore_l6_orderkey_rle, "%s/%s", db_name, l6_orderkey_rle);
  ib_trx_t ib_trx = ib_trx_begin(IB_TRX_REPEATABLE_READ);
  err = ib_cursor_open_table(cstore_l6_orderkey_rle, ib_trx, &crsr);
  if (err != DB_SUCCESS) { std::cout << ib_strerror(err) << " " << cstore_l6_orderkey_rle << std::endl; }
  err = ib_cursor_open_index_using_name(crsr, "SECONDARY_KEY", &index_crsr);
  if (err != DB_SUCCESS) { std::cout << ib_strerror(err) << std::endl; }

  ib_cursor_set_cluster_access(index_crsr);
  ib_tpl_t key = ib_sec_search_tuple_create(index_crsr);
  ib_tuple_write_u32(key, 0, 330575);
  int res;
  err = ib_cursor_moveto(index_crsr, key, IB_CUR_GE, &res);
  std::cout << "res: " << res << std::endl;
  assert(err == DB_SUCCESS || err == DB_END_OF_INDEX || err == DB_RECORD_NOT_FOUND);
  tpl = ib_clust_read_tuple_create(crsr);
  while (err == DB_SUCCESS) {
    err = ib_cursor_read_row(index_crsr, tpl);
    if (err == DB_RECORD_NOT_FOUND || err == DB_END_OF_INDEX) {
      std::cerr << "not found" << std::endl;
    }
    ib_u32_t orderkey, pos, freq;
    ib_tuple_read_u32(tpl, 0, &orderkey);
    ib_tuple_read_u32(tpl, 1, &pos);
    ib_tuple_read_u32(tpl, 2, &freq);
    std::cout << "orderkey: " << orderkey << ", pos: " << pos << ", freq: " << freq << std::endl;
    err = ib_cursor_next(index_crsr);
    tpl = ib_tuple_clear(tpl);
    break;
  }
  ib_cursor_close(index_crsr); 
  ib_cursor_close(crsr); 
  ib_trx_commit(ib_trx);

  fin_db();

  return 0;
}
Example #7
0
/*********************************************************************
Open a table and return a cursor for the table. */
static
ib_err_t
open_table(
/*=======*/
	const char*	dbname,		/*!< in: database name */
	const char*	name,		/*!< in: table name */
	ib_trx_t	ib_trx,		/*!< in: transaction */
	ib_crsr_t*	crsr)		/*!< out: innodb cursor */
{
	ib_err_t	err = DB_SUCCESS;
	char		table_name[IB_MAX_TABLE_NAME_LEN];

#ifdef __WIN__
	sprintf(table_name, "%s/%s", dbname, name);
#else
	snprintf(table_name, sizeof(table_name), "%s/%s", dbname, name);
#endif
	err = ib_cursor_open_table(table_name, ib_trx, crsr);
	assert(err == DB_SUCCESS);

	return(err);
}
Example #8
0
int main(int argc,char **argv){
    if(argc != 2){
        printf("give me a database\table name\n");
        return 1;
    }
    char *dtname=argv[1];
    
    ib_err_t err;
    err=ib_init();
    if(err != DB_SUCCESS){
        puts(ib_strerror(err));
        return err;
    }
    
    err = ib_cfg_set_int("log_buffer_size", 8*1024*1024);
    if(err != DB_SUCCESS){
        puts(ib_strerror(err));
        return err;
    }
    err = ib_cfg_set_int("force_recovery", 1);
    if(err != DB_SUCCESS){
        puts(ib_strerror(err));
        return err;
    }
    err = ib_cfg_set_int("log_file_size", 128*1024*1024);
    if(err != DB_SUCCESS){
        puts(ib_strerror(err));
        return err;
    }
    err = ib_cfg_set_int("log_files_in_group", 3);
    if(err != DB_SUCCESS){
        puts(ib_strerror(err));
        return err;
    }
    err = ib_cfg_set_text("log_group_home_dir", "./");
    //err = ib_cfg_set_text("log_group_home_dir", "/var/lib/mysql/");
    if(err != DB_SUCCESS){
        puts(ib_strerror(err));
        return err;
    }
    err = ib_cfg_set_text("data_home_dir", "./");
    if(err != DB_SUCCESS){
        puts(ib_strerror(err));
        return err;
    }
    err = ib_cfg_set_text("data_file_path", "ibdata1:500M:autoextend");
    if(err != DB_SUCCESS){
        puts(ib_strerror(err));
        return err;
    }
    err = ib_cfg_set_bool_on("file_per_table");
    if(err != DB_SUCCESS){
        puts(ib_strerror(err));
        return err;
    }

    err=ib_startup("Antelope");
    if(err != DB_SUCCESS){
        puts(ib_strerror(err));
        return err;
    }

    ib_trx_t trx;
    ib_crsr_t crsr;
    trx=ib_trx_begin(IB_TRX_REPEATABLE_READ);
    assert(trx != NULL);
    err=ib_cursor_open_table(dtname,trx,&crsr);
    if(err != DB_SUCCESS){
        puts(ib_strerror(err));
        return err;
    }
    ib_tpl_t tpl;
    tpl=ib_clust_read_tuple_create(crsr);
    assert(tpl != NULL);
    
    err=ib_cursor_first(crsr);
    while(err == DB_SUCCESS){
        err=ib_cursor_read_row(crsr,tpl);
        print_tuple(stdout,tpl);
        err=ib_cursor_next(crsr);
        tpl=ib_tuple_clear(tpl);
    }
    ib_tuple_delete(tpl); 
    err=ib_cursor_close(crsr);
    if(err != DB_SUCCESS){
        puts(ib_strerror(err));
        return err;
    }
    err=ib_trx_commit(trx);
    if(err != DB_SUCCESS){
        puts(ib_strerror(err));
        return err;
    }
    
    err=ib_shutdown(IB_SHUTDOWN_NORMAL);
    if(err != DB_SUCCESS){
        puts(ib_strerror(err));
        return err;
    }
    return 0;
}
Example #9
0
void q3(void)
{
  char *l1_shipdate_rle = "l1_shipdate_rle";
  char *l1_extendedprice_uncompressed = "l1_extendedprice_uncompressed";
  char *l3_orderdate_rle = "l3_orderdate_rle";
  char *l3_custkey_uncompressed = "l3_custkey_uncompressed";
  char *l3_orderkey_uncompressed = "l3_orderkey_uncompressed";
  char *l5_customer_key_rle = "l5_customer_key_rle";
  char *l5_nationkey_uncompressed = "l5_nationkey_uncompressed";
  char *l6_orderkey_rle = "l6_orderkey_rle";
  char *l6_extendedprice_uncompressed = "l6_extendedprice_uncompressed";
  char *l6_shipdate_uncompressed = "l6_shipdate_uncompressed";
  char *ji_l3_l1 = "ji_l3-l1";

  char cstore_l1_shipdate_rle[64];
  char cstore_l1_extendedprice_uncompressed[64];
  char cstore_l3_orderdate_rle[64];
  char cstore_l3_custkey_uncompressed[64];
  char cstore_l3_orderkey_uncompressed[64];
  char cstore_l5_customer_key_rle[64];
  char cstore_l5_nationkey_uncompressed[64];
  char cstore_l6_orderkey_rle[64];
  char cstore_l6_extendedprice_uncompressed[64];
  char cstore_l6_shipdate_uncompressed[64];
  char cstore_ji_l3_l1[64];
  sprintf(cstore_l1_shipdate_rle, "%s/%s", db_name, l1_shipdate_rle);
  sprintf(cstore_l1_extendedprice_uncompressed, "%s/%s", db_name, l1_extendedprice_uncompressed);
  sprintf(cstore_l3_orderdate_rle, "%s/%s", db_name, l3_orderdate_rle);
  sprintf(cstore_l3_custkey_uncompressed, "%s/%s", db_name, l3_custkey_uncompressed);
  sprintf(cstore_l3_orderkey_uncompressed, "%s/%s", db_name, l3_orderkey_uncompressed);
  sprintf(cstore_l5_customer_key_rle, "%s/%s", db_name, l5_customer_key_rle);
  sprintf(cstore_l5_nationkey_uncompressed, "%s/%s", db_name, l5_nationkey_uncompressed);
  sprintf(cstore_l6_orderkey_rle, "%s/%s", db_name, l6_orderkey_rle);
  sprintf(cstore_l6_extendedprice_uncompressed, "%s/%s", db_name, l6_extendedprice_uncompressed);
  sprintf(cstore_l6_shipdate_uncompressed, "%s/%s", db_name, l6_shipdate_uncompressed);
  sprintf(cstore_ji_l3_l1, "%s/%s", db_name, ji_l3_l1);

  double t0 = gettimeofday_sec();
  ib_err_t err;
  //ib_crsr_t crsr_l1_s, crsr_l1_e, crsr_l3_o, crsr_l3_c, crsr_l5_c, crsr_l5_n, crsr_ji;

  ib_trx_t ib_trx = ib_trx_begin(IB_TRX_REPEATABLE_READ);
  err = ib_cursor_open_table(cstore_l1_shipdate_rle, ib_trx, &crsr_l1_s);
  if (err != DB_SUCCESS) { std::cout << ib_strerror(err) << " " << cstore_l1_shipdate_rle << std::endl; }
  err = ib_cursor_open_table(cstore_l1_extendedprice_uncompressed, ib_trx, &crsr_l1_e);
  if (err != DB_SUCCESS) { std::cout << ib_strerror(err) << " " << cstore_l1_extendedprice_uncompressed << std::endl; }
  err = ib_cursor_open_table(cstore_l3_orderdate_rle, ib_trx, &crsr_l3_o);
  if (err != DB_SUCCESS) { std::cout << ib_strerror(err) << " " << cstore_l3_orderdate_rle << std::endl; }
  err = ib_cursor_open_table(cstore_l3_custkey_uncompressed, ib_trx, &crsr_l3_c);
  if (err != DB_SUCCESS) { std::cout << ib_strerror(err) << " " << cstore_l3_custkey_uncompressed << std::endl; }
  err = ib_cursor_open_table(cstore_l3_orderkey_uncompressed, ib_trx, &crsr_l3_ok);
  if (err != DB_SUCCESS) { std::cout << ib_strerror(err) << " " << cstore_l3_orderkey_uncompressed << std::endl; }
  err = ib_cursor_open_table(cstore_l5_customer_key_rle, ib_trx, &crsr_l5_c);
  if (err != DB_SUCCESS) { std::cout << ib_strerror(err) << " " << cstore_l5_customer_key_rle << std::endl; }
  err = ib_cursor_open_table(cstore_l5_nationkey_uncompressed, ib_trx, &crsr_l5_n);
  if (err != DB_SUCCESS) { std::cout << ib_strerror(err) << " " << cstore_l5_nationkey_uncompressed << std::endl; }
  err = ib_cursor_open_table(cstore_l6_orderkey_rle, ib_trx, &crsr_l6_o);
  if (err != DB_SUCCESS) { std::cout << ib_strerror(err) << " " << cstore_l6_orderkey_rle << std::endl; }
  err = ib_cursor_open_table(cstore_l6_extendedprice_uncompressed, ib_trx, &crsr_l6_e);
  if (err != DB_SUCCESS) { std::cout << ib_strerror(err) << " " << cstore_l6_extendedprice_uncompressed << std::endl; }
  err = ib_cursor_open_table(cstore_l6_shipdate_uncompressed, ib_trx, &crsr_l6_s);
  if (err != DB_SUCCESS) { std::cout << ib_strerror(err) << " " << cstore_l6_shipdate_uncompressed << std::endl; }
  err = ib_cursor_open_table(cstore_ji_l3_l1, ib_trx, &crsr_ji);
  if (err != DB_SUCCESS) { std::cout << ib_strerror(err) << " " << cstore_ji_l3_l1 << std::endl; }

  tpl_l1_s = ib_clust_read_tuple_create(crsr_l1_s);
  tpl_l1_e = ib_clust_read_tuple_create(crsr_l1_e);
  tpl_l3_o = ib_clust_read_tuple_create(crsr_l3_o);
  tpl_l3_c = ib_clust_read_tuple_create(crsr_l3_c);
  tpl_l3_ok = ib_clust_read_tuple_create(crsr_l3_ok);
  tpl_l5_c = ib_clust_read_tuple_create(crsr_l5_c);
  tpl_l5_n = ib_clust_read_tuple_create(crsr_l5_n);
  tpl_l6_o = ib_clust_read_tuple_create(crsr_l6_o);
  tpl_l6_e = ib_clust_read_tuple_create(crsr_l6_e);
  tpl_l6_s = ib_clust_read_tuple_create(crsr_l6_s);
  tpl_ji = ib_clust_read_tuple_create(crsr_ji);

  ib_tpl_t key = ib_clust_search_tuple_create(crsr_l3_o);
  ib_tuple_write_u32(key, 0, pred_o_orderdate);
  int res;
  // move cursor
  //err = ib_cursor_moveto(l3_o, key, IB_CUR_L, &res);
  err = ib_cursor_first(crsr_l3_o);
  ib_tuple_delete(key);
  if (err == DB_SUCCESS) {
    //std::cout << "success" << std::endl;
  } else {
    std::cout << "failed" << std::endl;
    ib_cursor_close(crsr_l3_o); 
    return;
  }

  while (err == DB_SUCCESS) {
    err = ib_cursor_read_row(crsr_l3_o, tpl_l3_o);

    /* Possible handle locking and timeout errors too in multi-threaded applications. */
    if (err == DB_RECORD_NOT_FOUND || err == DB_END_OF_INDEX) {
      break;
    }
    ib_u32_t orderdate, pos, freq;
    ib_tuple_read_u32(tpl_l3_o, 0, &orderdate);
    if (orderdate >= pred_o_orderdate) { break; }
    ib_tuple_read_u32(tpl_l3_o, 1, &pos);
    ib_tuple_read_u32(tpl_l3_o, 2, &freq);

    double t1 = gettimeofday_sec();
    // get L3 o_custkey from position filtering
    std::vector<im_val_t> pos_custkey_array = get_l3_custkeys_from_sequences(pos, freq);
    std::sort(pos_custkey_array.begin(), pos_custkey_array.end(), val_asc);
    /*
    for (int i = 0; i < pos_custkey_array.size(); ++i) {
      std::cout << pos_custkey_array[i].pos << ": " << pos_custkey_array[i].val << std::endl;
    }
    */
    double t2 = gettimeofday_sec();
    std::cout << "orderdate: " << pred_o_orderdate << " get_l3_custkeys_from_sequences: " << t2 - t1 << std::endl;

    // join with L5 and apply c_nationkey predicate
    //std::vector<uint32_t> pos_array = apply_l5_predicate(pos_custkey_array);
    std::vector<uint32_t> pos_array = apply_l5_predicate_scan(pos_custkey_array);
    /*
    for (int i = 0; i < pos_array.size(); ++i) {
      std::cout << "pos: " << pos_array[i] << std::endl;
    }
    */
    double t3 = gettimeofday_sec();
    std::cout << "orderdate: " << pred_o_orderdate << " apply_l5_predicate: " << t3 - t2 << std::endl;

    // get L3 o_orderkey from position filtring
    std::vector<im_val_t> pos_orderkey_array = get_l3_orderkeys_from_positions(pos_array);
    /*
    for (int i = 0; i < pos_orderkey_array.size(); ++i) {
      std::cout << pos_orderkey_array[i].pos << ": " << pos_orderkey_array[i].val << std::endl;
    }
    */
    double t4 = gettimeofday_sec();
    std::cout << "orderdate: " << pred_o_orderdate << " get_l3_orderkeys_from_positions: " << t4 - t3 << std::endl;
    
    // join with L1 apply L1 l_shipdate predicate
    // TODO: we don't need orderkey if we have L3->L1 join-index (we only need positions)
    if (use_ji) {
      std::vector<im_agg_t> extendedprice_array = apply_l1_predicate_via_ji(pos_orderkey_array);
      double t5 = gettimeofday_sec();
      std::cout << "orderdate: " << pred_o_orderdate << " apply_l1_predicate(JI): " << t5 - t4 << std::endl;
    } else {
      std::sort(pos_orderkey_array.begin(), pos_orderkey_array.end(), val_asc);
      std::vector<im_agg_t> extendedprice_array = apply_l6_predicate(pos_orderkey_array);
      double t5 = gettimeofday_sec();
      std::cout << "orderdate: " << pred_o_orderdate << " apply_l6_predicate: " << t5 - t4 << std::endl;
    }

    /*
    for (int i = 0; i < extendedprice_array.size(); ++i) {
      std::cout << "orderdate: " << orderdate << ", orderkey: " << pos_orderkey_array[i].val << ", SUM(extendedprice): " << extendedprice_array[i].agg << std::endl;
    }
    */

    // here we have L3.o_orderdate, L1.l_extendedprice
    // aggratation if needed (omitted)

    err = ib_cursor_next(crsr_l3_o);

    /* Possible handle locking and timeout errors too
    *  in multi-threaded applications. */
    if (err == DB_RECORD_NOT_FOUND || err == DB_END_OF_INDEX) {
      break;
    }
    tpl_l3_o = ib_tuple_clear(tpl_l3_o);
  }
  ib_tuple_delete(tpl_l3_o);
  ib_cursor_close(crsr_l1_s);
  ib_cursor_close(crsr_l1_e);
  ib_cursor_close(crsr_l3_o); 
  ib_cursor_close(crsr_l3_c); 
  ib_cursor_close(crsr_l3_ok); 
  ib_cursor_close(crsr_l5_c); 
  ib_cursor_close(crsr_l5_n); 
  ib_cursor_close(crsr_l6_o); 
  ib_cursor_close(crsr_l6_e); 
  ib_cursor_close(crsr_l6_s); 
  ib_cursor_close(crsr_ji); 
  ib_trx_commit(ib_trx);
  double t6 = gettimeofday_sec();
  std::cout << "orderdate: " << pred_o_orderdate << " total:" << t6-t0 << std::endl;
}