コード例 #1
0
        /// <summary>
        /// Compact the log until specified address, moving active
        /// records to the tail of the log
        /// </summary>
        /// <param name="untilAddress"></param>
        public void Compact(long untilAddress)
        {
            long originalUntilAddress = untilAddress;

            var tempKv = new FasterKV <Key, Value, Input, Output, Context, LogCompactFunctions>
                             (fht.IndexSize, new LogCompactFunctions(), new LogSettings(), comparer: fht.Comparer);

            tempKv.StartSession();

            int cnt = 0;

            using (var iter1 = fht.Log.Scan(fht.Log.BeginAddress, untilAddress))
            {
                while (iter1.GetNext(out RecordInfo recordInfo, out Key key, out Value value))
                {
                    if (recordInfo.Tombstone)
                    {
                        tempKv.Delete(ref key, default(Context), 0);
                    }
                    else
                    {
                        tempKv.Upsert(ref key, ref value, default(Context), 0);
                    }

                    if (++cnt % 1000 == 0)
                    {
                        fht.Refresh();
                        tempKv.Refresh();
                    }
                }
            }

            // TODO: Scan until SafeReadOnlyAddress
            long scanUntil = untilAddress;

            LogScanForValidity(ref untilAddress, ref scanUntil, ref tempKv);

            // Make sure key wasn't inserted between SafeReadOnlyAddress and TailAddress

            cnt = 0;
            using (var iter3 = tempKv.Log.Scan(tempKv.Log.BeginAddress, tempKv.Log.TailAddress))
            {
                while (iter3.GetNext(out RecordInfo recordInfo, out Key key, out Value value))
                {
                    if (!recordInfo.Tombstone)
                    {
                        if (fht.ContainsKeyInMemory(ref key, scanUntil) == Status.NOTFOUND)
                        {
                            fht.Upsert(ref key, ref value, default(Context), 0);
                        }
                    }
                    if (++cnt % 1000 == 0)
                    {
                        fht.Refresh();
                        tempKv.Refresh();
                    }
                    if (scanUntil < fht.Log.SafeReadOnlyAddress)
                    {
                        LogScanForValidity(ref untilAddress, ref scanUntil, ref tempKv);
                    }
                }
            }
            tempKv.StopSession();
            tempKv.Dispose();

            ShiftBeginAddress(originalUntilAddress);
        }