Beispiel #1
0
        internal ReadOnlySpan <byte> EncodeBatch(KeyValuePair <byte[], ResultCacheEntry>[] operations)
        {
            if (operations.Length == 0)
            {
                throw new ArgumentException("Zero size batch", nameof(operations));
            }

            long maxSize = 0;

            maxSize += 8;                     // sequence
            maxSize += 4 * operations.Length; // count
            foreach (KeyValuePair <byte[], ResultCacheEntry> entry in operations)
            {
                maxSize += 1;                 // op code
                maxSize += 10;                // varint max
                maxSize += entry.Key.Length;
                if (entry.Value.ResultState == ResultState.Exist)
                {
                    maxSize += 10;                     // varint max
                    maxSize += entry.Value.Data?.Length ?? 0;
                }
            }

            Span <byte> data = new byte[maxSize];            // big enough to contain all data regardless of size

            var writer = new SpanWriter(data);

            // write sequence
            writer.Write((ulong)operations.First().Value.Sequence);
            // write operations count
            writer.Write((uint)operations.Length);

            foreach (KeyValuePair <byte[], ResultCacheEntry> operation in operations)
            {
                byte[]           key   = operation.Key;
                ResultCacheEntry entry = operation.Value;
                // write op type (byte)
                writer.Write(entry.ResultState == ResultState.Exist ? (byte)OperationType.Value : (byte)OperationType.Delete);
                // write key
                writer.WriteLengthPrefixed(key);

                if (entry.ResultState == ResultState.Exist)
                {
                    // write data
                    writer.WriteLengthPrefixed(entry.Data);
                }
            }

            return(data.Slice(0, writer.Position));
        }
Beispiel #2
0
        public static Span <byte> EncodeVersion(Version version)
        {
            var array  = new byte[4096];
            var buffer = new Span <byte>(array);
            var writer = new SpanWriter(buffer);

            //	case Manifest.LogTagType.Comparator:
            if (!string.IsNullOrEmpty(version.Comparator))
            {
                writer.WriteVarLong((ulong)LogTagType.Comparator);
                writer.Write(version.Comparator);
            }
            //	case Manifest.LogTagType.LogNumber:
            {
                writer.WriteVarLong((ulong)LogTagType.LogNumber);
                writer.WriteVarLong((ulong)version.LogNumber);
            }
            //	case Manifest.LogTagType.PrevLogNumber:
            {
                writer.WriteVarLong((ulong)LogTagType.PrevLogNumber);
                writer.WriteVarLong((ulong)version.PreviousLogNumber);
            }
            //	case Manifest.LogTagType.NextFileNumber:
            {
                writer.WriteVarLong((ulong)LogTagType.NextFileNumber);
                writer.WriteVarLong((ulong)version.NextFileNumber);
            }
            //	case Manifest.LogTagType.LastSequence:
            {
                writer.WriteVarLong((ulong)LogTagType.LastSequence);
                writer.WriteVarLong((ulong)version.LastSequenceNumber);
            }
            //	case Manifest.LogTagType.CompactPointer:
            if (version.CompactPointers.Count > 0)
            {
                foreach (KeyValuePair <int, byte[]> pointer in version.CompactPointers)
                {
                    writer.WriteVarLong((ulong)LogTagType.CompactPointer);
                    writer.WriteVarLong((ulong)pointer.Key);
                    writer.WriteLengthPrefixed(pointer.Value);
                }
            }
            //	case Manifest.LogTagType.DeletedFile:
            //if (version.DeletedFiles.Count > 0)
            //{
            //	foreach (KeyValuePair<int, List<ulong>> files in version.DeletedFiles)
            //	{
            //		foreach (ulong fileNumber in files.Value)
            //		{
            //			writer.WriteVarLong((ulong) LogTagType.DeletedFile);
            //			writer.WriteVarLong((ulong) files.Key);
            //			writer.WriteVarLong(fileNumber);
            //		}
            //	}
            //}
            //	case Manifest.LogTagType.NewFile:
            if (version.Levels.Count > 0)
            {
                foreach (KeyValuePair <int, List <FileMetadata> > files in version.Levels)
                {
                    int level = files.Key;
                    foreach (FileMetadata fileMeta in files.Value)
                    {
                        writer.WriteVarLong((ulong)LogTagType.NewFile);
                        //int level = (int) reader.ReadVarLong();
                        writer.WriteVarLong((ulong)level);
                        //ulong fileNumber = reader.ReadVarLong();
                        writer.WriteVarLong((ulong)fileMeta.FileNumber);
                        //ulong fileSize = reader.ReadVarLong();
                        writer.WriteVarLong((ulong)fileMeta.FileSize);
                        //var smallest = reader.ReadLengthPrefixedBytes();
                        writer.WriteLengthPrefixed(fileMeta.SmallestKey);
                        //var largest = reader.ReadLengthPrefixedBytes();
                        writer.WriteLengthPrefixed(fileMeta.LargestKey);
                    }
                }
            }

            int length = writer.Position;

            return(buffer.Slice(0, length).ToArray());
        }