/**
 * Delete an item from the cache
 * @param key the key of the item to delete
 * @param nkey the length of the key
 * @return true if the item was deleted from the cache
 */
bool delete_item(const void* key, size_t nkey) {
  ib_trx_t transaction= ib_trx_begin(IB_TRX_REPEATABLE_READ);

  bool ret= do_delete_item(transaction, key, nkey);

  if (ret)
  {
    /* object found. commit transaction */
    ib_err_t error= ib_trx_commit(transaction);
    if (error != DB_SUCCESS)
    {
      fprintf(stderr, "Failed to delete key:\n\t%s\n",
              ib_strerror(error));
      ret= false;
    }
  }
  else
  {
    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));
  }

  return ret;
}
/**
 * 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));
}
Exemple #3
0
bool init_db(void)
{
  ib_err_t err;
  /* Initialize the memory sub-system. */
  ib_init();

  /* Call the ib_cfg_*() functions to setup the directory etc. */
  err = ib_cfg_set_bool_off("adaptive_hash_index");
  err = ib_cfg_set_int("additional_mem_pool_size", 16*1024*1024);
  err = ib_cfg_set_int("buffer_pool_size", 1024*1024*1024);
  err = ib_cfg_set_int("flush_log_at_trx_commit", 2);
  err = ib_cfg_set_int("log_buffer_size", 8*1024*1024);
  err = ib_cfg_set_int("log_file_size", 256*1024*1024);
  err = ib_cfg_set_text("data_home_dir", "/data/");
  err = ib_cfg_set_text("log_group_home_dir", "/data/");
  err = ib_cfg_set_text("flush_method", "O_DIRECT");

  /* Create system files if this is the first time
   * or do recovery if starting an existing instance. */
  err = ib_startup("barracuda");
  /* File format "barracuda" supports all
   * the currently available table formats. */

  if (err == DB_SUCCESS) {
    printf("InnoDB started!\n");
  } else {
    printf("Error starting up InnoDB: %s\n", ib_strerror(err));
    return false;
  }
  return true;
}
/**
 * Initialize the database storage
 * @return true if the database was initialized successfully, false otherwise
 */
bool initialize_storage(void) 
{
  ib_err_t error;
  ib_id_t tid;

  checked(ib_init());
  checked(ib_cfg_set_text("data_home_dir", "/tmp/memcached_light"));
  checked(ib_cfg_set_text("log_group_home_dir", "/tmp/memcached_light"));
  checked(ib_cfg_set_bool_on("file_per_table"));
  checked(ib_startup("barracuda"));

  /* check to see if the table exists or if we should create the schema */
  error= ib_table_get_id(tablename, &tid);
  if (error == DB_TABLE_NOT_FOUND) 
  {
    if (!create_schema()) 
    {
      return false;
    }
  } 
  else if (error != DB_SUCCESS) 
  {
    fprintf(stderr, "Failed to get table id: %s\n", ib_strerror(error));
    return false;
  }

  return true;

 error_exit:

  return false;
}
Exemple #5
0
static void innostore_drv_finish()
{
    erl_drv_mutex_destroy(G_ENGINE_STATE_LOCK);

    // Shutdown the engine, if it's running -- note that this blocks the
    // the calling VM thread and may be a long running operation.
    if (G_ENGINE_STATE == ENGINE_STARTED)
    {
        ib_err_t result = ib_shutdown(IB_SHUTDOWN_NORMAL);
        if (result != DB_SUCCESS)
        {
            log("ib_shutdown failed: %s\n", ib_strerror(result));
        }
    }

    // Clean up logging after inno has shutdown completely
    erl_drv_mutex_destroy(G_LOGGER_LOCK); 
    if (G_LOGGER_BUF != NULL)
    {
        driver_free(G_LOGGER_BUF);
        G_LOGGER_BUF = NULL;
        G_LOGGER_SIZE = 0;
    }
    if (G_LOGGER_FH != NULL)
    {
        fclose(G_LOGGER_FH);
        G_LOGGER_FH = NULL;
        G_LOGGER_FN = raw_logger;
    }

    G_ENGINE_STATE = ENGINE_STOPPED;
}
Exemple #6
0
/*********************************************************************
CREATE TABLE T(C1 INT, C2 VARCHAR(10), C3 BLOB); */
static
ib_err_t
create_table(
/*=========*/
	const char*	dbname,			/*!< in: database name */
	const char*	name)			/*!< in: table name */
{
	ib_trx_t	ib_trx;
	ib_id_t		table_id = 0;
	ib_err_t	err = DB_SUCCESS;
	ib_tbl_sch_t	ib_tbl_sch = NULL;
	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

	/* Pass a table page size of 0, ie., use default page size. */
	err = ib_table_schema_create(
		table_name, &ib_tbl_sch, IB_TBL_COMPACT, 0);

	assert(err == DB_SUCCESS);

	err = ib_table_schema_add_col(
		ib_tbl_sch, "c1", IB_INT, IB_COL_NONE, 0, sizeof(ib_i32_t));

	assert(err == DB_SUCCESS);

	err = ib_tbl_sch_add_varchar_col(ib_tbl_sch, "c2", 10);
	assert(err == DB_SUCCESS);

	err = ib_tbl_sch_add_blob_col(ib_tbl_sch, "c3");
	assert(err == DB_SUCCESS);

	/* create table */
	ib_trx = ib_trx_begin(IB_TRX_REPEATABLE_READ);
	err = ib_schema_lock_exclusive(ib_trx);
	assert(err == DB_SUCCESS);

	err = ib_table_create(ib_trx, ib_tbl_sch, &table_id);

	if (err == DB_SUCCESS) {
		err = ib_trx_commit(ib_trx);
	} else {
		fprintf(stderr, "Table: %s create failed: %s\n",
				table_name, ib_strerror(err));

		err = ib_trx_rollback(ib_trx);
	}
	assert(err == DB_SUCCESS);

	if (ib_tbl_sch != NULL) {
		ib_table_schema_delete(ib_tbl_sch);
	}

	return(err);
}
Exemple #7
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;
}
Exemple #8
0
bool fin_db(void)
{
  ib_err_t err = ib_shutdown(IB_SHUTDOWN_NORMAL);
  if (err == DB_SUCCESS) {
      printf("InnoDB shutdown succeed!\n");
  } else {
      printf("InnoDB shutdown failed: err %s\n", ib_strerror(err));
  }
}
/**
 * Store an item in the databse
 *
 * @param item the item to store
 */
void put_item(struct item* item) 
{
  ib_trx_t transaction= ib_trx_begin(IB_TRX_SERIALIZABLE);
  if (do_put_item(transaction, item)) 
  {
    ib_err_t error= ib_trx_commit(transaction);
    if (error != DB_SUCCESS) 
    {
      fprintf(stderr, "Failed to store key:\n\t%s\n",
              ib_strerror(error));
    }
  } 
  else 
  {
    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));
  }
}
Exemple #10
0
static void do_start(void* arg)
{
    PortState* state = (PortState*)arg;

    erl_drv_mutex_lock(G_ENGINE_STATE_LOCK);
    if (G_ENGINE_STATE == ENGINE_STOPPED)
    {
        // Engine was stopped; set the flag, unlock and run the start
        G_ENGINE_STATE = ENGINE_STARTING;
        erl_drv_mutex_unlock(G_ENGINE_STATE_LOCK);

        // Run the startup without holding any lock -- this can take a while
        // if we are recovering from previous errors
        ib_err_t error = ib_startup("barracuda");

        if (error == DB_SUCCESS)
        {
            // Make sure the innokeystore database exists
            // TODO: Avoid hard-coding the db name here...
            if (ib_database_create("innokeystore") != IB_TRUE)
            {
                error = DB_ERROR;
            }
        }

        // Relock and sort out results
        erl_drv_mutex_lock(G_ENGINE_STATE_LOCK);
        if (error == DB_SUCCESS)
        {
            G_ENGINE_STATE = ENGINE_STARTED;
            send_ok(state);
        }
        else
        {
            G_ENGINE_STATE = ENGINE_STOPPED;
            send_error_str(state, ib_strerror(error));
        }
    }
    else if (G_ENGINE_STATE == ENGINE_STARTED)
    {
        // another thread has already completed startup
        send_ok(state);
    }
    else
    {
        // Engine was not in stopped state when do_start was called.
        // Probably due to multiple threads trying to start at the
        // same time.
        assert(G_ENGINE_STATE == ENGINE_STARTING);
        send_error_atom(state, "starting");        
    }

    erl_drv_mutex_unlock(G_ENGINE_STATE_LOCK);
}
/**
 * Get an item from the engine
 * @param key the key to grab
 * @param nkey number of bytes in the key
 * @return pointer to the item if found
 */
struct item* get_item(const void* key, size_t nkey) 
{
  ib_trx_t transaction= ib_trx_begin(IB_TRX_SERIALIZABLE);
  struct item* ret= do_get_item(transaction, key, nkey);
  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));

  return ret;
}
Exemple #12
0
std::vector<uint32_t>
apply_l5_predicate_scan(std::vector<im_val_t> pos_custkey_array)
{
  ib_err_t err;
  std::vector<uint32_t> pos_array;
  ib_crsr_t index_crsr;
  err = ib_cursor_open_index_using_name(crsr_l5_c, "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_l5_c = ib_sec_search_tuple_create(index_crsr);
  ib_tpl_t key_l5_n = ib_clust_search_tuple_create(crsr_l5_n);
  size_t size = pos_custkey_array.size();
  int res;
  // TODO: first fetches all l5_pos for custkeys
  std::vector<uint32_t> l5_pos_array;
  for (int i = 0; i < size; ++i) {
    // custkey
    ib_tuple_write_u32(key_l5_c, 0, pos_custkey_array[i].val);
    err = ib_cursor_moveto(index_crsr, key_l5_c, IB_CUR_GE, &res);
    if (err != DB_SUCCESS) {
      std::cout << "failed moving cursor for l5_c" << std::endl;
    }
    err = ib_cursor_read_row(index_crsr, tpl_l5_c);
    if (err == DB_RECORD_NOT_FOUND || err == DB_END_OF_INDEX) {
    }
    ib_u32_t l5_pos;
    ib_tuple_read_u32(tpl_l5_c, 1, &l5_pos);
    l5_pos_array.push_back(l5_pos);
    tpl_l5_c = ib_tuple_clear(tpl_l5_c);
  }
  for (int i = 0; i < size; ++i) {
    ib_tuple_write_u32(key_l5_n, 0, l5_pos_array[i]);
    err = ib_cursor_moveto(crsr_l5_n, key_l5_n, IB_CUR_GE, &res);
    if (err != DB_SUCCESS) {
      std::cout << "failed moving cursor for l5_c" << std::endl;
    }
    if (res == 0) {
      err = ib_cursor_read_row(crsr_l5_n, tpl_l5_n);
      ib_u32_t c_nationkey;
      ib_tuple_read_u32(tpl_l5_n, 1, &c_nationkey);
      if (c_nationkey == pred_c_nationkey) {
        pos_array.push_back(pos_custkey_array[i].pos);
      }
    }
    tpl_l5_n = ib_tuple_clear(tpl_l5_n);
  }
  ib_tuple_delete(key_l5_c);
  ib_tuple_delete(key_l5_n);
  ib_cursor_close(index_crsr);
  return pos_array;
}
/**
 * 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;
}
Exemple #14
0
static void do_get(void* arg)
{
    PortState* state = (PortState*)arg;

    // Unpack key from work buffer
    // table - 8 bytes
    // keysz - 1 byte
    // key   - variable
    ib_id_t table      ; UNPACK_INT(state->work_buffer, 0, &table);
    unsigned char keysz = UNPACK_BYTE(state->work_buffer, sizeof(table));
    char* key          = UNPACK_BLOB(state->work_buffer, sizeof(table)+1);

    ib_trx_t txn = ib_trx_begin(IB_TRX_REPEATABLE_READ);

    ib_crsr_t cursor;
    FAIL_ON_ERROR(ib_cursor_open_table_using_id(table, txn, &cursor),
                  ROLLBACK_RETURN(txn));

    ib_tpl_t key_tuple = ib_clust_search_tuple_create(cursor);
    ib_col_set_value(key_tuple, KEY_COL, key, keysz);

    int searchloc;
    ib_err_t error = ib_cursor_moveto(cursor, key_tuple, IB_CUR_GE, &searchloc);

    // Drop the key tuple -- cursor is at desired location
    ib_tuple_delete(key_tuple);

    // If we encountered an error, bail
    if (error != DB_SUCCESS && error != DB_RECORD_NOT_FOUND && error != DB_END_OF_INDEX)
    {
        ib_cursor_close(cursor);
        send_error_str(state, ib_strerror(error));
        ROLLBACK_RETURN(txn);
    }

    // Found it, read the value and send back to caller
    if (searchloc == 0)
    {
        ib_tpl_t tuple = ib_clust_read_tuple_create(cursor);

        // TODO: May need better error handling here
        FAIL_ON_ERROR(ib_cursor_read_row(cursor, tuple),
                      {
                          ib_tuple_delete(tuple);
                          ib_cursor_close(cursor);
                          ROLLBACK_RETURN(txn);
                      });
/**
 * Create the database schema.
 * @return true if the database schema was created without any problems
 *         false otherwise.
 */
static bool create_schema(void) 
{
  ib_tbl_sch_t schema= NULL;
  ib_idx_sch_t dbindex= NULL;

  if (ib_database_create("memcached") != IB_TRUE)
  {
    fprintf(stderr, "Failed to create database\n");
    return false;
  }

  ib_trx_t transaction= ib_trx_begin(IB_TRX_SERIALIZABLE);
  ib_id_t table_id;

  checked(ib_table_schema_create(tablename, &schema, IB_TBL_COMPACT, 0));
  checked(ib_table_schema_add_col(schema, "key", IB_BLOB,
                                  IB_COL_NOT_NULL, 0, 32767));
  checked(ib_table_schema_add_col(schema, "data", IB_BLOB,
                                  IB_COL_NONE, 0, 1024*1024));
  checked(ib_table_schema_add_col(schema, "flags", IB_INT,
                                  IB_COL_UNSIGNED, 0, 4));
  checked(ib_table_schema_add_col(schema, "cas", IB_INT,
                                  IB_COL_UNSIGNED, 0, 8));
  checked(ib_table_schema_add_col(schema, "exp", IB_INT,
                                  IB_COL_UNSIGNED, 0, 4));
  checked(ib_table_schema_add_index(schema, "PRIMARY_KEY", &dbindex));
  checked(ib_index_schema_add_col(dbindex, "key", 0));
  checked(ib_index_schema_set_clustered(dbindex));
  checked(ib_schema_lock_exclusive(transaction));
  checked(ib_table_create(transaction, schema, &table_id));
  checked(ib_trx_commit(transaction));
  ib_table_schema_delete(schema);

  return true;

 error_exit:
  /* @todo release resources! */
  {
    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));
  }
  return false;
}
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;
}
Exemple #17
0
static void do_set_cfg(void* arg)
{
    PortState* state = (PortState*)arg;

    erl_drv_mutex_lock(G_ENGINE_STATE_LOCK);
    if (G_ENGINE_STATE == ENGINE_STOPPED)
    {
        char* key   = UNPACK_STRING(state->work_buffer, 0);
        const char* value = UNPACK_STRING(state->work_buffer, strlen(key)+1);

        if (strcmp(key, "error_log") == 0)
        {
            if (set_log_file(value) == 0)
            {
                send_ok(state);
            }
            else
            {
                send_error_atom(state, "einval");
            }
        }
        else
        {
            // Check the expected type of the provided key so as to 1. validate it's a good key
            // and 2. know what setter to use.
            ib_cfg_type_t key_type;
            ib_err_t error = ib_cfg_var_get_type(key, &key_type);
            if (error == DB_SUCCESS)
            {
                if (key_type == IB_CFG_TEXT)
                {
                    // HACK: Semantics of setting a text configuration value for innodb changed
                    // to be pointer assignment (from copy) for vsn 1.0.6.6750. So, we strdup the
                    // value to ensure everything works as expected.
                    // TODO: Setup some sort of list of strdup'd values to ensure they all get
                    // cleaned up properly. In typical usage, this isn't going to be a problem
                    // as you only initialize once per run, but it bothers me just the same.
                    error = ib_cfg_set(key, strdup(value));
                }
                else
                {
                    ErlDrvUInt value_i;
                    UNPACK_INT(state->work_buffer, strlen(key)+1, &value_i);
                    error = ib_cfg_set(key, value_i);
                }

            }

            if (error == DB_SUCCESS)
            {
                send_ok(state);
            }
            else
            {
                send_error_str(state, ib_strerror(error));
            }
        }
    }
    else
    {
        send_error_atom(state, "starting");
    }

    erl_drv_mutex_unlock(G_ENGINE_STATE_LOCK);
}
Exemple #18
0
static void do_init_table(void* arg)
{
    PortState* state = (PortState*)arg;

    unsigned char fmt_code = UNPACK_BYTE(state->work_buffer, 0);
    // Unpack the table name (pre-formatted to be Database/TableName)
    char* table = UNPACK_STRING(state->work_buffer, 1);
    ib_id_t table_id;
    ib_tbl_fmt_t table_fmt;
    
    switch(fmt_code)
    {
      case FORMAT_REDUNDANT:
        table_fmt = IB_TBL_REDUNDANT;
        break;
      case FORMAT_COMPACT:
        table_fmt = IB_TBL_COMPACT;
        break;
      case FORMAT_DYNAMIC:
        table_fmt = IB_TBL_DYNAMIC;
        break;
      case FORMAT_COMPRESSED:
        table_fmt = IB_TBL_COMPRESSED;
        break;
      default:
        send_error_atom(state, "bad_format");
        return;
    }

    // If the table doesn't exist, create it
    if (ib_table_get_id(table, &table_id) != DB_SUCCESS)
    {
        // Start a txn for schema access and be sure to make it serializable
        ib_trx_t txn = ib_trx_begin(IB_TRX_SERIALIZABLE);
        ib_schema_lock_exclusive(txn);

        // Create the table schema
        ib_tbl_sch_t schema;
        ib_table_schema_create(table, &schema, table_fmt, 0);
        ib_table_schema_add_col(schema, "key", IB_VARBINARY, IB_COL_NONE, 0, 255);
        ib_table_schema_add_col(schema, "value", IB_BLOB, IB_COL_NONE, 0, 0);

        // Create primary index on key
        ib_idx_sch_t index;
        ib_table_schema_add_index(schema, "PRIMARY_KEY", &index);
        ib_index_schema_add_col(index, "key", 0);
        ib_index_schema_set_clustered(index);

        // Create the actual table
        ib_err_t rc = ib_table_create(txn, schema, &table_id);

        // Release the schema -- doesn't matter if table was created or not at this point
        ib_schema_unlock(txn);

        if (rc == DB_SUCCESS)
        {
            // Commit changes to schema (if any)
            ib_trx_commit(txn);
        }
        else
        {
            // Failed to create table -- rollback and exit
            ib_trx_rollback(txn);
            send_error_str(state, ib_strerror(rc));
            return;
        }
    }

    // Guaranteed at this point to have a valid table_id
    ErlDrvTermData response[] = { ERL_DRV_ATOM,   driver_mk_atom("innostore_ok"),
                                  ERL_DRV_BUF2BINARY, (ErlDrvTermData)&table_id,
                                                      (ErlDrvUInt)sizeof(table_id),
                                  ERL_DRV_TUPLE, 2};
    driver_send_term(state->port, state->port_owner, response,
                     sizeof(response) / sizeof(response[0]));
}
Exemple #19
0
/*********************************************************************
CREATE TABLE T(
	vchar	VARCHAR(128),
	blob	VARCHAR(n),
	count	INT,
	PRIMARY KEY(vchar); */
static
ib_err_t
create_table(
/*=========*/
	const char*	dbname,			/*!< in: database name */
	const char*	name)			/*!< in: table name */
{
	ib_trx_t	ib_trx;
	ib_id_t		table_id = 0;
	ib_err_t	err = DB_SUCCESS;
	ib_tbl_sch_t	ib_tbl_sch = NULL;
	ib_idx_sch_t	ib_idx_sch = NULL;
	ib_tbl_fmt_t	tbl_fmt = IB_TBL_COMPACT;
	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

	if (page_size > 0) {
		tbl_fmt = IB_TBL_COMPRESSED;

		printf("Creating compressed table with page size %d\n",
			page_size);
	}

	err = ib_table_schema_create(
		table_name, &ib_tbl_sch, tbl_fmt, page_size);

	assert(err == DB_SUCCESS);

	err = ib_table_schema_add_col(
		ib_tbl_sch, "vchar",
		IB_VARCHAR, IB_COL_NONE, 0, 128);
	assert(err == DB_SUCCESS);

	err = ib_table_schema_add_col(
		ib_tbl_sch, "blob",
		IB_BLOB, IB_COL_NONE, 0, 0);
	assert(err == DB_SUCCESS);

	err = ib_table_schema_add_col(
		ib_tbl_sch, "count",
		IB_INT, IB_COL_UNSIGNED, 0, 4);

	assert(err == DB_SUCCESS);

	err = ib_table_schema_add_index(ib_tbl_sch, "PRIMARY", &ib_idx_sch);
	assert(err == DB_SUCCESS);

	/* Set prefix length to 0. */
	err = ib_index_schema_add_col( ib_idx_sch, "vchar", 0);
	assert(err == DB_SUCCESS);

	err = ib_index_schema_set_clustered(ib_idx_sch);
	assert(err == DB_SUCCESS);

	err = ib_index_schema_set_unique(ib_idx_sch);
	assert(err == DB_SUCCESS);

	/* create table */
	ib_trx = ib_trx_begin(IB_TRX_REPEATABLE_READ);
	err = ib_schema_lock_exclusive(ib_trx);
	assert(err == DB_SUCCESS);

	err = ib_table_create(ib_trx, ib_tbl_sch, &table_id);
	if (err != DB_SUCCESS) {
		fprintf(stderr, "Warning: table create failed: %s\n",
				ib_strerror(err));
		err = ib_trx_rollback(ib_trx);
	} else {
		err = ib_trx_commit(ib_trx);
	}
	assert(err == DB_SUCCESS);

	if (ib_tbl_sch != NULL) {
		ib_table_schema_delete(ib_tbl_sch);
	}

	return(err);
}
Exemple #20
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;
}
Exemple #21
0
std::vector<im_agg_t>
apply_l6_predicate(std::vector<im_val_t> pos_orderkey_array)
{
  ib_err_t err;
  std::vector<im_agg_t> extendedprice_array;
  ib_crsr_t index_crsr;
  err = ib_cursor_open_index_using_name(crsr_l6_o, "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_l6_o = ib_sec_search_tuple_create(index_crsr);
  ib_tpl_t key_l6_s = ib_clust_search_tuple_create(crsr_l6_s);
  ib_tpl_t key_l6_e = ib_clust_search_tuple_create(crsr_l6_e);
  size_t size = pos_orderkey_array.size();
  int res;
  for (int i = 0; i < size; ++i) {
    uint32_t sum_extendedprice = 0;
    ib_tuple_write_u32(key_l6_o, 0, pos_orderkey_array[i].val);
    err = ib_cursor_moveto(index_crsr, key_l6_o, IB_CUR_GE, &res);
    if (err != DB_SUCCESS) {
      std::cout << "failed moving cursor for index_crsr" << std::endl;
    }
    err = ib_cursor_read_row(index_crsr, tpl_l6_o);
    if (err == DB_RECORD_NOT_FOUND || err == DB_END_OF_INDEX) {
    }
    ib_u32_t orderkey, pos, freq;
    ib_tuple_read_u32(tpl_l6_o, 0, &orderkey);
    ib_tuple_read_u32(tpl_l6_o, 1, &pos);
    ib_tuple_read_u32(tpl_l6_o, 2, &freq);
    //std::cout << "orderkey: " << orderkey << ", pos: " << pos << ", freq: " << freq << std::endl;
    if (orderkey != pos_orderkey_array[i].val) {
      break;
    }
    tpl_l6_o = ib_tuple_clear(tpl_l6_o);

    for (int i = pos; i < pos + freq; ++i) {
      ib_tuple_write_u32(key_l6_s, 0, i);
      err = ib_cursor_moveto(crsr_l6_s, key_l6_s, IB_CUR_GE, &res);
      if (err != DB_SUCCESS) {
        std::cout << "failed moving cursor for l6_s" << std::endl;
      }
      err = ib_cursor_read_row(crsr_l6_s, tpl_l6_s);
      ib_u32_t shipdate;
      ib_tuple_read_u32(tpl_l6_s, 1, &shipdate);
      //std::cout << "shipdate: " << shipdate << std::endl;
      if (shipdate > pred_l_shipdate) {
        ib_tuple_write_u32(key_l6_e, 0, i);
        err = ib_cursor_moveto(crsr_l6_e, key_l6_e, IB_CUR_GE, &res);
        if (err != DB_SUCCESS) {
          std::cout << "failed moving cursor for l6_e" << std::endl;
        }
        err = ib_cursor_read_row(crsr_l6_e, tpl_l6_e);
        ib_u32_t extendedprice;
        ib_tuple_read_u32(tpl_l6_e, 1, &extendedprice);
        sum_extendedprice += extendedprice;
        tpl_l6_e = ib_tuple_clear(tpl_l6_e);
      }
      tpl_l6_s = ib_tuple_clear(tpl_l6_s);
    }
    im_agg_t im_agg = {sum_extendedprice};
    extendedprice_array.push_back(im_agg);
  }
  ib_tuple_delete(key_l6_o);
  ib_tuple_delete(key_l6_e);
  ib_tuple_delete(key_l6_s);
  ib_cursor_close(index_crsr);

  return extendedprice_array;
}