internal UnmanagedSliceStream(USlice slice)
		{
			Contract.Requires(slice.Count == 0 || slice.Data != null);

			m_begin = slice.Data;
			m_size = slice.Count;
		}
Пример #2
0
        public ushort USliceCoordS()
        {
            List <byte> arr = new List <byte>(4);
            int         i, j, s, x = 0;

            foreach (Cubie e in edges)
            {
                if (USlice.Contains(e.pos))
                {
                    arr.Add(e.pos);
                }
            }

            for (i = 3; i > 0; i--)
            {
                s = 0;
                for (j = i; j >= 0; j--)
                {
                    if (arr[j] > arr[i])
                    {
                        s++;
                    }
                }

                x = (x + s) * i;
            }

            return((ushort)(USliceCoord() * 24 + x));
        }
Пример #3
0
        public void Test_Uuid80_Read_From_Bytes()
        {
            // test buffer with included padding
            byte[] buf      = { 0x55, 0x55, 0x55, 0x55, /* start */ 0x1E, 0x2D, 0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, /* stop */ 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA, 0xAA };
            var    original = Uuid80.Parse("1E2D-01234567-89ABCDEF");

            (var hi, var lo) = original;
            Assume.That(hi, Is.EqualTo(0x1E2D));
            Assume.That(lo, Is.EqualTo(0x0123456789ABCDEF));

            // Slice
            Assert.That(Uuid80.Read(buf.AsSlice(4, 10)), Is.EqualTo(original));

            // byte[]
            Assert.That(Uuid80.Read(buf.AsSlice(4, 10).GetBytesOrEmpty()), Is.EqualTo(original));

#if ENABLE_SPAN
            // ReadOnlySpan<byte>
            Assert.That(Uuid80.Read(buf.AsSpan(4, 10)), Is.EqualTo(original));

            unsafe
            {
                fixed(byte *ptr = &buf[4])
                {
                    Assert.That(Uuid80.Read(ptr, 10), Is.EqualTo(original));
                    Assert.That(Uuid80.Read(USlice.FromUnmanagedPointer(ptr, 10)), Is.EqualTo(original));
                    Assert.That(Uuid80.Read(new ReadOnlySpan <byte>(ptr, 10)), Is.EqualTo(original));
                }
            }
#endif
        }
		public static void CopyUnsafe(byte* dest, USlice src)
		{
			if (src.Count > 0)
			{
				Contract.Requires(dest != null && src.Data != null);
				CopyUnsafe(dest, src.Data, src.Count);
			}
		}
Пример #5
0
        public Key *Append(USlice buffer)
        {
            int bucket = GetBucket(buffer.Count + Key.SizeOf);

            var page  = m_currents[bucket];
            var entry = page != null?page.TryAppend(buffer) : null;

            if (entry == null)
            {              // allocate a new page and try again
                entry = AppendSlow(bucket, buffer);
            }
            return(entry);
        }
Пример #6
0
        public void Test_UUid64_WriteTo()
        {
            var original = Uuid64.Parse("01234567-89ABCDEF");

            Assume.That(original.ToUInt64(), Is.EqualTo(0x0123456789ABCDEF));

            // span with more space
            var scratch = Slice.Repeat(0xAA, 16);

            original.WriteTo(scratch.AsSpan());
            Assert.That(scratch.ToString("X"), Is.EqualTo("01 23 45 67 89 AB CD EF AA AA AA AA AA AA AA AA"));

            // span with no offset and exact size
            scratch = Slice.Repeat(0xAA, 16);
            original.WriteTo(scratch.AsSpan(0, 8));
            Assert.That(scratch.ToString("X"), Is.EqualTo("01 23 45 67 89 AB CD EF AA AA AA AA AA AA AA AA"));

            // span with offset
            scratch = Slice.Repeat(0xAA, 16);
            original.WriteTo(scratch.AsSpan(4));
            Assert.That(scratch.ToString("X"), Is.EqualTo("AA AA AA AA 01 23 45 67 89 AB CD EF AA AA AA AA"));

            // span with offset and exact size
            scratch = Slice.Repeat(0xAA, 16);
            original.WriteTo(scratch.AsSpan(4, 8));
            Assert.That(scratch.ToString("X"), Is.EqualTo("AA AA AA AA 01 23 45 67 89 AB CD EF AA AA AA AA"));

            scratch = Slice.Repeat(0xAA, 16);
            original.WriteToUnsafe(scratch.Array, scratch.Offset);
            Assert.That(scratch.ToString("X"), Is.EqualTo("01 23 45 67 89 AB CD EF AA AA AA AA AA AA AA AA"));

            unsafe
            {
                byte *buf  = stackalloc byte[16];
                var   span = USlice.FromUnmanagedPointer(buf, 16);
                span.Fill(0xAA);

                original.WriteToUnsafe(buf + 2);
                Assert.That(span.ToString("X"), Is.EqualTo("AA AA 01 23 45 67 89 AB CD EF AA AA AA AA AA AA"));
            }

            // errors

            Assert.That(() => original.WriteTo(Span <byte> .Empty), Throws.InstanceOf <ArgumentException>(), "Target buffer is empty");
            Assert.That(() => original.WriteTo(null, 8), Throws.InstanceOf <ArgumentException>(), "Target buffer is null");
            Assert.That(() => original.WriteTo(null, 0), Throws.InstanceOf <ArgumentException>(), "Target buffer is null");

            scratch = Slice.Repeat(0xAA, 16);
            Assert.That(() => original.WriteTo(scratch.AsSpan(0, 7)), Throws.InstanceOf <ArgumentException>(), "Target buffer is too small");
            Assert.That(scratch.ToString("X"), Is.EqualTo("AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA AA"), "Buffer should not have been overwritten!");
        }
Пример #7
0
        private Key *AppendSlow(int bucket, USlice buffer)
        {
            var page = CreateNewPage(bucket);

            Contract.Assert(page != null);
            m_currents[bucket] = page;
            m_buckets[bucket].Pages.Add(page);

            var entry = page.TryAppend(buffer);

            if (entry == null)
            {
                throw new OutOfMemoryException(String.Format("Failed to allocate memory from the key heap ({0})", m_buckets[bucket].PageSize));
            }
            return(entry);
        }
            public Value *TryAppend(USlice buffer)
            {
                Contract.Requires(buffer.Data != null &&
                                  buffer.Count >= Value.SizeOf &&
                                  ((Key *)buffer.Data)->Size == buffer.Count - Value.SizeOf);

                var entry = (Value *)TryAllocate(buffer.Count);

                if (entry == null)
                {
                    return(null);                               // the page is full
                }
                UnmanagedHelpers.CopyUnsafe((byte *)entry, buffer.Data, buffer.Count);

                return(entry);
            }
Пример #9
0
            public Key *TryAppend(USlice buffer)
            {
                Contract.Requires(buffer.Data != null &&
                                  buffer.Count >= Key.SizeOf &&
                                  ((Key *)buffer.Data)->Size == buffer.Count - Key.SizeOf);

                var entry = (Key *)TryAllocate(buffer.Count);

                if (entry == null)
                {
                    return(null);                               // this page is full
                }
                UnmanagedHelpers.CopyUnsafe((byte *)entry, buffer.Data, buffer.Count);
                entry->Header = ((ushort)EntryType.Key) << Entry.TYPE_SHIFT;

                return(entry);
            }
		public unsafe void Add(ulong sequence, USlice userKey, USlice userValue)
		{
			// allocate the key
			var tmp = MemoryDatabaseHandler.PackUserKey(m_scratch, userKey);
			Key* key = m_keys.Append(tmp);
			Contract.Assert(key != null, "key == null");

			// allocate the value
			uint size = userValue.Count;
			Value* value = m_values.Allocate(size, sequence, null, key);
			Contract.Assert(value != null, "value == null");
			UnmanagedHelpers.CopyUnsafe(&(value->Data), userValue);

			key->Values = value;

			m_list.Add(new IntPtr(key));
		}
Пример #11
0
        public unsafe void Add(ulong sequence, USlice userKey, USlice userValue)
        {
            // allocate the key
            var  tmp = MemoryDatabaseHandler.PackUserKey(m_scratch, userKey);
            Key *key = m_keys.Append(tmp);

            Contract.Assert(key != null, "key == null");

            // allocate the value
            uint   size  = userValue.Count;
            Value *value = m_values.Allocate(size, sequence, null, key);

            Contract.Assert(value != null, "value == null");
            UnmanagedHelpers.CopyUnsafe(&(value->Data), userValue);

            key->Values = value;

            m_list.Add(new IntPtr(key));
        }
Пример #12
0
        public ushort USliceCoord()
        {
            int k = -1, i = 0, s = 0;

            foreach (Cubie e in edges.Reverse())
            {
                if (USlice.Contains(e.pos))
                {
                    k += 1;
                }
                else if (k != -1)
                {
                    s += Tools.nChooseK(i, k);
                }

                i += 1;
            }

            return((ushort)s);
        }
		/// <summary>Copy the content of an unmanaged slice of memory, using a specific alignment</summary>
		/// <param name="data">Slice of unmanaged memory to copy</param>
		/// <param name="align">Required memory alignment. MUST BE A POWER OF 2 !</param>
		/// <returns>New slice pointing to the copied bytes in the allocator memory. The start address should be aligned to either 4 or 8 bytes, depending on the platform architecture.</returns>
		private USlice Memoize(USlice data, uint align)
		{
			if (data.Count == 0) return default(USlice);
			byte* ptr = Allocate(data.Count, align);
			if (ptr == null) throw new OutOfMemoryException();
			UnmanagedHelpers.CopyUnsafe(ptr, data);
			return new USlice(ptr, data.Count);
		}
		public UnmanagedSliceBuilder(USlice slice)
			: this(slice.Data, slice.Count)
		{ }
		public void Set(USlice source)
		{
			m_count = 0;
			if (source.Count > 0)
			{
				if (source.Data == null) ThrowInvalidSource();

				var ptr = AllocateInternal(source.Count, zeroed: false);
				Contract.Assert(ptr != null);
				UnmanagedHelpers.CopyUnsafe(ptr, source);
			}
		}
        public void ReadLevel(int level, LevelWriter writer, CancellationToken ct)
        {
            Contract.Requires(level >= 0 && writer != null);
            ct.ThrowIfCancellationRequested();

            if (!m_hasJumpTable)
            {
                throw new InvalidOperationException("Cannot read a level without reading the Jump Table first!");
            }

            int itemCount = checked (1 << level);

            var address = m_jumpTable[level];

            if (address.Offset < m_dataStart || address.Offset > m_dataEnd)
            {
                throw ParseError("Level {0} offset ({1}) is invalid", level, address.Offset);
            }
            if (checked (address.Offset + address.PaddedSize) > m_dataEnd)
            {
                throw ParseError("Level {0} size ({1}) is invalid", level, address.PaddedSize);
            }

            var reader = m_file.CreateReader(address.Offset, address.PaddedSize);

            // "LVL_"
            var signature = reader.ReadFixed32();
            // Level Flags
            var flags = reader.ReadFixed32();
            // Level ID
            int levelId = (int)reader.ReadFixed32();
            // Item count (always 2^level)
            int levelCount = (int)reader.ReadFixed32();

            if (signature != SnapshotFormat.LEVEL_MAGIC_NUMBER)
            {
                throw ParseError("Page does not appear to be a valid Level header");
            }
            //TODO: check flags
            if (levelId != level)
            {
                throw ParseError("Page contains the header of a different Level ({0} != {1})", levelId, level);
            }
            if (levelCount != itemCount)
            {
                throw ParseError("Item count ({0}) in level {1} header is not valid", levelCount, level);
            }

            for (int i = 0; i < levelCount; i++)
            {
                // read the key
                uint keySize = reader.ReadVarint32();
                if (keySize > MemoryDatabaseHandler.MAX_KEY_SIZE)
                {
                    throw ParseError("Key size ({0}) is too big", keySize);
                }
                USlice key = keySize == 0 ? USlice.Nil : reader.ReadBytes(keySize);

                // read the sequence
                ulong sequence = reader.ReadVarint64();

                // read the value
                uint valueSize = reader.ReadVarint32();
                if (valueSize > MemoryDatabaseHandler.MAX_VALUE_SIZE)
                {
                    throw ParseError("Value size ({0) is too big", valueSize);
                }
                USlice value = valueSize == 0 ? USlice.Nil : reader.ReadBytes(valueSize);

                writer.Add(sequence, key, value);
            }

            if (reader.ReadFixed32() != uint.MaxValue)
            {
                throw ParseError("Invalid end marker in level");
            }
            //TODO: check end marker, CRC, ... ?
            uint checksum = reader.ReadFixed32();
            //TODO: verify checksum!
        }
		/// <summary>Copy the content of an unmanaged slice of memory, starting at an aligned address</summary>
		/// <param name="data">Slice of unmanaged memory to copy</param>
		/// <returns>New slice pointing to the copied bytes in the allocator memory. The start address should be aligned to either 4 or 8 bytes, depending on the platform architecture.</returns>
		public USlice MemoizeAligned(USlice data)
		{
			return Memoize(data, m_alignment);
		}
		/// <summary>Copy the content of an unmanaged slice of memory</summary>
		/// <param name="data">Slice of unmanaged memory to copy</param>
		/// <returns>New slice pointing to the copied bytes in the allocator memory</returns>
		public USlice Memoize(USlice data)
		{
			return Memoize(data, 1);
		}
		public static void CopyUnsafe(USlice dest, byte* src, uint count)
		{
			if (count > 0)
			{
				Contract.Requires(dest.Data != null && src != null);
				CopyUnsafe(dest.Data, src, count);
			}
		}
		public static int ComputeHashCode(ref USlice slice)
		{
			if (slice.Data == null) return 0;
			return ComputeHashCodeUnsafe(slice.Data, slice.Count);
		}
Пример #21
0
		/// <summary>Creates a reader on a byte array</summary>
		public static UnamangedSliceReader FromSlice(USlice slice)
		{
			return new UnamangedSliceReader(slice.Data, slice.Count);
		}
		public void Append(USlice source)
		{
			if (source.Count == 0) return;
			if (source.Data == null) ThrowInvalidSource();

			byte* ptr = AllocateInternal(source.Count, zeroed: false);
			Contract.Assert(ptr != null);
			UnmanagedHelpers.CopyUnsafe(ptr, source);
		}