/* * __curindex_search_near -- * WT_CURSOR->search_near method for index cursors. */ static int __curindex_search_near(WT_CURSOR *cursor, int *exact) { WT_CURSOR *child; WT_CURSOR_INDEX *cindex; WT_DECL_RET; WT_ITEM found_key; WT_SESSION_IMPL *session; int cmp; cindex = (WT_CURSOR_INDEX *)cursor; child = cindex->child; JOINABLE_CURSOR_API_CALL(cursor, session, search, NULL); /* * We are searching using the application-specified key, which * (usually) doesn't contain the primary key, so it is just a prefix of * any matching index key. That said, if there is an exact match, we * want to find the first matching index entry and set exact equal to * zero. * * Do a search_near, and if we find an entry that is too small, step to * the next one. In the unlikely event of a search past the end of the * tree, go back to the last key. */ __wt_cursor_set_raw_key(child, &cursor->key); WT_ERR(child->search_near(child, &cmp)); if (cmp < 0) { if ((ret = child->next(child)) == WT_NOTFOUND) ret = child->prev(child); WT_ERR(ret); } /* * We expect partial matches, and want the smallest record with a key * greater than or equal to the search key. * * If the found key starts with the search key, we indicate a match by * setting exact equal to zero. * * The compare function expects application-supplied keys to come first * so we flip the sign of the result to match what callers expect. */ found_key = child->key; if (found_key.size > cursor->key.size) found_key.size = cursor->key.size; WT_ERR(__wt_compare( session, cindex->index->collator, &cursor->key, &found_key, exact)); *exact = -*exact; WT_ERR(__curindex_move(cindex)); if (0) { err: F_CLR(cursor, WT_CURSTD_KEY_INT | WT_CURSTD_VALUE_INT); } API_END_RET(session, ret); }
/* * __curindex_search -- * WT_CURSOR->search method for index cursors. */ static int __curindex_search(WT_CURSOR *cursor) { WT_CURSOR *child; WT_CURSOR_INDEX *cindex; WT_DECL_RET; WT_ITEM found_key; WT_SESSION_IMPL *session; int cmp; cindex = (WT_CURSOR_INDEX *)cursor; child = cindex->child; JOINABLE_CURSOR_API_CALL(cursor, session, search, NULL); /* * We are searching using the application-specified key, which * (usually) doesn't contain the primary key, so it is just a prefix of * any matching index key. Do a search_near, step to the next entry if * we land on one that is too small, then check that the prefix * matches. */ __wt_cursor_set_raw_key(child, &cursor->key); WT_ERR(child->search_near(child, &cmp)); if (cmp < 0) WT_ERR(child->next(child)); /* * We expect partial matches, and want the smallest record with a key * greater than or equal to the search key. * * If the key we find is shorter than the search key, it can't possibly * match. * * The only way for the key to be exactly equal is if there is an index * on the primary key, because otherwise the primary key columns will * be appended to the index key, but we don't disallow that (odd) case. */ found_key = child->key; if (found_key.size < cursor->key.size) WT_ERR(WT_NOTFOUND); found_key.size = cursor->key.size; WT_ERR(__wt_compare( session, cindex->index->collator, &cursor->key, &found_key, &cmp)); if (cmp != 0) { ret = WT_NOTFOUND; goto err; } WT_ERR(__curindex_move(cindex)); if (0) { err: F_CLR(cursor, WT_CURSTD_KEY_INT | WT_CURSTD_VALUE_INT); } API_END_RET(session, ret); }
/* * __curindex_prev -- * WT_CURSOR->prev method for index cursors. */ static int __curindex_prev(WT_CURSOR *cursor) { WT_CURSOR_INDEX *cindex; WT_DECL_RET; WT_SESSION_IMPL *session; cindex = (WT_CURSOR_INDEX *)cursor; JOINABLE_CURSOR_API_CALL(cursor, session, prev, NULL); F_CLR(cursor, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET); if ((ret = cindex->child->prev(cindex->child)) == 0) ret = __curindex_move(cindex); err: API_END_RET(session, ret); }
/* * __curindex_search_near -- * WT_CURSOR->search_near method for index cursors. */ static int __curindex_search_near(WT_CURSOR *cursor, int *exact) { WT_CURSOR_INDEX *cindex; WT_DECL_RET; WT_SESSION_IMPL *session; cindex = (WT_CURSOR_INDEX *)cursor; JOINABLE_CURSOR_API_CALL(cursor, session, search_near, NULL); __wt_cursor_set_raw_key(cindex->child, &cursor->key); if ((ret = cindex->child->search_near(cindex->child, exact)) == 0) ret = __curindex_move(cindex); else F_CLR(cursor, WT_CURSTD_KEY_INT | WT_CURSTD_VALUE_INT); err: API_END_RET(session, ret); }