int db_cursor_seekr(DB_cursor *const cursor, DB_range const *const range, DB_val *const key, DB_val *const data, int const dir) { assert(db_cursor_cmp(cursor, range->min, range->max) < 0); int rc = db_cursor_seek(cursor, key, data, dir); if(rc < 0) return rc; DB_val const *const limit = dir < 0 ? range->min : range->max; int x = db_cursor_cmp(cursor, key, limit); if(x * dir < 0) return 0; db_cursor_clear(cursor); return DB_NOTFOUND; }
int SLNSessionGetSubmittedFile(SLNSessionRef const session, DB_txn *const txn, strarg_t const URI) { uint64_t const sessionID = SLNSessionGetID(session); DB_cursor *cursor = NULL; int rc = db_txn_cursor(txn, &cursor); if(rc < 0) return rc; DB_range range[1]; DB_val filekey[1]; SLNURIAndFileIDRange1(range, txn, URI); rc = db_cursor_firstr(cursor, range, filekey, NULL, +1); if(rc < 0) return rc; for(; rc >= 0; rc = db_cursor_nextr(cursor, range, filekey, NULL, +1)) { strarg_t u; uint64_t fileID; SLNURIAndFileIDKeyUnpack(filekey, txn, &u, &fileID); DB_val sessionkey[1]; SLNFileIDAndSessionIDKeyPack(sessionkey, txn, fileID, sessionID); rc = db_cursor_seek(cursor, sessionkey, NULL, 0); if(DB_NOTFOUND == rc) continue; return rc; } return SLN_NOSESSION; }
int db_cursor_firstr(DB_cursor *const cursor, DB_range const *const range, DB_val *const key, DB_val *const data, int const dir) { assert(db_cursor_cmp(cursor, range->min, range->max) < 0); if(0 == dir) return DB_EINVAL; DB_val const *const first = dir > 0 ? range->min : range->max; DB_val k = *first; int rc = db_cursor_seek(cursor, &k, data, dir); if(rc < 0) return rc; int x = db_cursor_cmp(cursor, &k, first); assert(x * dir >= 0); if(0 == x) { rc = db_cursor_next(cursor, &k, data, dir); if(rc < 0) return rc; } DB_val const *const last = dir < 0 ? range->min : range->max; x = db_cursor_cmp(cursor, &k, last); if(x * dir < 0) { if(key) *key = k; return 0; } else { db_cursor_clear(cursor); return DB_NOTFOUND; } }
int db_get(DB_txn *const txn, DB_val *const key, DB_val *const data) { DB_cursor *cursor; int rc = db_txn_cursor(txn, &cursor); if(rc < 0) return rc; return db_cursor_seek(cursor, key, data, 0); }