this.mutex = new Mutex()
this.log = null
this.eof = 0
- this.dirty = false
this.value = undefined
}
this.log = await fsPromises.open(path, 'w+')
this.eof = 0
- this.dirty = false
this.value = undefined
this.mutex.release()
}
this.eof = (await this.log.stat()).size
- this.dirty = false
try {
this.value = await this.find_root()
}
}
async close() {
- this.flush()
-
await this.mutex.acquire()
assert(this.log !== null)
throw new Error('can\'t find logjson end marker')
}
+ Transaction() {
+ this.mutex.acquire()
+ return new Transaction(this, this.value)
+ }
+}
+
+class Transaction {
+ constructor(database, value) {
+ this.database = database
+ this.dirty = false
+ this.value = value
+ }
+
async get(default_value) {
if (this.value === undefined) {
if (default_value === undefined)
if (new_value === undefined) {
let buffer = Buffer.alloc(len)
assert(
- (await this.log.read(buffer, 0, len, ptr)).bytesRead === len
+ (await this.database.log.read(buffer, 0, len, ptr)).bytesRead === len
)
new_value = JSON.parse(buffer.toString('utf-8'))
if (typeof new_value === 'object' && new_value !== null)
//assert(
// typeof value !== 'object' ||
// value === null ||
- // (value instanceof Lazy && value.database === this)
+ // (value instanceof Lazy && value.transaction === this)
//)
this.dirty = true
if (typeof value === 'object' && value !== null) {
- assert(value instanceof Lazy && value.database === this)
+ assert(value instanceof Lazy && value.transaction === this)
value = [-1, 0, value]
}
this.value = value
}
- async flush() {
- await this.mutex.acquire()
-
- if (this.value === undefined) {
- await this.mutex.release()
- return
- }
+ async commit() {
+ assert(this.value !== undefined)
if (this.value instanceof Array) {
let [ptr, len, value] = this.value
'utf-8'
)
- ptr = this.eof
+ ptr = this.database.eof
len = buffer.length
assert(
- (await this.log.write(buffer, 0, len, ptr)).bytesWritten === len
+ (await this.database.log.write(buffer, 0, len, ptr)).bytesWritten === len
)
- this.eof += len
+ this.database.eof += len
- this.value[0] = ptr + 1
- this.value[1] = len - 3
- //this.dirty = true
+ this.database.value = [ptr + 1, len - 3]
}
}
else if (this.dirty) {
'utf-8'
)
- ptr = this.eof
+ ptr = this.database.eof
len = buffer.length
assert(
- (await this.log.write(buffer, 0, len, ptr)).bytesWritten === len
+ (await this.database.log.write(buffer, 0, len, ptr)).bytesWritten === len
)
- this.eof += len
+ this.database.eof += len
+
+ this.database.value = this.value
}
- this.dirty = false
- this.mutex.release()
+ this.database.mutex.release()
+ }
+
+ rollback() {
+ this.database.mutex.release()
}
LazyArray(...args) {
// logjson array or object
class Lazy {
- constructor(database) {
- this.database = database
+ constructor(transaction) {
+ this.transaction = transaction
this.dirty = false
}
}
class LazyArray extends Lazy {
- constructor(database, array) {
- super(database)
+ constructor(transaction, array) {
+ super(transaction)
this.array = array || []
this.length = this.array.length
}
if (new_value === undefined) {
let buffer = Buffer.alloc(len)
assert(
- (await this.database.log.read(buffer, 0, len, ptr)).bytesRead === len
+ (await this.transaction.database.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.database, new_value) :
- new LazyObject(this.database, new_value)
+ new LazyArray(this.transaction, new_value) :
+ new LazyObject(this.transaction, new_value)
value[2] = new_value
}
value = new_value
//assert(
// typeof value !== 'object' ||
// value === null ||
- // (value instanceof Lazy && value.database === this.database)
+ // (value instanceof Lazy && value.transaction === this.transaction)
//)
this.dirty = true
if (typeof value === 'object' && value !== null) {
- assert(value instanceof Lazy && value.database === this.database)
+ assert(value instanceof Lazy && value.transaction === this.transaction)
value = [-1, 0, value]
}
this.array[key] = value
'utf-8'
)
- ptr = this.database.eof
+ ptr = this.transaction.database.eof
len = buffer.length
assert(
- (await this.database.log.write(buffer, 0, len, ptr)).bytesWritten ===
+ (await this.transaction.database.log.write(buffer, 0, len, ptr)).bytesWritten ===
len
)
- this.database.eof += len
+ this.transaction.database.eof += len
item[0] = ptr
item[1] = len - 1
}
class LazyObject extends Lazy {
- constructor(database, object) {
- super(database)
+ constructor(transaction, object) {
+ super(transaction)
this.object = object || {}
}
if (new_value === undefined) {
let buffer = Buffer.alloc(len)
assert(
- (await this.database.log.read(buffer, 0, len, ptr)).bytesRead === len
+ (await this.transaction.database.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.database, new_value) :
- new LazyObject(this.database, new_value)
+ new LazyArray(this.transaction, new_value) :
+ new LazyObject(this.transaction, new_value)
value[2] = new_value
}
value = new_value
//assert(
// typeof value !== 'object' ||
// value === null ||
- // (value instanceof Lazy && value.database === this.database)
+ // (value instanceof Lazy && value.transaction === this.transaction)
//)
this.dirty = true
if (typeof value === 'object' && value !== null) {
- assert(value instanceof Lazy && value.database === this.database)
+ assert(value instanceof Lazy && value.transaction === this.transaction)
value = [-1, 0, value]
}
this.object[key] = value
'utf-8'
)
- ptr = this.database.eof
+ ptr = this.transaction.database.eof
len = buffer.length
assert(
- (await this.database.log.write(buffer, 0, len, ptr)).bytesWritten ===
+ (await this.transaction.database.log.write(buffer, 0, len, ptr)).bytesWritten ===
len
)
- this.database.eof += len
+ this.transaction.database.eof += len
item[0] = ptr
item[1] = len