From de2fa2b4c7812c95635c3268696a708076c56547 Mon Sep 17 00:00:00 2001 From: Roy Hashimoto <156154+rhashimoto@users.noreply.github.com> Date: Wed, 29 May 2024 09:58:53 -0700 Subject: [PATCH] Update README.md --- src/examples/README.md | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/examples/README.md b/src/examples/README.md index 3687063..211f9bc 100644 --- a/src/examples/README.md +++ b/src/examples/README.md @@ -5,30 +5,44 @@ production is not prohibited but that isn't their primary purpose. ## VFS examples ### MemoryVFS and MemoryAsyncVFS -These are minimal working examples for writing a VFS. First-time VFS implementers should -probably start by looking at these classes, as well as the -[SQLite VFS documentation](https://www.sqlite.org/vfs.html). +These implementations store database pages in memory. The default SQLite VFS already does that, so their value is mainly to provide minimal working examples for writing a VFS. First-time VFS implementers should probably start by looking at these classes, as well as the [SQLite VFS documentation](https://www.sqlite.org/vfs.html). ### IDBBatchAtomicVFS -This IndexedDB VFS is the most general and compatible implementation. +This VFS stores database pages in IndexedDB. IndexedDB works on all contexts - Window, Worker, SharedWorker, service worker, extension - which makes IDBBatchAtomicVFS a good general purpose VFS. + +SQLite supports a special mode for filesystems that can make "batch atomic" writes, i.e. guaranteeing that an arbitrary set of changes is made either completely or not at all, and IDBBatchAtomicVFS leverages IndexedDB to do this. When this mode can be used, an external journal file is not needed which improves performance. Changing the page size after the database is created is not supported. ### OPFSAdaptiveVFS -This OPFS VFS supports multiple connections without the proposed "readwrite-unsafe" locking mode, but is more performant if it is available. +This VFS is fundamentally a straightforward mapping of OPFS access handles to VFS methods, but adds two different techniques to support multiple connections. + +The current OPFS spec allows only one open access handle on a file at a time. Supporting multiple connections to a database thus requires closing the access handle on one connection before opening it on another. This open/close is expensive so OPFSAdaptiveVFS does this lazily, i.e. it only closes the access handle when another connection needs it. -If the new mode is not supported then only journaling modes "delete" (default), "memory", and "off" are allowed. +A proposed change to OPFS allows there to be multiple open access handles on a file. OPFSAdaptiveVFS will take advantage of this on browsers that support it, and this will improve performance as well as allow overlapping multiple read transactions with a write transaction. + +If the new modes are not supported then only journaling modes "delete" (default), "memory", and "off" are allowed. ### AccessHandlePoolVFS -This OPFS VFS can be used with the synchronous WebAssembly build. +This is an OPFS VFS that has all synchronous methods, i.e. they don't return Promises. This allows it to be used with a with a synchronous WebAssembly build and that has definite performance advantages. + +AccessHandlePoolVFS works by pre-opening a number of access handles and associating them with SQLite open requests as needed. Operation is restricted to a single wa-sqlite instance, so multiple connections are not supported. + +This VFS is not filesystem transparent, which means that its database files in OPFS cannot be directly imported and exported. ### OPFSCoopSyncVFS -This is a new VFS that works with the synchronous WebAssembly build but also supports multiple connections and is filesystem transparent. +This VFS is a synchronous OPFS VFS (like AccessHandlePoolVFS) that allows multiple connections (unlike AccessHandlePoolVFS). + +OPFSCoopSyncVFS uses an access handle pool for files other than the main database and its journal file. For the shared files, it closes them lazily (like OPFSAdaptiveVFS) to support multiple connections while retaining performance with a single connection. + +To keep all the methods synchronous, when asynchronous operations are necessary (e.g. for locking) a method returns an error. The library wrapper API internally handles the error, waits for the asynchronous operation to complete, and then repeats the operation. This is not very efficient, but is only necessary when opening a database or under active multiple connection contention. Transactions involving more than one main (non-temporary) database are not supported. ### OPFSPermutedVFS -This is a hybrid OPFS/IndexedDB VFS that allows multiple-reader with single-writer concurrency (like WAL, but without using the SQLite WAL implementation). It requires the proposed "readwrite-unsafe" locking mode for OPFS access handles. +This is a hybrid OPFS/IndexedDB VFS that allows high concurrency - simultaneous access by multiple readers and a single writer. It requires the proposed "readwrite-unsafe" locking mode for OPFS access handles. + +OPFSPermutedVFS is a lot like SQLite WAL except that it writes directly to the database file instead of a separate write-ahead log file, so there may be more than one version of a page in the file and the location of pages is generally not sequential. All the page data is stored in the file and IndexedDB is used to manage the page versions and locations. Changing the page size after the database is created is not supported. Not filesystem transparent except immediately after VACUUM.