@x5e/gink
Version:
an eventually consistent database
40 lines (36 loc) • 1.59 kB
text/typescript
import { ensure } from "./utils";
import { LogFileBuilder } from "./builders";
import { LockableFile } from "./LockableFile";
export class LockableLog extends LockableFile {
protected async writeMagicNumber(): Promise<number> {
ensure(this.fileLocked);
const size = await this.getFileLength();
if (size !== 0) throw new Error("file not empty!");
const logFragment = new LogFileBuilder();
logFragment.setMagicNumber(1263421767);
return await this.writeLogFragment(logFragment, true);
}
protected async writeLogFragment(
fragment: LogFileBuilder,
sync?: boolean,
): Promise<number> {
ensure(this.fileLocked);
const bytes: Uint8Array = fragment.serializeBinary();
await this.fileHandle.writeFile(bytes);
if (sync) await this.fileHandle.sync();
return bytes.byteLength;
}
async getLogContents(
start: number = 0,
finish?: number,
): Promise<LogFileBuilder> {
// I could imagine replacing this with a async iterator that only reads fragments of the
// file, though that would only be worth the trouble if the file gets large enough that
// the memory required to read the whole thing is an expensive resource.
finish = finish ?? (await this.getFileLength());
const needToReed = finish - start;
const uint8Array = new Uint8Array(needToReed);
await this.fileHandle.read(uint8Array, 0, needToReed, start);
return <LogFileBuilder>LogFileBuilder.deserializeBinary(uint8Array);
}
}