{"record":{"id":"07cc4186ac13a8af","repo":"microsoft/FASTER","slug":"blittableallocator-memory-pages-are-sector-aligned-use-07cc41","errorCode":null,"errorMessage":"BlittableAllocator memory pages are sector aligned - use direct copy","messagePattern":"BlittableAllocator memory pages are sector aligned - use direct copy","errorType":"exception","errorClass":"FasterException","httpStatus":null,"severity":"error","filePath":"cs/src/core/Allocator/VarLenBlittableAllocator.cs","lineNumber":494,"sourceCode":"        }\n\n        /// <summary>\n        /// Whether KVS has values to serialize/deserialize\n        /// </summary>\n        /// <returns></returns>\n        public override bool ValueHasObjects()\n        {\n            return false;\n        }\n\n        public override long[] GetSegmentOffsets()\n        {\n            return null;\n        }\n\n        internal override void PopulatePage(byte* src, int required_bytes, long destinationPage)\n        {\n            throw new FasterException(\"BlittableAllocator memory pages are sector aligned - use direct copy\");\n            // Buffer.MemoryCopy(src, (void*)pointers[destinationPage % BufferSize], required_bytes, required_bytes);\n        }\n\n        /// <summary>\n        /// Iterator interface for pull-scanning FASTER log\n        /// </summary>\n        public override IFasterScanIterator<Key, Value> Scan(FasterKV<Key, Value> store, long beginAddress, long endAddress, ScanBufferingMode scanBufferingMode) \n            => new VariableLengthBlittableScanIterator<Key, Value>(store, this, beginAddress, endAddress, scanBufferingMode, epoch, logger: logger);\n\n        /// <summary>\n        /// Implementation for push-scanning FASTER log, called from LogAccessor\n        /// </summary>\n        internal override bool Scan<TScanFunctions>(FasterKV<Key, Value> store, long beginAddress, long endAddress, ref TScanFunctions scanFunctions, ScanBufferingMode scanBufferingMode)\n        {\n            using VariableLengthBlittableScanIterator<Key, Value> iter = new(store, this, beginAddress, endAddress, scanBufferingMode, epoch, logger: logger);\n            return PushScanImpl(store, beginAddress, endAddress, ref scanFunctions, iter);\n        }\n","sourceCodeStart":476,"sourceCodeEnd":512,"githubUrl":"https://github.com/microsoft/FASTER/blob/321d872eabda6a0345c8bd76419f89723ed864ae/cs/src/core/Allocator/VarLenBlittableAllocator.cs#L476-L512","documentation":"VarLenBlittableAllocator allocates its memory pages directly as sector-aligned device-sized buffers, so a read page already lands in its final memory location and there is nothing to 'populate' by copying. PopulatePage — used by allocators that copy device data into separately allocated memory pages — is therefore invalid and throws FasterException as a guard. The commented-out MemoryCopy shows the base-class behavior it intentionally disables.","triggerScenarios":"Invoking PopulatePage on a VarLenBlittableAllocator-backed log (hlog), typically from code or a generic path written for the standard BlittableAllocator/FasterBaseAllocator where pages must be copied from a device buffer. Reached via internal page-load logic or custom allocator-abusing code, not a normal user API.","commonSituations":"Porting scan/replay code that used PopulatePage with the default BlittableAllocator to the varlen blittable allocator; writing a custom device or read path that manually populates pages; mixing code samples across allocator types.","solutions":["Use the direct copy path: with VarLenBlittableAllocator, the sector-aligned device buffer is the page, so consume it in place instead of calling PopulatePage.","If you need PopulatePage-style copying, switch to the standard BlittableAllocator (which stages pages) instead of VarLenBlittableAllocator.","Update custom read/flush code to respect the allocator's sector-aligned page contract (disk read lands directly in the page)."],"exampleFix":"// before\nallocator.PopulatePage(src, requiredBytes, destinationPage);\n// after: for VarLenBlittableAllocator, use the device-read page directly\n// (issue async read into the page buffer and consume it in place; no PopulatePage call)","handlingStrategy":"type-guard","validationCode":"if (hlog is VarLenBlittableAllocator<K, V>) {\n    // read directly into the sector-aligned page; skip PopulatePage entirely\n}","typeGuard":"static bool NeedsPopulatePage(AllocatorBase<K, V> hlog)\n    => hlog is not VarLenBlittableAllocator<K, V>;","tryCatchPattern":null,"preventionTips":["Check the allocator type before touching page-population internals","Remember VarLenBlittableAllocator pages ARE the device buffers (sector-aligned, zero-copy)","Prefer public read/scan APIs over PopulatePage-style internals"],"tags":["blittable","allocator","sector-aligned","unsupported-operation"],"backgroundTag":"unsupported-operation","analyzedSha":"321d872eabda6a0345c8bd76419f89723ed864ae","analyzedAt":"2026-09-15T22:18:00.693Z","contentChangedAt":"2026-09-15T22:18:00.693Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}