int _findsmallest(struct basement **bsms, int bsms_size, struct cursor *cur, struct search *so) { int i; int ret; int end; struct basement_iter *smallest = NULL; struct basement_iter iters[bsms_size]; /* seek each level */ for (i = (bsms_size - 1); i >= 0; i--) { struct basement *bsm; struct basement_iter *iter; bsm = bsms[i]; iter = &iters[i]; basement_iter_init(iter, bsm); if (so->key) { /* * sought position is >= position(so->key) * so we should ensure that all sought iters positioned after so->key */ basement_iter_seek(iter, so->key); if (so->slip != SLIP_ZERO) { if (basement_iter_valid(iter) && (so->key_compare_func(&iter->key, so->key) == 0)) basement_iter_next(iter); } } else { basement_iter_seektofirst(iter); } } for (i = (bsms_size - 1); i >= 0; i--) { struct basement_iter *iter = &iters[i]; if (basement_iter_valid(iter)) { if (smallest == NULL) { smallest = iter; } else if (so->key_compare_func(&iter->key, &smallest->key) < 0) { smallest = iter; } } } end = (basement_iter_valid(&iters[0]) == 0); if (end) { if (smallest) { cur->valid = 1; cur->key = smallest->key; cur->val = smallest->val; } else { cur->valid = 0; } ret = CURSOR_EOF; } else { cur->valid = 1; cur->key = smallest->key; cur->val = smallest->val; ret = CURSOR_CONTINUE; } return ret; }
CTEST(basement, multiversion) { int i; int ret; int R = 123; char kbuf[KEY_SIZE]; char vbuf[VAL_SIZE]; struct basement_iter iter; struct basement *bsm = basement_new(); struct txnid_pair xidpair = { .child_xid = TXNID_NONE, .parent_xid = TXNID_NONE }; _random_key(vbuf, VAL_SIZE); MSN msn = 0U; for (i = 0; i < R; i++) { memset(kbuf, 0, KEY_SIZE); snprintf(kbuf, KEY_SIZE, "key-%d", i); struct msg k = {.data = kbuf, .size = KEY_SIZE}; struct msg v = {.data = vbuf, .size = VAL_SIZE}; basement_put(bsm, msn++, MSG_INSERT, &k, &v, &xidpair ); } /* 3 versions of key-66 */ R = 3; for (i = 0; i < R; i++) { memset(kbuf, 0, KEY_SIZE); snprintf(kbuf, KEY_SIZE, "key-66"); struct msg k = {.data = kbuf, .size = KEY_SIZE}; struct msg v = {.data = vbuf, .size = VAL_SIZE}; basement_put(bsm, msn++, MSG_INSERT, &k, &v, &xidpair ); } /* 5 versions of key-88 */ R = 5; for (i = 0; i < R; i++) { memset(kbuf, 0, KEY_SIZE); snprintf(kbuf, KEY_SIZE, "key-88"); struct msg k = {.data = kbuf, .size = KEY_SIZE}; struct msg v = {.data = vbuf, .size = VAL_SIZE}; basement_put(bsm, msn++, MSG_INSERT, &k, &v, &xidpair ); } /* key-66 */ memset(kbuf, 0, KEY_SIZE); snprintf(kbuf, KEY_SIZE, "key-66"); struct msg k1 = {.data = kbuf, .size = KEY_SIZE}; basement_iter_init(&iter, bsm); basement_iter_seek(&iter, &k1); ret = basement_iter_valid(&iter); ASSERT_EQUAL(1, ret); ASSERT_EQUAL(66, iter.msn); basement_iter_next(&iter); ret = basement_iter_valid(&iter); ASSERT_EQUAL(1, ret); ASSERT_EQUAL(123, iter.msn); /* less than valid */ ret = basement_iter_valid_lessorequal(&iter, &k1); ASSERT_EQUAL(1, ret); memset(kbuf, 0, KEY_SIZE); snprintf(kbuf, KEY_SIZE, "key-67"); k1.size = KEY_SIZE; k1.data = kbuf; ret = basement_iter_valid_lessorequal(&iter, &k1); ASSERT_EQUAL(1, ret); memset(kbuf, 0, KEY_SIZE); snprintf(kbuf, KEY_SIZE, "key-65"); k1.size = KEY_SIZE; k1.data = kbuf; ret = basement_iter_valid_lessorequal(&iter, &k1); ASSERT_EQUAL(0, ret); /* key-88 */ memset(kbuf, 0, KEY_SIZE); snprintf(kbuf, KEY_SIZE, "key-88"); struct msg k2 = {.data = kbuf, .size = KEY_SIZE}; basement_iter_seek(&iter, &k2); ret = basement_iter_valid(&iter); ASSERT_EQUAL(1, ret); ASSERT_EQUAL(88, iter.msn); basement_iter_next(&iter); basement_iter_next(&iter); ret = basement_iter_valid(&iter); ASSERT_EQUAL(1, ret); ASSERT_EQUAL(127, iter.msn); /* next&prev diff key */ /* key-87 */ memset(kbuf, 0, KEY_SIZE); snprintf(kbuf, KEY_SIZE, "key-87"); struct msg k3 = {.data = kbuf, .size = KEY_SIZE}; basement_iter_prev_diff_key(&iter); ret = msg_key_compare(&k3, &iter.key); ASSERT_EQUAL(0, ret); /* key-88 */ basement_iter_next(&iter); memset(kbuf, 0, KEY_SIZE); snprintf(kbuf, KEY_SIZE, "key-88"); struct msg k22 = {.data = kbuf, .size = KEY_SIZE}; ret = msg_key_compare(&k22, &iter.key); ASSERT_EQUAL(0, ret); /* key-89 */ memset(kbuf, 0, KEY_SIZE); snprintf(kbuf, KEY_SIZE, "key-89"); struct msg k4 = {.data = kbuf, .size = KEY_SIZE}; basement_iter_next_diff_key(&iter); ret = msg_key_compare(&k4, &iter.key); ASSERT_EQUAL(0, ret); basement_free(bsm); xcheck_all_free(); }