Exemplo n.º 1
0
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 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());
}
Exemplo n.º 3
0
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());
        }
    }
}