public void CtorTest() { int next = 23; PersistentHeapFreeSpace freeSpace = new PersistentHeapFreeSpace(8, 10, next); Assert.AreEqual(next, freeSpace.NextFreeSpace); }
private BoundingFreeSpaces GetBoundingSpaces(int token) { IEnumerator <PersistentHeapFreeSpace> freeSpaces = GetFreeSpaces().GetEnumerator(); //get last free space before and first free space after PersistentHeapFreeSpace before = null; PersistentHeapFreeSpace after = null; if (freeSpaces.MoveNext()) // prime the pump { after = freeSpaces.Current; while (freeSpaces.MoveNext() && after.StartIndex < token) { before = after; after = freeSpaces.Current; if (after.SizeIndex == token) //the token passed in is already a free space { throw new InvalidIndexException("The space passed in is already free"); } } } if (after != null && after.StartIndex < token) // the freed space is at the end of the list (The loop ran out of spaces before getting a free space that is after freedSpace. { before = after; after = null; } freeSpaces.Dispose(); return(new BoundingFreeSpaces { SpaceAfter = after, SpaceBefore = before }); }
public void SerializeTest() { PersistentHeapFreeSpace freeSpace = new PersistentHeapFreeSpace(5, 20, 35); byte[] freeSpaceBytes = freeSpace.Serialize(); TestHelper.AssertByteArraysAreSame(freeSpace.UserSize.ToBytes().Append(freeSpace.NextFreeSpace.ToBytes()), freeSpaceBytes); }
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 MergeAfterTestAssert(int sizeIndex1, int endIndex1, int sizeIndex2, int endIndex2) { PersistentHeapFreeSpace freeSpace1 = new PersistentHeapFreeSpace(sizeIndex1, endIndex1, 5); PersistentHeapFreeSpace freeSpace2 = new PersistentHeapFreeSpace(sizeIndex2, endIndex2, 6); freeSpace1.MergeAfter(freeSpace2); Assert.AreEqual(endIndex2, freeSpace1.EndIndex); Assert.AreEqual(endIndex2 - sizeIndex1 - PersistentHeapSpace.GetUserSizeSize() + 1, freeSpace1.UserSize); }
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 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; } } }
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 IEnumerable <PersistentHeapFreeSpace> GetFreeSpaces() { int freeSpaceHead = GetFreeSpaceHead(); if (freeSpaceHead == FreeLinkedListNullPointer) { yield break; } PersistentHeapFreeSpace before = GetFreeSpaceAt(freeSpaceHead); Debug.Assert(before != null, "The check on the header's _freeSpaceHead should prevent this from being null"); yield return(before); while (before.NextFreeSpace != FreeLinkedListNullPointer) { before = GetFreeSpaceAt(before.NextFreeSpace); yield return(before); } }
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); } } }
public int Allocate(int allocationSize) { AssertUserSize(allocationSize); PersistentHeapFreeSpace freeSpot = GetFreeSpaceThatIsAtLeast(allocationSize); PersistentHeapUsedSpace usedSpot; if (freeSpot.UserSize > allocationSize) { usedSpot = freeSpot.Split(allocationSize); PutFullSpace(freeSpot); } else //the freeSpot is the perfect size { Debug.Assert(freeSpot.UserSize == allocationSize); usedSpot = ToUsedSpace(freeSpot); } PutFullSpace(usedSpot); Debug.Assert(usedSpot.UserSize == allocationSize); return(usedSpot.StartIndex); }
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 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); }