示例#1
0
        void IUnorderedTypeCodec <TDocument> .EncodeUnorderedSelfTerm(ref SliceWriter output, TDocument value)
        {
            var packed = EncodeInternal(value);

            Contract.Assert(packed.Count >= 0);
            output.WriteVarint32((uint)packed.Count);
            output.WriteBytes(packed);
        }
        public async Task WriteLevelAsync(int level, IntPtr[] segment, CancellationToken ct)
        {
            ct.ThrowIfCancellationRequested();

            if (m_jumpTable[level].Value > 0)
            {
                throw new InvalidOperationException("The level has already be written to this snapshot");
            }

            var levelStart = checked (m_file.Length + (uint)m_writer.Position);

            //Console.WriteLine("## level " + level + " starts at " + levelStart);

            //TODO: ensure that we start on a PAGE?

            //Console.WriteLine("> Writing level " + level);

            // "LVL_"
            m_writer.WriteFixed32(SnapshotFormat.LEVEL_MAGIC_NUMBER);
            // Level Flags
            m_writer.WriteFixed32(0);             //TODO: flags!
            // Level ID
            m_writer.WriteFixed32((uint)level);
            // Item count (always 2^level)
            m_writer.WriteFixed32((uint)segment.Length);

            for (int i = 0; i < segment.Length; i++)
            {
                unsafe
                {
#if __MonoCS__
                    var valuePointer = new IntPtr((void *)MemoryDatabaseHandler.ResolveValueAtVersion(segment[i], m_sequence));

                    if (valuePointer == IntPtr.Zero)
                    {
                        continue;
                    }

                    Value value = new Value();
                    Marshal.PtrToStructure(valuePointer, value);

                    var keyPointer = new IntPtr((void *)segment[i]);

                    Key key = new Key();
                    Marshal.PtrToStructure(keyPointer, key);

                    Contract.Assert(key.Size <= MemoryDatabaseHandler.MAX_KEY_SIZE);

                    // Key Size
                    uint size = key.Size;
                    m_writer.WriteVarint32(size);
                    m_writer.WriteBytesUnsafe(&(key.Data), (int)size);

                    // Value
                    m_writer.WriteVarint64(value.Sequence);                     // sequence
                    size = value.Size;
                    if (size == 0)
                    {                     // empty key
                        m_writer.WriteByte(0);
                    }
                    else
                    {
                        m_writer.WriteVarint32(size);                         // value size
                        m_writer.WriteBytesUnsafe(&(value.Data), (int)size);  // value data
                    }
#else
                    Value *value = MemoryDatabaseHandler.ResolveValueAtVersion(segment[i], m_sequence);
                    if (value == null)
                    {
                        continue;
                    }
                    Key *key = (Key *)segment[i];                    //.ToPointer();

                    Contract.Assert(key != null && key->Size <= MemoryDatabaseHandler.MAX_KEY_SIZE);

                    // Key Size
                    uint size = key->Size;
                    m_writer.WriteVarint32(size);
                    m_writer.WriteBytesUnsafe(&(key->Data), (int)size);

                    // Value

                    m_writer.WriteVarint64(value->Sequence);                     // sequence
                    size = value->Size;
                    if (size == 0)
                    {                     // empty key
                        m_writer.WriteByte(0);
                    }
                    else
                    {
                        m_writer.WriteVarint32(size);                         // value size
                        m_writer.WriteBytesUnsafe(&(value->Data), (int)size); // value data
                    }
#endif
                }

                if (m_writer.Position >= SnapshotFormat.FLUSH_SIZE)
                {
                    //Console.WriteLine("> partial flush (" + writer.Position + ")");
                    int written = await m_file.WriteCompletePagesAsync(m_writer.Buffer, m_writer.Position, ct).ConfigureAwait(false);

                    if (written > 0)
                    {
                        m_writer.Flush(written);
                    }
                }
            }

            m_writer.WriteFixed32(uint.MaxValue);

            //TODO: CRC? (would need to be computed on the fly, because we don't have the full slice in memory probably)
            m_writer.WriteFixed32(0);

            var levelEnd = checked (m_file.Length + (uint)m_writer.Position);
            m_jumpTable[level] = new KeyValuePair <ulong, ulong>(levelStart, levelEnd - levelStart);
            //Console.WriteLine("## level " + level + " ends at " + levelEnd);

            // optional padding to fill the rest of the page
            PadPageIfNeeded(SnapshotFormat.PAGE_SIZE, (byte)(0xFC - level));
        }