|
Zero
0.1.0
|
A cursor object to sequentially read BTree. More...
#include <btcursor.h>
Public Member Functions | |
| bt_cursor_t (StoreID store, bool forward) | |
| bt_cursor_t (StoreID store, const w_keystr_t &lower, bool lower_inclusive, const w_keystr_t &upper, bool upper_inclusive, bool forward) | |
| bt_cursor_t (StoreID store, const w_keystr_t &bound, bool inclusive, bool forward) | |
| ~bt_cursor_t () | |
| rc_t | next () |
| bool | is_valid () const |
| bool | is_forward () const |
| void | close () |
| const w_keystr_t & | key () |
| bool | eof () |
| int | elen () const |
| char * | elem () |
Private Member Functions | |
| void | _init (StoreID store, const w_keystr_t &lower, bool lower_inclusive, const w_keystr_t &upper, bool upper_inclusive, bool forward) |
| rc_t | _locate_first () |
| rc_t | _check_page_update (btree_page_h &p) |
| rc_t | _find_next (btree_page_h &p, bool &eof) |
| void | _release_current_page () |
| void | _set_current_page (btree_page_h &page) |
| w_rc_t | _refix_current_key (btree_page_h &p) |
| Re-fix the page at which the cursor was on with SH mode. More... | |
| rc_t | _advance_one_slot (btree_page_h &p, bool &eof) |
| Chooses next slot and potentially next page for cursor access. More... | |
| rc_t | _make_rec (const btree_page_h &page) |
Private Attributes | |
| StoreID | _store |
| w_keystr_t | _lower |
| w_keystr_t | _upper |
| bool | _lower_inclusive |
| bool | _upper_inclusive |
| bool | _forward |
| bool | _needs_lock |
| bool | _ex_lock |
| bool | _dont_move_next |
| bool | _first_time |
| bool | _eof |
| PageID | _pid |
| pin_for_refix_holder | _pid_bfidx |
| slotid_t | _slot |
| lsn_t | _lsn |
| w_keystr_t | _key |
| w_keystr_t | _tmp_next_key_buf |
| smsize_t | _elen |
| char | _elbuf [SM_PAGESIZE] |
A cursor object to sequentially read BTree.
This class is used as follows.
// constructs a cursor with search conditions.
bt_cursor_t cursor (volid, storeid,
lower_bound, lower_inclusive,
upper_bound, upper_inclusive,
is_forward_direction);
do {
W_DO(cursor.next());
if (cursor.eof()) {
break;
}
w_keystr_t key = cursor.key();
cvec_t el (cursor.elem(), cursor.elen());
....
} while (true);A cursor object releases latches on the page after each next() call to allow concurrent accesses. Thus, it also checks if the current page has been changed after its last access using _lsn variable.
If it has been changed, and if the page still contains the key we previously read, we just re-locate _slot in the page and goes on.
If it has been changed and also the page doesn't contain the key we previously read any more, we re-locate _pid by re-traversing the tree.
These two events are expensive, but happen only after the LSN check, so they are rare too.
A cursor object also takes locks on the keys and their intervals it read. Here, the complication is that the cursor object has two modes; forward and backward. Unfortunately, these two are not quite symmetric because the key range locks are on half-open interval (a key and open interval on its right).
Also, there's a trade-off between concurrency and overhead. In this class, we try to minimize overhead rather than concurrency. See jira ticket:89 "Cursor case: overhead-concurrency trade-off" (originally trac ticket:91) for more details.
| bt_cursor_t::bt_cursor_t | ( | StoreID | store, |
| bool | forward | ||
| ) |
Constructs a full scan cursor.
| [in] | store | Store ID |
| [in] | forward | true if this cursor goes forward from lower bound, false if this cursor goes backwards from upper bound. |
| bt_cursor_t::bt_cursor_t | ( | StoreID | store, |
| const w_keystr_t & | lower, | ||
| bool | lower_inclusive, | ||
| const w_keystr_t & | upper, | ||
| bool | upper_inclusive, | ||
| bool | forward | ||
| ) |
Creates a BTree cursor object for the given search conditions.
| [in] | store | Store ID |
| [in] | lower | lower bound of the search range |
| [in] | lower_inclusive | true if returning a tuple exactly matching the lower bound |
| [in] | upper | upper bound of the search range |
| [in] | upper_inclusive | true if returning a tuple exactly matching the upper bound |
| [in] | forward | true if this cursor goes forward from lower bound, false if this cursor goes backwards from upper bound. |
| bt_cursor_t::bt_cursor_t | ( | StoreID | store, |
| const w_keystr_t & | bound, | ||
| bool | inclusive, | ||
| bool | forward | ||
| ) |
Constructs an open-end scan, with a start condition only.
| [in] | store | Store ID |
| [in] | bound | start condition for the scan (lower if forward, upper otherwise) |
| [in] | inclusive | true if returning a tuple exactly matching the bound |
| [in] | forward | true if this cursor goes forward from lower bound, false if this cursor goes backwards from upper bound. |
|
inline |
|
private |
Chooses next slot and potentially next page for cursor access.
Computes the next slot, which might be on a successor to p, or even a successor to the successor, in which case, p will be re-fixed to the page, and "slot" indicate where on that page it is. Leave exactly one page fixed.
| [in] | p | fixed current page |
| [out] | eof | whether this cursor reached the end |
|
private |
|
private |
|
private |
|
private |
|
private |
Make the cursor point to record at "slot" on "page".
|
private |
Re-fix the page at which the cursor was on with SH mode.
In most cases, this method just re-fixes the page ID we observed before. However, fix_direct might fail if the disk page is corrupted. In that case, we need the parent page to apply Single-Page-Recovery on the corrupted page (eBF_DIRECTFIX_SWIZZLED_PTR). Thus, we re-locate the key by traversing from the root. This is expensive, but does not happen often.
| [out] | p | page handle that will hold the re-fixed page |
|
private |
|
private |
| void bt_cursor_t::close | ( | ) |
|
inline |
|
inline |
|
inline |
Admittedly bad naming, but this means if the cursor still has record to return. So, even if it's not quite the end of file or index, it returns true when it exceeds the upper-condition.
|
inline |
|
inline |
|
inline |
| rc_t bt_cursor_t::next | ( | ) |
Moves the BTree cursor to next slot.
|
private |
Whether we should move on to next key on the subsequent next() call.
|
private |
buffer to store the current record (el).
|
private |
length of current record(el).
|
private |
true if no element left.
|
private |
|
private |
true if the first next() has not been called.
|
private |
|
private |
current key.
|
private |
|
private |
|
private |
lsn of the current page AS OF last access.
|
private |
these are retrieved from xct() when the cursur object is made.
|
private |
id of current page. current page has additional pin_count for refix().
|
private |
current page's corresponding slot index in the bufferpool.
|
private |
current slot in the current page.
|
private |
|
private |
only internally used as temporary variable.
|
private |
|
private |
1.8.12