rc_t bt_cursor_t::_check_page_update(btree_page_h &p) { // was the page changed? if (_pid != p.pid() || p.get_page_lsn() != _lsn) { // check if the page still contains the key we are based on bool found = false; if (p.fence_contains(_key)) { // it still contains. just re-locate _slot p.search(_key, found, _slot); } else { // we have to re-locate the page W_DO( btree_impl::_ux_traverse(_store, _key, btree_impl::t_fence_contain, LATCH_SH, p)); p.search(_key, found, _slot); } w_assert1(found || !_needs_lock || (!_forward && !_upper_inclusive && !_dont_move_next)); // see _locate_first _set_current_page(p); } return RCOK; }
rc_t btree_impl::_ux_lock_range(const StoreID& stid, btree_page_h& leaf, const void* keystr, size_t keylen, slotid_t slot, latch_mode_t latch_mode, const okvl_mode& exact_hit_lock_mode, const okvl_mode& miss_lock_mode, bool check_only) { w_assert1(slot >= -1 && slot <= leaf.nrecs()); w_assert1(exact_hit_lock_mode.get_gap_mode() == okvl_mode::N); w_assert1(miss_lock_mode.is_keylock_empty()); if (slot == -1) { // this means we should search it again bool found; leaf.search((const char *) keystr, keylen, found, slot); w_assert1(!found); // precondition } w_assert1(slot >= 0 && slot <= leaf.nrecs()); #if W_DEBUG_LEVEL > 1 w_keystr_t key, key_at_slot; key.construct_from_keystr(keystr, keylen); if (slot<leaf.nrecs()) { leaf.get_key(slot, key_at_slot); w_assert1(key_at_slot.compare(key)>0); } #endif // W_DEBUG_LEVEL > 1 slot--; // want range lock from previous key if (slot == -1 && w_keystr_t::compare_bin_str(keystr, keylen, leaf.get_fence_low_key(), leaf.get_fence_low_length()) == 0) { // We were searching for the low-fence key! then, we take key lock on it and // subsequent structural modification (e.g., merge) will add the low-fence as // ghost record to be aware of the lock. W_DO (_ux_lock_key(stid, leaf, leaf.get_fence_low_key(), leaf.get_fence_low_length(), latch_mode, exact_hit_lock_mode, check_only)); } else { w_keystr_t prevkey; if (slot == -1) { leaf.copy_fence_low_key(prevkey); } else { leaf.get_key(slot, prevkey); } #if W_DEBUG_LEVEL > 1 w_assert1(prevkey.compare(key) < 0); #endif // W_DEBUG_LEVEL > 1 W_DO (_ux_lock_key(stid, leaf, prevkey, latch_mode, miss_lock_mode, check_only)); } return RCOK; }