{"record":{"id":"389d6ec5c0f27810","repo":"microsoft/FASTER","slug":"blittableallocator-memory-pages-are-sector-aligned-use","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/BlittableAllocator.cs","lineNumber":372,"sourceCode":"        /// 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 IHeapContainer<Key> GetKeyContainer(ref Key key) => new StandardHeapContainer<Key>(ref key);\n        public override IHeapContainer<Value> GetValueContainer(ref Value value) => new StandardHeapContainer<Value>(ref value);\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        }\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 BlittableScanIterator<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 BlittableScanIterator<Key, Value> iter = new(store, this, beginAddress, endAddress, scanBufferingMode, epoch, logger: logger);\n            return PushScanImpl(store, beginAddress, endAddress, ref scanFunctions, iter);\n        }\n\n        /// <summary>","sourceCodeStart":354,"sourceCodeEnd":390,"githubUrl":"https://github.com/microsoft/FASTER/blob/321d872eabda6a0345c8bd76419f89723ed864ae/cs/src/core/Allocator/BlittableAllocator.cs#L354-L390","documentation":"PopulatePage copies caller-supplied bytes into a freshly allocated page; blittable pages are already sector-aligned device memory filled directly by I/O, so software population is meaningless and intentionally unimplemented. The override throws FasterException to catch any code path attempting the object-allocator's page-population flow on a BlittableAllocator.","triggerScenarios":"An internal or custom code path invoking PopulatePage on the BlittableAllocator - e.g. a custom allocator/commit-manager patch, or object-log-style page fill logic reused against a blittable log.","commonSituations":"Extending FASTER with custom device/commit logic modeled on the object allocator; misuse of internal (internal-visibility) APIs in patched builds rather than end-user scenarios.","solutions":["Do not call PopulatePage for blittable logs; pages are filled directly via device I/O with sector-aligned copies.","If copying into a blittable page, write to the page's pointer (direct memcpy) respecting sector alignment instead of the PopulatePage hook.","If object-style population is needed, switch to the ObjectAllocator (class-typed Key/Value)."],"exampleFix":"// before\nallocator.PopulatePage(src, requiredBytes, destinationPage); // on BlittableAllocator\n\n// after\n// copy directly into the aligned page buffer:\nBuffer.MemoryCopy((void*)pagePointer, (void*)src, requiredBytes, requiredBytes);","handlingStrategy":"validation","validationCode":"// internal API: only call PopulatePage on ObjectAllocator, never BlittableAllocator\nif (allocator is BlittableAllocator<K, V>)\n    throw new InvalidOperationException(\"Use direct sector-aligned copy for blittable pages\");","typeGuard":"bool NeedsPopulatePage(FasterKV<K, V>.ILogAllocator a) => a is ObjectAllocator<K, V>;","tryCatchPattern":"try { allocator.PopulatePage(src, bytes, page); }\ncatch (FasterException ex) when (ex.Message.Contains(\"sector aligned - use direct copy\")) { /* memcpy into page pointer instead */ }","preventionTips":["Model custom device/commit code on the allocator type you actually use.","For blittable logs, always copy via the page pointer with sector alignment.","Gate internal population paths on allocator type checks."],"tags":["csharp","faster","unsupported-operation","blittable"],"backgroundTag":"unsupported-operation","analyzedSha":"321d872eabda6a0345c8bd76419f89723ed864ae","analyzedAt":"2026-09-15T22:18:00.693Z","contentChangedAt":"2026-09-15T22:18:00.693Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}