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

Gavin Ray ray.gavin97 at gmail.com
Mon Aug 15 20:51:07 UTC 2022


I'm learning about databases by implementing one from scratch, 
and decided I'd do it in D since it has the highest-level syntax 
for low-level code & seemed a natural fit.

Currently I am trying to implement the "slotted page" structure 
and storage (serialization/de-serialization from binary data 
on-disk)

"Slotted pages" are a data structure that store:

![](https://www.cs.swarthmore.edu/~soni/cs44/f18/Labs/images/2/heappage_array.jpg)

I tried to implement this using `OutBuffer`, but found that the 
buffer resized itself to greater than `PAGE_SIZE` bytes 
automatically =(

Is there an alternative to `OutBuffer` or a method you can call 
to set a byte limit on the resizing?

RUNNABLE DEMO: https://ldc.godbolt.org/z/ev78xos5b

```d
enum PAGE_SIZE = 4096;
enum HEADER_SIZE = (uint.sizeof) * 6;
enum TUPLE_SLOT_SIZE = (uint.sizeof) * 2;

struct TupleSlot
{
     uint offset;
     uint size;
}

struct Tuple
{
     uint size;
     ubyte[] data;
}

struct PageHeader
{
     uint logStorageNumber = 0;
     uint pageId = 0;
     uint prevPageId = 0;
     uint nextPageId = 0;
     uint freeSpacePointer = PAGE_SIZE;
     uint tupleCount = 0;
     TupleSlot[] slots;
}

struct SlottedPage
{
     PageHeader header;
     Tuple[] tuples;
     ubyte[PAGE_SIZE] buffer;

     void insertTuple(Tuple tuple)
     {
         tuples ~= tuple;
         header.slots ~= TupleSlot(header.freeSpacePointer, 
cast(uint) tuple.sizeof);
         header.tupleCount++;
         header.freeSpacePointer -= tuple.sizeof;
     }

     void serialize(OutBuffer buf)
     {
         with (header)
         {
             buf.write(pageId);
             buf.write(logStorageNumber);
             buf.write(prevPageId);
             buf.write(nextPageId);
             buf.write(freeSpacePointer);
             buf.write(tupleCount);
         }

         foreach (TupleSlot slot; header.slots)
         {
             buf.write(slot.offset);
             buf.write(slot.size);
         }

         buf.fill0(header.freeSpacePointer);

         foreach (Tuple tuple; tuples)
         {
             buf.write(tuple.size);
             buf.write(tuple.data);
         }
     }
}

void main()
{
     OutBuffer buffer = new OutBuffer();
	buffer.reserve(4096);

	auto page = new SlottedPage(PageHeader());
	foreach (i; 0 .. 10)
	{
		OutBuffer buf = new OutBuffer();
		buf.write(i);
		page.insertTuple(Tuple(cast(uint) buf.data.length, buf.data));
	}

	page.serialize(buffer);
     // Writes 8206
     writeln("Buffer size is: ", buffer.data.length);
}
```


More information about the Digitalmars-d-learn mailing list