public void EnsureMinBufferSize(int desiredBufferSize = 0) { if (desiredBufferSize <= 0) { desiredBufferSize = CurrentBuffer.Memory.Length * 2; if (desiredBufferSize < DefaultMinBufferSize) { desiredBufferSize = DefaultMinBufferSize; } } else if (CurrentBuffer.Memory.Length >= desiredBufferSize) { return; } IMemoryOwner <byte> newBuffer; if (UseMemoryPooling) { newBuffer = LazinatorUtilities.GetRentedMemory(desiredBufferSize); } else { newBuffer = new ReadWriteBytes(new Memory <byte>(new byte[desiredBufferSize])); } if (TrackMemoryAllocations) { MemoryAllocations[(int)AllocationID].SetTarget(newBuffer); } CurrentBuffer.Memory.Span.CopyTo(newBuffer.Memory.Span); var oldBuffer = CurrentBuffer; CurrentBuffer = newBuffer; oldBuffer.Dispose(); }
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); } }
public void TopNodesComparisonWorks() { ExampleChild c1 = new ExampleChild() { MyShort = 3 }; ExampleChild c2 = new ExampleChild() { MyShort = 3 }; LazinatorUtilities.TopNodesOfHierarchyEqual(c1, c2, out string comparison).Should().BeTrue(); c2.MyShort = 5; LazinatorUtilities.TopNodesOfHierarchyEqual(c1, c2, out comparison).Should().BeFalse(); LazinatorTuple <ExampleChild, ExampleChild> e1 = new LazinatorTuple <ExampleChild, ExampleChild>() { Item1 = new ExampleChild() { MyWrapperContainer = new WrapperContainer() { WrappedInt = 3 } }, Item2 = null }; var e2 = e1.CloneLazinatorTyped(); LazinatorUtilities.TopNodesOfHierarchyEqual(e1, e2, out comparison).Should().BeTrue(); e2.Item1.MyWrapperContainer.WrappedInt = 5; LazinatorUtilities.TopNodesOfHierarchyEqual(e1, e2, out comparison).Should().BeTrue(); // top node is still equal LazinatorList <ExampleChild> l1 = new LazinatorList <ExampleChild>() { new ExampleChild() { MyWrapperContainer = new WrapperContainer() { WrappedInt = 3 } } }; LazinatorList <ExampleChild> l2 = new LazinatorList <ExampleChild>() { new ExampleChild() { MyWrapperContainer = new WrapperContainer() { WrappedInt = 6 } } }; LazinatorUtilities.TopNodesOfHierarchyEqual(l1, l2, out comparison).Should().BeTrue(); l2.Add(null); LazinatorUtilities.TopNodesOfHierarchyEqual(l1, l2, out comparison).Should().BeFalse(); // number of elements differs }
public void VerifyHierarchyWorks() { var original = GetTypicalExample(); var another = GetTypicalExample(); LazinatorUtilities.ConfirmHierarchiesEqual(original, another); var clone = original.CloneLazinatorTyped(); LazinatorUtilities.ConfirmHierarchiesEqual(original, clone); }
public void UsingReturnedMemoryTriggersException() { const int bufferSize = 64 * 1024; IMemoryOwner <byte> rentedMemory = LazinatorUtilities.GetRentedMemory(bufferSize); rentedMemory.Dispose(); Action a = () => { var m = rentedMemory.Memory.Span; m[0] = 1; }; a.Should().Throw <ObjectDisposedException>(); }
public void MemoryPoolWorks() { const int bufferSize = 64 * 1024; for (int i = 0; i < 10; i++) { // note: If we set this to a very large number of iterations, we can confirm that there is no memory leak here. If, on the other hand, we add each rented memory to a list that stays in memory, then we quickly use all available system memory. But we will do neither for the purpose of general testing. IMemoryOwner <byte> rentedMemory = LazinatorUtilities.GetRentedMemory(bufferSize); var bytes = rentedMemory.Memory; bytes.Length.Should().BeGreaterOrEqualTo(bufferSize); } }
public ExpandableBytes(int minBufferSize) { int minimumSize = Math.Max(minBufferSize, DefaultMinBufferSize); if (UseMemoryPooling) { CurrentBuffer = LazinatorUtilities.GetRentedMemory(minimumSize); } else { CurrentBuffer = new ReadWriteBytes(new Memory <byte>(new byte[minimumSize])); } unchecked { AllocationID = Interlocked.Increment(ref NextAllocationID) - 1; } if (TrackMemoryAllocations) { MemoryAllocations.Add(new WeakReference <IMemoryOwner <byte> >(CurrentBuffer)); MemoryAllocationsManuallyReturned.Add(false); } }
public void LazinatorListDirtinessWorks() { LazinatorListContainer nonGenericContainer = new LazinatorListContainer() { }; nonGenericContainer.MyList = new LazinatorList <ExampleChild>(); nonGenericContainer.MyList.IsDirty.Should().BeTrue(); nonGenericContainer.IsDirty.Should().BeTrue(); nonGenericContainer.DescendantIsDirty.Should().BeTrue(); var v2 = nonGenericContainer.CloneLazinatorTyped(); v2.IsDirty.Should().BeFalse(); v2.DescendantIsDirty.Should().BeFalse(); v2.MyList.IsDirty.Should().BeFalse(); v2.MyList.Add(GetExampleChild(1)); v2.MyList.IsDirty.Should().BeTrue(); v2.IsDirty.Should().BeFalse(); v2.DescendantIsDirty.Should().BeTrue(); var v3 = v2.CloneLazinatorTyped(); v3.MyList.IsDirty.Should().BeFalse(); v3.MyList.DescendantIsDirty.Should().BeFalse(); v3.MyList[0].MyLong = 987654321; v3.MyList.IsDirty.Should().BeFalse(); v3.MyList.DescendantIsDirty.Should().BeTrue(); var v4 = v3.CloneLazinatorTyped(); v4.MyList[0].MyLong.Should().Be(987654321); // now, back to prior list v2.MyList.Add(GetExampleChild(1)); v2.MyList.Add(GetExampleChild(1)); v2.MyList.Add(GetExampleChild(1)); var v5 = v2.CloneLazinatorTyped(); v5.IsDirty.Should().BeFalse(); v5.DescendantIsDirty.Should().BeFalse(); v5.MyList.IsDirty.Should().BeFalse(); var x = v5.MyList[2]; v5.MyList.IsDirty.Should().BeFalse(); v5.MyList.DescendantIsDirty.Should().BeFalse(); x.MyLong = 25; v5.MyList.IsDirty.Should().BeFalse(); v5.MyList.DescendantIsDirty.Should().BeTrue(); v5.IsDirty.Should().BeFalse(); v5.DescendantIsDirty.Should().BeTrue(); // attaching dirty item var v6 = v5.CloneLazinatorTyped(); var v7 = v5.CloneLazinatorTyped(); var v6item = v6.MyList[0]; v6item.MyLong = 987654321; v6.DescendantIsDirty.Should().BeTrue(); v6item.IsDirty.Should().BeTrue(); v7.MyList[1] = v6item; v7.MyList.IsDirty.Should().BeTrue(); v7.MyList.DescendantIsDirty.Should().BeTrue(); v7.DescendantIsDirty.Should().BeTrue(); // attaching item with dirty descendant v5.MyList[0].MyWrapperContainer = new WrapperContainer() { WrappedInt = 4 }; v6 = v5.CloneLazinatorTyped(); v7 = v5.CloneLazinatorTyped(); LazinatorUtilities.ConfirmMatch(v6.LazinatorMemoryStorage, v7.LazinatorMemoryStorage.GetConsolidatedMemory()); v6item = v6.MyList[0]; v6item.MyWrapperContainer.WrappedInt = 5; v6item.IsDirty.Should().BeFalse(); v6item.DescendantIsDirty.Should().BeTrue(); v6.DescendantIsDirty.Should().BeTrue(); v7.MyList[1] = v6item; v7.MyList[1].IsDirty.Should().BeFalse(); v7.MyList[1].DescendantIsDirty.Should().BeTrue(); v7.MyList.IsDirty.Should().BeTrue(); v7.MyList.DescendantIsDirty.Should().BeTrue(); v7.DescendantIsDirty.Should().BeTrue(); // attaching item with dirty descendant after fully deserializing v5.MyList[0].MyWrapperContainer = new WrapperContainer() { WrappedInt = 4 }; v6 = v5.CloneLazinatorTyped(); v7 = v5.CloneLazinatorTyped(); v6item = v6.MyList[0]; v6item.MyWrapperContainer.WrappedInt = 5; v6item.IsDirty.Should().BeFalse(); v6item.DescendantIsDirty.Should().BeTrue(); v6.DescendantIsDirty.Should().BeTrue(); v7.MyList.Insert(0, null); v7.MyList.SerializeLazinator(); v7.MyList.IsDirty.Should().BeFalse(); v7.MyList.DescendantIsDirty.Should().BeFalse(); v7.MyList[1] = v6item; v7.MyList[1].IsDirty.Should().BeFalse(); v7.MyList[1].DescendantIsDirty.Should().BeTrue(); v7.MyList.DescendantIsDirty.Should().BeTrue(); v7.DescendantIsDirty.Should().BeTrue(); }