/// <summary> /// Creates merge operations for all indexes in the target collection. Source indexes for the operation are /// retreived from the source collections. When there is missing index in some collection the operation set /// to undefined. /// /// This method is for both phases of analysis. /// </summary> public void MergeContainers() { // Process all names which has unassociated index and creates one foreach (string indexName in undefinedIndexes) { targetContainer.Indexes[indexName] = targetIndex.CreateIndex(indexName); } foreach (var index in targetContainer.Indexes) { MergeOperation operation = new MergeOperation(index.Value); worker.addOperation(operation); if (isUndefined) { operation.SetUndefined(); } foreach (var source in sources) { ReadonlyIndexContainer container = source.Item1; Snapshot snapshot = source.Item2; MemoryIndex containerIndex; if (container.Indexes.TryGetValue(index.Key, out containerIndex)) { operation.Add(containerIndex, snapshot); } else { operation.Add(container.UnknownIndex, snapshot); } } } }
/// <summary> /// Stores given collection as the source of indexes and adds its unknown index into unknown operation. /// Also gets all indexes from the source collection and inserts it into target collection. /// /// This method is for the first phase of anaysis. /// </summary> /// <param name="sourceSnapshot">The source snapshot.</param> /// <param name="sourceIndex">Index of the source.</param> /// <param name="sourceContainer">The source container.</param> public void CollectIndexes( Snapshot sourceSnapshot, MemoryIndex sourceIndex, ReadonlyIndexContainer sourceContainer) { sources.Add(new Tuple <ReadonlyIndexContainer, Snapshot>(sourceContainer, sourceSnapshot)); unknownOperation.Add(sourceContainer.UnknownIndex, sourceSnapshot); bool indexEquals = targetIndex.Equals(sourceIndex); foreach (var index in sourceContainer.Indexes) { MemoryIndex containerIndex; if (targetContainer.Indexes.TryGetValue(index.Key, out containerIndex)) { if (containerIndex == null && indexEquals) { targetContainer.Indexes[index.Key] = index.Value; undefinedIndexes.Remove(index.Key); } } else if (indexEquals) { targetContainer.Indexes.Add(index.Key, index.Value); } else { targetContainer.Indexes.Add(index.Key, null); undefinedIndexes.Add(index.Key); } } }
/// <summary> /// Gets the string representation of the collection - dump of all indexes and theirs data. /// </summary> /// <param name="container">The container.</param> /// <param name="data">The data.</param> /// <param name="infos">The infos.</param> /// <param name="result">The result.</param> internal static void GetRepresentation(ReadonlyIndexContainer container, SnapshotData data, SnapshotData infos, StringBuilder result) { GetIndexRepresentation(container.UnknownIndex, data, infos, result); foreach (var item in container.Indexes) { MemoryIndex index = item.Value; GetIndexRepresentation(index, data, infos, result); } }
/// <summary> /// Initializes a new instance of the <see cref="IndexContainer"/> class by copying content from another container. /// </summary> /// <param name="indexContainer">The index container.</param> public IndexContainer(ReadonlyIndexContainer indexContainer) { UnknownIndex = indexContainer.UnknownIndex; Indexes = new Dictionary <string, MemoryIndex>(); foreach (var index in indexContainer.Indexes) { Indexes.Add(index.Key, index.Value); } }
/// <summary> /// Cotinues traversing using specified segment in given index container. /// </summary> /// <param name="segment">The segment.</param> /// <param name="container">The container.</param> /// <param name="isMust">if set to <c>true</c> [is must].</param> private void processSegment(PathSegment segment, ReadonlyIndexContainer container, bool isMust = true) { if (segment.IsAny) { mayIndexesProcess.Add(container.UnknownIndex); addToMay(container.UnknownIndex); foreach (var index in container.Indexes) { addToMay(index.Value); } } else if (segment.IsUnknown) { addToMust(container.UnknownIndex); } else if (segment.Names.Count == 1) { MemoryIndex processIndex; if (!container.Indexes.TryGetValue(segment.Names[0], out processIndex)) { creatorVisitor.Name = segment.Names[0]; creatorVisitor.IsMust = isMust; segment.Accept(creatorVisitor); processIndex = creatorVisitor.CreatedIndex; } if (isMust) { addToMust(processIndex); } else { addToMay(processIndex); } } else { creatorVisitor.IsMust = false; foreach (String name in segment.Names) { MemoryIndex processIndex; if (!container.Indexes.TryGetValue(name, out processIndex)) { creatorVisitor.Name = name; segment.Accept(creatorVisitor); processIndex = creatorVisitor.CreatedIndex; } addToMay(processIndex); } } }
/// <summary> /// Cotinues traversing using specified segment in given index container. /// </summary> /// <param name="segment">The segment.</param> /// <param name="container">The container.</param> private void process(PathSegment segment, ReadonlyIndexContainer container) { if (segment.IsAny) { mustIndexesProcess.Add(container.UnknownIndex); foreach (var index in container.Indexes) { mustIndexesProcess.Add(index.Value); } } else if (segment.IsUnknown) { mustIndexesProcess.Add(container.UnknownIndex); } else { bool isUnknown = false; foreach (String name in segment.Names) { MemoryIndex index; if (container.Indexes.TryGetValue(name, out index)) { mustIndexesProcess.Add(index); } else { isUnknown = true; } } if (isUnknown) { IsDefined = false; mustIndexesProcess.Add(container.UnknownIndex); } } }
/// <summary> /// Stores given collection as the source of indexes and adds its unknown index into unknown operation. /// Target collection is not modified. /// /// This method is for the second phase of anaysis. /// </summary> /// <param name="sourceContainer">The source container.</param> /// <param name="sourceSnapshot">The source snapshot.</param> public void AddContainer(ReadonlyIndexContainer sourceContainer, Snapshot sourceSnapshot) { sources.Add(new Tuple <ReadonlyIndexContainer, Snapshot>(sourceContainer, sourceSnapshot)); unknownOperation.Add(sourceContainer.UnknownIndex, sourceSnapshot); }