private void VerifyCloningEquivalence(ILazinator lazinator, IncludeChildrenMode includeChildrenMode) { var clonedWithBuffer = lazinator.CloneLazinator(includeChildrenMode, CloneBufferOptions.IndependentBuffers); var clonedNoBuffer = lazinator.CloneLazinator(includeChildrenMode, CloneBufferOptions.NoBuffer); string clonedWithBufferString = new HierarchyTree(clonedWithBuffer).ToString(); string clonedNoBufferString = new HierarchyTree(clonedNoBuffer).ToString(); try { LazinatorUtilities.ConfirmHierarchiesEqual(clonedWithBuffer, clonedNoBuffer); } catch (Exception ex) { int i = 0; if (clonedNoBuffer.IsStruct) { clonedNoBuffer = clonedNoBuffer.CloneLazinator(); } for (; i < Math.Min(clonedWithBuffer.LazinatorMemoryStorage.Length, clonedNoBuffer.LazinatorMemoryStorage.Length); i++) { if (clonedWithBuffer.LazinatorMemoryStorage.OnlyMemory.Span[i] != clonedNoBuffer.LazinatorMemoryStorage.OnlyMemory.Span[i]) { break; } } throw new Exception("Verify cloning failed at position " + i + ". See inner exception.", ex); } }
/// <summary> /// Returns the sole node that is of the specified type and is the closest on the path from the node to the root. /// Throws if there are multiple paths to a hierarchy root with different closest ancestors of the specified type. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="node"></param> /// <returns></returns> public static T GetSoleClosestAncestorOfType <T>(this ILazinator node) where T : class, ILazinator { ILazinator startPosition = node; // first, see if we can get from this node to an ancestor of the specified type without hitting a place where there might be two ancestors while (node != null && node.LazinatorParents.Count == 1) { node = node.LazinatorParents.LastAdded; if (node is T correctTypeNode) { return(correctTypeNode); } } // now, we need to use a more cumbersome procedure List <T> matches = GetAllClosestAncestorsOfType <T>(startPosition).ToList(); if (!matches.Any()) { return(default(T)); } if (matches.Count() == 1) { return(matches.First()); } throw new Exception($"Expected there to be a sole matching ancestor of type {typeof(T)} but there were {matches.Count()}."); }
/// <summary> /// Confirm that two nodes have distinct roots. This is useful as a way to ensure that the same node is not added /// in multiple places in the same hierarchy. /// </summary> /// <param name="node1"></param> /// <param name="node2"></param> public static void VerifyDistinctRoots(ILazinator node1, ILazinator node2) { // Try to verify with distinct roots ILazinator soleRoot1 = node1.GetSoleRoot(); if (soleRoot1 != null) { ILazinator soleRoot2 = node2.GetSoleRoot(); if (soleRoot2 != null) { if (soleRoot1 != soleRoot2) { throw new Exception("Nodes were expected to have distinct roots but did not."); } return; } } // At least one of these nodes has multiple roots, so we need to use a more expensive mechanism. HashSet <ILazinator> h1 = new HashSet <ILazinator>(node1.GetAllRoots()); HashSet <ILazinator> h2 = new HashSet <ILazinator>(node2.GetAllRoots()); h1.IntersectWith(h2); if (h1.Any()) { throw new Exception("Nodes were expected to have distinct roots but did not."); } }
protected override ILazinator AssignCloneProperties(ILazinator clone, IncludeChildrenMode includeChildrenMode) { base.AssignCloneProperties(clone, includeChildrenMode); LazinatorSortedLinkedList <T> typedClone = (LazinatorSortedLinkedList <T>)clone; return(typedClone); }
protected override ILazinator AssignCloneProperties(ILazinator clone, IncludeChildrenMode includeChildrenMode) { base.AssignCloneProperties(clone, includeChildrenMode); LazinatorFastReadListInt32 typedClone = (LazinatorFastReadListInt32)clone; return(typedClone); }
protected override ILazinator AssignCloneProperties(ILazinator clone, IncludeChildrenMode includeChildrenMode) { base.AssignCloneProperties(clone, includeChildrenMode); ConcreteFromGenericFromBase typedClone = (ConcreteFromGenericFromBase)clone; return(typedClone); }
public Task Set <TKey>(TKey key, ILazinator value) where TKey : ILazinator { string stringKey = key.ToString(); ReadOnlyMemory <byte> memory = value.SerializeToArray(); Storage[stringKey] = memory; return(Task.CompletedTask); }
/// <summary> /// Returns the root of a hierarchy if the hierarchy consists of all classes. Otherwise, it returns the highest class containing the node (or the node itself, if it is a struct.) /// Where a node has multiple parents, the hierarchy is considered to be the last added parent. /// </summary> /// <param name="node">A Lazinator object that may be part of a hierarchy</param> /// <returns></returns> public static ILazinator GetPrincipalRoot(this ILazinator node) { while (node.LazinatorParents.LastAdded is ILazinator nonNull) { node = nonNull; } return(node); }
private static LazinatorMemory GetLazinatorMemoryCopy(ILazinator e) { e.SerializeLazinator(); var buffer = e.LazinatorMemoryStorage.GetConsolidatedMemory(); BufferWriter b = new BufferWriter(); b.Write(buffer.Span); return(b.LazinatorMemory); }
protected override ILazinator AssignCloneProperties(ILazinator clone, IncludeChildrenMode includeChildrenMode) { base.AssignCloneProperties(clone, includeChildrenMode); ClosedGeneric typedClone = (ClosedGeneric)clone; typedClone.AnotherPropertyAdded = AnotherPropertyAdded; return(typedClone); }
protected override ILazinator AssignCloneProperties(ILazinator clone, IncludeChildrenMode includeChildrenMode) { base.AssignCloneProperties(clone, includeChildrenMode); MemoryBlockInsetLoadingInfo typedClone = (MemoryBlockInsetLoadingInfo)clone; typedClone.LoadingOffset = LoadingOffset; return(typedClone); }
protected override ILazinator AssignCloneProperties(ILazinator clone, IncludeChildrenMode includeChildrenMode) { base.AssignCloneProperties(clone, includeChildrenMode); MemorySegmentCollection typedClone = (MemorySegmentCollection)clone; typedClone.Segments = CloneOrChange_List_GMemoryBlockIDAndSlice_g(Segments, l => l?.CloneLazinator(includeChildrenMode, CloneBufferOptions.NoBuffer), false); return(typedClone); }
protected override ILazinator AssignCloneProperties(ILazinator clone, IncludeChildrenMode includeChildrenMode) { base.AssignCloneProperties(clone, includeChildrenMode); Concrete6 typedClone = (Concrete6)clone; typedClone.IntList6 = CloneOrChange_List_Gint_g(IntList6, l => l?.CloneLazinator(includeChildrenMode, CloneBufferOptions.NoBuffer), false); return(typedClone); }
private static void UpdateStoredBufferFromExisting(ILazinator e) { e.SerializeLazinator(); var buffer = e.LazinatorMemoryStorage.GetConsolidatedMemory(); BufferWriter b = new BufferWriter(); b.Write(buffer.Span); e.UpdateStoredBuffer(ref b, 0, buffer.Span.Length, IncludeChildrenMode.IncludeAllChildren, true); }
protected override ILazinator AssignCloneProperties(ILazinator clone, IncludeChildrenMode includeChildrenMode) { base.AssignCloneProperties(clone, includeChildrenMode); InheritingClosedGeneric typedClone = (InheritingClosedGeneric)clone; typedClone.YetAnotherInt = YetAnotherInt; return(typedClone); }
protected override ILazinator AssignCloneProperties(ILazinator clone, IncludeChildrenMode includeChildrenMode) { base.AssignCloneProperties(clone, includeChildrenMode); Derived_DotNetList_Nested_NonLazinator typedClone = (Derived_DotNetList_Nested_NonLazinator)clone; typedClone.MyLevel2Int = MyLevel2Int; typedClone.MyLevel2ListNestedNonLazinatorType = CloneOrChange_List_GList_GNonLazinatorClass_g_g(MyLevel2ListNestedNonLazinatorType, l => l?.CloneLazinator(includeChildrenMode, CloneBufferOptions.NoBuffer), false); return(typedClone); }
public async static Task SaveRemotes(ILazinator hierarchy, bool freeRemoteStorage = true, bool excludeTopOfHierarchy = false) { hierarchy.SerializeLazinator(); foreach (ILazinator remoteLazinator in hierarchy.EnumerateLazinatorNodes(x => x is IRemote && (!excludeTopOfHierarchy || x != hierarchy), true, x => true, true, false)) { await SaveRemotes(remoteLazinator, freeRemoteStorage, true); IRemote r = (IRemote)remoteLazinator; await r.SaveValue(freeRemoteStorage); } }
private static void ConfirmDeserializationFactoryWorks(DeserializationFactory df) { Example parent = new Example(); LazinatorMemory serializedBytes = new LazinatorMemory(new Memory <byte>()); ILazinator lazinatorObject = df.CreateKnownID((int)ExampleUniqueIDs.ExampleChild, serializedBytes, parent); lazinatorObject.Should().NotBeNull(); lazinatorObject.LazinatorMemoryStorage.Should().Be(serializedBytes); lazinatorObject.LazinatorParents.Should().Be(parent); }
public ExampleInterfaceContainer(LazinatorMemory serializedBytes, ILazinator parent = null, IncludeChildrenMode originalIncludeChildrenMode = IncludeChildrenMode.IncludeAllChildren, int?lazinatorObjectVersion = null) { if (lazinatorObjectVersion != null) { LazinatorObjectVersion = (int)lazinatorObjectVersion; } OriginalIncludeChildrenMode = originalIncludeChildrenMode; LazinatorParents = new LazinatorParentsCollection(parent); DeserializeLazinator(serializedBytes); HasChanged = false; DescendantHasChanged = false; }
public WNullableTimeSpan(LazinatorMemory serializedBytes, ILazinator parent = null, IncludeChildrenMode originalIncludeChildrenMode = IncludeChildrenMode.IncludeAllChildren, int?lazinatorObjectVersion = null) : this() { if (lazinatorObjectVersion != null) { LazinatorObjectVersion = (int)lazinatorObjectVersion; } OriginalIncludeChildrenMode = originalIncludeChildrenMode; LazinatorParents = new LazinatorParentsCollection(parent); DeserializeLazinator(serializedBytes); HasChanged = false; DescendantHasChanged = false; }
public Task <ILazinator> Get <TKey>(ILazinator key) where TKey : ILazinator { string stringKey = key.ToString(); if (Storage.ContainsKey(stringKey)) { ReadOnlyMemory <byte> memory = Storage[stringKey]; LazinatorMemory lazinatorMemory = new LazinatorMemory(memory); ILazinator result; result = DeserializationFactory.Instance.CreateFromBytesIncludingID(lazinatorMemory); return(Task.FromResult(result)); } return(Task.FromResult(default(ILazinator))); }
/// <summary> /// Returns the hierarchy root if there is a distinct root, or null if there are multiple roots. /// </summary> /// <param name="node">A Lazinator object that may be part of a hierarchy</param> /// <returns></returns> public static ILazinator GetSoleRoot(this ILazinator node) { do { int count = node.LazinatorParents.Count; if (count == 0) { return(node); } if (count > 1) { return(null); } node = node.LazinatorParents.LastAdded ?? node.LazinatorParents.EnumerateParents().FirstOrDefault(); // FirstOrDefault needed since the number of parents may have fallen, if the weak reference stored in the parents collection goes stale } while (true); }
/// <summary> /// Returns all hierarchy roots for a node. There may be more than one root if node or one or more of its /// ancestors has more than one parent. Note that the same root may be returned more than once. /// </summary> /// <param name="node"></param> /// <returns></returns> public static IEnumerable <ILazinator> GetAllRoots(this ILazinator node) { Queue <ILazinator> q = new Queue <ILazinator>(); q.Enqueue(node); while (q.Any()) { node = q.Dequeue(); if (node.LazinatorParents.Count == 0) { yield return(node); } foreach (var parent in node.LazinatorParents.EnumerateParents()) { q.Enqueue(parent); } } }
public void ChildOfLazinatorWithoutAttributeWorks() { ChildOfLazinatorWithoutAttribute b = new ChildOfLazinatorWithoutAttribute() { MyInt = 3 // property defined virtually in base class }; Action a = () => { var typedClone = b.CloneLazinatorTyped(); }; a.Should().Throw <Exception>(); // we can't return an item of same type as ChildOfLazinatorWithoutAttribute, since Lazinator doesn't know about that type ILazinator untypedClone = b.CloneLazinator(); (untypedClone as ChildOfLazinatorWithoutAttribute).Should().BeNull(); (untypedClone as FromNonLazinatorBase).MyInt.Should().Be(3); }
private static void ConfirmBuffersUpdateInTandem(ILazinator itemToUpdate) { itemToUpdate.SerializeLazinator(); var initialMemoryChunk = itemToUpdate.LazinatorMemoryStorage.SingleMemoryChunk; var allocationID = initialMemoryChunk.AllocationID; itemToUpdate.ForEachLazinator(x => { if (x.LazinatorMemoryStorage.IsEmpty == false) { MemoryChunk c = x.LazinatorMemoryStorage.SingleMemoryChunk; if (c != null) { c.AllocationID.Should().Be(allocationID); } } return(x); }, true, true); }
protected override ILazinator AssignCloneProperties(ILazinator clone, IncludeChildrenMode includeChildrenMode) { base.AssignCloneProperties(clone, includeChildrenMode); LazinatorLocationAwareTree <T> typedClone = (LazinatorLocationAwareTree <T>)clone; if (includeChildrenMode != IncludeChildrenMode.ExcludeAllChildren && includeChildrenMode != IncludeChildrenMode.IncludeOnlyIncludableChildren) { if (Locations == null) { typedClone.Locations = null; } else { typedClone.Locations = (LazinatorDictionary <T, LazinatorList <WInt32> >)Locations.CloneLazinator(includeChildrenMode, CloneBufferOptions.NoBuffer); } } return(typedClone); }
protected override ILazinator AssignCloneProperties(ILazinator clone, IncludeChildrenMode includeChildrenMode) { base.AssignCloneProperties(clone, includeChildrenMode); ExampleChildInherited typedClone = (ExampleChildInherited)clone; typedClone.MyInt = MyInt; if (includeChildrenMode != IncludeChildrenMode.ExcludeAllChildren && includeChildrenMode != IncludeChildrenMode.IncludeOnlyIncludableChildren) { if (MyGrandchildInInherited == null) { typedClone.MyGrandchildInInherited = null; } else { typedClone.MyGrandchildInInherited = (ExampleGrandchild)MyGrandchildInInherited.CloneLazinator(includeChildrenMode, CloneBufferOptions.NoBuffer); } } return(typedClone); }
protected override ILazinator AssignCloneProperties(ILazinator clone, IncludeChildrenMode includeChildrenMode) { base.AssignCloneProperties(clone, includeChildrenMode); GenericFromBase <T> typedClone = (GenericFromBase <T>)clone; typedClone.MyInt = MyInt; if (includeChildrenMode != IncludeChildrenMode.ExcludeAllChildren && includeChildrenMode != IncludeChildrenMode.IncludeOnlyIncludableChildren) { if (MyT == null) { typedClone.MyT = default(T); } else { typedClone.MyT = (T)MyT.CloneLazinator(includeChildrenMode, CloneBufferOptions.NoBuffer); } } return(typedClone); }
public Task <TValue> Get <TKey, TValue>(ILazinator key) where TKey : ILazinator where TValue : ILazinator { string stringKey = key.ToString(); if (Storage.ContainsKey(stringKey)) { ReadOnlyMemory <byte> memory = Storage[stringKey]; LazinatorMemory lazinatorMemory = new LazinatorMemory(memory); TValue result; try { result = (TValue)DeserializationFactory.Instance.CreateFromBytesIncludingID(lazinatorMemory); } catch (InvalidCastException) { throw new LazinatorDeserializationException($"Item stored at key {key} was not of expected type {typeof(TValue)}."); } return(Task.FromResult(result)); } return(Task.FromResult(default(TValue))); }
/// <summary> /// Finds each node that is the closest ancestor of the specified type on a path from the node to a hierarchy root. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="node"></param> /// <returns></returns> public static IEnumerable <T> GetAllClosestAncestorsOfType <T>(this ILazinator node) where T : class, ILazinator { Queue <ILazinator> q = new Queue <ILazinator>(); ILazinator startingNode = node; q.Enqueue(node); while (q.Any()) { node = q.Dequeue(); if (node != startingNode && node is T correctTypeNode) { yield return(correctTypeNode); } else { foreach (var parent in node.LazinatorParents.EnumerateParents()) { q.Enqueue(parent); } } } }