static TCLIST* hash2tclist(lua_State *L, int index){ int len = 0; lua_pushnil(L); while(lua_next(L, index) != 0){ len++; lua_pop(L, 1); } TCLIST *list = tclistnew2(len); lua_pushnil(L); while(lua_next(L, index) != 0){ const char *key, *value; size_t ksize, vsize; if(lua_type(L, -2)==LUA_TNUMBER){ lua_pushvalue(L, -2); key = lua_tolstring(L, -1, &ksize); lua_pop(L, 1); } else { key = lua_tolstring(L, -2, &ksize); } tclistpush(list, key, ksize); if(lua_type(L, -1)==LUA_TNUMBER){ lua_pushvalue(L, -1); value = lua_tolstring(L, -1, &vsize); lua_pop(L, 1); } else { value = lua_tolstring(L, -1, &vsize); } tclistpush(list, value, vsize); lua_pop(L, 1); } return list; }
static void putlist_test(void *db, const char *command, int num, int vsiz, int batch, unsigned int seed) { TCADB *adb = db; struct keygen keygen; char *value = xmalloc(vsiz); TCLIST *list = tclistnew(); int i; keygen_init(&keygen, seed); for (i = 0; i < num; i++) { tclistpush2(list, keygen_next_key(&keygen)); tclistpush(list, value, vsiz); if (tclistnum(list) / 2 >= batch) { tclistdel(do_tcadbmisc(adb, command, list)); tclistclear(list); } } if (tclistnum(list)) tclistdel(do_tcadbmisc(adb, command, list)); tclistdel(list); free(value); }
/* parse arguments of misc command */ static int runmisc(int argc, char **argv){ char *name = NULL; char *func = NULL; TCLIST *args = tcmpoollistnew(tcmpoolglobal()); bool sx = false; int sep = -1; bool px = false; for(int i = 2; i < argc; i++){ if(!name && argv[i][0] == '-'){ if(!strcmp(argv[i], "-sx")){ sx = true; } else if(!strcmp(argv[i], "-sep")){ if(++i >= argc) usage(); sep = sepstrtochr(argv[i]); } else if(!strcmp(argv[i], "-px")){ px = true; } else { usage(); } } else if(!name){ name = argv[i]; } else if(!func){ func = argv[i]; } else { if(sx){ int size; char *buf = tchexdecode(argv[i], &size); tclistpush(args, buf, size); tcfree(buf); } else if(sep > 0){ int size; char *buf = strtozsv(argv[i], sep, &size); tclistpush(args, buf, size); tcfree(buf); } else { tclistpush2(args, argv[i]); } } } if(!name || !func) usage(); int rv = procmisc(name, func, args, sep, px); return rv; }
extern TCLIST *varytolist(VALUE vary){ VALUE vval; TCLIST *list; int i, num; num = RARRAY_LEN(vary); list = tclistnew2(num); for(i = 0; i < num; i++){ vval = rb_ary_entry(vary, i); vval = StringValueEx(vval); tclistpush(list, RSTRING_PTR(vval), RSTRING_LEN(vval)); } return list; }
static TCLIST* array2tclist(lua_State *L, int index){ int len = lua_objlen(L, index); TCLIST *list = tclistnew2(len); int i; for(i=1; i<=len; i++){ lua_rawgeti(L, index, i); size_t vsiz; const char *vbuf = lua_tolstring(L, -1, &vsiz); if(vbuf) tclistpush(list, vbuf, vsiz); lua_pop(L, 1); } return list; }
TCLIST *grok_pattern_name_list(const grok_t *grok) { TCLIST *names; const void *data; int datalen; TCTREE *patterns = grok->patterns; names = tclistnew(); tctreeiterinit(patterns); while ((data = tctreeiternext(patterns, &datalen)) != NULL) { tclistpush(names, data, datalen); } return names; }
extern TCLIST *vhashtolist(VALUE vhash){ /* Seems like something like this might work just as well vary = rb_hash_to_a(vhash); vary = rb_ary_flatten(vary); args = varytolist(vary); */ VALUE vkeys, vkey, vval; TCLIST *list; int i, num; vkeys = rb_funcall(vhash, rb_intern("keys"), 0); num = RARRAY_LEN(vkeys); list = tclistnew2(num); for(i = 0; i < num; i++){ vkey = rb_ary_entry(vkeys, i); vval = rb_hash_aref(vhash, vkey); vkey = StringValueEx(vkey); vval = StringValueEx(vval); tclistpush(list, RSTRING_PTR(vkey), RSTRING_LEN(vkey)); tclistpush(list, RSTRING_PTR(vval), RSTRING_LEN(vval)); } return list; }
static int _sandbox_listen(const char *type, NOTIFY_HANDLER handler, void *listener, TCMAP *map) { TCLIST **p, *list; int sp; if (!type || !handler) return -1; p = (TCLIST **)tcmapget(map, type, strlen(type), &sp); if (p) { list = *p; //free(p); } else { list = tclistnew2(8); tcmapput(map, type, strlen(type), &list, sizeof(list)); } tclistpush(list, &handler, sizeof(handler)); //DEBUG_PRINT("sandbox_listen(): type=%s, handler=%X, s=%d\n", type, (unsigned int)handler, sizeof(handler)); return 0; }
/* putlist */ JNIEXPORT jboolean JNICALL Java_tokyocabinet_BDB_putlist (JNIEnv *env, jobject self, jbyteArray key, jobject values){ if(!key || !values){ throwillarg(env); return false; } TCBDB *bdb = (TCBDB *)(intptr_t)(*env)->GetLongField(env, self, bdb_fid_ptr); jboolean ick; jbyte *kbuf = (*env)->GetByteArrayElements(env, key, &ick); if(!kbuf){ throwoutmem(env); return false; } int ksiz = (*env)->GetArrayLength(env, key); jclass clslist = (*env)->GetObjectClass(env, values); jmethodID midit = (*env)->GetMethodID(env, clslist, "iterator", "()L" CLSITERATOR ";"); jobject itobj = (*env)->CallObjectMethod(env, values, midit); jclass clsit = (*env)->GetObjectClass(env, itobj); jmethodID midhn = (*env)->GetMethodID(env, clsit, "hasNext", "()Z"); jmethodID midnx = (*env)->GetMethodID(env, clsit, "next", "()L" CLSOBJECT ";"); jclass clsbyteary = (*env)->FindClass(env, "[B"); TCLIST *tvals = tclistnew(); while((*env)->CallBooleanMethod(env, itobj, midhn)){ jobject val = (*env)->CallObjectMethod(env, itobj, midnx); if(!(*env)->IsInstanceOf(env, val, clsbyteary)) continue; jboolean icv; jbyte *vbuf = (*env)->GetByteArrayElements(env, val, &icv); if(!vbuf){ throwoutmem(env); return false; } int vsiz = (*env)->GetArrayLength(env, val); tclistpush(tvals, vbuf, vsiz); (*env)->ReleaseByteArrayElements(env, val, vbuf, JNI_ABORT); } bool rv = tcbdbputdup3(bdb, kbuf, ksiz, tvals); tclistdel(tvals); (*env)->ReleaseByteArrayElements(env, key, kbuf, JNI_ABORT); return rv; }
void main () { uint32_t key = 123; const char *val = "abcdefkrnglrg"; // Make a new tree TCTREE *tree = tctreenew(); // Put an integer key tctreeput(tree, &key, sizeof(key), val, strlen(val)); // Put a different key key = 122; tctreeput(tree, &key, sizeof(key), val, strlen(val)); // Put the same key twice tctreeput(tree, &key, sizeof(key), val, strlen(val)); // Put the same key but keep the old value tctreeputkeep(tree, &key, sizeof(key), val, strlen(val)); // Get back a value int size; void *newVal = tctreeget(tree, &key, sizeof(key), &size); printf("Got value %s\n", newVal); // Create an iterator tctreeiterinit(tree); // Walk the tree tctreeiternext(tree, &size); tctreeiternext(tree, &size); tctreeiternext(tree, &size); // Clear the tree tctreeclear(tree); // Put one value back in the tree to make sure it's freed on delete tctreeput(tree, &key, sizeof(key), val, strlen(val)); // Delete the tree tctreedel(tree); // Make a list TCLIST *list = tclistnew(); // Push a few times tclistpush(list, &key, sizeof(key)); key += 1; tclistpush(list, &key, sizeof(key)); key += 1; tclistpush(list, &key, sizeof(key)); // Overwrite an existing element tclistover(list, 1, &key, sizeof(key)); // Get a value tclistval(list, 2, &size); // Remove some values newVal = tclistremove(list, 2, &size); free(newVal); newVal = tclistremove(list, 0, &size); free(newVal); // Free the whole list tclistdel(list); }
void grok_capture_add(grok_t *grok, const grok_capture *gct, int only_renamed) { grok_log(grok, LOG_CAPTURE, "Adding pattern '%s' as capture %d (pcrenum %d)", gct->name, gct->id, gct->pcre_capture_number); if (only_renamed && strstr(gct->name, ":") == NULL) { return; } /* Primary key is id */ tctreeput(grok->captures_by_id, &(gct->id), sizeof(gct->id), gct, sizeof(grok_capture)); /* Tokyo Cabinet doesn't seem to support 'secondary indexes' like BDB does, * so let's manually update all the other 'captures_by_*' trees */ int unused_size; tctreeput(grok->captures_by_capture_number, &(gct->pcre_capture_number), sizeof(gct->pcre_capture_number), gct, sizeof(grok_capture)); int i, listsize; /* TCTREE doesn't permit dups, so let's make the structure a tree of arrays, * keyed on a string. */ /* captures_by_name */ TCLIST *by_name_list; by_name_list = (TCLIST *) tctreeget(grok->captures_by_name, (const char *)gct->name, gct->name_len, &unused_size); if (by_name_list == NULL) { by_name_list = tclistnew(); } /* delete a capture with the same capture id so we can replace it*/ listsize = tclistnum(by_name_list); for (i = 0; i < listsize; i++) { grok_capture *list_gct; list_gct = (grok_capture *)tclistval(by_name_list, i, &unused_size); if (list_gct->id == gct->id) { tclistremove(by_name_list, i, &unused_size); break; } } tclistpush(by_name_list, gct, sizeof(grok_capture)); tctreeput(grok->captures_by_name, gct->name, gct->name_len, by_name_list, sizeof(TCLIST)); /* end captures_by_name */ /* captures_by_subname */ TCLIST *by_subname_list; by_subname_list = (TCLIST *) tctreeget(grok->captures_by_subname, (const char *)gct->subname, gct->subname_len, &unused_size); if (by_subname_list == NULL) { by_subname_list = tclistnew(); } /* delete a capture with the same capture id so we can replace it*/ listsize = tclistnum(by_subname_list); for (i = 0; i < listsize; i++) { grok_capture *list_gct; list_gct = (grok_capture *)tclistval(by_subname_list, i, &unused_size); if (list_gct->id == gct->id) { tclistremove(by_subname_list, i, &unused_size); break; } } tclistpush(by_subname_list, gct, sizeof(grok_capture)); tctreeput(grok->captures_by_subname, gct->subname, gct->subname_len, by_subname_list, sizeof(TCLIST)); /* end captures_by_subname */ }
static void lua_val_to_bson(lua_State *L, const char *key, int vpos, bson *bs, int tref) { int vtype = lua_type(L, vpos); char nbuf[TCNUMBUFSIZ]; if (key == NULL && vtype != LUA_TTABLE) { luaL_error(L, "lua_val_to_bson: Table must be on top of lua stack"); return; } switch (vtype) { case LUA_TTABLE: { if (vpos < 0) { vpos = lua_gettop(L) + vpos + 1; } lua_checkstack(L, 3); int bsontype_found = luaL_getmetafield(L, vpos, "__bsontype"); if (!bsontype_found) { lua_rawgeti(L, LUA_REGISTRYINDEX, tref); //+ reg table lua_pushvalue(L, vpos); //+ val lua_rawget(L, -2); //-val +reg table val if (lua_toboolean(L, -1)) { //already traversed lua_pop(L, 2); break; } lua_pop(L, 1); //-reg table val lua_pushvalue(L, vpos); lua_pushboolean(L, 1); lua_rawset(L, -3); lua_pop(L, 1); //-reg table int len = 0; bool query = false; bool array = true; if (luaL_getmetafield(L, vpos, "__query")) { lua_pop(L, 1); query = true; array = false; } if (array) { for (lua_pushnil(L); lua_next(L, vpos); lua_pop(L, 1)) { ++len; if ((lua_type(L, -2) != LUA_TNUMBER) || (lua_tointeger(L, -2) != len)) { lua_pop(L, 2); array = false; break; } } } if (array) { if (key) bson_append_start_array(bs, key); int i; for (i = 1; i <= len; ++i, lua_pop(L, 1)) { lua_rawgeti(L, vpos, i); bson_numstrn(nbuf, TCNUMBUFSIZ, (int64_t) i); lua_val_to_bson(L, nbuf, -1, bs, tref); } if (key) bson_append_finish_array(bs); } else if (query) { //special query builder case //oarr format: //{ {fname1, v1, v2...}, {fname2, v21, v22,..}, ... } //where: vN: {op, val} OR {val} with '__bval' metafield //Eg: {fname : {$inc : {...}, $dec : {...}}} -> {fname, {$inc, {}}, {$dec, {}}} lua_getfield(L, vpos, "_oarr"); //+oarr if (!lua_istable(L, -1)) { //it is not array lua_pop(L, 1); break; } if (key) bson_append_start_object(bs, key); //iterate over _oarr int ipos = lua_gettop(L); size_t ilen = lua_objlen(L, ipos); lua_checkstack(L, 2); size_t i; for (i = 1; i <= ilen; ++i, lua_pop(L, 1)) { lua_rawgeti(L, ipos, i); //gettop == 3 if (!lua_istable(L, -1)) continue; char *fname = NULL; int jpos = lua_gettop(L); size_t jlen = lua_objlen(L, jpos); lua_checkstack(L, 3); bool wrapped = false; size_t j; for (j = 1; j <= jlen; ++j, lua_pop(L, 1)) { lua_rawgeti(L, jpos, j); if (j == 1) { fname = strdup(lua_tostring(L, -1)); continue; } if (!fname || !lua_istable(L, -1)) { //invalid state lua_pop(L, 1); //pop val break; } int vblkpos = lua_gettop(L); if (j == 2 && luaL_getmetafield(L, -1, "__bval")) { //{val} single value +metafield lua_pop(L, 1); //-metafield lua_rawgeti(L, vblkpos, 1); //+val lua_val_to_bson(L, fname, lua_gettop(L), bs, tref); lua_pop(L, 2); //-val -lua_rawgeti break; //Terminate due single val } else { //{op, val} value if (!wrapped) { bson_append_start_object(bs, fname); wrapped = true; } lua_rawgeti(L, vblkpos, 1); //+op const char *op = lua_tostring(L, -1); if (op) { lua_rawgeti(L, vblkpos, 2); //+val lua_val_to_bson(L, op, lua_gettop(L), bs, tref); lua_pop(L, 1); //-val } lua_pop(L, 1); //-op } } if (wrapped) { bson_append_finish_object(bs); } if (fname) { free(fname); fname = NULL; } } if (key) bson_append_finish_object(bs); lua_pop(L, 1); //-oarr } else { if (key) bson_append_start_object(bs, key); TCLIST *keys = tclistnew(); //we need to sort keys due to unordered nature of lua tables for (lua_pushnil(L); lua_next(L, vpos);) { lua_pop(L, 1); //-val size_t ksize = 0; int ktype = lua_type(L, -1); if (ktype == LUA_TSTRING) { //accept only string keys const char* key = lua_tolstring(L, -1, &ksize); tclistpush(keys, key, ksize); } } tclistsort(keys); int i; for (i = 0; i < TCLISTNUM(keys); ++i) { int vkeysz = TCLISTVALSIZ(keys, i); const char *vkey = TCLISTVALPTR(keys, i); lua_pushlstring(L, vkey, vkeysz); lua_rawget(L, vpos); //+val if (key == NULL && lua_type(L, -1) == LUA_TSTRING && vkeysz == JDBIDKEYNAMEL && !strcmp(JDBIDKEYNAME, vkey)) { //root level OID as string //pack OID as type table lua_push_bsontype_table(L, BSON_OID); //+type table lua_pushvalue(L, -2); //dup oid(val) on stack lua_rawseti(L, -2, 1); //pop oid val if (ejdbisvalidoidstr(lua_tostring(L, -2))) { lua_val_to_bson(L, vkey, lua_gettop(L), bs, tref); } else { luaL_error(L, "OID _id='%s' is not valid", lua_tostring(L, -2)); } lua_pop(L, 1); //-type table } else { lua_val_to_bson(L, vkey, lua_gettop(L), bs, tref); } lua_pop(L, 1); //-val } tclistdel(keys); if (key) bson_append_finish_object(bs); } } else { //metafield __bsontype on top int bson_type = lua_tointeger(L, -1); if (!key && bson_type != BSON_OBJECT && bson_type != BSON_ARRAY) { lua_pop(L, 1); luaL_error(L, "Invalid object structure"); } lua_pop(L, 1); //-metafield __bsontype lua_rawgeti(L, -1, 1); //get first value switch (bson_type) { case BSON_OID: { const char* boid = lua_tostring(L, -1); if (boid && strlen(boid) == 24) { bson_oid_t oid; bson_oid_from_string(&oid, boid); bson_append_oid(bs, key, &oid); } break; } case BSON_DATE: bson_append_date(bs, key, (bson_date_t) lua_tonumber(L, -1)); break; case BSON_REGEX: { const char* regex = lua_tostring(L, -1); lua_rawgeti(L, -2, 2); // re opts const char* options = lua_tostring(L, -1); if (regex && options) { bson_append_regex(bs, key, regex, options); } lua_pop(L, 1); break; } case BSON_BINDATA: { size_t len; const char* cbuf = lua_tolstring(L, -1, &len); bson_append_binary(bs, key, BSON_BIN_BINARY, cbuf, len); break; } case BSON_NULL: bson_append_null(bs, key); break; case BSON_UNDEFINED: bson_append_undefined(bs, key); break; case BSON_OBJECT: if (key) bson_append_start_object(bs, key); lua_val_to_bson(L, NULL, vpos, bs, tref); if (key) bson_append_finish_object(bs); break; case BSON_ARRAY: if (key) bson_append_start_array(bs, key); lua_val_to_bson(L, NULL, vpos, bs, tref); if (key) bson_append_finish_array(bs); break; case BSON_DOUBLE: bson_append_double(bs, key, (double) lua_tonumber(L, -1)); break; case BSON_INT: bson_append_int(bs, key, (int32_t) lua_tonumber(L, -1)); break; case BSON_LONG: bson_append_long(bs, key, (int64_t) lua_tonumber(L, -1)); break; case BSON_BOOL: bson_append_bool(bs, key, lua_toboolean(L, -1)); break; default: break; } lua_pop(L, 1); //-1 first value } break; } case LUA_TNIL: bson_append_null(bs, key); break; case LUA_TNUMBER: { lua_Number numval = lua_tonumber(L, vpos); if (numval == floor(numval)) { int64_t iv = (int64_t) numval; if (-(1LL << 31) <= iv && iv <= (1LL << 31)) { bson_append_int(bs, key, iv); } else { bson_append_long(bs, key, iv); } } else { bson_append_double(bs, key, numval); } break; } case LUA_TBOOLEAN: bson_append_bool(bs, key, lua_toboolean(L, vpos)); break; case LUA_TSTRING: bson_append_string(bs, key, lua_tostring(L, vpos)); break; } }
void push(const Value & value) { tclistpush( list_, ser::cptr(value), ser::len(value) ); }