BTree::Iterator BTree::lowerBound(Key key) { BlockStack path; keepTracingToLeaf(key, path); return findInLeaf(path.top(), key); }
void ReversePostOrderTraversal::analyze(Function& function) { typedef util::LargeSet<BasicBlock*> BlockSet; typedef std::stack<BasicBlock*> BlockStack; order.clear(); BlockSet visited; BlockStack stack; auto cfgAnalysis = getAnalysis("ControlFlowGraph"); auto cfg = static_cast<ControlFlowGraph*>(cfgAnalysis); report("Creating reverse post order traversal over function '" + function.name() + "'"); // reverse post order is reversed topological order stack.push(&*function.entry_block()); while(order.size() != function.size()) { if(stack.empty()) { for(auto block : order) { auto successors = cfg->getSuccessors(*block); for(auto successor : successors) { if(visited.insert(successor).second) { stack.push(successor); break; } } if(!stack.empty()) break; } } assertM(!stack.empty(), (function.size() - order.size()) << " blocks are not connected."); while(!stack.empty()) { BasicBlock* top = stack.top(); stack.pop(); auto successors = cfg->getSuccessors(*top); for(auto successor : successors) { assert(successor != nullptr); auto predecessors = cfg->getPredecessors(*successor); bool allPredecessorsVisited = true; for(auto predecessor : predecessors) { if(visited.count(predecessor) == 0) { allPredecessorsVisited = false; break; } } if(!allPredecessorsVisited) continue; if(visited.insert(successor).second) { stack.push(successor); } } order.push_back(top); report(" " << top->name()); } } // reverse the order std::reverse(order.begin(), order.end()); }
BTree::Iterator BTree::insert(Key key) { BlockStack path; keepTracingToLeaf(key, path); if (getHeaderFromNode(path.top())->entry_count >= maximumEntryPerLeaf()) { Iterator ret = end(); Length split_offset = getHeaderFromNode(path.top())->entry_count / 2; Block new_node = splitLeaf(path.top(), split_offset); Key split_key = makeKey( getKeyFromLeafEntry(getFirstEntryInLeaf(new_node)).start(), _key_size ); if (maximumEntryPerLeaf() > 1 && _less(getPointerOfKey(key), getPointerOfKey(split_key)) ) { ret = insertInLeaf(path.top(), key); } else { ret = insertInLeaf(new_node, key); } path.pop(); while (!path.empty() && getHeaderFromNode(path.top())->entry_count >= maximumEntryPerNode()) { Block node_to_insert = std::move(new_node); auto index_to_insert = node_to_insert.index(); auto split_offset = getHeaderFromNode(path.top())->entry_count / 2; new_node = splitNode(path.top(), split_offset); if (_less(getPointerOfKey(split_key), getKeyFromNodeEntry(getFirstEntryInNode(new_node)).start())) { insertInNode(path.top(), split_key, index_to_insert); } else { insertInNode(new_node, split_key, index_to_insert); } split_key = makeKey( getKeyFromNodeEntry(getFirstEntryInNode(new_node)).start(), _key_size ); path.pop(); } if (path.empty()) { _root = newRoot(split_key, _root, new_node); } else { insertInNode(path.top(), split_key, new_node.index()); } return std::move(ret); } else { return insertInLeaf(path.top(), key); } }
void BTree::erase(Key key) { Buffer removal_key_buffer(_key_size); Key removal_key(key); if (_key_size > sizeof(Key::value)) { std::copy( key.pointer, key.pointer + _key_size, removal_key_buffer.content() ); removal_key.pointer = removal_key_buffer.content(); } BlockStack path; keepTracingToLeaf(key, path); Block leaf = std::move(path.top()); path.pop(); auto *header = getHeaderFromNode(leaf); eraseInLeaf(leaf, key); if (leaf.index() == _root.index()) { return; } if (header->entry_count) { Block &parent = path.top(); auto parent_last_entry = getLastEntryInNode(parent); auto parent_last_index = getIndexFromNodeEntry(parent_last_entry); updateKey( path.top(), makeKey( getKeyFromLeafEntry(getFirstEntryInLeaf(leaf)).start(), _key_size ), leaf.index() ); if (*parent_last_index == leaf.index()) { return; } Block next_leaf = _accesser->aquire(header->next); auto *next_header = getHeaderFromNode(next_leaf); if (next_header->entry_count + header->entry_count > maximumEntryPerLeaf()) { return; } if (_key_size >= sizeof(Key::value)) { std::copy( getKeyFromLeafEntry(getFirstEntryInLeaf(next_leaf)), getKeyFromLeafEntry(getFirstEntryInLeaf(next_leaf)) + _key_size, removal_key_buffer.content() ); } else { removal_key = makeKey( getKeyFromLeafEntry(getFirstEntryInLeaf(next_leaf)).start(), _key_size ); } mergeLeaf(leaf, next_leaf); _accesser->freeBlock(next_leaf.index()); } else { updateLinkBeforeFreeLeaf(leaf); _accesser->freeBlock(leaf.index()); } while (true) { Block node = std::move(path.top()); path.pop(); auto *header = getHeaderFromNode(node); eraseInNode(node, removal_key); if (node.index() == _root.index()) { if (header->entry_count == 0) { auto prev_root_index = _root.index(); _root = _accesser->aquire(getMarkFromNode(node)->before); _accesser->freeBlock(prev_root_index); return; } return; } if (header->entry_count) { Block &parent = path.top(); auto parent_last_entry = getLastEntryInNode(parent); auto parent_last_index = getIndexFromNodeEntry(parent_last_entry); updateKey( parent, makeKey( getKeyFromNodeEntry(getFirstEntryInNode(node)).start(), _key_size ), node.index() ); if (*parent_last_index == node.index()) { return; } Block next_node = _accesser->aquire(header->next); auto *next_header = getHeaderFromNode(next_node); if (next_header->entry_count + header->entry_count > maximumEntryPerNode()) { return; } if (_key_size > sizeof(Key::value)) { std::copy( getKeyFromNodeEntry(getFirstEntryInNode(next_node)), getKeyFromNodeEntry(getFirstEntryInNode(next_node)) + _key_size, removal_key_buffer.content() ); } else { removal_key = makeKey( getKeyFromNodeEntry(getFirstEntryInNode(next_node)).start(), _key_size ); } mergeNode(node, next_node); _accesser->freeBlock(next_node.index()); } else { updateLinkBeforeFreeNode(node); _accesser->freeBlock(node.index()); } } }