int main(int argc, char** argv) { leveldb_t* db; leveldb_comparator_t* cmp; leveldb_cache_t* cache; leveldb_env_t* env; leveldb_options_t* options; leveldb_readoptions_t* roptions; leveldb_writeoptions_t* woptions; char* err = NULL; int run = -1; CheckCondition(leveldb_major_version() >= 1); CheckCondition(leveldb_minor_version() >= 1); snprintf(dbname, sizeof(dbname), "%s/leveldb_c_test-%di/meta/0", GetTempDir(), ((int) geteuid())); StartPhase("create_objects"); cmp = leveldb_comparator_create(NULL, CmpDestroy, CmpCompare, CmpName); env = leveldb_create_default_env(); cache = leveldb_cache_create_lru(100000); options = leveldb_options_create(); leveldb_options_set_comparator(options, cmp); leveldb_options_set_error_if_exists(options, 1); leveldb_options_set_cache(options, cache); leveldb_options_set_env(options, env); leveldb_options_set_info_log(options, NULL); leveldb_options_set_write_buffer_size(options, 100000); leveldb_options_set_paranoid_checks(options, 1); leveldb_options_set_max_open_files(options, 10); leveldb_options_set_block_size(options, 1024); leveldb_options_set_block_restart_interval(options, 8); leveldb_options_set_compression(options, leveldb_no_compression); roptions = leveldb_readoptions_create(); leveldb_readoptions_set_verify_checksums(roptions, 1); leveldb_readoptions_set_fill_cache(roptions, 0); woptions = leveldb_writeoptions_create(); leveldb_writeoptions_set_sync(woptions, 1); StartPhase("destroy"); leveldb_destroy_db(options, dbname, &err); Free(&err); StartPhase("open"); db = leveldb_open(options, dbname, &err); CheckNoError(err); CheckGet(db, roptions, "foo", NULL); StartPhase("put"); leveldb_put(db, woptions, "foo", 3, "hello", 5, &err); CheckNoError(err); CheckGet(db, roptions, "foo", "hello"); StartPhase("compactall"); leveldb_compact_range(db, NULL, 0, NULL, 0); CheckGet(db, roptions, "foo", "hello"); StartPhase("compactrange"); leveldb_compact_range(db, "a", 1, "z", 1); CheckGet(db, roptions, "foo", "hello"); StartPhase("writebatch"); { leveldb_writebatch_t* wb = leveldb_writebatch_create(); leveldb_writebatch_put(wb, "foo", 3, "a", 1); leveldb_writebatch_clear(wb); leveldb_writebatch_put(wb, "bar", 3, "b", 1); leveldb_writebatch_put(wb, "box", 3, "c", 1); leveldb_writebatch_delete(wb, "bar", 3); leveldb_write(db, woptions, wb, &err); CheckNoError(err); CheckGet(db, roptions, "foo", "hello"); CheckGet(db, roptions, "bar", NULL); CheckGet(db, roptions, "box", "c"); int pos = 0; leveldb_writebatch_iterate(wb, &pos, CheckPut, CheckDel); CheckCondition(pos == 3); leveldb_writebatch_destroy(wb); } StartPhase("iter"); { leveldb_iterator_t* iter = leveldb_create_iterator(db, roptions); CheckCondition(!leveldb_iter_valid(iter)); leveldb_iter_seek_to_first(iter); CheckCondition(leveldb_iter_valid(iter)); CheckIter(iter, "box", "c"); leveldb_iter_next(iter); CheckIter(iter, "foo", "hello"); leveldb_iter_prev(iter); CheckIter(iter, "box", "c"); leveldb_iter_prev(iter); CheckCondition(!leveldb_iter_valid(iter)); leveldb_iter_seek_to_last(iter); CheckIter(iter, "foo", "hello"); leveldb_iter_seek(iter, "b", 1); CheckIter(iter, "box", "c"); leveldb_iter_get_error(iter, &err); CheckNoError(err); leveldb_iter_destroy(iter); } StartPhase("approximate_sizes"); { int i; int n = 20000; char keybuf[100]; char valbuf[100]; uint64_t sizes[2]; const char* start[2] = { "a", "k00000000000000010000" }; size_t start_len[2] = { 1, 21 }; const char* limit[2] = { "k00000000000000010000", "z" }; size_t limit_len[2] = { 21, 1 }; leveldb_writeoptions_set_sync(woptions, 0); for (i = 0; i < n; i++) { snprintf(keybuf, sizeof(keybuf), "k%020d", i); snprintf(valbuf, sizeof(valbuf), "v%020d", i); leveldb_put(db, woptions, keybuf, strlen(keybuf), valbuf, strlen(valbuf), &err); CheckNoError(err); } leveldb_approximate_sizes(db, 2, start, start_len, limit, limit_len, sizes); CheckCondition(sizes[0] > 0); CheckCondition(sizes[1] > 0); } StartPhase("property"); { char* prop = leveldb_property_value(db, "nosuchprop"); /* CheckCondition(prop == NULL);*/ prop = leveldb_property_value(db, "leveldb.stats"); CheckCondition(prop != NULL); Free(&prop); } StartPhase("snapshot"); { const leveldb_snapshot_t* snap; snap = leveldb_create_snapshot(db); leveldb_delete(db, woptions, "foo", 3, &err); CheckNoError(err); leveldb_readoptions_set_snapshot(roptions, snap); CheckGet(db, roptions, "foo", "hello"); leveldb_readoptions_set_snapshot(roptions, NULL); CheckGet(db, roptions, "foo", NULL); leveldb_release_snapshot(db, snap); } StartPhase("repair"); { leveldb_close(db); leveldb_options_set_error_if_exists(options, 0); leveldb_repair_db(options, dbname, &err); CheckNoError(err); db = leveldb_open(options, dbname, &err); CheckNoError(err); CheckGet(db, roptions, "foo", NULL); CheckGet(db, roptions, "bar", NULL); CheckGet(db, roptions, "box", "c"); leveldb_options_set_error_if_exists(options, 1); } StartPhase("filter"); for (run = 0; run < 2; run++) { // First run uses custom filter, second run uses bloom filter CheckNoError(err); leveldb_filterpolicy_t* policy; if (run == 0) { policy = leveldb_filterpolicy_create( NULL, FilterDestroy, FilterCreate, FilterKeyMatch, FilterName); } else { policy = leveldb_filterpolicy_create_bloom(10); } // Create new database leveldb_close(db); leveldb_destroy_db(options, dbname, &err); leveldb_options_set_filter_policy(options, policy); db = leveldb_open(options, dbname, &err); CheckNoError(err); leveldb_put(db, woptions, "foo", 3, "foovalue", 8, &err); CheckNoError(err); leveldb_put(db, woptions, "bar", 3, "barvalue", 8, &err); CheckNoError(err); leveldb_compact_range(db, NULL, 0, NULL, 0); fake_filter_result = 1; CheckGet(db, roptions, "foo", "foovalue"); CheckGet(db, roptions, "bar", "barvalue"); if (phase == 0) { // Must not find value when custom filter returns false fake_filter_result = 0; CheckGet(db, roptions, "foo", NULL); CheckGet(db, roptions, "bar", NULL); fake_filter_result = 1; CheckGet(db, roptions, "foo", "foovalue"); CheckGet(db, roptions, "bar", "barvalue"); } leveldb_options_set_filter_policy(options, NULL); leveldb_filterpolicy_destroy(policy); } StartPhase("cleanup"); leveldb_close(db); leveldb_options_destroy(options); leveldb_readoptions_destroy(roptions); leveldb_writeoptions_destroy(woptions); leveldb_cache_destroy(cache); leveldb_comparator_destroy(cmp); leveldb_env_destroy(env); fprintf(stderr, "PASS\n"); return 0; }
char *ldb_info(struct _leveldb_stuff *ldbs, int *size) { char *result = (char *)calloc(1, INFO_MAX); /* #Server: */ strcpy(result, "+\n#Server:\n"); { /* version */ strcat(result, TSDB_VERSION"\n"); /* node type */ switch (g_cfg_pool.node_type) { case SINGLE: strcat(result, "type:SINGLE\n"); break; case CLUSTER: strcat(result, "type:CLUSTER\n"); break; } /* tsdb mode */ if (LDB_READONLY_SWITCH == 1) { strcat(result, "mode:READONLY\n"); } else { strcat(result, "mode:READ WRITE\n"); } /* os */ struct utsname name; uname(&name); sprintf(result + strlen(result), "os:%s %s %s\n", name.sysname, name.release, name.machine); /* pid */ sprintf(result + strlen(result), "process_id:%ld\n",(long) getpid()); /* write_port */ sprintf(result + strlen(result), "write_port:%d\n",W_PORT); /* read_port */ sprintf(result + strlen(result), "read_port:%d\n",R_PORT); /* uptime_in_seconds */ time_t curtime; time(&curtime); sprintf(result + strlen(result), "uptime_in_seconds:%ld\n", curtime - LDB_START_TIME); /* uptime_in_days */ sprintf(result + strlen(result), "uptime_in_days:%ld\n", (curtime - LDB_START_TIME) / (24 * 3600)); /* db_size */ log_debug("%s", ldbs->dbname); if (!ldbs->dbname || access(ldbs->dbname, R_OK)) { log_error("%s", "failed to get database size!"); return NULL ; } dbsize = 0; if (ftw(ldbs->dbname, &sum, 1)) { log_error("%s", "failed to get database size!"); return NULL ; } sprintf(result + strlen(result), "db_size_in_bytes:%ld\n", dbsize); if (dbsize >= 1073741824) { // 1024*1024*1024: GB sprintf(result + strlen(result), "db_size_in_human:%.2fG\n", dbsize*1.0 / (1073741824)); } else if (dbsize >= 1048576) { // 1024*1024: MB sprintf(result + strlen(result), "db_size_in_human:%.2fM\n", dbsize*1.0 / (1048576)); } else if (1048576 >= 1024) { // 1024: KB sprintf(result + strlen(result), "db_size_in_human:%.2fK\n", dbsize*1.0 / (1024)); } else { sprintf(result + strlen(result), "db_size_in_human:%ldB\n", dbsize); } } /* # Keyspace. */ strcat(result, "\n#Keyspace:\n"); { /* key_set. */ sprintf(result + strlen(result), "key_set:[%ld, %ld]\n", g_cfg_pool.key_start, g_cfg_pool.key_end); /* time range. */ sprintf(result + strlen(result), "time_range:[%ld ,%ld)\n", g_cfg_pool.start_time, g_cfg_pool.end_time); } /* # Replication. */ strcat(result, "\n#Replication:\n"); { switch (g_cfg_pool.role) { case MASTER: strcat(result, "role:MASTER\n"); break; case SLAVE: strcat(result, "role:SLAVE\n"); break; default: strcat(result, "role:SINGLE\n"); break; } if (g_cfg_pool.has_slave == 0) { strcat(result, "has_slave:NO\n"); } else { strcat(result, "has_slave:YES\n"); sprintf(result + strlen(result), "slave_ip:%s\n", g_cfg_pool.slave_ip); sprintf(result + strlen(result), "slave_port:%d\n", g_cfg_pool.slave_wport); sprintf(result + strlen(result), "is_connect:%s\n", "TODO"); } } /* #LeveldbStatus: */ strcat(result, "\n#Leveldb status:\n"); { /* get property. */ strcat(result, leveldb_property_value(ldbs->db, "leveldb.stats")); } strcat(result, "\r\n"); *size = strlen(result); return result; }
char *db_property_value(db_t *db, const char *propname) { return leveldb_property_value(db, propname); }
int main(int argc, char** argv) { leveldb_t* db; leveldb_comparator_t* cmp; leveldb_cache_t* cache; leveldb_env_t* env; leveldb_options_t* options; leveldb_readoptions_t* roptions; leveldb_writeoptions_t* woptions; char* err = NULL; #if defined(LEVELDB_PLATFORM_WINDOWS) snprintf(dbname, sizeof(dbname), "tmp\\leveldb_c_test"); #else snprintf(dbname, sizeof(dbname), "/tmp/leveldb_c_test-%d", ((int) geteuid())); #endif StartPhase("create_objects"); cmp = leveldb_comparator_create(NULL, CmpDestroy, CmpCompare, CmpName); env = leveldb_create_default_env(); cache = leveldb_cache_create_lru(100000); options = leveldb_options_create(); leveldb_options_set_comparator(options, cmp); leveldb_options_set_error_if_exists(options, 1); leveldb_options_set_cache(options, cache); leveldb_options_set_env(options, env); leveldb_options_set_info_log(options, NULL); leveldb_options_set_write_buffer_size(options, 100000); leveldb_options_set_paranoid_checks(options, 1); leveldb_options_set_max_open_files(options, 10); leveldb_options_set_block_size(options, 1024); leveldb_options_set_block_restart_interval(options, 8); leveldb_options_set_compression(options, leveldb_no_compression); roptions = leveldb_readoptions_create(); leveldb_readoptions_set_verify_checksums(roptions, 1); leveldb_readoptions_set_fill_cache(roptions, 0); woptions = leveldb_writeoptions_create(); leveldb_writeoptions_set_sync(woptions, 1); StartPhase("destroy"); leveldb_destroy_db(options, dbname, &err); leveldb_free(&err); StartPhase("open_error"); db = leveldb_open(options, dbname, &err); CheckCondition(err != NULL); leveldb_free(&err); StartPhase("open"); leveldb_options_set_create_if_missing(options, 1); db = leveldb_open(options, dbname, &err); CheckNoError(err); CheckGet(db, roptions, "foo", NULL); StartPhase("put"); leveldb_put(db, woptions, "foo", 3, "hello", 5, &err); CheckNoError(err); CheckGet(db, roptions, "foo", "hello"); StartPhase("writebatch"); { int pos = 0; leveldb_writebatch_t* wb = leveldb_writebatch_create(); leveldb_writebatch_put(wb, "foo", 3, "a", 1); leveldb_writebatch_clear(wb); leveldb_writebatch_put(wb, "bar", 3, "b", 1); leveldb_writebatch_put(wb, "box", 3, "c", 1); leveldb_writebatch_delete(wb, "bar", 3); leveldb_write(db, woptions, wb, &err); CheckNoError(err); CheckGet(db, roptions, "foo", "hello"); CheckGet(db, roptions, "bar", NULL); CheckGet(db, roptions, "box", "c"); leveldb_writebatch_iterate(wb, &pos, CheckPut, CheckDel); CheckCondition(pos == 3); leveldb_writebatch_destroy(wb); } StartPhase("iter"); { leveldb_iterator_t* iter = leveldb_create_iterator(db, roptions); CheckCondition(!leveldb_iter_valid(iter)); leveldb_iter_seek_to_first(iter); CheckCondition(leveldb_iter_valid(iter)); CheckIter(iter, "box", "c"); leveldb_iter_next(iter); CheckIter(iter, "foo", "hello"); leveldb_iter_prev(iter); CheckIter(iter, "box", "c"); leveldb_iter_prev(iter); CheckCondition(!leveldb_iter_valid(iter)); leveldb_iter_seek_to_last(iter); CheckIter(iter, "foo", "hello"); leveldb_iter_seek(iter, "b", 1); CheckIter(iter, "box", "c"); leveldb_iter_get_error(iter, &err); CheckNoError(err); leveldb_iter_destroy(iter); } StartPhase("approximate_sizes"); { int i; int n = 20000; char keybuf[100]; char valbuf[100]; uint64_t sizes[2]; const char* start[2] = { "a", "k00000000000000010000" }; size_t start_len[2] = { 1, 21 }; const char* limit[2] = { "k00000000000000010000", "z" }; size_t limit_len[2] = { 21, 1 }; leveldb_writeoptions_set_sync(woptions, 0); for (i = 0; i < n; i++) { snprintf(keybuf, sizeof(keybuf), "k%020d", i); snprintf(valbuf, sizeof(valbuf), "v%020d", i); leveldb_put(db, woptions, keybuf, strlen(keybuf), valbuf, strlen(valbuf), &err); CheckNoError(err); } leveldb_approximate_sizes(db, 2, start, start_len, limit, limit_len, sizes); CheckCondition(sizes[0] > 0); CheckCondition(sizes[1] > 0); } StartPhase("property"); { char* prop = leveldb_property_value(db, "nosuchprop"); CheckCondition(prop == NULL); prop = leveldb_property_value(db, "leveldb.stats"); CheckCondition(prop != NULL); leveldb_free(&prop); } StartPhase("snapshot"); { const leveldb_snapshot_t* snap; snap = leveldb_create_snapshot(db); leveldb_delete(db, woptions, "foo", 3, &err); CheckNoError(err); leveldb_readoptions_set_snapshot(roptions, snap); CheckGet(db, roptions, "foo", "hello"); leveldb_readoptions_set_snapshot(roptions, NULL); CheckGet(db, roptions, "foo", NULL); leveldb_release_snapshot(db, snap); } StartPhase("repair"); { leveldb_close(db); leveldb_options_set_create_if_missing(options, 0); leveldb_options_set_error_if_exists(options, 0); leveldb_repair_db(options, dbname, &err); CheckNoError(err); db = leveldb_open(options, dbname, &err); CheckNoError(err); CheckGet(db, roptions, "foo", NULL); CheckGet(db, roptions, "bar", NULL); CheckGet(db, roptions, "box", "c"); } StartPhase("cleanup"); leveldb_close(db); leveldb_options_destroy(options); leveldb_readoptions_destroy(roptions); leveldb_writeoptions_destroy(woptions); leveldb_cache_destroy(cache); leveldb_comparator_destroy(cmp); leveldb_env_destroy(env); fprintf(stderr, "PASS\n"); return 0; }
char *ldb_info(struct _leveldb_stuff *ldbs, int *size) { int cnt = 0; *size = 0; /* #server */ char svr[16] = "# Server:"; ++cnt; *size += strlen(svr) + get_number_len(strlen(svr)); /* tsdb version */ char vers[32] = TSDB_VERSION; ++cnt; *size += strlen(vers) + get_number_len(strlen(vers)); /* os */ char os[64] = { 0 }; struct utsname name; uname(&name); sprintf(os, "os: %s %s %s", name.sysname, name.release, name.machine); ++cnt; *size += strlen(os) + get_number_len(strlen(os)); /* pid */ char pid[32] = { 0 }; sprintf(pid, "process_id: %ld", (long) getpid()); ++cnt; *size += strlen(pid) + get_number_len(strlen(pid)); /* mode. */ char mode[32] = { 0 }; sprintf(mode, "mode: %s", LDB_READONLY_SWITCH ? "readonly" : "read/write"); ++cnt; *size += strlen(mode) + get_number_len(strlen(mode)); /* write_port */ char wport[32] = { 0 }; sprintf(wport, "write_port: %d", W_PORT); ++cnt; *size += strlen(wport) + get_number_len(strlen(wport)); /* read_port */ char rport[32] = { 0 }; sprintf(rport, "read_port: %d", R_PORT); ++cnt; *size += strlen(rport) + get_number_len(strlen(rport)); /* uptime_in_seconds */ char uptis[64] = { 0 }; time_t curtime; time(&curtime); sprintf(uptis, "uptime_in_seconds: %ld", (curtime - LDB_START_TIME)); ++cnt; *size += strlen(uptis) + get_number_len(strlen(uptis)); /* uptime_in_days */ char uptid[64] = { 0 }; sprintf(uptid, "uptime_in_days: %ld", (curtime - LDB_START_TIME) / (24 * 3600)); ++cnt; *size += strlen(uptid) + get_number_len(strlen(uptid)); /* # Keyspace. */ char keyspace[32] = "\n# Keyspace:\nTODO"; ++cnt; *size += strlen(keyspace) + get_number_len(strlen(keyspace)); /* #LeveldbStatus: */ char ldbstat[32] = "\n# Leveldbstatus:"; ++cnt; *size += strlen(ldbstat) + get_number_len(strlen(ldbstat)); /* get property. */ char *property = leveldb_property_value(ldbs->db, "leveldb.stats"); ++cnt; *size += strlen(property) + get_number_len(strlen(property)); /* create result */ *size += strlen("*\r\n") + get_number_len(cnt) + strlen("$\r\n\r\n") * cnt; int index = GET_NEED_COUNT( *size, G_PAGE_SIZE ) * G_PAGE_SIZE; char *result = (char *) malloc(index); char *ptr = NULL; sprintf(result, "*%d\r\n", cnt); /* #Server */ ptr = result + strlen(result); ptr = set_bulk(ptr, svr, strlen(svr)); ptr = set_bulk(ptr, vers, strlen(vers)); ptr = set_bulk(ptr, os, strlen(os)); ptr = set_bulk(ptr, mode, strlen(mode)); ptr = set_bulk(ptr, pid, strlen(pid)); ptr = set_bulk(ptr, wport, strlen(wport)); ptr = set_bulk(ptr, rport, strlen(rport)); ptr = set_bulk(ptr, uptis, strlen(uptis)); ptr = set_bulk(ptr, uptid, strlen(uptid)); /* #Keyspace */ ptr = set_bulk(ptr, keyspace, strlen(keyspace)); /* #Leveldbstatus */ ptr = set_bulk(ptr, ldbstat, strlen(ldbstat)); ptr = set_bulk(ptr, property, strlen(property)); leveldb_free(property); log_debug("%s\n", result); return result; }