Fixed-size OutBuffer that doesn't call .resize() automatically? (for database page buffers)

Gavin Ray ray.gavin97 at gmail.com
Fri Aug 19 16:19:04 UTC 2022


On Monday, 15 August 2022 at 22:47:21 UTC, frame wrote:
> On Monday, 15 August 2022 at 20:51:07 UTC, Gavin Ray wrote:
>
>> Is there an alternative to `OutBuffer` or a method you can 
>> call to set a byte limit on the resizing?
>
> Are you looking for a circular buffer?
>
> https://code.dlang.org/packages/ringbuffer

Thanks for this suggestion, I hadn't considered it

I discovered 3 ways of doing it:

1. Calling `.toBytes()` on an `OutBuffer` will discard the extra 
bytes allocated past what was reserved and used. But this will 
still allocate the memory in the first place I guess (will the 
compiler optimize this away?)

2. Copy the `OutBuffer` class into a new `FixedSizeOutBuffer(T)` 
and alter its behavior

3. Use `ubyte[PAGE_SIZE]` and manually write like below:

```d
ubyte[] toBytes(uint value)
{
     static ubyte[4] bytes = new ubyte[4];
     bytes[0] = cast(ubyte)(value >> 24);
     bytes[1] = cast(ubyte)(value >> 16);
     bytes[2] = cast(ubyte)(value >> 8);
     bytes[3] = cast(ubyte)(value);
     return bytes;
}

void serialize(out ubyte[PAGE_SIZE] outbuf)
{
     ubyte[] buf;
     reserve(buf, PAGE_SIZE);

     buf ~= toBytes(header.pageId);
     buf ~= toBytes(header.logStorageNumber);
     buf ~= toBytes(header.prevPageId);
     buf ~= toBytes(header.nextPageId);
     buf ~= toBytes(header.freeSpacePointer);
     buf ~= toBytes(header.tupleCount);

     foreach (idx, ref slot; header.slots)
     {
         buf ~= toBytes(slot.offset);
         buf ~= toBytes(slot.size);
     }

     // Skip over free space
     ubyte[] padding = new ubyte[header.freeSpacePointer];
     padding[] = 0;
     buf ~= padding;

     foreach (idx, ref tuple; tuples)
     {
         buf ~= toBytes(tuple.size);
         buf ~= tuple.data;
     }

     move(buf.ptr, outbuf.ptr);
}
```


More information about the Digitalmars-d-learn mailing list