Beispiel #1
0
void tc_Error_SetBDB(TCBDB *bdb) {
  log_trace("ENTER");
  int ecode = tcbdbecode(bdb);
  if (ecode == TCENOREC) {
    PyErr_SetString(PyExc_KeyError, tcbdberrmsg(ecode));
  } else {
    tc_Error_SetCodeAndString(ecode, tcbdberrmsg(ecode));
  }
}
Beispiel #2
0
int main(int argc, char **argv){

  if (argc != 3) {
    std::cerr << "Usage: " << argv[0] << " dbname record_num" << std::endl; 
    exit(1);
  }

  double t1, t2;
  int rnum = atoi(argv[2]);
  int ecode;
  char *key, *value;

  t1 = gettimeofday_sec();
  TCBDB *bdb = tcbdbnew();
  tcbdbtune(bdb, 5, -1, -1, -1, -1, 0);
  tcbdbsetcache(bdb, 300, 100);

  if (!tcbdbopen(bdb, argv[1], BDBOWRITER | BDBOCREAT)) {
    ecode = tcbdbecode(bdb);
    fprintf(stderr, "open error: %s\n", tcbdberrmsg(ecode));
  }

  for (int i = 0; i < rnum; ++i) {
    char key[9];
    memset(key, 0, 9);
    sprintf(key,"%08d", i);
    char *val = new char[307201]; // 100K
    memset(val, 0, 307201);
    sprintf(val, "%0102400d", i);
    sprintf(val + 102400, "%0102400d", i);
    sprintf(val + 102400*2, "%0102400d", i);

    int size;
    void *data = tcbdbget(bdb, key, strlen(key), &size);
    if (data != NULL) {
      if (strcmp(val, (char *) data) != 0) {
        std::cout << "[error] value incorrect." << std::endl;
      }
      free(data);
    } else {
      std::cout << "[error] entry not found." << std::endl;
    } 
    delete [] val;
  }

  if (!tcbdbclose(bdb)) {
    ecode = tcbdbecode(bdb);
    fprintf(stderr, "close error: %s\n", tcbdberrmsg(ecode));
  }
  tcbdbdel(bdb);
  t2 = gettimeofday_sec();
  std::cout << "get time: " << t2 - t1 << std::endl;

  return 0;
}
Beispiel #3
0
static int tc_txn_abort(void *vhandle) {
    dbh_t *dbh = vhandle;
    if (!dbh->dbp->wmode || tcbdbtranabort(dbh->dbp))
        return DST_OK;
    print_error(__FILE__, __LINE__, "tc_txn_abort(%p), err: %d, %s", dbh->dbp,
                tcbdbecode(dbh->dbp), tcbdberrmsg(tcbdbecode(dbh->dbp)));
    return DST_FAILURE;
}
Beispiel #4
0
/*
   Flush any data in memory to disk
*/
void db_flush(void *vhandle)
{
    dbh_t *handle = vhandle;
    TCBDB * dbp = handle->dbp;

    if (!tcbdbsync(dbp))
	print_error(__FILE__, __LINE__, "(tc) tcbdbsync err: %d, %s",
		    tcbdbecode(dbp), tcbdberrmsg(tcbdbecode(dbp)));
}
Beispiel #5
0
/* Open the database handle */
TCBDB *
tc_bdb_create (const char *dbname, int module)
{
    TCBDB *bdb;
    char *path = NULL;
    int ecode;
    uint32_t lcnum, ncnum, lmemb, nmemb, bnum, flags;

    path = tc_db_set_path (dbname, module);
    bdb = tcbdbnew ();

    lcnum = conf.cache_lcnum > 0 ? conf.cache_lcnum : TC_LCNUM;
    ncnum = conf.cache_ncnum > 0 ? conf.cache_ncnum : TC_NCNUM;

    /* set the caching parameters of a B+ tree database object */
    if (!tcbdbsetcache (bdb, lcnum, ncnum)) {
        free (path);
        FATAL ("Unable to set TCB cache");
    }

    /* set the size of the extra mapped memory */
    if (conf.xmmap > 0 && !tcbdbsetxmsiz (bdb, conf.xmmap)) {
        free (path);
        FATAL ("Unable to set TCB xmmap.");
    }

    lmemb = conf.tune_lmemb > 0 ? conf.tune_lmemb : TC_LMEMB;
    nmemb = conf.tune_nmemb > 0 ? conf.tune_nmemb : TC_NMEMB;
    bnum = conf.tune_bnum > 0 ? conf.tune_bnum : TC_BNUM;

    /* compression */
    flags = BDBTLARGE;
    if (conf.compression == TC_BZ2) {
        flags |= BDBTBZIP;
    } else if (conf.compression == TC_ZLIB) {
        flags |= BDBTDEFLATE;
    }

    /* set the tuning parameters */
    tcbdbtune (bdb, lmemb, nmemb, bnum, 8, 10, flags);

    /* open flags */
    flags = BDBOWRITER | BDBOCREAT;
    if (!conf.load_from_disk)
        flags |= BDBOTRUNC;

    /* attempt to open the database */
    if (!tcbdbopen (bdb, path, flags)) {
        free (path);
        ecode = tcbdbecode (bdb);

        FATAL ("%s", tcbdberrmsg (ecode));
    }
    free (path);

    return bdb;
}
/* ecode */
JNIEXPORT jstring JNICALL Java_tokyocabinet_BDB_errmsg
(JNIEnv *env, jclass cls, jint ecode){
  jstring jmsg = (*env)->NewStringUTF(env, tcbdberrmsg(ecode));
  if(!jmsg){
    throwoutmem(env);
    return NULL;
  }
  return jmsg;
}
Beispiel #7
0
static void
dberror(rotz_t ctx, const char *premsg)
{
	int ecode = tcbdbecode(ctx->db);

	fputs(premsg, stderr);
	fputs(tcbdberrmsg(ecode), stderr);
	fputc('\n', stderr);
	return;
}
Beispiel #8
0
static PyObject *tc_BDB_errmsg(PyTypeObject *type, PyObject *args, PyObject *keywds) {
  log_trace("ENTER");
  int ecode;
  static char *kwlist[] = {"ecode", NULL};

  if (!PyArg_ParseTupleAndKeywords(args, keywds, "i:errmsg", kwlist,
                                   &ecode)) {
    return NULL;
  }
  return PyBytes_FromString(tcbdberrmsg(ecode));
}
Beispiel #9
0
static void _tc_release_conn(mapcache_context *ctx, mapcache_tile *tile, struct tc_conn conn)
{
  if(!conn.readonly)
    tcbdbsync(conn.bdb);

  if(!tcbdbclose(conn.bdb)) {
    int ecode = tcbdbecode(conn.bdb);
    ctx->set_error(ctx,500, "tokyocabinet close error: %s\n",tcbdberrmsg(ecode));
  }
  tcbdbdel(conn.bdb);
}
Beispiel #10
0
IoObject *IoTokyoCabinetPrefixCursor_remove(IoObject *self, IoObject *locals, IoMessage *m)
{
	/*doc TokyoCabinetPrefixCursor remove
	Removes the current cursor postion. Returns self.
	*/

	IOASSERT(TokyoCabinetPrefixCursor(self), "invalid TokyoCabinetPrefixCursor");

	IOASSERT(tcbdbcurout(TokyoCabinetPrefixCursor(self)), tcbdberrmsg(tcbdbecode(TokyoCabinet(self))));

	return self;
}
Beispiel #11
0
ex_t db_foreach(void *vhandle, db_foreach_t hook, void *userdata)
{
    int ret = 0;

    dbh_t *handle = vhandle;
    TCBDB *dbp = handle->dbp;
    BDBCUR *cursor;

    dbv_t dbv_key, dbv_data;
    int ksiz, dsiz;
    char *key, *data;

    cursor = tcbdbcurnew(dbp);
    ret = tcbdbcurfirst(cursor);
    if (ret) {
	while ((key = tcbdbcurkey(cursor, &ksiz))) {
	    data = tcbdbcurval(cursor, &dsiz);
	    if (data) {
		/* switch to "dbv_t *" variables */
		dbv_key.leng = ksiz;
		dbv_key.data = xmalloc(dbv_key.leng+1);
		memcpy(dbv_key.data, key, ksiz);
		((char *)dbv_key.data)[dbv_key.leng] = '\0';

		dbv_data.data = data;
		dbv_data.leng = dsiz;		/* read count */

		/* call user function */
		ret = hook(&dbv_key, &dbv_data, userdata);

		xfree(dbv_key.data);

		if (ret != 0)
		    break;
		free(data); /* not xfree() as allocated by dpget() */
	    }
	    free(key); /* not xfree() as allocated by dpiternext() */

	    tcbdbcurnext(cursor);
	}
    } else {
	print_error(__FILE__, __LINE__, "(tc) tcbdbcurfirst err: %d, %s",
		    tcbdbecode(dbp), tcbdberrmsg(tcbdbecode(dbp)));
	exit(EX_ERROR);
    }

    tcbdbcurdel(cursor);
    return EX_OK;
}
Beispiel #12
0
/* The freelist is a btree with as key the number
   of blocks (512 bytes). The value is offset.
*/
void put_on_freelist(INUSE * inuse)
{
    unsigned long long calc;
    FUNC;
    int ecode;

    calc = round_512(inuse->size);
    calc = calc / 512;
    if (!tcbdbputdup(freelist, (void *) &calc, sizeof(unsigned long long),
                     (void *) &inuse->offset,
                     sizeof(unsigned long long))) {
        ecode = tcbdbecode(freelist);
        die_dberr("tcbdbputdup failed : %s", tcbdberrmsg(ecode));
    }
    LDEBUG("put_on_freelist : %llu blocks at offset %llu", calc,
           inuse->offset);
    EFUNC;
    return;
}
Beispiel #13
0
/*
  Initialize database.
  Returns: pointer to database handle on success, NULL otherwise.
*/
void *db_open(void * dummy, bfpath *bfp, dbmode_t open_mode)
{
    dbh_t *handle;

    bool res;
    int open_flags;
    TCBDB *dbp;

    UNUSED(dummy);

    if (open_mode & DS_WRITE)
	open_flags = BDBOWRITER;
    else
	open_flags = BDBOREADER;

    handle = dbh_init(bfp);

    if (handle == NULL) return NULL;

    dbp = handle->dbp = tcbdbnew();
    res = tcbdbopen(dbp, handle->name, open_flags);
    if (!res && (open_mode & DS_WRITE)) {
        res = tcbdbopen(dbp, handle->name, open_flags | BDBOCREAT);
        handle->created |= res;
    }

    if (!res)
	goto open_err;

    if (DEBUG_DATABASE(1))
	fprintf(dbgout, "(tc) tcbdbopen( %s, %d )\n", handle->name, open_mode);

    return handle;

 open_err:
    print_error(__FILE__, __LINE__, "(tc) tcbdbopen(%s, %d), err: %d, %s",
		handle->name, open_flags, 
		tcbdbecode(dbp), tcbdberrmsg(tcbdbecode(dbp)));
    dbh_free(handle);

    return NULL;
}
Beispiel #14
0
int db_delete(void *vhandle, const dbv_t *token)
{
    int ret;
    dbh_t *handle = vhandle;
    TCBDB *dbp;

    dbp = handle->dbp;
    ret = tcbdbout(dbp, token->data, token->leng);

    if (ret == 0) {
	print_error(__FILE__, __LINE__, "(tc) tcbdbout('%.*s'), err: %d, %s",
		    CLAMP_INT_MAX(token->leng),
		    (char *)token->data, 
		    tcbdbecode(dbp), tcbdberrmsg(tcbdbecode(dbp)));
	exit(EX_ERROR);
    }
    ret = ret ^ 1;	/* ok is 1 in qdbm and 0 in bogofilter */

    return ret;		/* 0 if ok */
}
Beispiel #15
0
static void _mapcache_cache_tc_set(mapcache_context *ctx, mapcache_tile *tile)
{
  struct tc_conn conn;
  mapcache_cache_tc *cache = (mapcache_cache_tc*)tile->tileset->cache;
  char *skey = mapcache_util_get_tile_key(ctx,tile,cache->key_template,NULL,NULL);
  apr_time_t now = apr_time_now();
  conn = _tc_get_conn(ctx,tile,0);
  GC_CHECK_ERROR(ctx);

  if(!tile->encoded_data) {
    tile->encoded_data = tile->tileset->format->write(ctx, tile->raw_image, tile->tileset->format);
    GC_CHECK_ERROR(ctx);
  }
  mapcache_buffer_append(tile->encoded_data,sizeof(apr_time_t),&now);
  if(!tcbdbput(conn.bdb, skey, strlen(skey), tile->encoded_data->buf, tile->encoded_data->size)) {
    int ecode = tcbdbecode(conn.bdb);
    ctx->set_error(ctx,500, "tokyocabinet put error: %s\n",tcbdberrmsg(ecode));
  }
  _tc_release_conn(ctx,tile,conn);
}
Beispiel #16
0
int db_set_dbvalue(void *vhandle, const dbv_t *token, const dbv_t *val)
{
    int ret;
    dbh_t *handle = vhandle;
    TCBDB *dbp = handle->dbp;

    ret = tcbdbput(dbp, token->data, token->leng, val->data, val->leng);

    if (ret == 0) {
	print_error(__FILE__, __LINE__,
		    "(tc) db_set_dbvalue( '%.*s' ) err: %d, %s",
		    CLAMP_INT_MAX(token->leng), (char *)token->data,
		    tcbdbecode(dbp), tcbdberrmsg(tcbdbecode(dbp)));
	exit(EX_ERROR);
    }

    db_optimize(dbp, handle->name);

    return 0;
}
Beispiel #17
0
/* Close the database handle */
int
tc_bdb_close (void *db, char *dbname)
{
    TCBDB *bdb = db;
    int ecode;

    if (bdb == NULL)
        return 1;

    /* close the database */
    if (!tcbdbclose (bdb)) {
        ecode = tcbdbecode (bdb);
        FATAL ("%s", tcbdberrmsg (ecode));
    }
    /* delete the object */
    tcbdbdel (bdb);

    /* remove database file */
    if (!conf.keep_db_files && !tcremovelink (dbname))
        LOG_DEBUG (("Unable to remove DB: %s\n", dbname));
    free (dbname);

    return 0;
}
Beispiel #18
0
/*
   Close files and clean up.
*/
void db_close(void *vhandle)
{
    dbh_t *handle = vhandle;
    TCBDB *dbp;

    if (handle == NULL) return;

    if (DEBUG_DATABASE(1))
	fprintf(dbgout, "(tc) tcbdbclose(%s)\n", handle->name);

    dbp = handle->dbp;

    db_optimize(dbp, handle->name);

    if (!tcbdbclose(dbp))
	print_error(__FILE__, __LINE__, "(tc) tcbdbclose for %s err: %d, %s",
		    handle->name, 
		    tcbdbecode(dbp), tcbdberrmsg(tcbdbecode(dbp)));

    tcbdbdel(dbp);
    handle->dbp = NULL;

    dbh_free(handle);
}
Beispiel #19
0
static struct tc_conn _tc_get_conn(mapcache_context *ctx, mapcache_tile* tile, int readonly) {
  struct tc_conn conn;
  /* create the object */
  conn.bdb = tcbdbnew();
  mapcache_cache_tc *cache = (mapcache_cache_tc*)tile->tileset->cache;

  /* open the database */
  if(!readonly) {
    if(!tcbdbopen(conn.bdb, apr_pstrcat(ctx->pool, cache->basedir,"/tc.tcb",NULL), BDBOWRITER | BDBOCREAT)) {
      int ecode = tcbdbecode(conn.bdb);
      ctx->set_error(ctx,500, "tokyocabinet open error on %s: %s\n",apr_pstrcat(ctx->pool, cache->basedir,"/tc.tcf",NULL),tcbdberrmsg(ecode));
    }
    conn.readonly = 0;
  } else {
    if(!tcbdbopen(conn.bdb, apr_pstrcat(ctx->pool, cache->basedir,"/tc.tcb",NULL), BDBOREADER)) {
      if(!tcbdbopen(conn.bdb, apr_pstrcat(ctx->pool, cache->basedir,"/tc.tcb",NULL), BDBOWRITER | BDBOCREAT)) {
        int ecode = tcbdbecode(conn.bdb);
        ctx->set_error(ctx,500, "tokyocabinet open error on %s: %s\n",apr_pstrcat(ctx->pool, cache->basedir,"/tc.tcf",NULL),tcbdberrmsg(ecode));
      }
      conn.readonly = 0;
    }
    conn.readonly = 1;
  }
  return conn;
}
Beispiel #20
0
/* Get the message string corresponding to an error code. */
const char *tcwdberrmsg(int ecode){
  return tcbdberrmsg(ecode);
}
Beispiel #21
0
int main(int argc, char **argv){

  if (argc != 3) {
    std::cerr << "Usage: " << argv[0] << " file dbname" << std::endl; 
    exit(1);
  }

  double t1, t2;
  FILE *fp = fopen(argv[1], "r");
  if (fp == NULL) {
    std::cerr << "failed to open " << argv[1] << std::endl;
    exit(1);
  }

  int ecode;
  char *key, *value;

  t1 = gettimeofday_sec();
  TCBDB *bdb = tcbdbnew();
  tcbdbtune(bdb, 5, -1, -1, -1, -1, 0);
  tcbdbsetcache(bdb, 300, 100);

  if (!tcbdbopen(bdb, argv[2], BDBOWRITER | BDBOCREAT)) {
    ecode = tcbdbecode(bdb);
    fprintf(stderr, "open error: %s\n", tcbdberrmsg(ecode));
  }

  char buf[256];
  while (fgets(buf, 256, fp)) {
    char *key = strchr(buf, ' ');
    if (key == NULL) { continue; }
    *key++ = '\0';
    char *valp = strchr(key, ' ');
    if (valp == NULL) { continue; }
    *valp++ = '\0';
    char *val = new char[102401]; // 100K
    sprintf(val, "%0102400d", atoi(valp));

    int size;
    void *data = tcbdbget(bdb, key, strlen(key), &size);
    if (data != NULL) {
      if (strcmp(val, (char *) data) != 0) {
        std::cout << "[error] value incorrect." << std::endl;
      }
      free(data);
    } else {
      std::cout << "[error] entry not found." << std::endl;
    } 
    delete [] val;
  }

  if (!tcbdbclose(bdb)) {
    ecode = tcbdbecode(bdb);
    fprintf(stderr, "close error: %s\n", tcbdberrmsg(ecode));
  }
  tcbdbdel(bdb);
  t2 = gettimeofday_sec();
  std::cout << "get time: " << t2 - t1 << std::endl;

  fclose(fp);

  return 0;
}
Beispiel #22
0
static int control(ErlDrvData handle, unsigned int command, char* buf, int count, char** res, int res_size) {
  tcbdb_drv_t *driver = (tcbdb_drv_t*)handle;
  TCBDB *bdb = driver->bdb;

  int index = 1, tp, sz, version;
  char key[MAX_KEY_SIZE], value[MAX_VALUE_SIZE];
  long key_size, value_size;
  long long long_tmp;
  bool rs;
  const char *value_tmp = NULL;

  ei_x_buff x;
  ei_x_new_with_version(&x);
  if (bdb == NULL && command != OPEN)
    return ei_error(&x, "database_not_opened", res, res_size);

  ei_decode_version(buf, &index, &version);

  switch (command) {
    case OPEN:
      // open(Filepath::string())
      if (bdb == NULL) {
        ei_get_type(buf, &index, &tp, &sz);
        if (tp != ERL_STRING_EXT)
          return ei_error(&x, "invalid_argument", res, res_size);

        TCBDB *bdb = tcbdbnew();
        tcbdbsetmutex(bdb);
        tcbdbsetcache(bdb, 104800, 51200);
        tcbdbsetxmsiz(bdb, 1048576);
        tcbdbtune(bdb, 0, 0, 0, 7, -1, BDBTLARGE);

        char *file = driver_alloc(sz + 1);
        ei_decode_string(buf, &index, file);
        rs = tcbdbopen(bdb, file, BDBOWRITER | BDBOCREAT);
        driver_free(file);
        if (!rs)
          return ei_error(&x, tcbdberrmsg(tcbdbecode(bdb)), res, res_size);
        driver->bdb = bdb;
        ei_x_encode_atom(&x, "ok");
      } else
        return ei_error(&x, "database already opened", res, res_size);
      break;

    case CLOSE:
      tcbdbclose(bdb);
      tcbdbdel(bdb);
      driver->bdb = NULL;
      ei_x_encode_atom(&x, "ok");
      break;

    case PUT:
    case PUTDUP:
    case PUTCAT:
    case PUTKEEP:
      // put({Key::binary(), Value::binary()})
      ei_get_type(buf, &index, &tp, &sz);
      if (tp != ERL_SMALL_TUPLE_EXT || sz != 2)
        return ei_error(&x, "invalid_argument", res, res_size);
      ei_decode_tuple_header(buf, &index, &sz);

      ei_get_type(buf, &index, &tp, &sz);
      if (tp != ERL_BINARY_EXT || sz > MAX_KEY_SIZE)
        return ei_error(&x, "invalid_argument", res, res_size);
      ei_decode_binary(buf, &index, &key[0], &key_size);
      ei_get_type(buf, &index, &tp, &sz);
      if (tp != ERL_BINARY_EXT)
        return ei_error(&x, "invalid_argument", res, res_size);
      if (sz <= MAX_VALUE_SIZE) {
        ei_decode_binary(buf, &index, &value[0], &value_size);
        switch (command) {
          case PUT: rs = tcbdbput(bdb, &key[0], key_size, &value[0], value_size); break;
          case PUTDUP: rs = tcbdbputdup(bdb, &key[0], key_size, &value[0], value_size); break;
          case PUTCAT: rs = tcbdbputcat(bdb, &key[0], key_size, &value[0], value_size); break;
          default: rs = tcbdbputkeep(bdb, &key[0], key_size, &value[0], value_size);
        }
      } else {
        void *p = driver_alloc(sz);
        if (p) {
          ei_decode_binary(buf, &index, p, &value_size);
          switch (command) {
            case PUT: rs = tcbdbput(bdb, &key[0], key_size, p, value_size); break;
            case PUTDUP: rs = tcbdbputdup(bdb, &key[0], key_size, p, value_size); break;
            case PUTCAT: rs = tcbdbputcat(bdb, &key[0], key_size, p, value_size); break;
            default: rs = tcbdbputkeep(bdb, &key[0], key_size, p, value_size);
          }
          driver_free(p);
        } else
          return ei_error(&x, "too long value", res, res_size);
      };
      if (!rs)
        return ei_error(&x, tcbdberrmsg(tcbdbecode(bdb)), res, res_size);
      ei_x_encode_atom(&x, "ok");
      break;

    case GET:
      // get(Key::binary()) -> {ok, Value} | {error, not_found}
      ei_get_type(buf, &index, &tp, &sz);
      if (tp != ERL_BINARY_EXT || sz > MAX_KEY_SIZE)
        return ei_error(&x, "invalid_argument", res, res_size);
      ei_decode_binary(buf, &index, &key[0], &key_size);

      value_tmp = tcbdbget3(bdb, &key[0], key_size, &sz);
      ei_x_encode_tuple_header(&x, 2);
      if (value_tmp != NULL) {
        ei_x_encode_atom(&x, "ok");
        ei_x_encode_binary(&x, value_tmp, sz);
      } else {
        ei_x_encode_atom(&x, "error");
        ei_x_encode_atom(&x, "not_found");
      }
      break;

    case GETDUP:
      // get(Key::binary()) -> {ok, Values}
      ei_get_type(buf, &index, &tp, &sz);
      if (tp != ERL_BINARY_EXT || sz > MAX_KEY_SIZE)
        return ei_error(&x, "invalid_argument", res, res_size);
      ei_decode_binary(buf, &index, &key[0], &key_size);

      TCLIST *vals = tcbdbget4(bdb, key, key_size);
      if (vals) {
        ei_x_encode_tuple_header(&x, 2);
        ei_x_encode_atom(&x, "ok");
        int j;
        for (j=0; j<tclistnum(vals); j++) {
          value_tmp = tclistval(vals, j, &sz);
          ei_x_encode_list_header(&x, 1);
          ei_x_encode_binary(&x, value_tmp, sz);
        }
        tclistdel(vals);
        ei_x_encode_empty_list(&x);
      } else {
        ei_x_encode_tuple_header(&x, 2);
        ei_x_encode_atom(&x, "ok");
        ei_x_encode_empty_list(&x);
      }
      break;

    case REMOVE:
      // remove(Keys::list())
      // remove(Key::binary())
      // remove({Key::binary(), Value::binary()})
      ei_get_type(buf, &index, &tp, &sz);
      if (tp == ERL_LIST_EXT) {
        int count, j;
        ei_decode_list_header(buf, &index, &count);
        for (j=0; j<count; j++) {
          ei_get_type(buf, &index, &tp, &sz);
          if (tp != ERL_BINARY_EXT || sz > MAX_KEY_SIZE)
            return ei_error(&x, "invalid_argument", res, res_size);
          ei_decode_binary(buf, &index, &key[0], &key_size);
          if (!tcbdbout3(bdb, &key[0], key_size))
            return ei_error(&x, tcbdberrmsg(tcbdbecode(bdb)), res, res_size);
        }
        ei_x_encode_atom(&x, "ok");
      } else if (tp == ERL_BINARY_EXT && sz <= MAX_KEY_SIZE) {
        ei_decode_binary(buf, &index, &key[0], &key_size);
        tcbdbout3(bdb, &key[0], key_size);
        ei_x_encode_atom(&x, "ok");
      } else if (tp == ERL_SMALL_TUPLE_EXT && sz == 2) {
        ei_decode_tuple_header(buf, &index, &sz);
        // get key
        ei_get_type(buf, &index, &tp, &sz);
        if (tp != ERL_BINARY_EXT || sz > MAX_KEY_SIZE)
          return ei_error(&x, "invalid_argument", res, res_size);
        ei_decode_binary(buf, &index, &key[0], &key_size);
        // get value
        ei_get_type(buf, &index, &tp, &sz);
        if (tp != ERL_BINARY_EXT || sz > MAX_VALUE_SIZE)
          return ei_error(&x, "invalid_argument", res, res_size);
        ei_decode_binary(buf, &index, &value[0], &value_size);
        // remove by key&value
        BDBCUR *cur = tcbdbcurnew(bdb);
        if (!tcbdbcurjump(cur, &key[0], key_size))
          return ei_error(&x, "record_not_found", res, res_size);
        
        bool removed = false, not_found = false;
        while (!removed && !not_found) {
          int cur_key_size, cur_val_size;
          const void *curkey = tcbdbcurkey3(cur, &cur_key_size);
          if (cur_key_size == key_size && memcmp(curkey, key, key_size) == 0) {
            const void *curval = tcbdbcurval3(cur, &cur_val_size);
            if (cur_val_size == value_size && memcmp(curval, value, value_size) == 0) {
              tcbdbcurout(cur);
              removed = true;
            } else
              if (!tcbdbcurnext(cur))
                not_found = true;
          } else not_found = true;
        }
        if (not_found) ei_x_encode_atom(&x, "not_found");
        else ei_x_encode_atom(&x, "ok");
        
      } else
        return ei_error(&x, "invalid_argument", res, res_size);
      break;

    case RANGE:
      /*
       * range({Prefix::binary(), limit:integer()})
       * range({StartKey::binary(), BeginInclusion::boolean(), EndKey::binary(), EndInclusion::binary(), limit:integer()})
       */
      ei_get_type(buf, &index, &tp, &sz);
      if (tp != ERL_SMALL_TUPLE_EXT || sz < 2)
        return ei_error(&x, "invalid_argument", res, res_size);
      ei_decode_tuple_header(buf, &index, &sz);

      ei_get_type(buf, &index, &tp, &sz);
      if (tp == ERL_BINARY_EXT && sz <= MAX_KEY_SIZE) {
        char keys[MAX_KEY_SIZE], keyf[MAX_KEY_SIZE];
        long keys_size, keyf_size;
        int keys_inc, keyf_inc;
        long max = -1;
        TCLIST *range;

        ei_decode_binary(buf, &index, &keys[0], &keys_size);
        ei_get_type(buf, &index, &tp, &sz);
        if (tp == ERL_ATOM_EXT) {
          // range
          ei_decode_boolean(buf, &index, &keys_inc);
          ei_get_type(buf, &index, &tp, &sz);
          if (tp != ERL_BINARY_EXT || sz > MAX_KEY_SIZE)
            return ei_error(&x, "invalid_argument", res, res_size);
          ei_decode_binary(buf, &index, &keyf[0], &keyf_size);
          ei_get_type(buf, &index, &tp, &sz);
          if (tp != ERL_ATOM_EXT)
            return ei_error(&x, "invalid_argument", res, res_size);
          ei_decode_boolean(buf, &index, &keyf_inc);

          ei_get_type(buf, &index, &tp, &sz);
          if (tp != ERL_INTEGER_EXT)
            return ei_error(&x, "invalid_argument", res, res_size);
          ei_decode_long(buf, &index, &max);

          range = tcbdbrange(bdb, &keys[0], keys_size, keys_inc == 1, &keyf[0], keyf_size, keyf_inc == 1, max);
        } else if (tp == ERL_INTEGER_EXT) {
          // prefix
          ei_get_type(buf, &index, &tp, &sz);
          if (tp != ERL_INTEGER_EXT)
            return ei_error(&x, "invalid_argument", res, res_size);
          ei_decode_long(buf, &index, &max);

          range = tcbdbfwmkeys(bdb, &keys[0], keys_size, max);
        } else
          return ei_error(&x, "invalid_argument", res, res_size);

        const char *key;
        int key_size, value_size;
        int idx, cnt = 0, rcount = tclistnum(range);

        ei_x_encode_tuple_header(&x, 2);
        ei_x_encode_atom(&x, "ok");

        BDBCUR *cur = tcbdbcurnew(bdb);
        for (idx=0; idx<rcount; idx++) {
          key = tclistval(range, idx, &key_size);
          TCLIST *vals = tcbdbget4(bdb, key, key_size);
          if (vals) {
            int j;
            for (j=0; j<tclistnum(vals); j++) {
              ei_x_encode_list_header(&x, 1);
              value_tmp = tclistval(vals, j, &value_size);
              ei_x_encode_binary(&x, value_tmp, value_size);
              if (max >= 0 && ++cnt >= max) break;
            }
            tclistdel(vals);
          }
          idx++;
        }
        tcbdbcurdel(cur);
        tclistdel(range);
        ei_x_encode_empty_list(&x);

      } else
        return ei_error(&x, "invalid_argument", res, res_size);
      break;

    case SYNC:
      // sync()
      if (!tcbdbsync(bdb))
        return ei_error(&x, tcbdberrmsg(tcbdbecode(bdb)), res, res_size);
      ei_x_encode_atom(&x, "ok");
      break;

    case INFO:
      // info()
      ei_x_encode_tuple_header(&x, 3);
      ei_x_encode_atom(&x, "ok");
      long_tmp = tcbdbrnum(bdb);
      ei_x_encode_longlong(&x, long_tmp);
      long_tmp = tcbdbfsiz(bdb);
      ei_x_encode_longlong(&x, long_tmp);
      break;

    case ITERATE:
      // Read(none) -> {ok, Key} | {error, not_found}
      // Read(Key::binary()) -> {ok, Key} | {error, not_found}
      ei_get_type(buf, &index, &tp, &sz);
      BDBCUR *cur = tcbdbcurnew(bdb);
      if (tp == ERL_BINARY_EXT && sz <= MAX_KEY_SIZE) {
        ei_decode_binary(buf, &index, &key[0], &key_size);
        rs = tcbdbcurjump(cur, &key[0], key_size) && tcbdbcurnext(cur);
      } else
        rs = tcbdbcurfirst(cur);
      if (rs) {
        int key_size;
        const char *key = tcbdbcurkey3(cur, &key_size);

        ei_x_encode_tuple_header(&x, 2);
        ei_x_encode_atom(&x, "ok");
        ei_x_encode_binary(&x, key, key_size);
        tcbdbcurdel(cur);
      } else {
        tcbdbcurdel(cur);
        return ei_error(&x, "not_found", res, res_size);
      }
      break;

    case VANISH:
      // vanish() -> ok
      if (!tcbdbvanish(bdb))
        return ei_error(&x, tcbdberrmsg(tcbdbecode(bdb)), res, res_size);
      ei_x_encode_atom(&x, "ok");
      break;

    case BACKUP:
      // backup(path::string()) -> ok | {error, Reason}
      ei_get_type(buf, &index, &tp, &sz);
      if (tp == ERL_STRING_EXT) {
        char *file = driver_alloc(sz + 1);
        ei_decode_string(buf, &index, file);
        if (tcbdbcopy(driver->bdb, file))
          ei_x_encode_atom(&x, "ok");
        else
          return ei_error(&x, tcbdberrmsg(tcbdbecode(bdb)), res, res_size);
      } else
        return ei_error(&x, "invalid_argument", res, res_size);
      break;

    default:
      return ei_error(&x, "invalid_command", res, res_size);
  }

  if (res_size < x.index)
    (*res) = (char *)driver_alloc(x.index);
  int n = x.index;
  memcpy(*res, x.buff, x.index);
  ei_x_free(&x);
  return n;
};
Beispiel #23
0
const char *db_str_err(int e)
{
    return tcbdberrmsg(e);
}
Beispiel #24
0
IoObject *IoTokyoCabinetPrefixCursor_put(IoObject *self, IoObject *locals, IoMessage *m)
{
	/*doc TokyoCabinetPrefixCursor put(value)
	Sets the value at the current cursor postion. Returns self.
	*/
	
	IoSeq *value = IoMessage_locals_seqArgAt_(m, locals, 0);

	IOASSERT(TokyoCabinetPrefixCursor(self), "invalid TokyoCabinetPrefixCursor");

	IOASSERT(tcbdbcurput(TokyoCabinetPrefixCursor(self), (const char *)IoSeq_rawBytes(value), IoSeq_rawSizeInBytes(value), BDBCPCURRENT), tcbdberrmsg(tcbdbecode(TokyoCabinet(self))));

	return self;
}
Beispiel #25
0
/* print error information */
static void printerr(TCBDB *bdb) {
    const char *path = tcbdbpath(bdb);
    int ecode = tcbdbecode(bdb);
    fprintf(stderr, "%s: %s: %d: %s\n", g_progname, path ? path : "-", ecode, tcbdberrmsg(ecode));
}