Ejemplo n.º 1
0
 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);
 }
Ejemplo n.º 2
0
        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();
        }
Ejemplo n.º 3
0
 private (Status status, OutputStruct output) CompletePendingResult()
 {
     session.CompletePendingWithOutputs(out var completedOutputs);
     return(TestUtils.GetSinglePendingResult(completedOutputs));
 }
Ejemplo n.º 4
0
        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();
        }