private void AddElement(Element element, string baseName, string name) { if (baseName != null && element is SymLinkElement) { // no versions for SymLinkElement _changeSet.SymLinks.Add(new Tuple <string, string>(baseName + name, ((SymLinkElement)element).Target.Replace("\\", "/"))); return; } ElementVersion currentVersion; if (!_elementsVersions.TryGetValue(element, out currentVersion)) { // assumed to be (empty) version 0 return; } if (element.IsDirectory) { foreach (var subElement in ((DirectoryVersion)currentVersion).Content) { AddElement(subElement.Value, baseName == null ? null : baseName + name + "/", subElement.Key); } return; } List <ChangeSet.NamedVersion> existing = _changeSet.Versions.Where(v => v.Version.Element == element).ToList(); if (existing.Count > 1) { throw new Exception("Unexpected number of versions (" + existing.Count + ") of file element " + element + " in ChangeSet " + _changeSet); } string fullName = baseName == null ? null : baseName + name; if (existing.Count == 1) { if (existing[0].Version != currentVersion) { throw new Exception("Unexpected mismatch of versions of file element " + element + " in ChangeSet " + _changeSet + " : " + existing[0].Version + " != " + currentVersion); } if (fullName != null && !existing[0].Names.Contains(fullName)) { existing[0].Names.Add(fullName); if (existing[0].Names.Count > 1) { Logger.TraceData(TraceEventType.Information, (int)TraceId.CreateChangeSet, "Version " + existing[0].Version + " has several names : " + string.Join(", ", existing[0].Names)); } } return; } if (fullName == null) { // sadly another orphan var newOrphan = new ChangeSet.NamedVersion(currentVersion, null, false); _orphanedVersionsByElement.AddToCollection(element, new Tuple <string, ChangeSet.NamedVersion>(_changeSet.Branch, newOrphan)); _newOrphans.Add(currentVersion); return; } _changeSet.Add(currentVersion, fullName, false); // we've got a name here, maybe some orphans just found their parent ? List <Tuple <string, ChangeSet.NamedVersion> > orphanedVersions; if (!_orphanedVersionsByElement.TryGetValue(element, out orphanedVersions)) { // no, no orphan to happily return to their family return; } foreach (var namedVersion in orphanedVersions.ToList()) { if (namedVersion.Item1 == _changeSet.Branch && namedVersion.Item2.Version == currentVersion) { orphanedVersions.Remove(namedVersion); } } if (orphanedVersions.Count == 0) { _orphanedVersionsByElement.Remove(element); } _newOrphans.Remove(currentVersion); }
private static void AddVersion(List <ChangeSet> changeSets, ElementVersion version) { // used either for search or for new ChangeSet var changeSet = new ChangeSet(version.AuthorName, version.AuthorLogin, version.Branch.BranchName, version.Date); if (changeSets.Count == 0) { changeSet.Add(version); changeSets.Add(changeSet); return; } int index = changeSets.BinarySearch(changeSet, _timeComparer); if (index >= 0) { changeSets[index].Add(version); return; } index = ~index; // index of first element bigger if (index == changeSets.Count) { // so even the last one is not bigger ChangeSet candidate = changeSets[index - 1]; if (version.Date <= candidate.FinishTime.AddSeconds(MAX_DELAY)) { candidate.Add(version); } else { changeSet.Add(version); changeSets.Add(changeSet); } return; } if (index == 0) { ChangeSet candidate = changeSets[0]; if (version.Date >= candidate.StartTime.AddSeconds(-MAX_DELAY)) { candidate.Add(version); } else { changeSet.Add(version); changeSets.Insert(0, changeSet); } return; } DateTime lowerBound = changeSets[index - 1].FinishTime; DateTime upperBound = changeSets[index].StartTime; if (version.Date <= lowerBound.AddSeconds(MAX_DELAY) && version.Date < upperBound.AddSeconds(-MAX_DELAY)) { changeSets[index - 1].Add(version); return; } if (version.Date > lowerBound.AddSeconds(MAX_DELAY) && version.Date >= upperBound.AddSeconds(-MAX_DELAY)) { changeSets[index].Add(version); return; } if (version.Date > lowerBound.AddSeconds(MAX_DELAY) && version.Date < upperBound.AddSeconds(-MAX_DELAY)) { changeSet.Add(version); changeSets.Insert(index, changeSet); return; } // last case : we should merge the two ChangeSets (that are now "linked" by the version we are adding) changeSets[index - 1].Add(version); foreach (var v in changeSets[index].Versions) { changeSets[index - 1].Add(v.Version); } changeSets.RemoveAt(index); }