this.mutex = new Mutex()
this.log = null
this.eof = 0
- this.ptr = 0
- this.len = 0
- this.value = undefined
+ this.value = [-1, 0]
}
async open(path, default_value) {
this.log = await fsPromises.open(path, 'w+')
this.eof = 0
- let {ptr, len} = await this.write(default_value, true)
- this.ptr = ptr
- this.len = len
-
- // not yet, as it's JSON rather than logjson at the moment:
- //this.value = default_value
+ this.value = await this.write(default_value, true)
return
}
this.eof = (await this.log.stat()).size
- let {ptr, len} = await this.find_root()
- this.ptr = ptr
- this.len = len
+ this.value = await this.find_root()
// optional: trim any garbage off the end of the file
- this.eof = this.ptr + this.len + 2
+ let [ptr, len] = this.value
+ this.eof = ptr + len + 2
await this.log.truncate(this.eof)
this.mutex.release()
while (true) {
if (i && (i = buffer.lastIndexOf(open_angle, i - 2)) != -1) {
let start = i + ptr + 2
- return {ptr: start, len: end - start}
+ return [start, end - start] // ptr, len
}
if (ptr === 0)
// special case for < at start of file
if (count && buffer[0] === 0x3c) {
let start = 1
- return {ptr: start, len: end - start}
+ return [start, end - start] // ptr, len
}
throw new Error('can\'t find logjson start marker')
async write(value, is_root) {
if (typeof value === 'object' && value !== null)
if (value instanceof Array) {
- let value1 = []
+ let new_value = []
for (let i = 0; i < value.length; ++i) {
let item = value[i]
- if (typeof item === 'object' && item !== null) {
- let {ptr, len} = await this.write(item, false)
- item = [ptr, len]
- }
- value1.push(item)
+ //if (typeof item === 'object' && item !== null)
+ item = await this.write(item, false)
+ new_value.push(item)
}
- value = value1
+ value = new_value
}
else {
- let value1 = {}
+ let new_value = {}
for (let i in value) {
let item = value[i]
- if (typeof item === 'object' && item !== null) {
- let {ptr, len} = await this.write(item, false)
- item = [ptr, len]
- }
- value1[i] = item
+ //if (typeof item === 'object' && item !== null)
+ item = await this.write(item, false)
+ new_value[i] = item
}
- value = value1
+ value = new_value
}
let data = JSON.stringify(value, null, 2)
(await this.log.write(buffer, 0, len, ptr)).bytesWritten === len
)
this.eof += len
- return {ptr: ptr + 1, len: len - 3}
+ return [ptr + 1, len - 3] // ptr, len
}
let buffer = Buffer.from(`${data}\n`)
let ptr = this.eof
(await this.log.write(buffer, 0, len, ptr)).bytesWritten === len
)
this.eof += len
- return {ptr, len: len - 1}
+ return [ptr, len - 1] // ptr, len
}
async get() {
- if (this.value === undefined) {
- let buffer = Buffer.alloc(this.len)
+ let [ptr, len, value] = this.value
+ if (value === undefined) {
+ let buffer = Buffer.alloc(len)
assert(
- (await this.log.read(buffer, 0, this.len, this.ptr)).bytesRead ===
- this.len
+ (await this.log.read(buffer, 0, len, ptr)).bytesRead === len
)
- let value = JSON.parse(buffer.toString('utf-8'))
+ 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 = value
+ this.value[2] = value
}
- return this.value
+ return value
}
}
delete(key) {
throw new Error('not implemented')
}
-
- keys() {
- throw new Error('not implemented')
- }
}
class LazyArray extends Lazy {
has(key) {
assert(typeof key === 'number')
- return key in this.array
+ return key >= 0 && key < this.length
}
async get(key, default_value) {
assert(typeof key === 'number')
- if (!(key in this.array))
+ if (key < 0 || key >= this.length)
return default_value
let value = this.array[key]
- if (value instanceof Array) {
+ //if (value instanceof Array) {
let [ptr, len, new_value] = value
if (new_value === undefined) {
let buffer = Buffer.alloc(len)
value[2] = new_value
}
value = new_value
- }
+ //}
return value
}
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
+ //if (typeof value === 'object' && value !== null) {
+ // assert(value instanceof Lazy)
+ // value = [-1, 0, value]
+ //}
+ //this.array[key] = value
+ this.array[key] = [-1, 0, value]
this.length = this.array.length
}
this.length = this.array.length
}
- keys() {
- let keys = []
- // this does not work well as it returns an array of strings:
- //for (let i in this.array)
- // keys.push(i)
- for (let i = 0; i < this.array.length; ++i)
- if (i in this.array)
- keys.push(i)
- return keys
+ push(value) {
+ set(this.length, value)
+ }
+
+ async pop() {
+ assert(this.length)
+ let i = this.length - 1
+ let value = await this.get(i)
+ this.delete(i)
+ return value
}
}
if (!Object.prototype.hasOwnProperty.call(this.object, key))
return default_value
let value = this.object[key]
- if (value instanceof Array) {
+ //if (value instanceof Array) {
let [ptr, len, new_value] = value
if (new_value === undefined) {
let buffer = Buffer.alloc(len)
value[2] = new_value
}
value = new_value
- }
+ //}
return value
}
}
let logjson_to_json = async value => {
- if (typeof value === 'object' && value !== null) {
- assert(value instanceof Lazy)
- let new_value = value instanceof LazyArray ? [] : {}
- let keys = value.keys()
- for (let i = 0; i < keys.length; ++i) {
- let key = keys[i]
- new_value[key] = await logjson_to_json(await value.get(key))
+ if (value instanceof Lazy) {
+ let new_value
+ if (value instanceof LazyArray) {
+ new_value = []
+ for (let i = 0; i < value.length; ++i)
+ new_value.push(await logjson_to_json(await value.get(i)))
+ }
+ else {
+ new_value = {}
+ let keys = value.keys()
+ for (let i = 0; i < keys.length; ++i) {
+ let key = keys[i]
+ new_value[key] = await logjson_to_json(await value.get(key))
+ }
}
value = new_value
}
let json_to_logjson = value => {
if (typeof value === 'object' && value !== null) {
- let new_value =
- value instanceof Array ? new LazyArray() : new LazyObject()
- for (let i in value)
- new_value.set(i, json_to_logjson(value[i]))
+ let new_value
+ if (value instanceof Array) {
+ new_value = LazyArray()
+ for (let i = 0; i < value.length; ++i)
+ new_value.push(json_to_logjson(value[i]))
+ }
+ else {
+ new_value = LazyObject()
+ for (let i in value)
+ new_value.set(i, json_to_logjson(value[i]))
+ }
value = new_value
}
return value