From: Nick Downing Date: Fri, 7 Jan 2022 00:07:54 +0000 (+1100) Subject: Make snapped references to Lazy(Array|Object) in the tree be stored as the Lazy(Array... X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=c4fa9ca4bb7b719b350a9793a4a52a8941546e49;p=logjson.git Make snapped references to Lazy(Array|Object) in the tree be stored as the Lazy(Array|Object) ref directly rather than [ptr, len, ref], since ptr, len not used --- diff --git a/logjson.mjs b/logjson.mjs index 08793b5..63d3195 100644 --- a/logjson.mjs +++ b/logjson.mjs @@ -130,7 +130,9 @@ class Database { this.mutex.release() } - async read(ptr, len) { + async read(ptr_len) { + let [ptr, len] = ptr_len + let buffer = Buffer.alloc(len) assert( (await this.log.read(buffer, 0, len, ptr)).bytesRead === len @@ -184,56 +186,50 @@ class Transaction { this.value = value } + async read(ptr_len) { + let value = await this.database.read(ptr_len) + if (typeof value === 'object' && value !== null) + value = + value instanceof Array ? + new LazyArray(this, ptr_len, value) : + new LazyObject(this, ptr_len, value) + return value + } + async get(default_value) { if (this.value === undefined) { if (default_value === undefined) return undefined set(default_value) } - let value = this.value - if (value instanceof Array) { - let [ptr, len, new_value] = value - if (new_value === undefined) { - new_value = await this.database.read(ptr, len) - if (typeof new_value === 'object' && new_value !== null) - new_value = - new_value instanceof Array ? - new LazyArray(this, [ptr, len], new_value) : - new LazyObject(this, [ptr, len], new_value) - value[2] = new_value - } - value = new_value - } - return value + if (this.value instanceof Array) + this.value = this.read(this.value) + return this.value } set(value) { this.dirty = true - if (typeof value === 'object' && value !== null) { - assert(value instanceof Lazy && value.transaction === this) - let [ptr, len] = value.ptr_len || [-1, 0] - value = [ptr, len, value] - } + assert( + typeof value !== 'object' || + value === null || + (value instanceof Lazy && value.transaction === this) + ) this.value = value } async commit() { assert(this.value !== undefined) - if (this.value instanceof Array) { - let [ptr, len, value] = this.value - if (value !== undefined) { - assert(value instanceof Lazy) - if (await value.commit()) - this.dirty = true - this.value = value.ptr_len - } + if (this.value instanceof Lazy) { + if (await this.value.commit()) + this.dirty = true + this.value = this.value.ptr_len } if (this.dirty) { await this.database.write_root(this.value) - this.database.value = value + this.database.value = this.value } this.database.mutex.release() @@ -318,32 +314,23 @@ class LazyArray extends Lazy { return undefined set(key, default_value) } - let value = this.array[key] + let value = this.array[key] if (value instanceof Array) { - let [ptr, len, new_value] = value - if (new_value === undefined) { - new_value = await this.transaction.database.read(ptr, len) - if (typeof new_value === 'object' && new_value !== null) - new_value = - new_value instanceof Array ? - new LazyArray(this.transaction, [ptr, len], new_value) : - new LazyObject(this.transaction, [ptr, len], new_value) - value[2] = new_value - } - value = new_value + value = this.transaction.read(value) + this.array[key] = value } return value } set(key, value) { assert(typeof key === 'number') + assert( + typeof value !== 'object' || + value === null || + (value instanceof Lazy && value.transaction === this.transaction) + ) this.ptr_len = null // mark dirty - if (typeof value === 'object' && value !== null) { - assert(value instanceof Lazy && value.transaction === this.transaction) - let [ptr, len] = value.ptr_len || [-1, 0] - value = [ptr, len, value] - } this.array[key] = value this.length = this.array.length } @@ -366,20 +353,16 @@ class LazyArray extends Lazy { async commit() { for (let i = 0; i < this.length; ++i) { - let item = this.array[i] - if (item instanceof Array) { - let [ptr, len, value] = item - if (value !== undefined) { - assert(value instanceof Lazy) - if (await value.commit()) - this.ptr_len = null // mark dirty - this.array[i] = value.ptr_len - } + let value = this.array[i] + if (value instanceof Lazy) { + if (await value.commit()) + this.ptr_len = null // mark dirty + this.array[i] = value.ptr_len } } if (this.ptr_len === null) { - this.ptr_len = await this.transaction.database.write(value) + this.ptr_len = await this.transaction.database.write(this.array) return true } return false @@ -404,32 +387,23 @@ class LazyObject extends Lazy { return undefined set(key, default_value) } - let value = this.object[key] + let value = this.object[key] if (value instanceof Array) { - let [ptr, len, new_value] = value - if (new_value === undefined) { - new_value = await this.transaction.database.read(ptr, len) - if (typeof new_value === 'object' && new_value !== null) - new_value = - new_value instanceof Array ? - new LazyArray(this.transaction, [ptr, len], new_value) : - new LazyObject(this.transaction, [ptr, len], new_value) - value[2] = new_value - } - value = new_value + value = this.transaction.read(value) + this.object[key] = value } return value } set(key, value) { assert(typeof key === 'string') + assert( + typeof value !== 'object' || + value === null || + (value instanceof Lazy && value.transaction === this.transaction) + ) this.ptr_len = null // mark dirty - if (typeof value === 'object' && value !== null) { - assert(value instanceof Lazy && value.transaction === this.transaction) - let [ptr, len] = value.ptr_len || [-1, 0] - value = [ptr, len, value] - } this.object[key] = value } @@ -446,20 +420,16 @@ class LazyObject extends Lazy { async commit() { for (let i in this.object) { - let item = this.object[i] - if (item instanceof Array) { - let [ptr, len, value] = item - if (value !== undefined) { - assert(value instanceof Lazy) - if (await value.commit()) - this.ptr_len = null // mark dirty - this.object[i] = value.ptr_len - } + let value = this.object[i] + if (value instanceof Lazy) { + if (await value.commit()) + this.ptr_len = null // mark dirty + this.object[i] = value.ptr_len } } if (this.ptr_len === null) { - this.ptr_len = await this.transaction.database.write(value) + this.ptr_len = await this.transaction.database.write(this.object) return true } return false