int oc_bpt_insert_range_b( struct Oc_wu *wu_p, Oc_bpt_state *s_p, int length, struct Oc_bpt_key *key_array, struct Oc_bpt_data *data_array) { int rc; if (0 == length) return 0; oc_bpt_trace_wu_lvl( 2, OC_EV_BPT_INSERT_RANGE, wu_p, "tid=%Lu [%s]", s_p->tid, oc_bpt_nd_string_of_2key( s_p, oc_bpt_nd_key_array_kth(s_p, key_array, 0), oc_bpt_nd_key_array_kth(s_p, key_array, length-1))); oc_utl_debugassert(s_p->cfg_p->initialized); oc_utl_trk_crt_lock_read(wu_p, &s_p->lock); rc = oc_bpt_op_insert_range_b(wu_p, s_p, length, key_array, data_array); oc_utl_trk_crt_unlock(wu_p, &s_p->lock); oc_bpt_trace_wu_lvl(3, OC_EV_BPT_INSERT_RANGE, wu_p, "rc=%d", rc); return rc; }
bool oc_bpt_dbg_validate_clones_b( struct Oc_wu *wu_p, int n_clones, Oc_bpt_state *st_array[]) { bool rc; int i; oc_bpt_trace_wu_lvl(2, OC_EV_BPT_VALIDATE_CLONES, wu_p, ""); // lock all the clones for (i=0; i<n_clones; i++) { Oc_bpt_state *s_p = st_array[i]; oc_utl_debugassert(s_p->cfg_p->initialized); oc_utl_trk_crt_lock_write(wu_p, &s_p->lock); } rc = oc_bpt_op_validate_clones_b(wu_p, n_clones, st_array); // unlock all the clones for (i=0; i<n_clones; i++) { Oc_bpt_state *s_p = st_array[i]; oc_utl_trk_crt_unlock(wu_p, &s_p->lock); } return rc; }
void oc_bpt_lookup_range_b( struct Oc_wu *wu_p, Oc_bpt_state *s_p, struct Oc_bpt_key *min_key_p, struct Oc_bpt_key *max_key_p, int max_num_keys_i, struct Oc_bpt_key *key_array_po, struct Oc_bpt_data *data_array_po, int *nkeys_found_po) { struct Oc_bpt_op_lookup_range lkr; oc_bpt_trace_wu_lvl(2, OC_EV_BPT_LOOKUP_RANGE, wu_p, "tid=%Lu [%s]", s_p->tid, oc_bpt_nd_string_of_2key(s_p, min_key_p, max_key_p)); oc_utl_debugassert(s_p->cfg_p->initialized); lkr.min_key_p = min_key_p; lkr.max_key_p = max_key_p; lkr.max_num_keys_i = max_num_keys_i; lkr.key_array_po = key_array_po; lkr.data_array_po = data_array_po; lkr.nkeys_found_po = nkeys_found_po; // There are too many arguments, we stuff them into a single structure oc_utl_trk_crt_lock_read(wu_p, &s_p->lock); oc_bpt_op_lookup_range_b(wu_p, s_p, &lkr); oc_utl_trk_crt_unlock(wu_p, &s_p->lock); }
static void node_release(Oc_wu *wu_p, Oc_bpt_node *node_p) { oc_utl_trk_crt_unlock(wu_p, &node_p->lock); g_refcnt--; oc_utl_assert(g_refcnt>=0); }
uint64 oc_bpt_create_b( struct Oc_wu *wu_p, Oc_bpt_state *s_p) { oc_utl_assert(NULL == s_p->root_node_p); oc_utl_debugassert(s_p->cfg_p->initialized); oc_utl_trk_crt_lock_write(wu_p, &s_p->lock); { s_p->root_node_p = s_p->cfg_p->node_alloc(wu_p); oc_bpt_nd_create_root(wu_p, s_p, s_p->root_node_p); oc_utl_trk_crt_unlock(wu_p, &s_p->root_node_p->lock); } oc_utl_trk_crt_unlock(wu_p, &s_p->lock); return s_p->root_node_p->disk_addr; }
void oc_bpt_iter_b( struct Oc_wu *wu_p, struct Oc_bpt_state *s_p, void (*iter_f)(struct Oc_wu *, Oc_bpt_node*)) { oc_bpt_trace_wu_lvl(2, OC_EV_BPT_ITER, wu_p, "tid=%Lu", s_p->tid); oc_utl_trk_crt_lock_write(wu_p, &s_p->lock); oc_bpt_utl_iter_b(wu_p, s_p, iter_f, s_p->root_node_p); oc_utl_trk_crt_unlock(wu_p, &s_p->lock); }
void oc_bpt_dbg_output_b( struct Oc_wu *wu_p, struct Oc_bpt_state *s_p, char *tag_p) { oc_utl_debugassert(s_p->cfg_p->initialized); oc_utl_trk_crt_lock_write(wu_p, &s_p->lock); oc_bpt_op_output_dot_b(wu_p, s_p, tag_p); oc_utl_trk_crt_unlock(wu_p, &s_p->lock); }
bool oc_bpt_dbg_validate_b( struct Oc_wu *wu_p, Oc_bpt_state *s_p) { bool rc; oc_bpt_trace_wu_lvl(2, OC_EV_BPT_VALIDATE, wu_p, "tid=%Lu", s_p->tid); oc_utl_debugassert(s_p->cfg_p->initialized); oc_utl_trk_crt_lock_write(wu_p, &s_p->lock); rc = oc_bpt_op_validate_b(wu_p, s_p); oc_utl_trk_crt_unlock(wu_p, &s_p->lock); return rc; }
bool oc_bpt_remove_key_b( struct Oc_wu *wu_p, struct Oc_bpt_state *s_p, struct Oc_bpt_key *key_p) { bool rc; oc_bpt_trace_wu_lvl(2, OC_EV_BPT_REMOVE_KEY, wu_p, "tid=%Lu %s", s_p->tid, oc_bpt_nd_string_of_key(s_p, key_p)); oc_utl_debugassert(s_p->cfg_p->initialized); oc_utl_trk_crt_lock_read(wu_p, &s_p->lock); rc = oc_bpt_op_remove_key_b(wu_p, s_p, key_p); oc_utl_trk_crt_unlock(wu_p, &s_p->lock); return rc; }
bool oc_bpt_lookup_key_b( struct Oc_wu *wu_p, struct Oc_bpt_state *s_p, struct Oc_bpt_key *key_p, struct Oc_bpt_data *data_po) { bool rc; oc_bpt_trace_wu_lvl(2, OC_EV_BPT_LOOKUP_KEY, wu_p, "tid=%Lu key=%s", s_p->tid, oc_bpt_nd_string_of_key(s_p, key_p)); oc_utl_debugassert(s_p->cfg_p->initialized); oc_utl_trk_crt_lock_read(wu_p, &s_p->lock); rc = oc_bpt_op_lookup_b(wu_p, s_p, key_p, data_po); oc_utl_trk_crt_unlock(wu_p, &s_p->lock); return rc; }
int oc_bpt_remove_range_b( struct Oc_wu *wu_p, Oc_bpt_state *s_p, struct Oc_bpt_key *min_key_p, struct Oc_bpt_key *max_key_p) { int rc; oc_bpt_trace_wu_lvl(2, OC_EV_BPT_REMOVE_RANGE, wu_p, "tid=%Lu [%s]", s_p->tid, oc_bpt_nd_string_of_2key(s_p, min_key_p, max_key_p)); oc_utl_debugassert(s_p->cfg_p->initialized); oc_utl_trk_crt_lock_write(wu_p, &s_p->lock); rc = oc_bpt_op_remove_range_b(wu_p, s_p, min_key_p, max_key_p); oc_utl_trk_crt_unlock(wu_p, &s_p->lock); return rc; }
void oc_bpt_delete_b( struct Oc_wu *wu_p, struct Oc_bpt_state *s_p) { oc_bpt_trace_wu_lvl(2, OC_EV_BPT_DELETE, wu_p, "tid=%Lu", s_p->tid); oc_utl_debugassert(s_p->cfg_p->initialized); oc_utl_trk_crt_lock_write(wu_p, &s_p->lock); /* We need to upgrade the root-lock to a shared-lock * because the delete-code unlocks all the pages after * deleting them. This means that the root cannot remain * unlocked, as usual. */ oc_utl_trk_crt_lock_read(wu_p, &s_p->root_node_p->lock); oc_bpt_utl_delete_subtree_b(wu_p, s_p, s_p->root_node_p); s_p->root_node_p = NULL; oc_utl_trk_crt_unlock(wu_p, &s_p->lock); }
uint64 oc_bpt_clone_b( struct Oc_wu *wu_p, Oc_bpt_state *src_p, Oc_bpt_state *trg_p) { // make sure the configurations are equivalent oc_utl_assert(trg_p->cfg_p == src_p->cfg_p); oc_bpt_trace_wu_lvl(2, OC_EV_BPT_CLONE, wu_p, "tid=%Lu -> tid=%Lu", src_p->tid, trg_p->tid); oc_utl_debugassert(src_p->cfg_p->initialized); oc_utl_debugassert(trg_p->cfg_p->initialized); oc_utl_assert(NULL == trg_p->root_node_p); oc_utl_trk_crt_lock_write(wu_p, &src_p->lock); oc_bpt_nd_clone_root(wu_p, src_p, trg_p); oc_utl_trk_crt_unlock(wu_p, &src_p->lock); return trg_p->root_node_p->disk_addr; }
void oc_bpt_cow_root_and_update_b( struct Oc_wu *wu_p, struct Oc_bpt_state *s_p, struct Oc_bpt_data *father_data_p, int size) { // Old disk-addr stored as data in father uint64 prev_addr = *((uint64*)father_data_p); Oc_bpt_node *node_p; int fs_refcnt; oc_bpt_trace_wu_lvl(2, OC_EV_BPT_COW_ROOT_AND_UPDATE, wu_p, "lba of root as appers in father (before update):%llu", prev_addr); oc_utl_assert(NULL != s_p->root_node_p); oc_utl_trk_crt_lock_write(wu_p, &s_p->lock); node_p = s_p->cfg_p->node_get_xl(wu_p, s_p->root_node_p->disk_addr); oc_utl_debugassert(node_p == s_p->root_node_p); fs_refcnt = s_p->cfg_p->fs_get_refcount( wu_p, s_p->root_node_p->disk_addr); s_p->cfg_p->node_mark_dirty(wu_p, s_p->root_node_p, (fs_refcnt > 1)); if (s_p->root_node_p->disk_addr != prev_addr) { uint64 new_addr = s_p->root_node_p->disk_addr; memcpy((char*)father_data_p, &new_addr, size); } oc_bpt_trace_wu_lvl(2, OC_EV_BPT_COW_ROOT_AND_UPDATE, wu_p, "lba of root as appers in father (AFTER update):%llu", *((uint64*)father_data_p)); oc_bpt_nd_release(wu_p, s_p, s_p->root_node_p);// Dalit: may not be needed oc_utl_trk_crt_unlock(wu_p, &s_p->lock); // Dalit: may not be needed }
void oc_bpt_dbg_output_clones_b( struct Oc_wu *wu_p, int n_clones, struct Oc_bpt_state *st_array[], char *tag_p) { int i; for (i=0 ; i < n_clones; i++) { struct Oc_bpt_state *s_p = st_array[i]; oc_utl_debugassert(s_p->cfg_p->initialized); oc_utl_trk_crt_lock_write(wu_p, &s_p->lock); } oc_bpt_op_output_clones_dot_b(wu_p, n_clones, st_array, tag_p); for (i=0 ; i < n_clones; i++) { struct Oc_bpt_state *s_p = st_array[i]; oc_utl_trk_crt_unlock(wu_p, &s_p->lock); } }