void CallChainRoot::AddCallChain(const std::vector<SampleEntry*>& callchain, uint64_t period) {
    children_period += period;
    CallChainNode* p = FindMatchingNode(children, callchain[0]);
    if (p == nullptr) {
        std::unique_ptr<CallChainNode> new_node = AllocateNode(callchain, 0, period, 0);
        children.push_back(std::move(new_node));
        return;
    }
    size_t callchain_pos = 0;
    while (true) {
        size_t match_length = GetMatchingLengthInNode(p, callchain, callchain_pos);
        CHECK_GT(match_length, 0u);
        callchain_pos += match_length;
        bool find_child = true;
        if (match_length < p->chain.size()) {
            SplitNode(p, match_length);
            find_child = false;  // No need to find matching node in p->children.
        }
        if (callchain_pos == callchain.size()) {
            p->period += period;
            return;
        }
        p->children_period += period;
        if (find_child) {
            CallChainNode* np = FindMatchingNode(p->children, callchain[callchain_pos]);
            if (np != nullptr) {
                p = np;
                continue;
            }
        }
        std::unique_ptr<CallChainNode> new_node = AllocateNode(callchain, callchain_pos, period, 0);
        p->children.push_back(std::move(new_node));
        break;
    }
}
예제 #2
0
// Create a proxy in the tree as a leaf node. We return the index
// of the node instead of a pointer so that we can grow
// the node pool.
int32 b2DynamicTree::CreateProxy(const b2AABB& aabb, void* userData)
{
	int32 proxyId = AllocateNode();

	// Fatten the aabb.
	b2Vec2 r(b2_aabbExtension, b2_aabbExtension);
	m_nodes[proxyId].aabb.lowerBound = aabb.lowerBound - r;
	m_nodes[proxyId].aabb.upperBound = aabb.upperBound + r;
	m_nodes[proxyId].userData = userData;

	InsertLeaf(proxyId);

	// Rebalance if necessary.
	int32 iterationCount = m_nodeCount >> 4;
	int32 tryCount = 0;
	int32 height = ComputeHeight();
	while (height > 64 && tryCount < 10)
	{
		Rebalance(iterationCount);
		height = ComputeHeight();
		++tryCount;
	}

	return proxyId;
}
static void SplitNode(CallChainNode* parent, size_t parent_length) {
    std::unique_ptr<CallChainNode> child =
        AllocateNode(parent->chain, parent_length, parent->period, parent->children_period);
    child->children = std::move(parent->children);
    parent->period = 0;
    parent->children_period = child->period + child->children_period;
    parent->chain.resize(parent_length);
    parent->children.clear();
    parent->children.push_back(std::move(child));
}
예제 #4
0
void VDFilterFrameCache::Add(VDFilterFrameBuffer *buf, sint64 key) {
	VDFilterFrameBufferCacheNode *hnode = AllocateNode();

	hnode->mKey = key;
	hnode->mpBuffer = buf;

	int htidx = (unsigned)hnode->mKey % (kBufferHashTableSize - 1);

	mHashTable[htidx].push_back(hnode);
	buf->AddCacheReference(hnode);
}
예제 #5
0
// Create a proxy in the tree as a leaf node. We return the index
// of the node instead of a pointer so that we can grow
// the node pool.
int32 b2DynamicTree::CreateProxy(const b2AABB& aabb, void* userData)
{
	int32 proxyId = AllocateNode();

	// Fatten the aabb.
	b2Vec2 r(b2_aabbExtension, b2_aabbExtension);
	m_nodes[proxyId].aabb.lowerBound = aabb.lowerBound - r;
	m_nodes[proxyId].aabb.upperBound = aabb.upperBound + r;
	m_nodes[proxyId].userData = userData;
	m_nodes[proxyId].height = 0;

	InsertLeaf(proxyId);

	return proxyId;
}
예제 #6
0
// Create a proxy in the tree as a leaf node. We return the index
// of the node instead of a pointer so that we can grow
// the node pool.
uint16 b2DynamicTree::CreateProxy(const b2AABB& aabb, void* userData)
{
	uint16 node = AllocateNode();

	// Fatten the aabb.
	b2Vec2 center = aabb.GetCenter();
	b2Vec2 extents = b2_fatAABBFactor * aabb.GetExtents();
	m_nodes[node].aabb.lowerBound = center - extents;
	m_nodes[node].aabb.upperBound = center + extents;
	m_nodes[node].userData = userData;

	InsertLeaf(node);

	return node;
}
예제 #7
0
// Split the child of x at the specified index (that is already loaded and available at y)
void DiskBTree::split(std::shared_ptr<BTreeNode> x, uint16_t i, std::shared_ptr<BTreeNode> y)
{
	auto z = std::make_shared<BTreeNode>(AllocateNode(), TFactor, MaxKeySize);
	z->isLeaf = y->isLeaf;
	z->KeyCount = y->KeyCount = TFactor - 1;

	// Move the largest t – 1 keys and corresponding t children from y to z
	for(int64_t j = 0; j < TFactor - 1; j++)
	{
		z->Keys[j] = y->Keys[j + TFactor];
		y->Keys[j + TFactor] = nullptr;
	}

	if(!y->isLeaf)
	{
		// Y isn't a leaf. Don't forget to move t child pointers
		for(auto j = 0; j < TFactor; j++)
		{
			z->Children[j] = y->Children[j + TFactor];
			y->Children[j + TFactor] = 0;
		}
	}

	// insert z as a child of x
	for(int64_t j = x->KeyCount; j >= i; j--)
	{
		x->Children[j + 1] = x->Children[j];
	}
	x->Children[i+1] = z->ID;

	// Make room for the median of the split
	for(int64_t j = x->KeyCount; j > i; j--)
	{
		x->Keys[j] = x->Keys[j-1];
	}

	// Promote the median
	x->Keys[i] = y->Keys[TFactor-1];
	y->Keys[TFactor - 1] = nullptr;

	// And update the key count of x
	x->KeyCount++;

	// Commit all the things
	commit(x);
	commit(y);
	commit(z, true);
}
static void MakeExprNode( ExprTree &tree, char token, Kind kind, ExprTree left, ExprTree right )
{
	tree = AllocateNode();
	tree->left = left;
	tree->right = right;
	tree->kind = kind;

	switch ( kind )
	{
	case CONDITIONAL:
		tree->data.cond = token;
		break;
	case LITERAL:
		tree->data.value = g_pGetSymbolProc( mIdentifier );
		break;
	case NOT:
		break;
	default:
		VPC_Error( "Error in ExpTree" );
	}
}
예제 #9
0
DiskBTree::DiskBTree(std::string path, uint16_t branchingFactor, uint16_t maxKeySize)
	: TreePath(path), TFactor(branchingFactor), MaxKeySize(maxKeySize)
{
	// Ensure the directory the tree should be placed in exists
	utils::createDirectories(utils::parent(path));

	FileHandle.open(path, std::ios::binary | std::ios::in | std::ios::out);

	readCount++;

	if(!FileHandle.good())
	{
		// We have to do this dance to ensure the file gets created...
		FileHandle.close();
		FileHandle.open(path, std::ios::out);
		FileHandle.close();
		FileHandle.open(path, std::ios::binary | std::ios::in | std::ios::out);
	
		// Probably a new tree, try to commit the empty metadata
		auto x = std::make_shared<BTreeNode>(AllocateNode(), TFactor, MaxKeySize);
		x->isLeaf = true;
		RootID = x->ID;
		commit(x, true);
	}
	else
	{
		// Existing tree
		utils::read_binary(FileHandle, NextNode);
		utils::read_binary(FileHandle, RootID);
		utils::read_binary(FileHandle, TFactor);
		utils::read_binary(FileHandle, MaxKeySize);
	}

	FileHandle.flush();
	FileHandle.close();
	FileHandle.open(path, std::ios::binary | std::ios::in | std::ios::out);
}
예제 #10
0
// Adds the word to the tree. If the word already exists, its occurrance count is incremeneted
void DiskBTree::add(std::string key)
{
	if (key.length() > MaxKeySize) throw std::runtime_error("Key to large. Try again with a larger max key size");

	auto r = load(RootID);
	assert(r != nullptr);

	if(r->isFull())
	{
		// If the root node is full, we have to push a new root out to the top
		auto s = std::make_shared<BTreeNode>(AllocateNode(), TFactor, MaxKeySize);

		RootID = s->ID;
		s->isLeaf = false;
		s->Children[s->KeyCount] = r->ID;
		commit(s, true);
		split(s, 0, r);
		insertNonFull(s, key);
	}
	else
	{
		insertNonFull(r, key);
	}
}
예제 #11
0
void b2DynamicTree::RebuildBottomUp()
{
	int32* nodes = (int32*)b2Alloc(m_nodeCount * sizeof(int32));
	int32 count = 0;

	// Build array of leaves. Free the rest.
	for (int32 i = 0; i < m_nodeCapacity; ++i)
	{
		if (m_nodes[i].height < 0)
		{
			// free node in pool
			continue;
		}

		if (m_nodes[i].IsLeaf())
		{
			m_nodes[i].parent = b2_nullNode;
			nodes[count] = i;
			++count;
		}
		else
		{
			FreeNode(i);
		}
	}

	while (count > 1)
	{
		float32 minCost = b2_maxFloat;
		int32 iMin = -1, jMin = -1;
		for (int32 i = 0; i < count; ++i)
		{
			b2AABB aabbi = m_nodes[nodes[i]].aabb;

			for (int32 j = i + 1; j < count; ++j)
			{
				b2AABB aabbj = m_nodes[nodes[j]].aabb;
				b2AABB b;
				b.Combine(aabbi, aabbj);
				float32 cost = b.GetPerimeter();
				if (cost < minCost)
				{
					iMin = i;
					jMin = j;
					minCost = cost;
				}
			}
		}

		int32 index1 = nodes[iMin];
		int32 index2 = nodes[jMin];
		b2TreeNode* child1 = m_nodes + index1;
		b2TreeNode* child2 = m_nodes + index2;

		int32 parentIndex = AllocateNode();
		b2TreeNode* parent = m_nodes + parentIndex;
		parent->child1 = index1;
		parent->child2 = index2;
		parent->height = 1 + b2Max(child1->height, child2->height);
		parent->aabb.Combine(child1->aabb, child2->aabb);
		parent->parent = b2_nullNode;

		child1->parent = parentIndex;
		child2->parent = parentIndex;

		nodes[jMin] = nodes[count-1];
		nodes[iMin] = parentIndex;
		--count;
	}

	m_root = nodes[0];
	b2Free(nodes);

	Validate();
}
예제 #12
0
void b2DynamicTree::InsertLeaf(int32 leaf)
{
	++m_insertionCount;

	if (m_root == b2_nullNode)
	{
		m_root = leaf;
		m_nodes[m_root].parent = b2_nullNode;
		return;
	}

	// Find the best sibling for this node
	b2AABB leafAABB = m_nodes[leaf].aabb;
	int32 index = m_root;
	while (m_nodes[index].IsLeaf() == false)
	{
		int32 child1 = m_nodes[index].child1;
		int32 child2 = m_nodes[index].child2;

		float32 area = m_nodes[index].aabb.GetPerimeter();

		b2AABB combinedAABB;
		combinedAABB.Combine(m_nodes[index].aabb, leafAABB);
		float32 combinedArea = combinedAABB.GetPerimeter();

		// Cost of creating a new parent for this node and the new leaf
		float32 cost = 2.0f * combinedArea;

		// Minimum cost of pushing the leaf further down the tree
		float32 inheritanceCost = 2.0f * (combinedArea - area);

		// Cost of descending into child1
		float32 cost1;
		if (m_nodes[child1].IsLeaf())
		{
			b2AABB aabb;
			aabb.Combine(leafAABB, m_nodes[child1].aabb);
			cost1 = aabb.GetPerimeter() + inheritanceCost;
		}
		else
		{
			b2AABB aabb;
			aabb.Combine(leafAABB, m_nodes[child1].aabb);
			float32 oldArea = m_nodes[child1].aabb.GetPerimeter();
			float32 newArea = aabb.GetPerimeter();
			cost1 = (newArea - oldArea) + inheritanceCost;
		}

		// Cost of descending into child2
		float32 cost2;
		if (m_nodes[child2].IsLeaf())
		{
			b2AABB aabb;
			aabb.Combine(leafAABB, m_nodes[child2].aabb);
			cost2 = aabb.GetPerimeter() + inheritanceCost;
		}
		else
		{
			b2AABB aabb;
			aabb.Combine(leafAABB, m_nodes[child2].aabb);
			float32 oldArea = m_nodes[child2].aabb.GetPerimeter();
			float32 newArea = aabb.GetPerimeter();
			cost2 = newArea - oldArea + inheritanceCost;
		}

		// Descend according to the minimum cost.
		if (cost < cost1 && cost < cost2)
		{
			break;
		}

		// Descend
		if (cost1 < cost2)
		{
			index = child1;
		}
		else
		{
			index = child2;
		}
	}

	int32 sibling = index;

	// Create a new parent.
	int32 oldParent = m_nodes[sibling].parent;
	int32 newParent = AllocateNode();
	m_nodes[newParent].parent = oldParent;
	m_nodes[newParent].userData = NULL;
	m_nodes[newParent].aabb.Combine(leafAABB, m_nodes[sibling].aabb);
	m_nodes[newParent].height = m_nodes[sibling].height + 1;

	if (oldParent != b2_nullNode)
	{
		// The sibling was not the root.
		if (m_nodes[oldParent].child1 == sibling)
		{
			m_nodes[oldParent].child1 = newParent;
		}
		else
		{
			m_nodes[oldParent].child2 = newParent;
		}

		m_nodes[newParent].child1 = sibling;
		m_nodes[newParent].child2 = leaf;
		m_nodes[sibling].parent = newParent;
		m_nodes[leaf].parent = newParent;
	}
	else
	{
		// The sibling was the root.
		m_nodes[newParent].child1 = sibling;
		m_nodes[newParent].child2 = leaf;
		m_nodes[sibling].parent = newParent;
		m_nodes[leaf].parent = newParent;
		m_root = newParent;
	}

	// Walk back up the tree fixing heights and AABBs
	index = m_nodes[leaf].parent;
	while (index != b2_nullNode)
	{
		index = Balance(index);

		int32 child1 = m_nodes[index].child1;
		int32 child2 = m_nodes[index].child2;

		b2Assert(child1 != b2_nullNode);
		b2Assert(child2 != b2_nullNode);

		m_nodes[index].height = 1 + b2Max(m_nodes[child1].height, m_nodes[child2].height);
		m_nodes[index].aabb.Combine(m_nodes[child1].aabb, m_nodes[child2].aabb);

		index = m_nodes[index].parent;
	}

	//Validate();
}
예제 #13
0
void b2DynamicTree::InsertLeaf(int32 leaf)
{
	++m_insertionCount;

	if (m_root == b2_nullNode)
	{
		m_root = leaf;
		m_nodes[m_root].parent = b2_nullNode;
		return;
	}

	// Find the best sibling for this node.
	b2Vec2 center = m_nodes[leaf].aabb.GetCenter();
	int32 sibling = m_root;
	if (m_nodes[sibling].IsLeaf() == false)
	{
		do 
		{
			int32 child1 = m_nodes[sibling].child1;
			int32 child2 = m_nodes[sibling].child2;

			b2Vec2 delta1 = b2Abs(m_nodes[child1].aabb.GetCenter() - center);
			b2Vec2 delta2 = b2Abs(m_nodes[child2].aabb.GetCenter() - center);

			float32 norm1 = delta1.x + delta1.y;
			float32 norm2 = delta2.x + delta2.y;

			if (norm1 < norm2)
			{
				sibling = child1;
			}
			else
			{
				sibling = child2;
			}

		}
		while(m_nodes[sibling].IsLeaf() == false);
	}

	// Create a parent for the siblings.
	int32 node1 = m_nodes[sibling].parent;
	int32 node2 = AllocateNode();
	m_nodes[node2].parent = node1;
	m_nodes[node2].userData = NULL;
	m_nodes[node2].aabb.Combine(m_nodes[leaf].aabb, m_nodes[sibling].aabb);

	if (node1 != b2_nullNode)
	{
		if (m_nodes[m_nodes[sibling].parent].child1 == sibling)
		{
			m_nodes[node1].child1 = node2;
		}
		else
		{
			m_nodes[node1].child2 = node2;
		}

		m_nodes[node2].child1 = sibling;
		m_nodes[node2].child2 = leaf;
		m_nodes[sibling].parent = node2;
		m_nodes[leaf].parent = node2;

		do 
		{
			if (m_nodes[node1].aabb.Contains(m_nodes[node2].aabb))
			{
				break;
			}

			m_nodes[node1].aabb.Combine(m_nodes[m_nodes[node1].child1].aabb, m_nodes[m_nodes[node1].child2].aabb);
			node2 = node1;
			node1 = m_nodes[node1].parent;
		}
		while(node1 != b2_nullNode);
	}
	else
	{
		m_nodes[node2].child1 = sibling;
		m_nodes[node2].child2 = leaf;
		m_nodes[sibling].parent = node2;
		m_nodes[leaf].parent = node2;
		m_root = node2;
	}
}