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