let data = JSON.stringify(value, null, 2)
if (is_root) {
- let buffer = Buffer.from(`<${data}>\n`)
+ let buffer = Buffer.from(`<${data}>\n`, 'utf-8')
let ptr = this.eof
let len = buffer.length
assert(
this.eof += len
return [ptr + 1, len - 3] // ptr, len
}
- let buffer = Buffer.from(`${data}\n`)
+ let buffer = Buffer.from(`${data}\n`, 'utf-8')
let ptr = this.eof
let len = buffer.length
assert(
}
async get() {
- let [ptr, len, value] = this.value
- if (value === undefined) {
- let buffer = Buffer.alloc(len)
- assert(
- (await this.log.read(buffer, 0, len, ptr)).bytesRead === len
- )
- value = JSON.parse(buffer.toString('utf-8'))
- if (typeof value === 'object' && value !== null)
- value =
- value instanceof Array ?
- new LazyArray(this, value) :
- new LazyObject(this, value)
- this.value[2] = value
- }
+ let value = this.value
+
+ //if (value instanceof Array) {
+ let [ptr, len, new_value] = value
+ if (new_value === undefined) {
+ let buffer = Buffer.alloc(len)
+ assert(
+ (await this.log.read(buffer, 0, len, ptr)).bytesRead === len
+ )
+ new_value = JSON.parse(buffer.toString('utf-8'))
+ if (typeof new_value === 'object' && new_value !== null)
+ new_value =
+ new_value instanceof Array ?
+ new LazyArray(this, new_value) :
+ new LazyObject(this, new_value)
+ value[2] = new_value
+ }
+ value = new_value
+ //}
return value
}
+
+ set(value) {
+ assert(
+ typeof value !== 'object' ||
+ value === null ||
+ value instanceof Lazy
+ )
+ //if (typeof value === 'object' && value !== null)
+ value = [-1, 0, value]
+ this.value = value
+ }
+
+ async flush() {
+ //if (this.value instanceof Array) {
+ let [ptr, len, value] = this.value
+ if (
+ (value instanceof Lazy && await value.flush(this)) ||
+ ptr === -1
+ ) {
+ if (value instanceof Lazy)
+ value = value.pack()
+ let buffer = Buffer.from(
+ `<${JSON.stringify(value, null, 2)}>\n`,
+ 'utf-8'
+ )
+
+ ptr = this.eof
+ len = buffer.length
+ assert(
+ (await this.log.write(buffer, 0, len, ptr)).bytesWritten === len
+ )
+ this.eof += len
+
+ this.value[0] = ptr + 1
+ this.value[1] = len - 3
+ }
+ //}
+ }
}
// logjson array or object
delete(key) {
throw new Error('not implemented')
}
+
+ async flush(file) {
+ throw new Error('not implemented')
+ }
+
+ pack() {
+ throw new Error('not implemented')
+ }
}
class LazyArray extends Lazy {
if (key < 0 || key >= this.length)
return default_value
let value = this.array[key]
+
//if (value instanceof Array) {
let [ptr, len, new_value] = value
if (new_value === undefined) {
set(key, value) {
assert(typeof key === 'number')
- //if (typeof value === 'object' && value !== null) {
- // assert(value instanceof Lazy)
- // value = [-1, 0, value]
- //}
- //this.array[key] = value
- this.array[key] = [-1, 0, value]
+ assert(
+ typeof value !== 'object' ||
+ value === null ||
+ value instanceof Lazy
+ )
+ //if (typeof value === 'object' && value !== null)
+ value = [-1, 0, value]
+ this.array[key] = value
this.length = this.array.length
}
}
push(value) {
- set(this.length, value)
+ this.set(this.length, value)
}
async pop() {
this.delete(i)
return value
}
+
+ async flush(file) {
+ if (file != this.file) {
+ assert(this.file === null)
+ this.file = file
+ }
+
+ let dirty = false
+ for (let i = 0; i < this.length; ++i) {
+ let item = this.array[i]
+ //if (item instanceof Array) {
+ let [ptr, len, value] = item
+ if (
+ (value instanceof Lazy && await value.flush(file)) ||
+ ptr === -1
+ ) {
+ if (value instanceof Lazy)
+ value = value.pack()
+ let buffer = Buffer.from(
+ JSON.stringify(value, null, 2) + '\n',
+ 'utf-8'
+ )
+
+ ptr = this.file.eof
+ len = buffer.length
+ assert(
+ (await this.file.log.write(buffer, 0, len, ptr)).bytesWritten ===
+ len
+ )
+ this.file.eof += len
+
+ item[0] = ptr
+ item[1] = len - 1
+ dirty = true
+ }
+ //}
+ }
+ return dirty
+ }
+
+ pack() {
+ let new_array = []
+ for (let i = 0; i < this.length; ++i) {
+ let item = this.array[i]
+ //if (item instanceof Array)
+ item = item.slice(0, 2)
+ new_array.push(item)
+ }
+ return new_array
+ }
}
class LazyObject extends Lazy {
if (!Object.prototype.hasOwnProperty.call(this.object, key))
return default_value
let value = this.object[key]
+
//if (value instanceof Array) {
let [ptr, len, new_value] = value
if (new_value === undefined) {
set(key, value) {
assert(typeof key === 'string')
- if (typeof value === 'object' && value !== null) {
- assert(value instanceof Lazy)
+ assert(
+ typeof value !== 'object' ||
+ value === null ||
+ value instanceof Lazy
+ )
+ //if (typeof value === 'object' && value !== null)
value = [-1, 0, value]
- }
this.object[key] = value
}
keys.push(i)
return keys
}
+
+ async flush(file) {
+ if (file != this.file) {
+ assert(this.file === null)
+ this.file = file
+ }
+
+ let dirty = false
+ for (let i in this.object) {
+ let item = this.object[i]
+ //if (item instanceof Array) {
+ let [ptr, len, value] = item
+ if (
+ (value instanceof Lazy && await value.flush(file)) ||
+ ptr === -1
+ ) {
+ if (value instanceof Lazy)
+ value = value.pack()
+ let buffer = Buffer.from(
+ JSON.stringify(value, null, 2) + '\n',
+ 'utf-8'
+ )
+
+ ptr = this.file.eof
+ len = buffer.length
+ assert(
+ (await this.file.log.write(buffer, 0, len, ptr)).bytesWritten ===
+ len
+ )
+ this.file.eof += len
+
+ item[0] = ptr
+ item[1] = len
+ dirty = true
+ }
+ //}
+ }
+ return dirty
+ }
+
+ pack() {
+ let new_object = {}
+ for (let i in this.object) {
+ let item = this.object[i]
+ //if (item instanceof Array)
+ item = item.slice(0, 2)
+ new_object[i] = item
+ }
+ return new_object
+ }
}
let logjson_to_json = async value => {
if (typeof value === 'object' && value !== null) {
let new_value
if (value instanceof Array) {
- new_value = LazyArray()
+ new_value = new LazyArray()
for (let i = 0; i < value.length; ++i)
new_value.push(json_to_logjson(value[i]))
}
else {
- new_value = LazyObject()
+ new_value = new LazyObject()
for (let i in value)
new_value.set(i, json_to_logjson(value[i]))
}