Created
August 30, 2018 22:59
-
-
Save kendru/4069defe2e94885cad2053f53072a69f to your computer and use it in GitHub Desktop.
Simple database that packs records into contiguous memory
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const POOL_SIZE = 4 * 1024; | |
let mySchema = ['int32', 'char(32)', 'int32']; | |
let bufferPool = new ArrayBuffer(POOL_SIZE); | |
let dir = { | |
tbl: { | |
people: { offset: 0, size: 0 } | |
} | |
}; | |
function colSize(col) { | |
if (col === 'int32') { | |
return 4; | |
} | |
if (col.startsWith('char')) { | |
let [ _, chars ] = col.match(/char\((\d+)\)/); | |
return parseInt(chars); | |
} | |
return 0; | |
} | |
function rowSize(schema) { | |
let size = 0; | |
for (const col of schema) { | |
size += colSize(col); | |
} | |
return size; | |
} | |
function readRow(tblOffset, rowOffset, schema) { | |
let out = []; | |
const rs = rowSize(schema); | |
let rowView = new DataView(bufferPool, tblOffset + rowOffset * rs, rs); | |
for (let i = 0, colOffset = 0; i < schema.length; i++) { | |
const col = schema[i]; | |
const cs = colSize(col); | |
if (col === 'int32') { | |
out.push(rowView.getInt32(colOffset)); | |
} else if (col.startsWith('char')) { | |
let chars = new Array(cs); | |
for (let j = 0; j < cs; j++) { | |
let byte = rowView.getUint8(colOffset + j); | |
if (byte === 0) { | |
break; | |
} | |
chars[j] = String.fromCharCode(byte); | |
} | |
out.push(chars.join('')); | |
} | |
colOffset += cs; | |
} | |
return out; | |
} | |
function writeRow(tblOffset, rowOffset, schema, row) { | |
const rs = rowSize(schema); | |
let rowView = new DataView(bufferPool, tblOffset + rowOffset * rs, rs); | |
if (schema.length !== row.length) { | |
throw new Error('Row length does not match schema length'); | |
} | |
for (let i = 0, colOffset = 0; i < schema.length; i++) { | |
const col = schema[i]; | |
const val = row[i]; | |
const cs = colSize(col); | |
if (col === 'int32') { | |
rowView.setInt32(colOffset, val); | |
} else if (col.startsWith('char')) { | |
// Could the rest of the col buffer be uninitialized? | |
for (let j = 0; j < val.length; j++) { | |
rowView.setUint8(colOffset + j, val.charCodeAt(j)); | |
} | |
} | |
colOffset += cs; | |
} | |
} | |
const tblOffset = dir.tbl.people.offset; | |
writeRow(tblOffset, 0, mySchema, [1, 'Andrew', 28]); | |
writeRow(tblOffset, 1, mySchema, [2, 'Diana', 31]); | |
writeRow(tblOffset, 2, mySchema, [3, 'Audrey', 6]); | |
writeRow(tblOffset, 3, mySchema, [4, 'Jonah', 4]); | |
writeRow(tblOffset, 4, mySchema, [5, 'Abel', 3]); | |
// console.log(new Uint8Array(bufferPool)); | |
console.log(readRow(tblOffset, 4, mySchema)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment