예제 #1
0
        public void TestMergingUnclaimedRanges()
        {
            var parentRanges = new NestedRanges <int>(-1, 0);

            var range1 = parentRanges.ClaimSubrangeAtEnd(1, 1);
            var range2 = parentRanges.ClaimSubrangeAtEnd(2, 1);
            var range3 = parentRanges.ClaimSubrangeAtEnd(3, 1);
            var range4 = parentRanges.ClaimSubrangeAtEnd(4, 1);

            AssertLengthAndOffsets(parentRanges, 4, 0, 0);
            AssertLengthAndOffsets(range1, 1, 0, 0);
            AssertLengthAndOffsets(range2, 1, 1, 1);
            AssertLengthAndOffsets(range3, 1, 2, 2);
            AssertLengthAndOffsets(range4, 1, 3, 3);

            range2.FreeAndMarkAsUnclaimed();
            range3.FreeAndMarkAsUnclaimed();
            range4.FreeAndMarkAsUnclaimed();

            AssertLengthAndOffsets(parentRanges, 4, 0, 0);
            AssertLengthAndOffsets(range1, 1, 0, 0);

            range1.ResizeInPlace(4);

            AssertLengthAndOffsets(parentRanges, 4, 0, 0);
            AssertLengthAndOffsets(range1, 4, 0, 0);
        }
예제 #2
0
        public void TestUnclaimedRanges()
        {
            var parentRanges = new NestedRanges <int>(-1, 0, 10);

            var range1 = parentRanges.ClaimSubrangeWithin(1, 1, 1);
            var range2 = parentRanges.ClaimSubrangeWithin(2, 3, 1);
            var range3 = parentRanges.ClaimSubrangeWithin(3, 5, 1);
            var range4 = parentRanges.ClaimSubrangeWithin(4, 7, 1);

            AssertLengthAndOffsets(parentRanges, 10, 0, 0);
            AssertLengthAndOffsets(range1, 1, 1, 1);
            AssertLengthAndOffsets(range2, 1, 3, 3);
            AssertLengthAndOffsets(range3, 1, 5, 5);
            AssertLengthAndOffsets(range4, 1, 7, 7);

            range1.ResizeInPlace(2);
            range2.ResizeSelfAndParents(2);
            range3.ClaimSubrangeAtEnd(-1, 1);
            range4.FreeAndMarkAsUnclaimed();

            AssertLengthAndOffsets(parentRanges, 12, 0, 0);
            AssertLengthAndOffsets(range1, 2, 1, 1);
            AssertLengthAndOffsets(range2, 2, 3, 3);
            AssertLengthAndOffsets(range3, 2, 6, 6);

            parentRanges.RemoveAllUnclaimedSpace();

            AssertLengthAndOffsets(parentRanges, 6, 0, 0);
            AssertLengthAndOffsets(range1, 2, 0, 0);
            AssertLengthAndOffsets(range2, 2, 2, 2);
            AssertLengthAndOffsets(range3, 2, 4, 4);
        }
예제 #3
0
        public void TestResizingNestedRanges()
        {
            var outerRanges    = new NestedRanges <int>(-1, 0);
            var middleRanges1  = outerRanges.ClaimSubrangeAtEnd(-1);
            var innerRanges1_1 = middleRanges1.ClaimSubrangeAtEnd(-1);
            var innerRanges1_2 = middleRanges1.ClaimSubrangeAtEnd(-1);
            var middleRanges2  = outerRanges.ClaimSubrangeAtEnd(-1);
            var innerRanges2_1 = middleRanges2.ClaimSubrangeAtEnd(-1);
            var innerRanges2_2 = middleRanges2.ClaimSubrangeAtEnd(-1);

            AssertLengthAndOffsets(outerRanges, 0, 0, 0);
            AssertLengthAndOffsets(middleRanges1, 0, 0, 0);
            AssertLengthAndOffsets(innerRanges1_1, 0, 0, 0);
            AssertLengthAndOffsets(innerRanges1_2, 0, 0, 0);
            AssertLengthAndOffsets(middleRanges2, 0, 0, 0);
            AssertLengthAndOffsets(innerRanges2_1, 0, 0, 0);
            AssertLengthAndOffsets(innerRanges2_2, 0, 0, 0);

            innerRanges1_1.ResizeSelfAndParents(1);
            innerRanges1_2.ResizeSelfAndParents(2);
            innerRanges2_1.ResizeSelfAndParents(3);
            innerRanges2_2.ResizeSelfAndParents(4);

            AssertLengthAndOffsets(outerRanges, 10, 0, 0);
            AssertLengthAndOffsets(middleRanges1, 3, 0, 0);
            AssertLengthAndOffsets(innerRanges1_1, 1, 0, 0);
            AssertLengthAndOffsets(innerRanges1_2, 2, 1, 1);
            AssertLengthAndOffsets(middleRanges2, 7, 3, 3);
            AssertLengthAndOffsets(innerRanges2_1, 3, 0, 3);
            AssertLengthAndOffsets(innerRanges2_2, 4, 3, 6);
        }
예제 #4
0
 private NestedRanges(
     MemoryRangeType type,
     NestedRanges <T> parent,
     T nullData,
     T data)
 {
     this.type_     = type;
     this.parent_   = parent;
     this.nullData_ = nullData;
     this.Data      = data;
 }
예제 #5
0
        public void TestClaimingChildrenWithin()
        {
            var nestedRanges = new NestedRanges <int>(-1, -1, 10);

            Assert.AreEqual(-1, nestedRanges.Data);
            Assert.AreEqual(10, nestedRanges.Length);

            var zeroethChild = nestedRanges.ClaimSubrangeWithin(0, 0, 0);

            Assert.AreEqual(0, zeroethChild.Data);
            Assert.AreEqual(0, zeroethChild.GetAbsoluteOffset());
            Assert.AreEqual(0, zeroethChild.GetRelativeOffset());
            Assert.AreEqual(0, zeroethChild.Length);

            var firstChild = nestedRanges.ClaimSubrangeWithin(1, 0, 1);

            Assert.AreEqual(1, firstChild.Data);
            Assert.AreEqual(0, firstChild.GetAbsoluteOffset());
            Assert.AreEqual(0, firstChild.GetRelativeOffset());
            Assert.AreEqual(1, firstChild.Length);

            var secondChild = nestedRanges.ClaimSubrangeWithin(2, 1, 2);

            Assert.AreEqual(2, secondChild.Data);
            Assert.AreEqual(1, secondChild.GetAbsoluteOffset());
            Assert.AreEqual(1, secondChild.GetRelativeOffset());
            Assert.AreEqual(2, secondChild.Length);

            var thirdChild = nestedRanges.ClaimSubrangeWithin(3, 3, 3);

            Assert.AreEqual(3, thirdChild.Data);
            Assert.AreEqual(3, thirdChild.GetAbsoluteOffset());
            Assert.AreEqual(3, thirdChild.GetRelativeOffset());
            Assert.AreEqual(3, thirdChild.Length);

            var fourthChild = nestedRanges.ClaimSubrangeWithin(4, 6, 4);

            Assert.AreEqual(4, fourthChild.Data);
            Assert.AreEqual(6, fourthChild.GetAbsoluteOffset());
            Assert.AreEqual(6, fourthChild.GetRelativeOffset());
            Assert.AreEqual(4, fourthChild.Length);

            Assert.AreEqual(10, nestedRanges.Length);
        }
예제 #6
0
        public void TestInvalidatingLengthsAllClaimed()
        {
            var outerRanges    = new NestedRanges <int>(-1, 0);
            var middleRanges1  = outerRanges.ClaimSubrangeAtEnd(-1);
            var innerRanges1_1 = middleRanges1.ClaimSubrangeAtEnd(-1);
            var innerRanges1_2 = middleRanges1.ClaimSubrangeAtEnd(-1);
            var middleRanges2  = outerRanges.ClaimSubrangeAtEnd(-1);
            var innerRanges2_1 = middleRanges2.ClaimSubrangeAtEnd(-1);
            var innerRanges2_2 = middleRanges2.ClaimSubrangeAtEnd(-1);

            outerRanges.InvalidateLengthOfSelfAndChildren();

            Assert.False(outerRanges.IsLengthValid);
            Assert.False(middleRanges1.IsLengthValid);
            Assert.False(innerRanges1_1.IsLengthValid);
            Assert.False(innerRanges1_2.IsLengthValid);
            Assert.False(middleRanges2.IsLengthValid);
            Assert.False(innerRanges2_1.IsLengthValid);
            Assert.False(innerRanges2_2.IsLengthValid);

            innerRanges1_1.ResizeSelfAndParents(1);
            innerRanges1_2.ResizeSelfAndParents(2);
            innerRanges2_1.ResizeSelfAndParents(3);
            innerRanges2_2.ResizeSelfAndParents(4);

            AssertLengthAndOffsets(outerRanges, 10, 0, 0);
            AssertLengthAndOffsets(middleRanges1, 3, 0, 0);
            AssertLengthAndOffsets(innerRanges1_1, 1, 0, 0);
            AssertLengthAndOffsets(innerRanges1_2, 2, 1, 1);
            AssertLengthAndOffsets(middleRanges2, 7, 3, 3);
            AssertLengthAndOffsets(innerRanges2_1, 3, 0, 3);
            AssertLengthAndOffsets(innerRanges2_2, 4, 3, 6);
            Assert.True(outerRanges.IsLengthValid);
            Assert.True(middleRanges1.IsLengthValid);
            Assert.True(innerRanges1_1.IsLengthValid);
            Assert.True(innerRanges1_2.IsLengthValid);
            Assert.True(middleRanges2.IsLengthValid);
            Assert.True(innerRanges2_1.IsLengthValid);
            Assert.True(innerRanges2_2.IsLengthValid);
        }
예제 #7
0
        public void TestResizingSingleRange()
        {
            var nestedRanges = new NestedRanges <int>(-1, 0, 25);

            Assert.AreEqual(25, nestedRanges.Length);

            {
                nestedRanges.ResizeInPlace(50);
                Assert.AreEqual(50, nestedRanges.Length);

                nestedRanges.ResizeInPlace(25);
                Assert.AreEqual(25, nestedRanges.Length);
            }

            {
                nestedRanges.ResizeSelfAndParents(50);
                Assert.AreEqual(50, nestedRanges.Length);

                nestedRanges.ResizeSelfAndParents(25);
                Assert.AreEqual(25, nestedRanges.Length);
            }
        }
예제 #8
0
        public INestedRanges <T> ClaimSubrangeAtEnd(T data, long length)
        {
            if (length < 0)
            {
                throw new ArgumentOutOfRangeException(
                          nameof(length),
                          "Memory range length must be a nonnegative number!");
            }

            if (this.children_ == null)
            {
                this.children_ = new List <NestedRanges <T> >();

                if (this.length_ > 0)
                {
                    this.children_.Add(
                        new NestedRanges <T>(
                            MemoryRangeType.UNCLAIMED,
                            this,
                            this.nullData_,
                            data,
                            this.Length));
                }
            }

            var newRange = new NestedRanges <T>(
                MemoryRangeType.CLAIMED,
                this,
                this.nullData_,
                data,
                length);

            this.children_.Add(newRange);

            this.ResizeSelfAndParents(this.Length + length);

            return(newRange);
        }
예제 #9
0
        public INestedRanges <T> ClaimSubrangeWithin(
            T data,
            long offset,
            long length)
        {
            if (offset < 0)
            {
                throw new ArgumentOutOfRangeException(
                          nameof(offset),
                          "Memory range offset must be a nonzero number!");
            }
            if (length < 0)
            {
                throw new ArgumentOutOfRangeException(
                          nameof(length),
                          "Memory range length must be a nonzero number!");
            }
            if (offset + length > this.Length)
            {
                throw new Exception(
                          "Memory range offset + length must less than the parent length!");
            }

            var(index, absoluteOffset, child) =
                this.FindRangeContainingRelativeOffset_(offset);

            if (child == null)
            {
                this.children_ = new List <NestedRanges <T> >();

                var beforeLength = offset;
                if (beforeLength > 0)
                {
                    this.children_.Add(
                        new NestedRanges <T>(
                            MemoryRangeType.UNCLAIMED,
                            this,
                            this.nullData_,
                            this.nullData_,
                            beforeLength));
                }

                var newRange = new NestedRanges <T>(
                    MemoryRangeType.CLAIMED,
                    this,
                    this.nullData_,
                    data,
                    length);
                this.children_.Add(newRange);

                var afterLength = this.Length - (beforeLength + length);
                if (afterLength > 0)
                {
                    this.children_.Add(
                        new NestedRanges <T>(
                            MemoryRangeType.UNCLAIMED,
                            this,
                            this.nullData_,
                            this.nullData_,
                            afterLength));
                }

                return(newRange);
            }

            if (child.type_ == MemoryRangeType.CLAIMED)
            {
                throw new Exception("Range at offset is already claimed!");
            }

            if (absoluteOffset == offset && child.Length == length)
            {
                child.type_ = MemoryRangeType.CLAIMED;
                child.Data  = data;
                return(child);
            }

            {
                this.children_.RemoveAt(index);

                var newRangeIndex = index;
                var beforeLength  = offset - absoluteOffset;
                if (beforeLength > 0)
                {
                    newRangeIndex = index + 1;
                    this.children_.Insert(
                        index,
                        new NestedRanges <T>(
                            MemoryRangeType.UNCLAIMED,
                            this,
                            this.nullData_,
                            this.nullData_,
                            beforeLength));
                }

                var newRange = new NestedRanges <T>(
                    MemoryRangeType.CLAIMED,
                    this,
                    this.nullData_,
                    data,
                    length);
                this.children_.Insert(newRangeIndex, newRange);

                var afterLength = child.Length - (beforeLength + length);
                if (afterLength > 0)
                {
                    this.children_.Insert(
                        newRangeIndex + 1,
                        new NestedRanges <T>(
                            MemoryRangeType.UNCLAIMED,
                            this,
                            this.nullData_,
                            this.nullData_,
                            afterLength));
                }

                return(newRange);
            }
        }