int kvs_helper_cursor_nextr(KVS_cursor *const cursor, KVS_range const *const range, KVS_val *const key, KVS_val *const data, int const dir) { assert(kvs_cursor_cmp(cursor, range->min, range->max) < 0); KVS_val tmp; KVS_val *k = key ? key : &tmp; int rc = kvs_cursor_next(cursor, k, data, dir); if(rc < 0) return rc; int const min = kvs_cursor_cmp(cursor, k, range->min); int const max = kvs_cursor_cmp(cursor, k, range->max); if(min > 0 && max < 0) return 0; kvs_cursor_clear(cursor); return KVS_NOTFOUND; }
/* * kvs_cursor_search_near -- * WT_CURSOR::search_near method. */ static int kvs_cursor_search_near(WT_CURSOR *wt_cursor, int *exact) { int ret; /* * XXX * I'm not confident this is sufficient: if there are multiple threads * of control, it's possible for the search for an exact match to fail, * another thread of control to insert (and commit) an exact match, and * then it's possible we'll return the wrong value. This needs to be * revisited once the transactional code is in place. */ /* Search for an exact match. */ if ((ret = kvs_cursor_search(wt_cursor)) == 0) { *exact = 0; return (0); } if (ret != WT_NOTFOUND) return (ret); /* Search for a key that's larger. */ if ((ret = kvs_cursor_next(wt_cursor)) == 0) { *exact = 1; return (0); } if (ret != WT_NOTFOUND) return (ret); /* Search for a key that's smaller. */ if ((ret = kvs_cursor_prev(wt_cursor)) == 0) { *exact = -1; return (0); } return (ret); }
int kvs_helper_cursor_firstr(KVS_cursor *const cursor, KVS_range const *const range, KVS_val *const key, KVS_val *const data, int const dir) { assert(kvs_cursor_cmp(cursor, range->min, range->max) < 0); if(0 == dir) return KVS_EINVAL; KVS_val const *const first = dir > 0 ? range->min : range->max; KVS_val k = *first; int rc = kvs_cursor_seek(cursor, &k, data, dir); if(rc < 0) return rc; int x = kvs_cursor_cmp(cursor, &k, first); assert(x * dir >= 0); if(0 == x) { rc = kvs_cursor_next(cursor, &k, data, dir); if(rc < 0) return rc; } KVS_val const *const last = dir < 0 ? range->min : range->max; x = kvs_cursor_cmp(cursor, &k, last); if(x * dir < 0) { if(key) *key = k; return 0; } else { kvs_cursor_clear(cursor); return KVS_NOTFOUND; } }