Пример #1
0
        static void RecoverAndTestStore(string path)
        {
            using var settings = new FasterKVSettings <MyKey, MyValue>(path, deleteDirOnDispose: true)
                  {
                      KeySerializer    = () => new MyKeySerializer(),
                      ValueSerializer  = () => new MyValueSerializer(),
                      TryRecoverLatest = true,
                  };

            using var store   = new FasterKV <MyKey, MyValue>(settings);
            using var session = store.NewSession(new Functions());

            // Test Read
            var key = new MyKey {
                key = 23
            };
            MyOutput g1     = default;
            var      status = session.Read(ref key, ref g1);

            if (status.Found && g1.value.value == key.key)
            {
                Console.WriteLine("Success!");
            }
            else
            {
                Console.WriteLine("Error!");
            }
        }
Пример #2
0
        static void PopulateStore(string path)
        {
            // We use class types MyKey and MyValue in this example, replace with blittable structs for
            // better performance. Serializers are required for class (non-blittable) types in order to
            // write to storage. You can also mark types as DataContract (lower performance).

            using var settings = new FasterKVSettings <MyKey, MyValue>(path)
                  {
                      KeySerializer   = () => new MyKeySerializer(),
                      ValueSerializer = () => new MyValueSerializer()
                  };

            using var store = new FasterKV <MyKey, MyValue>(settings);
            using var s     = store.NewSession(new Functions());

            for (int i = 0; i < 20000; i++)
            {
                var _key = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };
                s.Upsert(ref _key, ref value);
            }

            var key = new MyKey {
                key = 23
            };
            MyOutput g1     = default;
            var      status = s.Read(ref key, ref g1);

            if (status.Found && g1.value.value == key.key)
            {
                Console.WriteLine("Success!");
            }
            else
            {
                Console.WriteLine("Error!");
            }

            // Take index + fold-over checkpoint of FASTER, wait to complete
            store.TakeFullCheckpointAsync(CheckpointType.FoldOver).AsTask().GetAwaiter().GetResult();
        }
Пример #3
0
        static void InMemorySample()
        {
            Console.WriteLine("In-Memory Sample:\n");

            long key = 1, value = 1, output = 0;

            // Create a default config (null path indicates in-memory only)
            // Uses default config parameters. Update config fields to tune parameters.
            using var config = new FasterKVSettings <long, long>(null);
            Console.WriteLine($"FasterKV config:\n{config}\n");

            using var store = new FasterKV <long, long>(config);

            // Create functions for callbacks; we use a standard in-built function in this sample.
            // You can write your own by extending this or FunctionsBase.
            // In this in-built function, read-modify-writes will perform value merges via summation.
            var funcs = new SimpleFunctions <long, long>((a, b) => a + b);

            // Each logical sequence of calls to FASTER is associated with a FASTER session.
            // No concurrency allowed within a single session
            using var session = store.NewSession(funcs);

            // (1) Upsert and read back upserted value
            session.Upsert(ref key, ref value);

            // Reads are served back from memory and return synchronously
            var status = session.Read(ref key, ref output);

            if (status.Found && output == value)
            {
                Console.WriteLine("(1) Success!");
            }
            else
            {
                Console.WriteLine("(1) Error!");
            }

            /// (2) Delete key, read to verify deletion
            session.Delete(ref key);

            status = session.Read(ref key, ref output);
            if (status.Found)
            {
                Console.WriteLine("(2) Error!");
            }
            else
            {
                Console.WriteLine("(2) Success!");
            }

            // (4) Perform two read-modify-writes (summation), verify result
            key = 2;
            long input1 = 25, input2 = 27;

            session.RMW(ref key, ref input1);
            session.RMW(ref key, ref input2);

            status = session.Read(ref key, ref output);

            if (status.Found && output == input1 + input2)
            {
                Console.WriteLine("(3) Success!");
            }
            else
            {
                Console.WriteLine("(3) Error!");
            }


            // (5) Perform TryAdd using RMW and custom IFunctions
            using var tryAddSession = store.NewSession(new TryAddFunctions <long, long>());
            key = 3; input1 = 30; input2 = 31;

            // First TryAdd - success; status should be NotFound (does not already exist)
            status = tryAddSession.RMW(ref key, ref input1);

            // Second TryAdd - failure; status should be Found (already exists)
            var status2 = tryAddSession.RMW(ref key, ref input2);

            // Read, result should be input1 (first TryAdd)
            var status3 = session.Read(ref key, ref output);

            if (status.NotFound && status2.Found && status3.Found && output == input1)
            {
                Console.WriteLine("(4) Success!");
            }
            else
            {
                Console.WriteLine("(4) Error!");
            }
        }
Пример #4
0
        static void DiskSample()
        {
            Console.WriteLine("\nDisk Sample:\n");

            long key = 1, value = 1, output = 0;

            // Create FasterKV config based on specified base directory path.
            using var config = new FasterKVSettings <long, long>("./database")
                  {
                      TryRecoverLatest = true
                  };
            Console.WriteLine($"FasterKV config:\n{config}\n");

            // Create store using specified config
            using var store = new FasterKV <long, long>(config);

            // Create functions for callbacks; we use a standard in-built function in this sample.
            // You can write your own by extending this or FunctionsBase.
            // In this in-built function, read-modify-writes will perform value merges via summation.
            var funcs = new SimpleFunctions <long, long>((a, b) => a + b);

            // Each logical sequence of calls to FASTER is associated with a FASTER session.
            // No concurrency allowed within a single session
            using var session = store.NewSession(funcs);

            if (store.RecoveredVersion == 1) // did not recover
            {
                Console.WriteLine("Clean start; upserting key-value pair");

                // (1) Upsert and read back upserted value
                session.Upsert(ref key, ref value);

                // Take checkpoint so data is persisted for recovery
                Console.WriteLine("Taking full checkpoint");
                store.TryInitiateFullCheckpoint(out _, CheckpointType.Snapshot);
                store.CompleteCheckpointAsync().AsTask().GetAwaiter().GetResult();
            }
            else
            {
                Console.WriteLine($"Recovered store to version {store.RecoveredVersion}");
            }

            // Reads are served back from memory and return synchronously
            var status = session.Read(ref key, ref output);

            if (status.Found && output == value)
            {
                Console.WriteLine("(1) Success!");
            }
            else
            {
                Console.WriteLine("(1) Error!");
            }

            // (2) Force flush record to disk and evict from memory, so that next read is served from disk
            store.Log.FlushAndEvict(true);

            // Reads from disk will return PENDING status, result available via either asynchronous IFunctions callback
            // or on this thread via CompletePendingWithOutputs, shown below
            status = session.Read(ref key, ref output);
            if (status.IsPending)
            {
                session.CompletePendingWithOutputs(out var iter, true);
                while (iter.Next())
                {
                    if (iter.Current.Status.Found && iter.Current.Output == value)
                    {
                        Console.WriteLine("(2) Success!");
                    }
                    else
                    {
                        Console.WriteLine("(2) Error!");
                    }
                }
                iter.Dispose();
            }
            else
            {
                Console.WriteLine("(2) Error!");
            }

            /// (3) Delete key, read to verify deletion
            session.Delete(ref key);

            status = session.Read(ref key, ref output);
            if (status.Found)
            {
                Console.WriteLine("(3) Error!");
            }
            else
            {
                Console.WriteLine("(3) Success!");
            }

            // (4) Perform two read-modify-writes (summation), verify result
            key = 2;
            long input1 = 25, input2 = 27;

            session.RMW(ref key, ref input1);
            session.RMW(ref key, ref input2);

            status = session.Read(ref key, ref output);

            if (status.Found && output == input1 + input2)
            {
                Console.WriteLine("(4) Success!");
            }
            else
            {
                Console.WriteLine("(4) Error!");
            }


            // (5) Perform TryAdd using RMW and custom IFunctions
            using var tryAddSession = store.NewSession(new TryAddFunctions <long, long>());
            key = 3; input1 = 30; input2 = 31;

            // First TryAdd - success; status should be NOTFOUND (does not already exist)
            status = tryAddSession.RMW(ref key, ref input1);

            // Second TryAdd - failure; status should be OK (already exists)
            var status2 = tryAddSession.RMW(ref key, ref input2);

            // Read, result should be input1 (first TryAdd)
            var status3 = session.Read(ref key, ref output);

            if (!status.Found && status2.Found && status3.Found && output == input1)
            {
                Console.WriteLine("(5) Success!");
            }
            else
            {
                Console.WriteLine("(5) Error!");
            }
        }