public void SerializeTest()
        {
            PersistentHeapFreeSpace freeSpace = new PersistentHeapFreeSpace(5, 20, 35);

            byte[] freeSpaceBytes = freeSpace.Serialize();
            TestHelper.AssertByteArraysAreSame(freeSpace.UserSize.ToBytes().Append(freeSpace.NextFreeSpace.ToBytes()),freeSpaceBytes);
        }
        public void CtorTest()
        {
            int next = 23;
            PersistentHeapFreeSpace freeSpace = new PersistentHeapFreeSpace(8, 10, next);

            Assert.AreEqual(next, freeSpace.NextFreeSpace);
        }
 public void MergeBefore(PersistentHeapFreeSpace before)
 {
     Merge(before, this);
     SizeIndex     = before.SizeIndex;
     EndIndex      = before.EndIndex;
     NextFreeSpace = before.NextFreeSpace;
     NullOut(before);
 }
 public void MergeBefore(PersistentHeapFreeSpace before)
 {
     Merge(before, this);
     SizeIndex = before.SizeIndex;
     EndIndex = before.EndIndex;
     NextFreeSpace = before.NextFreeSpace;
     NullOut(before);
 }
 public void MergeAfter(PersistentHeapFreeSpace after)
 {
     Merge(this, after);
     NullOut(after);
 }
 private static void NullOut(PersistentHeapFreeSpace space)
 {
     space.SizeIndex = -1;
     space.EndIndex = -1;
     space.NextFreeSpace = -2;
 }
 private static void Merge(PersistentHeapFreeSpace before, PersistentHeapFreeSpace after)
 {
     AssertHeapSpaceComesRightBefore(before, after);
     before.EndIndex = after.EndIndex;
 }
 public void MergeAfter(PersistentHeapFreeSpace after)
 {
     Merge(this, after);
     NullOut(after);
 }
        private PersistentHeapFreeSpace GetFreeSpaceAt(int token)
        {
            PersistentHeapUsedSpace usedSpace = GetSpaceAt(token);
            int next = usedSpace.Data.ToInt();

            PersistentHeapFreeSpace freeSpace = new PersistentHeapFreeSpace(usedSpace.SizeIndex, usedSpace.EndIndex, next);
            return freeSpace;
        }
        private static void SplitTestAssert(int sizeIndex, int userSize, int newUserSize)
        {
            PersistentHeapFreeSpace freeSpace = new PersistentHeapFreeSpace(sizeIndex, sizeIndex + userSize + PersistentHeapSpace.GetUserSizeSize()-1, 29);

            PersistentHeapUsedSpace usedSpace = freeSpace.Split(newUserSize);

            Assert.AreEqual(newUserSize, freeSpace.UserSize);
            Assert.AreEqual(sizeIndex, freeSpace.SizeIndex);
            Assert.AreEqual(sizeIndex+newUserSize+PersistentHeapSpace.GetUserSizeSize()-1,freeSpace.EndIndex);

            Assert.AreEqual(userSize - newUserSize - PersistentHeapSpace.GetUserSizeSize(), usedSpace.UserSize);
            Assert.AreEqual(sizeIndex + newUserSize + PersistentHeapSpace.GetUserSizeSize()-1+1, usedSpace.SizeIndex);
        }
        private static void MergeBeforeTestAssert(int sizeIndex1, int endIndex1, int sizeIndex2, int endIndex2)
        {
            PersistentHeapFreeSpace freeSpace1 = new PersistentHeapFreeSpace(sizeIndex1, endIndex1, 5);
            PersistentHeapFreeSpace freeSpace2 = new PersistentHeapFreeSpace(sizeIndex2, endIndex2, 6);

            freeSpace1.MergeBefore(freeSpace2);

            Assert.AreEqual(endIndex1, freeSpace1.EndIndex);
            Assert.AreEqual(endIndex1 - sizeIndex2+1, freeSpace1.SizeInBytes);
            Assert.AreEqual(endIndex1 - sizeIndex2+1 - PersistentHeapSpace.GetUserSizeSize(), freeSpace1.UserSize);
        }
        public void Free(int token)
        {
            //free the space
            PersistentHeapUsedSpace usedSpace = GetUsedSpaceAt(token);
            usedSpace.Data = new byte[usedSpace.UserSize];

            PersistentHeapFreeSpace freedSpace = new PersistentHeapFreeSpace(usedSpace.SizeIndex, usedSpace.EndIndex, FreeLinkedListNullPointer);

            BoundingFreeSpaces boundingSpaces = GetBoundingSpaces(token);

            LinkBefore(freedSpace, boundingSpaces.SpaceBefore);

            LinkAfter(freedSpace, boundingSpaces.SpaceAfter);

            PutFullSpace(freedSpace);
        }
        private PersistentHeapUsedSpace ToUsedSpace(PersistentHeapFreeSpace freeSpace)
        {
            // remove free space from linked list of free spaces
            PersistentHeapFreeSpace before = GetFreeSpaceBefore(freeSpace.StartIndex);

            if (before == null) //there isn't free space before freeSpace
            {
                Debug.Assert(GetFreeSpaceHead() == freeSpace.StartIndex); //the first free space better be the free space passed in
                PutFreeSpaceHead(freeSpace.NextFreeSpace);
            }
            else //there is a free space before freeSpace
            {
                Debug.Assert(before.NextFreeSpace == freeSpace.StartIndex);
                before.NextFreeSpace = freeSpace.NextFreeSpace;
                PutFullSpace(before);
            }

            int usedSpaceDataSize = freeSpace.EndIndex - freeSpace.StartIndex + 1;
            PersistentHeapUsedSpace usedSpace = new PersistentHeapUsedSpace(freeSpace.SizeIndex, freeSpace.EndIndex, new byte[usedSpaceDataSize]);
            PutFullSpace(usedSpace);
            return usedSpace;
        }
 private void LinkBefore(PersistentHeapFreeSpace freedSpace, PersistentHeapFreeSpace before)
 {
     if (before == null) // there is no free space before the freed space
     {
         PutFreeSpaceHead(freedSpace.StartIndex);
     }
     else // there is at least one free space before the freed space
     {
         if (freedSpace.IsDirectlyAfter(before)) // the before space is next to freed space
         {
             freedSpace.MergeBefore(before);
         }
         else // the before space is not next to freed space
         {
             before.NextFreeSpace = freedSpace.StartIndex;
             PutFullSpace(before);
         }
     }
 }
        private PersistentHeapFreeSpace GetFreeSpaceThatIsAtLeast(int userSize)
        {
            PersistentHeapFreeSpace lastFreeSpace = null;
            //try to find a space in the free spaces list
            foreach (PersistentHeapFreeSpace persistentHeapFreeSpace in GetFreeSpaces())
            {
                if (persistentHeapFreeSpace.UserSize >= userSize)
                    return persistentHeapFreeSpace;
                lastFreeSpace = persistentHeapFreeSpace;
            }

            //couldn't freespace available that is big enough, going to make our own

            int openIndex = _file.GetNextIndex();
            int fullSize = userSize + PersistentHeapSpace.GetUserSizeSize();
            PersistentHeapFreeSpace freeSpaceOnTheEnd = new PersistentHeapFreeSpace(openIndex, openIndex + fullSize-1, FreeLinkedListNullPointer);

            //update the free linked list
            if (lastFreeSpace == null) //there are no nodes in the free space linked list
            {
                Debug.Assert(GetFreeSpaceHead() == FreeLinkedListNullPointer);
                PutFreeSpaceHead(freeSpaceOnTheEnd.StartIndex);
            }
            else //there are nodes in the free space linked list
            {
                Debug.Assert(lastFreeSpace != null);
                lastFreeSpace.NextFreeSpace = freeSpaceOnTheEnd.StartIndex;
                PutFullSpace(lastFreeSpace);
            }

            PutFullSpace(freeSpaceOnTheEnd);
            return freeSpaceOnTheEnd;
        }
 private static void Merge(PersistentHeapFreeSpace before, PersistentHeapFreeSpace after)
 {
     AssertHeapSpaceComesRightBefore(before, after);
     before.EndIndex = after.EndIndex;
 }
 private static void NullOut(PersistentHeapFreeSpace space)
 {
     space.SizeIndex     = -1;
     space.EndIndex      = -1;
     space.NextFreeSpace = -2;
 }
 private static void LinkAfter(PersistentHeapFreeSpace freedSpace, PersistentHeapFreeSpace after)
 {
     if (after == null) // there is no free space after the freed space
     {
         freedSpace.NextFreeSpace = FreeLinkedListNullPointer;
     }
     else // there is at least one free space after freed space
     {
         if (freedSpace.IsDirectlyBefore(after)) // the space after is next to freed space
         {
             freedSpace.MergeAfter(after);
         }
         else // the space after is not next to freed space
         {
             freedSpace.NextFreeSpace = after.StartIndex;
         }
     }
 }