commit 3e35b99b927939f442da656895ad2c576946f92e
parent 2f4010bc436a84cf5d14a1771fe6c5a6cffa6e7e
Author: Jacob R. Edwards <jacob@jacobedwards.org>
Date: Tue, 17 Sep 2024 12:59:46 -0700
Add history compression
Now, if there's a diff for the same object without a mark inbetween,
the old diff's value is set to the new value and no new diff is
created. It could be taken further by deleting a "new" operation
if there is a "remove" operation afterwords, but for now this should
be a large improvement.
One caveat of the current system is that each time this is done
(which is all the time in this program) the history truncated value
is updated causing the server to receive the full floorplan again.
This isn't such a big deal, but perhaps history should also store
the position that it was truncated at so allow delta updates whenever
possible.
Diffstat:
1 file changed, 17 insertions(+), 3 deletions(-)
diff --git a/files/floorplans/floorplan/backend.js b/files/floorplans/floorplan/backend.js
@@ -88,16 +88,30 @@ class BackendHistory {
this.truncate()
}
- let oldValue
- for (let i = this.place; !oldValue && i >= 0; --i) {
+ /*
+ * TODO: Keep a table of the last diffs for various paths
+ * to speed this up
+ */
+ let oldDiff
+ for (let i = this.place; !oldDiff && i >= 0; --i) {
if (this.diffs[i].path === path) {
if (this.diffs[i].op === "remove") {
throw new Error("Cannot reuse old ID")
}
- oldValue = this.diffs[i].value
+ oldDiff = i
}
}
+ if (op === "add" && oldDiff != undefined && this.diffMark(oldDiff) == this.diffMark()) {
+ let d = this.diffs[oldDiff]
+ d.value = value
+ d.time = Date.now()
+ this.truncated = Date.now()
+ console.debug("Backend.History.addDiff", "replacing", d.id)
+ return d
+ }
+
+ let oldValue = oldDiff ? this.diffs[oldDiff].value : undefined
if (op === "add") {
op = oldValue ? "replace" : "new"
} else {