Пример #1
0
        /// <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));
                }
            }
        }
Пример #2
0
        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));
        }
Пример #3
0
		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]);
        }
Пример #4
0
        /// <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));
        }
Пример #5
0
        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);
        }
Пример #6
0
        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();
                }
            }
        }
Пример #8
0
        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;
                    }
                }
            }
        }