/// <summary> /// Writes the bytes provided to the handle that was previously obtained by a call to Create(). /// The length must not be more than ((16*BlockSize)-32) bytes in length. The exact header size /// (32 bytes) may change without notice in a future release. /// </summary> public void Write(uint handle, byte[] bytes, int offset, int length) { HandleRef href = new HandleRef(handle, BlockSize); if (handle == 0 || href.Section >= _sections.Length || _freeHandles.Contains((int)handle)) { throw new ArgumentOutOfRangeException("handle"); } uint oldblockId = _sections[href.Section][href.Offset]; int blocksNeeded = Math.Max(1, (length + BlockHeaderSize + BlockSize - 1) / BlockSize); if (blocksNeeded > BlocksPerSection - 2) { throw new ArgumentOutOfRangeException("length"); } uint blockId = TakeBlocks(blocksNeeded); BlockRef block = new BlockRef(blockId, BlockSize, blocksNeeded); lock (_sync) { _sections[block.Section].Write(block, _fput, bytes, offset, length); _sections[href.Section].SetHandle(_fcommit, href.Offset, blockId); if (oldblockId != 0) { FreeBlocks(new BlockRef(oldblockId, BlockSize)); } } }
public void TestClone() { OrdinalList lista = new OrdinalList(new int[] { 0 }); OrdinalList listb = (OrdinalList) ((ICloneable) lista).Clone(); Assert.IsFalse(ReferenceEquals(lista, listb)); Assert.AreEqual(lista.Count, listb.Count); Assert.IsTrue(listb.Contains(0)); listb.Add(1); Assert.IsTrue(listb.Contains(1)); Assert.IsFalse(lista.Contains(1)); }
public void TestBasics() { OrdinalList list = new OrdinalList(); Assert.IsFalse(list.IsReadOnly); list.Ceiling = 0; for (int i = 512; i >= 0; i--) list.Add(i); int offset = 0; foreach (int item in list) Assert.AreEqual(offset++, item); Assert.AreEqual(513, offset); Assert.AreEqual(513, list.Count); Assert.AreEqual(519, list.Ceiling); list.Clear(); list.AddRange(new int[] { 5, 10, 20 }); list.AddRange(new int[] { }); Assert.AreEqual(3, list.Count); Assert.AreEqual(23, list.Ceiling); Assert.IsTrue(list.Contains(20)); Assert.IsTrue(list.Remove(20)); Assert.IsFalse(list.Contains(20)); Assert.IsFalse(list.Remove(20)); Assert.AreEqual(2, list.Count); int[] items = new int[2]; list.CopyTo(items, 0); Assert.AreEqual(5, items[0]); Assert.AreEqual(10, items[1]); items = list.ToArray(); Assert.AreEqual(5, items[0]); Assert.AreEqual(10, items[1]); byte[] bits = list.ToByteArray(); Assert.AreEqual(3, bits.Length); Assert.AreEqual(2, new OrdinalList(bits).Count); List<int> tmp = new List<int>(); foreach (int i in list) tmp.Add(i); Assert.AreEqual(2, tmp.Count); Assert.AreEqual(5, tmp[0]); Assert.AreEqual(10, tmp[1]); }
/// <summary> /// Reads all bytes from the from the handle specified /// </summary> public Stream Read(uint handle) { HandleRef href = new HandleRef(handle, BlockSize); if (handle == 0 || href.Section >= _sections.Length || _freeHandles.Contains((int)handle)) { throw new ArgumentOutOfRangeException("handle"); } uint blockId = _sections[href.Section][href.Offset]; if (blockId == 0) { return(new MemoryStream(new byte[0], false)); } if (_freeBlocks.Contains((int)blockId & 0x0FFFFFFF)) { throw new InvalidDataException(); } BlockRef block = new BlockRef(blockId, BlockSize); return(_sections[block.Section].Read(ref block, false, _fget)); }
public void TestIntersectUnionSameLength() { OrdinalList lista = new OrdinalList(new int[] { 1, 4, 5 }); OrdinalList listb = new OrdinalList(new int[] { 2, 4, 6 }); OrdinalList union = lista.UnionWith(listb); Assert.AreEqual(5, union.Count); foreach (int i in union) Assert.IsTrue(lista.Contains(i) || listb.Contains(i)); OrdinalList inter = lista.IntersectWith(listb); Assert.AreEqual(1, inter.Count); foreach (int i in inter) Assert.AreEqual(4, i); }
public void TestIntersectUnion() { OrdinalList lista = new OrdinalList(new int[] { 5, 10, 99 }); OrdinalList listb = new OrdinalList(new int[] { 2, 4, 6, 8, 10 }); OrdinalList union = lista.UnionWith(listb); Assert.AreEqual(7, union.Count); foreach (int i in union) Assert.IsTrue(lista.Contains(i) || listb.Contains(i)); OrdinalList inter = lista.IntersectWith(listb); Assert.AreEqual(1, inter.Count); foreach (int i in inter) Assert.AreEqual(10, i); }
private uint TakeBlocks(int blocksNeeded) { lock (_sync) { bool resized = false; while (true) { int found = 0; int last = int.MinValue; int first = int.MaxValue; foreach (int free in _freeBlocks.EnumerateFrom(_prevFreeBlock)) { if (_reservedBlocks.Contains(free)) { continue; } first = Math.Min(first, free); found = (last + 1 != free) ? 1 : found + 1; last = free; if (found == blocksNeeded) { _prevFreeBlock = first; int start = free - (blocksNeeded - 1); for (int i = start; i <= free; i++) { _freeBlocks.Remove(i); } uint blockId = (uint)start; blockId |= ((uint)Math.Min(16, blocksNeeded) - 1 << 28) & 0xF0000000u; return(blockId); } } if (resized) { throw new ArgumentOutOfRangeException("length"); } resized = true; AddSection(); } } }
private uint TakeBlocks(int blocksNeeded) { lock (_sync) { bool rescan = false; bool resized = false; int startingFrom = _prevFreeBlock; int endingBefore = int.MaxValue; while (true) { int found = 0; int last = int.MinValue; int first = int.MaxValue; foreach (int free in _freeBlocks.EnumerateRange(startingFrom, endingBefore)) { if (_reservedBlocks.Contains(free)) { continue; } if (found == 0) { _prevFreeBlock = free; if (!resized && rescan) { _firstFreeBlock = free; } } first = Math.Min(first, free); found = (last + 1 != free) ? 1 : found + 1; last = free; if (found == blocksNeeded) { int start = free - (blocksNeeded - 1); for (int i = start; i <= free; i++) { _freeBlocks.Remove(i); } uint blockId = (uint)start; blockId |= ((uint)Math.Min(16, blocksNeeded) - 1 << 28) & 0xF0000000u; return(blockId); } } if (resized) { throw new ArgumentOutOfRangeException("length"); } if (!rescan && _firstFreeBlock < startingFrom) { rescan = true; endingBefore = startingFrom + blocksNeeded - 1; startingFrom = _firstFreeBlock; } else { resized = true; startingFrom = AddSection(); endingBefore = int.MaxValue; } } } }