bool InnerNode::find(Slice key, Slice& value, InnerNode *parent) { bool ret = false; read_lock(); if (parent) { parent->unlock(); // lock coupling } int idx = find_pivot(key); MsgBuf* b = msgbuf(idx); assert(b); b->read_lock(); MsgBuf::Iterator it = b->find(key); if (it != b->end() && it->key == key ) { if (it->type == Put) { value = it->value.clone(); ret = true; } // otherwise deleted b->unlock(); unlock(); return ret; } b->unlock(); bid_t chidx = child(idx); if (chidx == NID_NIL) { assert(idx == 0); // must be the first child unlock(); return false; } // find in child DataNode* ch = tree_->load_node(chidx, true); assert(ch); ret = ch->find(key, value, this); ch->dec_ref(); return ret; }
void InnerNode::maybe_cascade() { int idx = -1; if (msgcnt_ >= tree_->options_.inner_node_msg_count) { idx = find_msgbuf_maxcnt(); } else if (size() >= tree_->options_.inner_node_page_size) { idx = find_msgbuf_maxsz(); } else { unlock(); return; } assert(idx >= 0); MsgBuf* b = msgbuf(idx); bid_t nid = child(idx); DataNode *node = NULL; if (nid == NID_NIL) { // cannot be inner node assert(bottom_); node = tree_->new_leaf_node(); set_child(idx, node->nid()); } else { node = tree_->load_node(nid, false); } assert(node); node->cascade(b, this); node->dec_ref(); // it's possible to cascade twice // lock is released in child, so it's nescessarty to obtain it again read_lock(); if (msgcnt_ >= tree_->options_.inner_node_msg_count || size() >= tree_->options_.inner_node_page_size) { maybe_cascade(); } else { unlock(); } }