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:

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
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);
}
 Permalink
Permalink Reply
Reply