Implement dirty flag, to prepare for reinstating primitive object optimization
authorNick Downing <nick@ndcode.org>
Wed, 5 Jan 2022 01:41:47 +0000 (12:41 +1100)
committerNick Downing <nick@ndcode.org>
Wed, 5 Jan 2022 01:41:47 +0000 (12:41 +1100)
logjson.mjs

index e9c7b15..460f224 100644 (file)
@@ -9,6 +9,7 @@ class File {
     this.mutex = new Mutex()
     this.log = null
     this.eof = 0
+    this.dirty = false
     this.value = undefined
   }
 
@@ -27,6 +28,7 @@ class File {
 
       this.log = await fsPromises.open(path, 'w+')
       this.eof = 0
+      this.dirty = false
       this.value = undefined
 
       this.mutex.release()
@@ -34,6 +36,7 @@ class File {
     }
 
     this.eof = (await this.log.stat()).size
+    this.dirty = false
     try {
       this.value = await this.find_root()
     }
@@ -62,6 +65,8 @@ class File {
   }
 
   async close() {
+    this.flush()
+
     await this.mutex.acquire()
     assert(this.log !== null)
 
@@ -162,14 +167,19 @@ class File {
       value === null ||
       value instanceof Lazy
     )
+    this.dirty = true
     //if (typeof value === 'object' && value !== null)
       value = [-1, 0, value]
     this.value = value
   }
 
   async flush() {
-    if (this.value === undefined)
+    await this.mutex.acquire()
+
+    if (this.value === undefined) {
+      await this.mutex.release()
       return
+    }
 
     //if (this.value instanceof Array) {
       let [ptr, len, value] = this.value
@@ -193,8 +203,25 @@ class File {
   
         this.value[0] = ptr + 1
         this.value[1] = len - 3
+        //this.dirty = true
       }
     //}
+    //else if (this.dirty) {
+    //  let buffer = Buffer.from(
+    //    `<${JSON.stringify(this.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.dirty = false
+    this.mutex.release()
   }
 }
 
@@ -202,6 +229,7 @@ class File {
 class Lazy {
   constructor(file) {
     this.file = file || null
+    this.dirty = false
   }
 
   has(key) {
@@ -277,6 +305,7 @@ class LazyArray extends Lazy {
       value === null ||
       value instanceof Lazy
     )
+    this.dirty = true
     //if (typeof value === 'object' && value !== null)
       value = [-1, 0, value]
     this.array[key] = value
@@ -304,9 +333,9 @@ class LazyArray extends Lazy {
     if (file != this.file) {
       assert(this.file === null)
       this.file = file
+      this.dirty = true
     }
 
-    let dirty = false
     for (let i = 0; i < this.length; ++i) {
       let item = this.array[i]
       //if (item instanceof Array) {
@@ -332,14 +361,16 @@ class LazyArray extends Lazy {
 
           item[0] = ptr
           item[1] = len - 1
-          dirty = true
+          this.dirty = true
         }
       //}
     }
-    return dirty
+    return this.dirty
   }
 
   pack() {
+    this.dirty = false
+
     let new_array = []
     for (let i = 0; i < this.length; ++i) {
       let item = this.array[i]
@@ -398,6 +429,7 @@ class LazyObject extends Lazy {
       value === null ||
       value instanceof Lazy
     )
+    this.dirty = true
     //if (typeof value === 'object' && value !== null)
       value = [-1, 0, value]
     this.object[key] = value
@@ -418,9 +450,9 @@ class LazyObject extends Lazy {
     if (file != this.file) {
       assert(this.file === null)
       this.file = file
+      this.dirty = true
     }
 
-    let dirty = false
     for (let i in this.object) {
       let item = this.object[i]
       //if (item instanceof Array) {
@@ -446,14 +478,16 @@ class LazyObject extends Lazy {
 
           item[0] = ptr
           item[1] = len
-          dirty = true
+          this.dirty = true
         }
       //}
     }
-    return dirty
+    return this.dirty
   }
 
   pack() {
+    this.dirty = false
+
     let new_object = {}
     for (let i in this.object) {
       let item = this.object[i]