public unsafe void MultiReadSpanByteKeyTest() { TestUtils.DeleteDirectory(TestUtils.MethodTestDir, wait: true); try { using var log = Devices.CreateLogDevice(TestUtils.MethodTestDir + "/MultiReadSpanByteKeyTest.log", deleteOnClose: true); using var fht = new FasterKV <SpanByte, long>( size: 1L << 10, new LogSettings { LogDevice = log, MemorySizeBits = 15, PageSizeBits = 12 }); using var session = fht.For(new MultiReadSpanByteKeyTestFunctions()).NewSession <MultiReadSpanByteKeyTestFunctions>(); for (int i = 0; i < 200; i++) { var key = MemoryMarshal.Cast <char, byte>($"{i}".AsSpan()); fixed(byte *_ = key) session.Upsert(SpanByte.FromFixedSpan(key), i); } // Evict all records to disk fht.Log.FlushAndEvict(true); for (long key = 0; key < 50; key++) { // read each key multiple times for (int i = 0; i < 10; i++) { Assert.AreEqual(key, ReadKey($"{key}")); } } long ReadKey(string keyString) { Status status; var key = MemoryMarshal.Cast <char, byte>(keyString.AsSpan()); fixed(byte *_ = key) status = session.Read(key: SpanByte.FromFixedSpan(key), out var unused); // All keys need to be fetched from disk Assert.IsTrue(status.IsPending); session.CompletePendingWithOutputs(out var completedOutputs, wait: true); var count = 0; var value = 0L; using (completedOutputs) { while (completedOutputs.Next()) { count++; Assert.IsTrue(completedOutputs.Current.Status.Found); value = completedOutputs.Current.Output; } } Assert.AreEqual(1, count); return(value); } } finally { TestUtils.DeleteDirectory(TestUtils.MethodTestDir); } }