int seen_foreach(struct seen *seendb, seenproc_t *f, void *rock) { struct seendata_rock sdrock; sdrock.f = f; sdrock.rock = rock; return cyrusdb_foreach(seendb->db, "", 0, NULL, foreach_proc, &sdrock, NULL); }
int mboxkey_merge(const char *tmpfile, const char *tgtfile) { int r = 0; struct db *tmp = NULL, *tgt = NULL; struct mboxkey_merge_rock rock; /* xxx does this need to be CYRUSDB_CREATE? */ r = cyrusdb_open(DB, tmpfile, CYRUSDB_CREATE, &tmp); if(r) goto done; r = cyrusdb_open(DB, tgtfile, CYRUSDB_CREATE, &tgt); if(r) goto done; rock.db = tgt; rock.tid = NULL; r = cyrusdb_foreach(tmp, "", 0, NULL, mboxkey_merge_cb, &rock, &rock.tid); if(r) cyrusdb_abort(rock.db, rock.tid); else cyrusdb_commit(rock.db, rock.tid); done: if(tgt) cyrusdb_close(tgt); if(tmp) cyrusdb_close(tmp); return r; }
EXPORTED int denydb_foreach(denydb_proc_t proc, void *rock) { struct denydb_rock dr; if (!denydb) return 0; dr.proc = proc; dr.rock = rock; return cyrusdb_foreach(denydb, "", 0, denydb_foreach_cb, NULL, &dr, /* txn */NULL); }
EXPORTED int duplicate_find(const char *msgid, duplicate_find_proc_t proc, void *rock) { struct findrock frock; if (!msgid) msgid = ""; frock.proc = proc; frock.rock = rock; /* check each entry in our database */ cyrusdb_foreach(dupdb, msgid, strlen(msgid), NULL, find_cb, &frock, NULL); return 0; }
/* we want to merge records from "newfile" into * the already existing "currentfile", but only * if the record in newfile is actually newer * (or doesn't exist in currentfile yet) */ int seen_merge(struct seen *seendb, const char *newfile) { int r = 0; struct db *newdb = NULL; r = cyrusdb_open(DB, newfile, 0, &newdb); /* if it doesn't exist, there's nothing * to do, so abort without an error */ if (r == CYRUSDB_NOTFOUND) return 0; if (!r) r = cyrusdb_foreach(newdb, "", 0, NULL, seen_merge_cb, seendb, NULL); if (newdb) cyrusdb_close(newdb); return r; }
EXPORTED int quota_foreach(const char *prefix, quotaproc_t *proc, void *rock, struct txn **tid) { int r; char *search = prefix ? (char *)prefix : ""; struct quota_foreach_t foreach_d; foreach_d.proc = proc; foreach_d.rock = rock; foreach_d.tid = tid; r = cyrusdb_foreach(qdb, search, strlen(search), NULL, do_onequota, &foreach_d, tid); return r; }
int main(int argc, char *argv[]) { int iter; int seed; int i; char *key; char *val; struct db *db; int r; struct txn *txn; const char *data; int datalen; struct timeval t1, t2; int initsize; if (argc > 1) { iter = atoi(argv[1]); } else { printf("%s [iterations] [rndseed] [initsize]\n", argv[0]); printf("if iterations is negative, run forever and report every -iter\n"); exit(1); } TRY(DB->init(".", 0)); if (argc > 2) { srand(atoi(argv[2])); } TRY(cyrusdb_open(DB, "scratch", &db)); if (cyrusdb_consistent) { TRY(cyrusdb_consistent(db)); } if (argc > 3) { initsize = atoi(argv[3]); txn = NULL; for (i = 0; i < initsize; i++) { /* generate a random key */ key = genrand(10 + (rand() % 10)); /* generate a random value */ val = genrand(10 + (rand() % 100)); TRY(cyrusdb_store(db, key, strlen(key), val, strlen(val), &txn)); } TRY(cyrusdb_commit(db, txn)); if (cyrusdb_consistent) { TRY(cyrusdb_consistent(db)); } } printf("starting...\n"); /* repeat for ever if iter < 0 */ for (i = 0; iter > 0 ? (i < iter) : 1; i++) { int oper = rand() % 10; if (i > 0 && iter < 0 && ((i % -iter) == 0)) { do_report(); } switch (oper) { case 0: /* do an ADD */ if (verbose) printf("A"); /* insert it */ gettimeofday(&t1, NULL); /* generate a random key */ key = genrand(10 + (rand() % 10)); /* generate a random value */ val = genrand(10 + (rand() % 100)); txn = NULL; TRY(cyrusdb_store(db, key, strlen(key), val, strlen(val), &txn)); TRY(cyrusdb_commit(db, txn)); gettimeofday(&t2, NULL); ADDDIFF(t_add, t1, t2); c_add++; free(key); free(val); break; case 1: /* do a modify */ if (verbose) printf("M"); gettimeofday(&t1, NULL); /* pick a random victim */ count = 0; victim = NULL; txn = NULL; TRY(cyrusdb_foreach(db, NULL, 0, &countem, NULL, NULL, &txn)); if (count == 0) continue; TRY(cyrusdb_foreach(db, NULL, 0, &findvictim, NULL, NULL, &txn)); assert(victim != NULL); /* generate a random value */ val = genrand(10 + (rand() % 100)); /* do an add */ TRY(cyrusdb_store(db, victim, strlen(victim), val, strlen(val), &txn)); free(val); TRY(cyrusdb_commit(db, txn)); free(victim); victim = NULL; gettimeofday(&t2, NULL); ADDDIFF(t_mod, t1, t2); c_mod++; break; case 2: /* do a delete */ if (verbose) printf("D"); gettimeofday(&t1, NULL); /* pick a random victim */ count = 0; victim = NULL; txn = NULL; TRY(cyrusdb_foreach(db, NULL, 0, &countem, NULL, NULL, &txn)); if (count == 0) continue; TRY(cyrusdb_foreach(db, NULL, 0, &findvictim, NULL, NULL, &txn)); assert(victim != NULL); /* delete it */ TRY(cyrusdb_delete(db, victim, strlen(victim), &txn, 0)); TRY(cyrusdb_commit(db, txn)); free(victim); victim = NULL; gettimeofday(&t2, NULL); ADDDIFF(t_del, t1, t2); c_del++; break; default: /* do a "read" */ if (verbose) printf("R"); gettimeofday(&t1, NULL); /* generate a random key */ key = genrand(10 + (rand() % 10)); txn = NULL; TRY(cyrusdb_fetch(db, key, strlen(key), &data, &datalen, &txn)); TRY(cyrusdb_commit(db, txn)); gettimeofday(&t2, NULL); ADDDIFF(t_find, t1, t2); c_find++; free(key); } fflush(stdout); #if 0 /* run the consistency function, if any */ if (cyrusdb_consistent) { TRY(cyrusdb_consistent(db)); } #endif } TRY(cyrusdb_close(db)); TRY(DB->done()); do_report(); return 0; }