internal SSTable(Stream stream, IBlockCache?cache, PlaneDBOptions options) { this.stream = stream; comparer = options.Comparer; reader = OpenReaderStream(cache, options); index = new Lazy <Index>(() => new Index(reader), LazyThreadSafetyMode.ExecutionAndPublication); }
private static void BlockStreamWriterOnceTest(IBlockTransformer transformer, IBlockCache cache) { using var ms = new KeepOpenMemoryStream(); const int COUNT = 100_000; long expectedLength; using (var writer = new BlockWriteOnceStream(ms, transformer)) { using var binaryWriter = new BinaryWriter(writer, Encoding.ASCII, true); for (var i = 0; i < COUNT; ++i) { binaryWriter.Write(i); } writer.Write(new byte[1 << 22]); expectedLength = writer.Length; } using (var writer = new BlockReadOnlyStream(ms, transformer, cache: cache)) { Assert.AreEqual(expectedLength, writer.Length); using var binaryReader = new BinaryReader(writer, Encoding.ASCII, true); using var binaryCursorReader = new BinaryReader(writer.CreateCursor(), Encoding.ASCII, true); for (var i = 0; i < COUNT; ++i) { Assert.AreEqual(i, binaryReader.ReadInt32()); Assert.AreEqual(i, binaryCursorReader.ReadInt32()); } var buf = new byte[1 << 22]; Assert.AreEqual(buf.Length, writer.Read(buf)); Assert.IsTrue(buf.All(i => i == 0)); } }
public Index(BlockReadOnlyStream stream) { using var reader = stream.CreateCursor(); reader.Seek(-sizeof(long), SeekOrigin.End); var headerLen = reader.ReadInt64(); var headerBytes = new byte[headerLen]; var headerOffset = reader.Seek(-sizeof(long) - headerBytes.Length, SeekOrigin.End); reader.ReadFullBlock(headerBytes); using var header = new MemoryStream(headerBytes, false); var blen = header.ReadInt32(); var binit = new byte[blen]; header.ReadFullBlock(binit); Filter = new BloomFilter(binit); var len = header.ReadInt32(); var idx = new List <KeyValuePair <byte[], long> >(); for (var i = 0; i < len; ++i) { var logicalOffset = header.ReadInt32(); var klen = header.ReadInt32(); var key = new byte[klen]; header.ReadFullBlock(key); var absOffset = headerOffset - logicalOffset; idx.Add(new KeyValuePair <byte[], long>(key, absOffset)); } Indexes = idx.ToArray(); { var firstIndex = Indexes.First(); reader.Seek(firstIndex.Value, SeekOrigin.Begin); var items = reader.ReadInt32(); reader.ReadInt64(); var blengths = new byte[items * sizeof(int) * 2]; reader.ReadFullBlock(blengths); var lengths = blengths.AsSpan(); var klen = BinaryPrimitives.ReadInt32LittleEndian(lengths); FirstKey = reader.ReadFullBlock(klen); } LastKey = Indexes[Indexes.Length - 1].Key; }