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; }
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; } }