void CCSVWriter::WriteSkipRanges (std::ostream& os, const CCachedLogInfo& cache) { // header os << "PathID,Path,StartRevision,Length\n"; // content const CSkipRevisionInfo& info = cache.GetSkippedRevisions(); // ids will be added on-the-fly for (size_t i = 0; i < info.GetPathCount(); ++i) { CDictionaryBasedPath path = info.GetPath(i); CSkipRevisionInfo::TRanges ranges = info.GetRanges(i); for (size_t k = 0, count = ranges.size(); k < count; ++k) { os << path.GetIndex() << ",\"" << path.GetPath().c_str() << "\"," << ranges[k].first << ',' << ranges[k].second << "\n"; } } }
void CSkipRevisionInfo::Add ( const CDictionaryBasedPath& path , revision_t revision , revision_t size) { // violating these assertions will break our lookup algorithms assert (path.IsValid()); assert (revision != NO_REVISION); assert (size != NO_REVISION); assert (2*size > size); // reduce the range, if we have revision info at the boundaries TryReduceRange (revision, size); if (size == 0) return; // lookup / auto-insert entry for path SPerPathRanges* ranges = NULL; index_t dataIndex = index.find (path.GetIndex()); if (dataIndex == NO_INDEX) { ranges = new SPerPathRanges; ranges->pathID = path.GetIndex(); data.push_back (ranges); index.insert (path.GetIndex(), (index_t)data.size()-1); } else { ranges = data[dataIndex]; } // add range ranges->Add (revision, size); }
CRemovePathsBySubString::PathClassification CRemovePathsBySubString::QuickClassification (const CDictionaryBasedPath& path) const { // ensure the index is valid within classification cache if (pathClassification.size() <= path.GetIndex()) { size_t newSize = max (8, pathClassification.size()) * 2; while (newSize <= path.GetIndex()) newSize *= 2; pathClassification.resize (newSize, UNKNOWN); } // auto-calculate the entry PathClassification& classification = pathClassification[path.GetIndex()]; if (classification == UNKNOWN) classification = Classify (path.GetPath()); // done here return classification; }
revision_t CSkipRevisionInfo::GetPreviousRevision ( const CDictionaryBasedPath& path , revision_t revision) const { // above the root or invalid parameter ? if (!path.IsValid() || (revision == NO_REVISION)) return (revision_t)NO_REVISION; // lookup the entry for this path index_t dataIndex = index.find (path.GetIndex()); SPerPathRanges* ranges = dataIndex == NO_INDEX ? NULL : data[dataIndex]; // crawl this and the parent path data // until we found a gap (i.e. could not improve further) revision_t startRevision = revision; revision_t result = revision; do { result = revision; revision_t parentNext = GetPreviousRevision (path.GetParent(), revision); if (parentNext != NO_REVISION) revision = parentNext; if (ranges != NULL) { revision_t next = ranges->FindPrevious (revision); if (next != NO_REVISION) revision = next; } } while (revision < result); // ready return revision == startRevision ? NO_REVISION : result; }