public static void Run() { // VarLen types do not need an object log var log = Devices.CreateLogDevice("hlog.log", deleteOnClose: true); // Create store // For custom varlen (not SpanByte), you need to provide IVariableLengthStructSettings and IFasterEqualityComparer var store = new FasterKV <SpanByte, SpanByte>( size: 1L << 20, logSettings: new LogSettings { LogDevice = log, MemorySizeBits = 15, PageSizeBits = 12 }); // Create session var s = store.For(new CustomSpanByteFunctions(locking: false)).NewSession <CustomSpanByteFunctions>(); Random r = new Random(100); // Here, stackalloc implies fixed, so it can be used directly with SpanByte // For Span<byte> over heap data (e.g., strings or byte[]), make sure to use // fixed before the FASTER Read/Upsert/RMW operation. Span <byte> keyMem = stackalloc byte[1000]; Span <byte> valueMem = stackalloc byte[1000]; byte i; for (i = 0; i < 200; i++) { var keyLen = r.Next(1, 1000); var key = keyMem.Slice(0, keyLen); key.Fill(i); var valLen = r.Next(1, 1000); var value = valueMem.Slice(0, valLen); value.Fill((byte)valLen); // Option 1: Using overload for Span<byte> s.Upsert(key, value); } bool success = true; i = 0; using (IFasterScanIterator <SpanByte, SpanByte> iterator = store.Log.Scan(store.Log.BeginAddress, store.Log.TailAddress)) { while (iterator.GetNext(out RecordInfo recordInfo)) { ref var key = ref iterator.GetKey(); if (key.ToByteArray()[0] != i++) { success = false; break; } } }
public unsafe bool GetNext(out RecordInfo recordInfo) { while (true) { if (enumerationPhase == 0) { if (iter1.GetNext(out recordInfo)) { ref var key = ref iter1.GetKey(); ref var value = ref iter1.GetValue(); var bucket = default(HashBucket *); var slot = default(int); var entry = default(HashBucketEntry); var hash = fht.Comparer.GetHashCode64(ref key); var tag = (ushort)((ulong)hash >> Constants.kHashTagShift); if (fht.FindTag(hash, tag, ref bucket, ref slot, ref entry) && entry.Address == iter1.CurrentAddress) { if (recordInfo.PreviousAddress >= fht.Log.BeginAddress) { if (tempKvSession.ContainsKeyInMemory(ref key, out _) == Status.OK) { tempKvSession.Delete(ref key); } } if (!recordInfo.Tombstone) { return(true); } continue; } else { if (recordInfo.Tombstone) { tempKvSession.Delete(ref key); } else { tempKvSession.Upsert(ref key, ref value); } continue; } }