Exemple #1
0
        /// <summary>
        /// Compact the log until specified address, moving active records to the tail of the log.
        /// </summary>
        /// <param name="functions">Functions used to manage key-values during compaction</param>
        /// <param name="cf">User provided compaction functions (see <see cref="ICompactionFunctions{Key, Value}"/>).</param>
        /// <param name="untilAddress">Compact log until this address</param>
        /// <param name="shiftBeginAddress">Whether to shift begin address to untilAddress after compaction. To avoid
        /// data loss on failure, set this to false, and shift begin address only after taking a checkpoint. This
        /// ensures that records written to the tail during compaction are first made stable.</param>
        /// <returns>Address until which compaction was done</returns>
        public long Compact <Input, Output, Context, Functions, CompactionFunctions>(Functions functions, CompactionFunctions cf, long untilAddress, bool shiftBeginAddress)
            where Functions : IFunctions <Key, Value, Input, Output, Context>
            where CompactionFunctions : ICompactionFunctions <Key, Value>
        {
            if (untilAddress > fht.Log.SafeReadOnlyAddress)
            {
                throw new FasterException("Can compact only until Log.SafeReadOnlyAddress");
            }
            var originalUntilAddress = untilAddress;

            var lf = new LogCompactionFunctions <Key, Value, Input, Output, Context, Functions>(functions);

            using var fhtSession = fht.For(lf).NewSession <LogCompactionFunctions <Key, Value, Input, Output, Context, Functions> >();

            VariableLengthStructSettings <Key, Value> variableLengthStructSettings = null;

            if (allocator is VariableLengthBlittableAllocator <Key, Value> varLen)
            {
                variableLengthStructSettings = new VariableLengthStructSettings <Key, Value>
                {
                    keyLength   = varLen.KeyLength,
                    valueLength = varLen.ValueLength,
                };
            }

            using (var tempKv = new FasterKV <Key, Value>(fht.IndexSize, new LogSettings {
                LogDevice = new NullDevice(), ObjectLogDevice = new NullDevice()
            }, comparer: fht.Comparer, variableLengthStructSettings: variableLengthStructSettings))
                using (var tempKvSession = tempKv.NewSession <Input, Output, Context, Functions>(functions))
                {
                    using (var iter1 = fht.Log.Scan(fht.Log.BeginAddress, untilAddress))
                    {
                        while (iter1.GetNext(out var recordInfo))
                        {
                            ref var key   = ref iter1.GetKey();
                            ref var value = ref iter1.GetValue();

                            if (recordInfo.Tombstone || cf.IsDeleted(key, value))
                            {
                                tempKvSession.Delete(ref key, default, 0);