/// <summary> /// Prepares operation for every descendant index of target array. /// </summary> /// <param name="operation">The operation.</param> /// <returns>Array where the input arrays is merged into.</returns> private void mergeArrays(MergeOperation operation) { AssociativeArray targetArray = Structure.Readonly.GetArray(operation.TargetIndex); IArrayDescriptor targetDescriptor = Structure.Readonly.GetDescriptor(targetArray); ContainerOperations collectIndexes = new ContainerOperations(this, targetDescriptor, operation.TargetIndex, targetDescriptor.UnknownIndex); foreach (var operationData in operation.Indexes) { MemoryIndex index = operationData.Item1; Snapshot snapshot = operationData.Item2; AssociativeArray arrayValue; if (snapshot.Structure.Readonly.TryGetArray(index, out arrayValue)) { IArrayDescriptor descriptor = snapshot.Structure.Readonly.GetDescriptor(arrayValue); collectIndexes.AddContainer(descriptor, snapshot); } else { collectIndexes.SetUndefined(); } } collectIndexes.MergeContainers(); }
/// <summary> /// Creates the merge operation for all fields of specified object. /// </summary> /// <param name="objectValue">The object value.</param> private void mergeObject(ObjectValue objectValue) { IObjectDescriptorBuilder builder = Factories.StructuralContainersFactories.ObjectDescriptorFactory.CreateObjectDescriptor(writeableStrucure, objectValue, null, ObjectIndex.CreateUnknown(objectValue)) .Builder(writeableStrucure); ContainerOperations collectVariables = new ContainerOperations(this, builder, builder.UnknownIndex, builder.UnknownIndex); foreach (Snapshot snapshot in sourceSnapshots) { IObjectDescriptor descriptor; if (snapshot.Structure.Readonly.TryGetDescriptor(objectValue, out descriptor)) { collectVariables.CollectIndexes(snapshot, builder.UnknownIndex, descriptor); builder.SetType(descriptor.Type); } else { collectVariables.SetUndefined(); } } collectVariables.MergeContainers(); writeableStrucure.SetDescriptor(objectValue, builder.Build(writeableStrucure)); }
/// <summary> /// Prepares operation for every descendant index and merge the array into one which will be /// stored in the target memory entry. /// </summary> /// <param name="operation">The operation.</param> /// <returns>Array where the input arrays is merged into.</returns> private Value mergeArrays(MergeOperation operation) { var structure = writeableStrucure; IArrayDescriptorBuilder builder = Factories.StructuralContainersFactories.ArrayDescriptorFactory.CreateArrayDescriptor(writeableStrucure, null, operation.TargetIndex).Builder(structure); builder.SetUnknownIndex(operation.TargetIndex.CreateUnknownIndex()); ContainerOperations collectVariables = new ContainerOperations(this, builder, operation.TargetIndex, builder.UnknownIndex); // Collecting possible indexes of merged array AssociativeArray targetArray = null; foreach (var operationData in operation.Indexes) { MemoryIndex index = operationData.Item1; Snapshot snapshot = operationData.Item2; AssociativeArray arrayValue; if (snapshot.Structure.Readonly.TryGetArray(index, out arrayValue)) { // Target array value will be the firs one if (targetArray == null) { if (index.Equals(operation.TargetIndex)) { targetArray = arrayValue; } } IArrayDescriptor descriptor = snapshot.Structure.Readonly.GetDescriptor(arrayValue); collectVariables.CollectIndexes(snapshot, index, descriptor); } else { collectVariables.SetUndefined(); } } if (targetArray == null) { targetArray = targetSnapshot.CreateArray(); } builder.SetArrayValue(targetArray); collectVariables.MergeContainers(); structure.SetArray(operation.TargetIndex, targetArray); structure.SetDescriptor(targetArray, builder.Build(structure)); return(targetArray); }
/// <summary> /// Main method of merge algorithm. /// /// iI first phase prepares new empty data collection. Then collects all root memory locations and /// prepares their operations. As the final step process all merge operations which traverses the /// memory tree and merges data from all source indexes. /// </summary> internal void Merge() { ContainerOperations[] collectVariables = new ContainerOperations[targetCallLevel + 1]; ContainerOperations[] collectControl = new ContainerOperations[targetCallLevel + 1]; MergeOperation returnOperation = new MergeOperation(); for (int x = 0; x <= targetCallLevel; x++) { IReadonlyIndexContainer variables = Structure.Readonly.GetReadonlyStackContext(x).ReadonlyVariables; collectVariables[x] = new ContainerOperations(this, variables, variables.UnknownIndex, variables.UnknownIndex); IReadonlyIndexContainer control = Structure.Readonly.GetReadonlyStackContext(x).ReadonlyControllVariables; collectControl[x] = new ContainerOperations(this, control, control.UnknownIndex, control.UnknownIndex); } foreach (Snapshot snapshot in sourceSnapshots) { for (int sourceLevel = 0, targetLevel = 0; targetLevel <= targetCallLevel; sourceLevel++, targetLevel++) { if (sourceLevel == snapshot.CallLevel && snapshot.CallLevel != targetCallLevel) { if (isCallMerge) { break; } else { targetLevel = targetCallLevel; } } IReadonlyIndexContainer variables = snapshot.Structure.Readonly.GetReadonlyStackContext(sourceLevel).ReadonlyVariables; collectVariables[targetLevel].AddContainer(variables, snapshot); IReadonlyIndexContainer control = snapshot.Structure.Readonly.GetReadonlyStackContext(sourceLevel).ReadonlyControllVariables; collectControl[targetLevel].AddContainer(control, snapshot); } } mergeObjects(); for (int x = 0; x <= targetCallLevel; x++) { collectVariables[x].MergeContainers(); collectControl[x].MergeContainers(); mergeTemporary(x); } processMerge(); }
/// <summary> /// Creates the merge operation for all fields of specified object. /// </summary> /// <param name="objectValue">The object value.</param> private void mergeObject(ObjectValue objectValue) { IObjectDescriptor targetDescriptor = Structure.Readonly.GetDescriptor(objectValue); ContainerOperations collectVariables = new ContainerOperations(this, targetDescriptor, targetDescriptor.UnknownIndex, targetDescriptor.UnknownIndex); foreach (Snapshot snapshot in sourceSnapshots) { IObjectDescriptor descriptor; if (snapshot.Structure.Readonly.TryGetDescriptor(objectValue, out descriptor)) { collectVariables.AddContainer(descriptor, snapshot); } else { collectVariables.SetUndefined(); } } collectVariables.MergeContainers(); }
/// <summary> /// Main method of merge algorithm. /// /// in first phase prepares new empty structure and data collections. Then collects all root memory locations /// and prepares their operations. As the final step process all merge operations which traverses the memory tree /// and creates new memory locations in target structure with the data from all source indexes. /// </summary> internal void Merge() { ContainerOperations[] collectVariables = new ContainerOperations[targetSnapshotCallLevel + 1]; ContainerOperations[] collectControl = new ContainerOperations[targetSnapshotCallLevel + 1]; MergeOperation returnOperation = new MergeOperation(); // Prepares empty structure for target snapshot for (int x = 0; x <= targetSnapshotCallLevel; x++) { writeableStrucure.AddLocalLevel(); IWriteableIndexContainer variables = writeableStrucure.GetWriteableStackContext(x).WriteableVariables; collectVariables[x] = new ContainerOperations(this, variables, variables.UnknownIndex, variables.UnknownIndex); IWriteableIndexContainer control = writeableStrucure.GetWriteableStackContext(x).WriteableControllVariables; collectControl[x] = new ContainerOperations(this, control, control.UnknownIndex, control.UnknownIndex); } // Collects all objects and root locations from the source objects foreach (Snapshot snapshot in sourceSnapshots) { collectObjects(snapshot); for (int sourceLevel = 0, targetLevel = 0; targetLevel <= targetSnapshotCallLevel; sourceLevel++, targetLevel++) { // Local levels of snaphot has to be merged together no matter to call level of each snapshot. if (sourceLevel == snapshot.CallLevel && snapshot.CallLevel != targetSnapshotCallLevel) { if (isCallMerge) { // When this is the call merge the local level is forgotten break; } else { targetLevel = targetSnapshotCallLevel; } } // Gets all root locations IWriteableIndexContainer targetVariables = writeableStrucure.GetWriteableStackContext(targetLevel).WriteableVariables; IReadonlyIndexContainer sourceVariables = snapshot.Structure.Readonly.GetReadonlyStackContext(sourceLevel).ReadonlyVariables; collectVariables[targetLevel].CollectIndexes(snapshot, targetVariables.UnknownIndex, sourceVariables); IWriteableIndexContainer targetControlls = writeableStrucure.GetWriteableStackContext(targetLevel).WriteableControllVariables; IReadonlyIndexContainer sourceControlls = snapshot.Structure.Readonly.GetReadonlyStackContext(sourceLevel).ReadonlyControllVariables; collectControl[targetLevel].CollectIndexes(snapshot, targetControlls.UnknownIndex, sourceControlls); collectTemporary(snapshot, sourceLevel, targetLevel); } foreach (var name in snapshot.Structure.Readonly.GetFunctions()) { foreach (var decl in snapshot.Structure.Readonly.GetFunction(name)) { writeableStrucure.AddFunctiondeclaration(name, decl); } } foreach (var name in snapshot.Structure.Readonly.GetClasses()) { foreach (var decl in snapshot.Structure.Readonly.GetClass(name)) { writeableStrucure.AddClassDeclaration(name, decl); } } // When is it call merge remember which arrays was forgotten in order to support arrays in returns if (isCallMerge) { foreach (AssociativeArray array in snapshot.Structure.Readonly.ReadonlyLocalContext.ReadonlyArrays) { writeableStrucure.AddCallArray(array, snapshot); } } } mergeObjects(); // Prepares operations for all root locations for (int x = 0; x <= targetSnapshotCallLevel; x++) { collectVariables[x].MergeContainers(); collectControl[x].MergeContainers(); mergeTemporary(x); } processMerge(); // Build aliases foreach (var alias in memoryAliases) { writeableStrucure.SetAlias(alias.Key, alias.Value.Build(writeableStrucure)); } }