CDictionaryBasedTempPath CDictionaryBasedTempPath::ReplaceParent
    ( const CDictionaryBasedPath& oldParent
    , const CDictionaryBasedPath& newParent) const
{
    assert (oldParent.IsSameOrParentOf (*this));

    // I admit, this is the most stupid implementation possible ;)

    std::string newPath = newParent.GetPath()
                        + GetPath().substr (oldParent.GetPath().length());

    return CDictionaryBasedTempPath (GetDictionary(), newPath);
}
CDictionaryBasedTempPath CDictionaryBasedTempPath::GetCommonRoot
    (const CDictionaryBasedTempPath& rhs) const
{
    // short-cut: different base directories anyway?

    if (rhs.GetIndex() != GetIndex())
        return CDictionaryBasedTempPath (inherited::GetCommonRoot (rhs));

    // match relative paths

    typedef std::vector<std::string>::const_iterator IT;
    IT begin = relPathElements.begin();
    IT end = relPathElements.end();
    IT iter = begin;

    IT rhsEnd = relPathElements.end();
    IT rhsIter = relPathElements.begin();

    while ((iter != end) && (rhsIter != rhsEnd) && (*iter == *rhsIter))
    {
        ++iter;
        ++rhsIter;
    }

    // construct the result

    CDictionaryBasedTempPath result (GetBasePath());
    result.relPathElements.insert (result.relPathElements.begin(), begin, iter);

    // update the debug-only _path member

#ifdef _DEBUG
    result._path = result.GetPath();
#endif

    return result;
}
예제 #3
0
void CSearchPathTree::Link (CSearchPathTree* newParent)
{
	assert (parent == NULL);
	assert (newParent != NULL);

	// ensure that for every cached path element hierarchy level
	// there is a node in the tree hierarchy

	index_t pathID = path.GetBasePath().GetIndex();
	index_t parentPathID = path.IsFullyCachedPath()
						 ? path.GetDictionary()->GetParent (pathID)
						 : pathID;

	if (newParent->path.GetBasePath().GetIndex() < parentPathID)
	{
		CDictionaryBasedPath parentPath ( path.GetDictionary()
										, parentPathID);
		newParent = new CSearchPathTree ( CDictionaryBasedTempPath (parentPath)
										, (revision_t)NO_REVISION
										, newParent);
	}

	parent = newParent;

	// insert into parent's child list ordered by pathID

	// O(1) insertion in most cases

	if (parent->firstChild == NULL)
	{
		// no child yet

		parent->firstChild = this;
		parent->lastChild = this;
	}
	else if (parent->lastChild->path.GetBasePath().GetIndex() <= pathID)
	{
		// insert at the end

		previous = parent->lastChild;

		parent->lastChild = this;
		previous->next = this;
	}
	else if (parent->firstChild->path.GetBasePath().GetIndex() >= pathID)
	{
		// insert at the beginning

		next = parent->firstChild;

		parent->firstChild = this;
		next->previous = this;
	}
	else
	{
		assert (parent->firstChild != parent->lastChild);

		// scan for insertion position

		CSearchPathTree* node = parent->firstChild;
		while (node->path.GetBasePath().GetIndex() < pathID)
			node = node->next;

		// insert us there

		previous = node->previous;
		next = node;

		previous->next = this;
		node->previous = this;
	}
}