microsoft/FASTER · error · FasterException

should be at least of size 8 cache line (512 bytes)

Error message

{nameof(IndexSize)} should be at least of size 8 cache line (512 bytes)

What it means

FasterKVSettings.GetIndexSizeCacheLines enforces a minimum hash index size of 512 bytes (8 cache lines) by rounding IndexSize down to the previous power of 2 and validating it. An IndexSize below 512 is rejected because the hash index machinery assumes at least a full cache-line-set granularity.

Solutions

  1. Set IndexSize to at least 512 in FasterKVSettings
  2. Use a sensible power-of-2 value such as 1L<<20 or larger; the library rounds down to the previous power of 2 anyway

Example fix

// before
var settings = new FasterKVSettings<long, long> { IndexSize = 256 };
// after
var settings = new FasterKVSettings<long, long> { IndexSize = 1L << 20 }; // >= 512 bytes, power of 2
Defensive patterns

Strategy: validation

Validate before calling

if (settings.IndexSize < 512)
    throw new ArgumentException("IndexSize must be at least 512 bytes (8 cache lines)");

Try / catch

try { var kv = new FasterKV<long, long>(settings); }
catch (FasterException ex) when (ex.Message.Contains("should be at least of size 8 cache line"))
{
    settings.IndexSize = 512; // or a larger power-of-2
    var kv = new FasterKV<long, long>(settings);
}

Prevention

When it happens

Trigger: Constructing FasterKV (or calling GetIndexSizeCacheLines via the FasterKV ctor) with FasterKVSettings.IndexSize smaller than 512, e.g. IndexSize = 1L<<8 (256) or a tiny value like 64.

Common situations: Developers experimenting with minimal in-memory setups, unit tests with tiny indexes, misreading IndexSize units (it is a byte count of index memory, not an entry count).

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


AI-assisted analysis of microsoft/FASTER@321d872eab (2026-09-15). Data as JSON: /api/errors/e9a6e295fd6c10ca. Report an issue: GitHub.

Appendix: source

Thrown at cs/src/core/Index/Common/FasterKVSettings.cs:214

        /// <inheritdoc />
        public override string ToString()
        {
            var retStr = $"index: {Utility.PrettySize(IndexSize)}; log memory: {Utility.PrettySize(MemorySize)}; log page: {Utility.PrettySize(PageSize)}; log segment: {Utility.PrettySize(SegmentSize)}";
            retStr += $"; log device: {(LogDevice == null ? "null" : LogDevice.GetType().Name)}";
            retStr += $"; obj log device: {(ObjectLogDevice == null ? "null" : ObjectLogDevice.GetType().Name)}";
            retStr += $"; mutable fraction: {MutableFraction}; locking mode: {this.ConcurrencyControlMode}";
            retStr += $"; read cache (rc): {(ReadCacheEnabled ? "yes" : "no")}";
            retStr += $"; read copy options: {ReadCopyOptions}";
            if (ReadCacheEnabled)
                retStr += $"; rc memory: {Utility.PrettySize(ReadCacheMemorySize)}; rc page: {Utility.PrettySize(ReadCachePageSize)}";
            return retStr;
        }

        internal long GetIndexSizeCacheLines()
        {
            long adjustedSize = Utility.PreviousPowerOf2(IndexSize);
            if (adjustedSize < 512)
                throw new FasterException($"{nameof(IndexSize)} should be at least of size 8 cache line (512 bytes)");
            if (IndexSize != adjustedSize)  // Don't use string interpolation when logging messages because it makes it impossible to group by the message template.
                logger?.LogInformation("Warning: using lower value {0} instead of specified {1} for {2}", adjustedSize, IndexSize, nameof(IndexSize));
            return adjustedSize / 64;
        }

        internal LogSettings GetLogSettings()
        {
            return new LogSettings
            {
                ReadCopyOptions = ReadCopyOptions,
                LogDevice = LogDevice,
                ObjectLogDevice = ObjectLogDevice,
                MemorySizeBits = Utility.NumBitsPreviousPowerOf2(MemorySize),
                PageSizeBits = Utility.NumBitsPreviousPowerOf2(PageSize),
                SegmentSizeBits = Utility.NumBitsPreviousPowerOf2(SegmentSize),
                MutableFraction = MutableFraction,
                PreallocateLog = PreallocateLog,
                ReadCacheSettings = GetReadCacheSettings()

View on GitHub (pinned to 321d872eab)