internal void CompletePendingAndVerifyInsertedAddress() { // Note: Only Read and RMW have Pending results. this.session.CompletePendingWithOutputs(out var completedOutputs, wait: true); TestUtils.GetSinglePendingResult(completedOutputs, out var recordMetadata); Assert.AreEqual(this.expectedAddress, recordMetadata.Address); }
public void ReadAtAddressReadFlagsSkipReadCache() { // Another ReadFlag functional test so one device is enough deviceType = TestUtils.DeviceType.MLSD; Setup(128, new LogSettings { MemorySizeBits = 29, ReadCacheSettings = new ReadCacheSettings() }, deviceType); SkipReadCacheFunctions functions = new(); using var skipReadCacheSession = fht.For(functions).NewSession <SkipReadCacheFunctions>(); InputStruct input = default; OutputStruct output = default; var key1 = new KeyStruct { kfield1 = 13, kfield2 = 14 }; var value = new ValueStruct { vfield1 = 23, vfield2 = 24 }; var readAtAddress = fht.Log.BeginAddress; Status status; skipReadCacheSession.Upsert(ref key1, ref value, Empty.Default, 0); void VerifyOutput() { Assert.AreEqual(-1, functions.expectedReadAddress); // make sure the test executed Assert.AreEqual(value.vfield1, output.value.vfield1); Assert.AreEqual(value.vfield2, output.value.vfield2); Assert.AreEqual(13, key1.kfield1); Assert.AreEqual(14, key1.kfield2); } void VerifyResult() { if (status.IsPending) { skipReadCacheSession.CompletePendingWithOutputs(out var completedOutputs, wait: true); (status, output) = TestUtils.GetSinglePendingResult(completedOutputs); } Assert.IsTrue(status.Found); VerifyOutput(); } // This will just be an ordinary read, as the record is in memory. functions.expectedReadAddress = readAtAddress; status = skipReadCacheSession.Read(ref key1, ref input, ref output); Assert.IsTrue(status.Found); VerifyOutput(); // ReadCache is used when the record is read from disk. fht.Log.FlushAndEvict(wait: true); // SkipReadCache is primarily for indexing, so a read during index scan does not result in a readcache update. // Reading at a normal logical address will not use the readcache, because the "readcache" bit is not set in that logical address. // And we cannot get a readcache address, since reads satisfied from the readcache pass kInvalidAddress to functions. // Therefore, we test here simply that we do not put it in the readcache when we tell it not to. // Do not put it into the read cache. functions.expectedReadAddress = readAtAddress; ReadOptions readOptions = new() { StartAddress = readAtAddress, ReadFlags = ReadFlags.DisableReadCacheReads | ReadFlags.DisableReadCacheUpdates }; status = skipReadCacheSession.Read(ref key1, ref input, ref output, ref readOptions, out _); VerifyResult(); Assert.AreEqual(fht.ReadCache.BeginAddress, fht.ReadCache.TailAddress); // Put it into the read cache. functions.expectedReadAddress = readAtAddress; readOptions.ReadFlags = ReadFlags.None; status = skipReadCacheSession.Read(ref key1, ref input, ref output, ref readOptions, out _); VerifyResult(); Assert.Less(fht.ReadCache.BeginAddress, fht.ReadCache.TailAddress); // Now this will read from the read cache. functions.expectedReadAddress = Constants.kInvalidAddress; status = skipReadCacheSession.Read(ref key1, ref input, ref output); Assert.IsTrue(status.Found); VerifyOutput(); }
private (Status status, OutputStruct output) CompletePendingResult() { session.CompletePendingWithOutputs(out var completedOutputs); return(TestUtils.GetSinglePendingResult(completedOutputs)); }
public void ReadAtAddressReadFlagsSkipReadCache() { // Another ReadFlag functional test so one device is enough deviceType = TestUtils.DeviceType.MLSD; string filename = path + "ReadAtAddressReadFlagsSkipReadCache" + deviceType.ToString() + ".log"; log = TestUtils.CreateTestDevice(deviceType, filename); fht = new FasterKV <KeyStruct, ValueStruct> (128, new LogSettings { LogDevice = log, MemorySizeBits = 29, ReadCacheSettings = new ReadCacheSettings() }); SkipReadCacheFunctions functions = new(); using var skipReadCacheSession = fht.For(functions).NewSession <SkipReadCacheFunctions>(); InputStruct input = default; OutputStruct output = default; var key1 = new KeyStruct { kfield1 = 13, kfield2 = 14 }; var value = new ValueStruct { vfield1 = 23, vfield2 = 24 }; var readAtAddress = fht.Log.BeginAddress; Status status; skipReadCacheSession.Upsert(ref key1, ref value, Empty.Default, 0); void VerifyOutput() { Assert.AreEqual(-1, functions.expectedReadAddress); // make sure the test executed Assert.AreEqual(value.vfield1, output.value.vfield1); Assert.AreEqual(value.vfield2, output.value.vfield2); Assert.AreEqual(13, key1.kfield1); Assert.AreEqual(14, key1.kfield2); } void VerifyResult() { if (status == Status.PENDING) { skipReadCacheSession.CompletePendingWithOutputs(out var completedOutputs, wait: true); (status, output) = TestUtils.GetSinglePendingResult(completedOutputs); } Assert.AreEqual(Status.OK, status); VerifyOutput(); } // This will just be an ordinary read, as the record is in memory. functions.expectedReadAddress = readAtAddress; status = skipReadCacheSession.Read(ref key1, ref input, ref output); Assert.AreEqual(Status.OK, status); VerifyOutput(); // ReadCache is used when the record is read from disk. fht.Log.FlushAndEvict(wait: true); // SkipReadCache is primarily for indexing, so a read during index scan does not result in a readcache update. // Reading at a normal logical address will not use the readcache, because the "readcache" bit is not set in that logical address. // And we cannot get a readcache address, since reads satisfied from the readcache pass kInvalidAddress to functions. // Therefore, we test here simply that we do not put it in the readcache when we tell it not to. // Do not put it into the read cache. functions.expectedReadAddress = readAtAddress; RecordInfo recordInfo = new() { PreviousAddress = readAtAddress }; status = skipReadCacheSession.Read(ref key1, ref input, ref output, ref recordInfo, ReadFlags.SkipReadCache); VerifyResult(); Assert.AreEqual(fht.ReadCache.BeginAddress, fht.ReadCache.TailAddress); // Put it into the read cache. functions.expectedReadAddress = readAtAddress; recordInfo.PreviousAddress = readAtAddress; // Read*() sets this to the record's PreviousAddress (so caller can follow the chain), so reinitialize it. status = skipReadCacheSession.Read(ref key1, ref input, ref output, ref recordInfo); VerifyResult(); Assert.Less(fht.ReadCache.BeginAddress, fht.ReadCache.TailAddress); // Now this will read from the read cache. functions.expectedReadAddress = Constants.kInvalidAddress; status = skipReadCacheSession.Read(ref key1, ref input, ref output); Assert.AreEqual(Status.OK, status); VerifyOutput(); }