/* perform optimize command */ static int procoptimize(const char *path, int lmemb, int nmemb, int bnum, int apow, int fpow, TCCMP cmp, int opts, int omode, bool df) { TCBDB *bdb = tcbdbnew(); if (!INVALIDHANDLE(g_dbgfd)) tcbdbsetdbgfd(bdb, g_dbgfd); if (cmp && !tcbdbsetcmpfunc(bdb, cmp, NULL)) printerr(bdb); if (!tcbdbsetcodecfunc(bdb, _tc_recencode, NULL, _tc_recdecode, NULL)) printerr(bdb); if (!tcbdbopen(bdb, path, BDBOWRITER | omode)) { printerr(bdb); tcbdbdel(bdb); return 1; } bool err = false; if (df) { if (!tcbdbdefrag(bdb, INT64_MAX)) { printerr(bdb); err = true; } } else { if (!tcbdboptimize(bdb, lmemb, nmemb, bnum, apow, fpow, opts)) { printerr(bdb); err = true; } } if (!tcbdbclose(bdb)) { if (!err) printerr(bdb); err = true; } tcbdbdel(bdb); return err ? 1 : 0; }
static int opti(rotz_t ctx) { /* values are taken from tcbmgr.c */ static struct { int lmemb; int nmemb; int bnum; int8_t apow; int8_t fpow; uint8_t opts; } opt = { .lmemb = -1, .nmemb = -1, .bnum = -1, .apow = -1, .fpow = -1, .opts = UINT8_MAX, }; if (!tcbdboptimize( ctx->db, opt.lmemb, opt.nmemb, opt.bnum, opt.apow, opt.fpow, opt.opts)) { return -1; } return 0; } #endif /* USE_TCBDB */ #if defined STANDALONE int rotz_cmd_fsck(const struct yuck_cmd_fsck_s UNUSED(argi[static 1U])) { rotz_t ctx; if (UNLIKELY((ctx = make_rotz(db, O_CREAT | O_RDWR)) == NULL)) { fputs("Error opening rotz datastore\n", stderr); return 1; } /* first step is to defrag, ... */ if (UNLIKELY(dfrg(ctx) < 0)) { dberror(ctx, "Error during defrag: "); } else if (UNLIKELY(opti(ctx) < 0)) { dberror(ctx, "Error during optimisation: "); } /* big rcource freeing */ free_rotz(ctx); return 0; }
/* Optimize the file of a word database object. */ bool tcwdboptimize(TCWDB *wdb){ assert(wdb); if(!tcwdblockmethod(wdb, true)) return false; if(!wdb->open || !wdb->cc){ tcbdbsetecode(wdb->idx, TCEINVALID, __FILE__, __LINE__, __func__); tcwdbunlockmethod(wdb); return false; } bool err = false; if(!tcwdbmemsync(wdb, 1)) err = true; if(!tcbdboptimize(wdb->idx, 0, 0, 0, -1, -1, UINT8_MAX)) err = true; tcwdbunlockmethod(wdb); return !err; }
int main(int argc, char* argv[]) { // Parse the command line. if (argc != 3) usage(argv[0]); std::string outputFile = argv[2]; // Open the input file. std::cout << "Processing: " << argv[1] << std::endl; std::ifstream file(argv[1], std::ios_base::in | std::ios_base::binary); if (! file) { std::cerr << "ERROR: Could not open input file: " << argv[1] << std::endl; std::exit(1); } ::boost::iostreams::filtering_istream in; if (file.peek() == 0x1f) in.push(::boost::iostreams::gzip_decompressor()); in.push(file); // Initialise the database. #ifdef QDBM_AS_TOKYOCABINET VILLA* db; if (! (db = vlopen(outputFile.c_str(), VL_OWRITER | VL_OCREAT | VL_OTRUNC | VL_OZCOMP, VL_CMPLEX))) { std::cerr << "ERROR: Could not open QDBM database: " << outputFile << std::endl; std::exit(1); } #else TCBDB* db = tcbdbnew(); if (! tcbdbopen(db, outputFile.c_str(), BDBOWRITER | BDBOCREAT | BDBOTRUNC)) { std::cerr << "ERROR: Could not open Tokyo Cabinet database: " << outputFile << std::endl; std::exit(1); } #endif // Fill the database with the user-supplied key-value pairs. std::string sig, name; const char* pos; unsigned long tot = 0; while (true) { in >> sig; if (in.eof()) break; std::getline(in, name); if (in.eof()) { std::cerr << "ERROR: Signature " << sig << " is missing a corresponding name.\n\n"; DB_CLOSE(db); usage(argv[0]); } // Skip initial whitespace in the manifold name (which will // always be present, since the previous in >> sig // does not eat the separating whitespace). pos = name.c_str(); while (*pos && std::isspace(*pos)) ++pos; if (! *pos) { std::cerr << "ERROR: Signature " << sig << " has an empty name.\n\n"; DB_CLOSE(db); usage(argv[0]); } #ifdef QDBM_AS_TOKYOCABINET if (! vlput(db, sig.c_str(), sig.length(), pos, -1 /* strlen */, VL_DDUP)) { #else if (! tcbdbputdup2(db, sig.c_str(), pos)) { #endif std::cerr << "ERROR: Could not store the record for " << sig << " in the database." << std::endl; DB_CLOSE(db); std::exit(1); } ++tot; } // Close and tidy up. #ifdef QDBM_AS_TOKYOCABINET if (! vloptimize(db)) { std::cerr << "ERROR: Could not optimise QDBM database: " << outputFile << std::endl; DB_CLOSE(db); std::exit(1); } if (! vlclose(db)) { std::cerr << "ERROR: Could not close QDBM database: " << outputFile << std::endl; std::exit(1); } #else // The following call to tcbdboptimise() does not change any options // other than the bitwise compression option given in the final argument. if (! tcbdboptimize(db, 0, 0, 0, -1, -1, BDBTBZIP)) { std::cerr << "ERROR: Could not optimise Tokyo Cabinet database: " << outputFile << std::endl; std::cerr << "Tokyo cabinet error: " << tcerrmsg(tcbdbecode(db)) << std::endl; DB_CLOSE(db); std::exit(1); } if (! tcbdbclose(db)) { std::cerr << "ERROR: Could not close Tokyo Cabinet database: " << outputFile << std::endl; tcbdbdel(db); std::exit(1); } tcbdbdel(db); #endif std::cout << "Success: " << tot << " records." << std::endl; return 0; }
/* optimize */ JNIEXPORT jboolean JNICALL Java_tokyocabinet_BDB_optimize (JNIEnv *env, jobject self, jint lmemb, jint nmemb, jlong bnum, jint apow, jint fpow, jint opts){ TCBDB *bdb = (TCBDB *)(intptr_t)(*env)->GetLongField(env, self, bdb_fid_ptr); return tcbdboptimize(bdb, lmemb, nmemb, bnum, apow, fpow, opts); }