FlatDb LRU for data (key & value)

This commit is contained in:
Jaco Greeff
2018-09-04 10:49:25 +02:00
parent 52d7c5da56
commit 0b5d6bfb60
+32 -12
View File
@@ -47,6 +47,7 @@ const ENTRY_NUM = 16; // nibbles, 256 for bytes (where serialize would be noop)
const ENTRY_SIZE = 1 + UINT_SIZE;
const BRANCH_SIZE = ENTRY_NUM * ENTRY_SIZE;
const LRU_BRANCH_COUNT = 2048;
const LRU_DATA_COUNT = 4096;
const DEFAULT_FILE = 'store.db';
const l = logger('db/flat');
@@ -56,11 +57,13 @@ export default class FileFlatDb implements BaseDb {
private _file: string;
private _isCompressed: boolean;
private _lruBranch: LRUMap<number, Buffer>;
private _lruData: LRUMap<number, Buffer>;
constructor (base: string, file: string = DEFAULT_FILE, options: BaseDbOptions = {}) {
this._fd = -1;
this._file = path.join(base, file);
this._lruBranch = new LRUMap(LRU_BRANCH_COUNT);
this._lruData = new LRUMap(LRU_DATA_COUNT);
this._isCompressed = options && !isUndefined(options.isCompressed)
? options.isCompressed
: false;
@@ -70,14 +73,18 @@ export default class FileFlatDb implements BaseDb {
open (): void {
this._fd = this._open(this._file);
this._lruBranch.clear();
this._lruData.clear();
}
close (): void {
this.assertOpen();
fs.closeSync(this._fd);
this._lruBranch.clear();
this._lruData.clear();
}
maintain (fn: ProgressCb): void {
@@ -182,7 +189,15 @@ export default class FileFlatDb implements BaseDb {
};
}
private _getBranch (branchAt: number): Buffer {
private _cacheBranch (branchAt: number, branch: Buffer): void {
this._lruBranch.set(branchAt, branch);
}
private _cacheData (dataAt: number, data: Buffer): void {
this._lruData.set(dataAt, data);
}
private _getCachedBranch (branchAt: number): Buffer {
let branch = this._lruBranch.get(branchAt);
if (!branch) {
@@ -195,21 +210,26 @@ export default class FileFlatDb implements BaseDb {
return branch;
}
private _getKeyValue (keyAt: number): Buffer {
const keyValue = Buffer.alloc(KEY_TOTAL_SIZE);
private _getCachedData (dataAt: number, length: number): Buffer {
let data = this._lruData.get(dataAt);
fs.readSync(this._fd, keyValue, 0, KEY_TOTAL_SIZE, keyAt);
if (!data) {
data = Buffer.alloc(length);
return keyValue;
fs.readSync(this._fd, data, 0, length, dataAt);
this._cacheData(dataAt, data);
}
return data;
}
private _cacheBranch (branchAt: number, branch: Buffer): void {
this._lruBranch.set(branchAt, branch);
private _getKeyValue (keyAt: number): Buffer {
return this._getCachedData(keyAt, KEY_TOTAL_SIZE);
}
private _findKey (key: NibbleBuffer, doCreate: boolean, keyIndex: number, branchAt: number): Key | null {
const entryIndex = key.nibbles[keyIndex] * ENTRY_SIZE;
const branch = this._getBranch(branchAt);
const branch = this._getCachedBranch(branchAt);
l.debug(() => ['findKey', { key, doCreate, keyIndex, branchAt, branch, entryIndex }]);
@@ -282,9 +302,7 @@ export default class FileFlatDb implements BaseDb {
l.debug(() => ['readValue', { keyValue }]);
const { valueAt, valueLength } = this._extractValueInfo(keyValue);
const value = Buffer.alloc(valueLength);
fs.readSync(this._fd, value, 0, valueLength, valueAt);
const value = this._getCachedData(valueAt, valueLength);
return {
value,
@@ -307,6 +325,7 @@ export default class FileFlatDb implements BaseDb {
if (valueLength < value.length) {
valueAt = fs.fstatSync(this._fd).size;
this._cacheData(valueAt, value);
}
keyValue.writeUIntBE(value.length, KEY_SIZE, UINT_SIZE);
@@ -338,6 +357,7 @@ export default class FileFlatDb implements BaseDb {
keyValue.set(key.buffer, 0);
fs.writeSync(this._fd, keyValue, 0, KEY_TOTAL_SIZE, keyAt);
this._cacheData(keyAt, keyValue);
return {
key,
@@ -363,13 +383,13 @@ export default class FileFlatDb implements BaseDb {
let newBranchAt = fs.fstatSync(this._fd).size;
let newBranch = Buffer.alloc(BRANCH_SIZE);
// FIXME Combine this along with all the newBranch writes in the loop into a single write
newBranch.set([Slot.LEAF], keyIndex);
newBranch.writeUIntBE(keyAt, keyIndex + 1, UINT_SIZE);
newBranch.set([Slot.LEAF], prevIndex);
newBranch.writeUIntBE(prevAt, prevIndex + 1, UINT_SIZE);
fs.writeSync(this._fd, newBranch, 0, BRANCH_SIZE, newBranchAt);
this._cacheBranch(newBranchAt, newBranch);
for (let offset = 1; depth > 0; depth--, offset++) {