saghul / txiki.js

A tiny JavaScript runtime
MIT License
2.5k stars 167 forks source link

repl history doubles in size on each run #662

Open undernorthernsky opened 5 hours ago

undernorthernsky commented 5 hours ago
$ rm ~/.tjs/history.db
$ ./build/tjs 
Welcome to txiki.js - Type ".help" for help
> a
> b
> c

$ echo 'select count(*) from history' | sqlite3 ~/.tjs/history.db 
3

# start & exit repl multiple times

$ ./build/tjs 
$ echo 'select count(*) from history' | sqlite3 ~/.tjs/history.db 
6

$ ./build/tjs 
$ echo 'select count(*) from history' | sqlite3 ~/.tjs/history.db 
12

Closing the repl quickly becomes noticeably slower; a quick hack is to batch the inserts to avoid O(n) fsync calls.

     function save_history() {
         if (historyDb) {
-            for (const str of history) {
-                try {
-                    historyDb.prepare('INSERT INTO history (entry) VALUES(?)').run(str);
-                } catch (_) {}
-            }
+            const insert = historyDb.prepare('INSERT INTO history (entry) VALUES(?)');
+            const insertMany = historyDb.transaction(entries => {
+              for (const str of entries) {
+                insert.run(str);
+              }
+            });
+            insertMany(history);

Of course this doesn't fix the root cause; remember history length on load and only save history.slice(initial_length)?

undernorthernsky commented 5 hours ago

or maybe: