microsoft/garnet · error · NotImplementedException

Not implemented for TsavoriteLogAllocator

Error message

Not implemented for TsavoriteLogAllocator

What it means

TsavoriteLogAllocator is the allocator backing TsavoriteLog, an append-only log with no key comparisons or value operations (the struct's own comment states this). InitializeRecord — which writes a key into a newly allocated log record — is therefore meaningless for a log allocator and throws NotImplementedException. Keys exist in FasterKV stores, not in TsavoriteLog.

Source

Thrown at libs/storage/Tsavorite/cs/src/core/Allocator/TsavoriteLogAllocator.cs:42

            _this = (TsavoriteLogAllocatorImpl)@this;
        }

        /// <inheritdoc/>
        public readonly AllocatorBase<TsavoriteLogStoreFunctions, TAllocator> GetBase<TAllocator>()
            where TAllocator : IAllocator<TsavoriteLogStoreFunctions>
            => (AllocatorBase<TsavoriteLogStoreFunctions, TAllocator>)(object)_this;

        /// <inheritdoc/>
        public readonly bool HasObjectLog => false;

        /// <inheritdoc/>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public readonly void InitializeRecord<TKey>(TKey key, long logicalAddress, in RecordSizeInfo _, ref LogRecord newLogRecord)
            where TKey : IKey
#if NET9_0_OR_GREATER
                , allows ref struct
#endif
            => throw new NotImplementedException("Not implemented for TsavoriteLogAllocator");

        /// <inheritdoc/>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public readonly RecordSizeInfo GetRMWCopyRecordSize<TSourceLogRecord, TInput, TVariableLengthInput>(in TSourceLogRecord srcLogRecord, ref TInput input, TVariableLengthInput varlenInput)
            where TSourceLogRecord : ISourceLogRecord
            where TVariableLengthInput : IVariableLengthInput<TInput>
              => throw new NotImplementedException("Not implemented for TsavoriteLogAllocator");

        /// <inheritdoc/>
        [MethodImpl(MethodImplOptions.AggressiveInlining)]
        public readonly RecordSizeInfo GetRMWInitialRecordSize<TKey, TInput, TVariableLengthInput>(TKey key, ref TInput input, TVariableLengthInput varlenInput)
            where TKey : IKey
#if NET9_0_OR_GREATER
                , allows ref struct
#endif
            where TVariableLengthInput : IVariableLengthInput<TInput>
            => throw new NotImplementedException("Not implemented for TsavoriteLogAllocator");

View on GitHub (pinned to 951b0fc683)

Solutions

  1. Do not call KV record initialization on TsavoriteLog; use session.Append for the log instead.
  2. If you need keyed records (InitializeRecord/Upsert/RMW/Delete), use a FasterKV store, not TsavoriteLog.
  3. Add a type guard rejecting TsavoriteLogAllocator before dispatching to KV allocator methods.

Example fix

// before
allocator.InitializeRecord(key, addr, in sizeInfo, ref record);

// after
if (allocator.GetBase<TsavoriteLogAllocator>() is not null)
    throw new InvalidOperationException("TsavoriteLog does not support keyed records; use FasterKV.");
allocator.InitializeRecord(key, addr, in sizeInfo, ref record);
Defensive patterns

Strategy: type-guard

Type guard

static bool IsLogAllocator<TAllocator>(TAllocator a) where TAllocator : IAllocator =>
    a is TsavoriteLogAllocator;

Prevention

When it happens

Trigger: Invoking InitializeRecord on a TsavoriteLogAllocator instance, typically via generic plumbing that works against any IAllocator but was routed to the log allocator instead of a FasterKV allocator.

Common situations: Reusing FasterKV record-initialization helpers against a TsavoriteLog; reflection/dynamic dispatch hitting this stub; a bug in allocator selection that binds KV code to the log allocator.

Related errors


AI-assisted analysis of microsoft/garnet@951b0fc683 (2026-08-13). Data as JSON: /api/errors/cd7e082032bacd2e. Report an issue: GitHub.