]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
More internal refactoring and docs for opfs-sahpool.
authorstephan <stephan@noemail.net>
Wed, 19 Jul 2023 17:47:02 +0000 (17:47 +0000)
committerstephan <stephan@noemail.net>
Wed, 19 Jul 2023 17:47:02 +0000 (17:47 +0000)
FossilOrigin-Name: 64ccf6177a019eab46fb3345ad1e8ba80eaf2c9da55767031f9f04ccd16afb4d

ext/wasm/api/sqlite3-vfs-opfs-sahpool.js
manifest
manifest.uuid

index b0d71c50eea2668470034c095d58a7d7ba6dc0aa..f34c87004d990c8c4ac3207284b6fb3922c77d3f 100644 (file)
@@ -48,8 +48,9 @@
   incompatible with that VFS.
 
   - This VFS requires the "semi-fully-sync" FileSystemSyncAccessHandle
-  (hereafter "SAH") APIs released with Chrome v108. If that API
-  is not detected, the VFS is not registered.
+  (hereafter "SAH") APIs released with Chrome v108 (and all other
+  major browsers released since March 2023). If that API is not
+  detected, the VFS is not registered.
 */
 'use strict';
 globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
@@ -137,11 +138,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
     xClose: function(pFile){
       const pool = getPoolForPFile(pFile);
       pool.storeErr();
-      const file = pool.getFileForPtr(pFile);
+      const file = pool.getOFileForSFile(pFile);
       if(file) {
         try{
           pool.log(`xClose ${file.path}`);
-          pool.setFileForPtr(pFile, false);
+          pool.mapSFileToOFile(pFile, false);
           file.sah.flush();
           if(file.flags & capi.SQLITE_OPEN_DELETEONCLOSE){
             pool.deletePath(file.path);
@@ -162,7 +163,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
     xFileSize: function(pFile,pSz64){
       const pool = getPoolForPFile(pFile);
       pool.log(`xFileSize`);
-      const file = pool.getFileForPtr(pFile);
+      const file = pool.getOFileForSFile(pFile);
       const size = file.sah.getSize() - HEADER_OFFSET_DATA;
       //log(`xFileSize ${file.path} ${size}`);
       wasm.poke64(pSz64, BigInt(size));
@@ -172,14 +173,14 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
       const pool = getPoolForPFile(pFile);
       pool.log(`xLock ${lockType}`);
       pool.storeErr();
-      const file = pool.getFileForPtr(pFile);
+      const file = pool.getOFileForSFile(pFile);
       file.lockType = lockType;
       return 0;
     },
     xRead: function(pFile,pDest,n,offset64){
       const pool = getPoolForPFile(pFile);
       pool.storeErr();
-      const file = pool.getFileForPtr(pFile);
+      const file = pool.getOFileForSFile(pFile);
       pool.log(`xRead ${file.path} ${n} @ ${offset64}`);
       try {
         const nRead = file.sah.read(
@@ -203,7 +204,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
       const pool = getPoolForPFile(pFile);
       pool.log(`xSync ${flags}`);
       pool.storeErr();
-      const file = pool.getFileForPtr(pFile);
+      const file = pool.getOFileForSFile(pFile);
       //log(`xSync ${file.path} ${flags}`);
       try{
         file.sah.flush();
@@ -217,7 +218,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
       const pool = getPoolForPFile(pFile);
       pool.log(`xTruncate ${sz64}`);
       pool.storeErr();
-      const file = pool.getFileForPtr(pFile);
+      const file = pool.getOFileForSFile(pFile);
       //log(`xTruncate ${file.path} ${iSize}`);
       try{
         file.sah.truncate(HEADER_OFFSET_DATA + Number(sz64));
@@ -230,14 +231,14 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
     xUnlock: function(pFile,lockType){
       const pool = getPoolForPFile(pFile);
       pool.log('xUnlock');
-      const file = pool.getFileForPtr(pFile);
+      const file = pool.getOFileForSFile(pFile);
       file.lockType = lockType;
       return 0;
     },
     xWrite: function(pFile,pSrc,n,offset64){
       const pool = getPoolForPFile(pFile);
       pool.storeErr();
-      const file = pool.getFileForPtr(pFile);
+      const file = pool.getOFileForSFile(pFile);
       pool.log(`xWrite ${file.path} ${n} ${offset64}`);
       try{
         const nBytes = file.sah.write(
@@ -349,7 +350,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
         // Subsequent I/O methods are only passed the sqlite3_file
         // pointer, so map the relevant info we need to that pointer.
         const file = {path, flags, sah};
-        pool.setFileForPtr(pFile, file);
+        pool.mapSFileToOFile(pFile, file);
         file.lockType = capi.SQLITE_LOCK_NONE;
         const sq3File = new capi.sqlite3_file(pFile);
         sq3File.$pMethods = opfsIoMethods.pointer;
@@ -436,6 +437,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
 
     /** Buffer used by [sg]etAssociatedPath(). */
     #apBody = new Uint8Array(HEADER_CORPUS_SIZE);
+    // DataView for this.#apBody
     #dvBody;
 
     // associated sqlite3_vfs instance
@@ -497,6 +499,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
       return this.getCapacity();
     }
 
+    /**
+       Reduce capacity by n, but can only reduce up to the limit
+       of currently-available SAHs. Returns a Promise which resolves
+       to the number of slots really removed.
+    */
     async reduceCapacity(n){
       let nRm = 0;
       for(const ah of Array.from(this.#availableSAH)){
@@ -514,7 +521,8 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
     }
 
     /**
-       Releases all currently-opened SAHs.
+       Releases all currently-opened SAHs. The only legal
+       operation after this is acquireAccessHandles().
     */
     releaseAccessHandles(){
       for(const ah of this.#mapSAHToName.keys()) ah.close();
@@ -637,8 +645,11 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
     }
 
     /**
-       Computes a digest for the given byte array and
-       returns it as a two-element Uint32Array.
+       Computes a digest for the given byte array and returns it as a
+       two-element Uint32Array. This digest gets stored in the
+       metadata for each file as a validation check. Changing this
+       algorithm invalidates all existing databases for this VFS, so
+       don't do that.
     */
     computeDigest(byteArray){
       let h1 = 0xdeadbeef;
@@ -730,14 +741,18 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
       return rc;
     }
 
-    getFileForPtr(ptr){
+    /**
+       Given an (sqlite3_file*), returns the mapped
+       xOpen file object.
+    */
+    getOFileForSFile(ptr){
       return this.#mapSqlite3FileToFile.get(ptr);
     }
     /**
        Maps or unmaps (if file is falsy) the given (sqlite3_file*)
        to an xOpen file object and to this pool object.
     */
-    setFileForPtr(pFile,file){
+    mapSFileToOFile(pFile,file){
       if(file){
         this.#mapSqlite3FileToFile.set(pFile, file);
         setPoolForPFile(pFile, this);
@@ -746,14 +761,34 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
         setPoolForPFile(pFile, false);
       }
     }
+
+    /**
+       Returns true if the given client-defined file name is in this
+       object's name-to-SAH map.
+    */
     hasFilename(name){
       return this.#mapFilenameToSAH.has(name)
     }
 
+    /**
+       Returns the SAH associated with the given
+       client-defined file name.
+    */
     getSAHForPath(path){
       return this.#mapFilenameToSAH.get(path);
     }
 
+    /**
+       Removes this object's sqlite3_vfs registration and shuts down
+       this object, releasing all handles, mappings, and whatnot,
+       including deleting its data directory. There is currently no
+       way to "revive" the object and reaquire its resources.
+
+       This function is intended primarily for testing.
+
+       Resolves to true if it did its job, false if the
+       VFS has already been shut down.
+    */
     async removeVfs(){
       if(!this.#cVfs.pointer) return false;
       capi.sqlite3_vfs_unregister(this.#cVfs.pointer);
@@ -773,6 +808,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
       return true;
     }
 
+    //! Documented elsewhere in this file.
     exportFile(name){
       const sah = this.#mapFilenameToSAH.get(name) || toss("File not found:",name);
       const n = sah.getSize() - HEADER_OFFSET_DATA;
@@ -781,6 +817,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
       return b;
     }
 
+    //! Documented elsewhere in this file.
     importDb(name, bytes){
       const n = bytes.byteLength;
       if(n<512 || n%512!=0){
@@ -803,13 +840,15 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
 
 
   /**
-     A SAHPoolUtil instance is exposed to clients in order to manipulate an OpfsSAHPool object without directly exposing that
+     A OpfsSAHPoolUtil instance is exposed to clients in order to
+     manipulate an OpfsSAHPool object without directly exposing that
      object and allowing for some semantic changes compared to that
      class.
 
-     Class docs are in the client-level docs for installOpfsSAHPoolVfs().
+     Class docs are in the client-level docs for
+     installOpfsSAHPoolVfs().
   */
-  class SAHPoolUtil {
+  class OpfsSAHPoolUtil {
     /* This object's associated OpfsSAHPool. */
     #p;
 
@@ -818,18 +857,14 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
       this.vfsName = sahPool.vfsName;
     }
 
-    async addCapacity(n){
-      return this.#p.addCapacity(n);
-    }
-    async reduceCapacity(n){
-      return this.#p.reduceCapacity(n);
-    }
-    getCapacity(){
-      return this.#p.getCapacity(this.#p);
-    }
-    getFileCount(){
-      return this.#p.getFileCount();
-    }
+    async addCapacity(n){ return this.#p.addCapacity(n) }
+
+    async reduceCapacity(n){ return this.#p.reduceCapacity(n) }
+
+    getCapacity(){ return this.#p.getCapacity(this.#p) }
+
+    getFileCount(){ return this.#p.getFileCount() }
+
     async reserveMinimumCapacity(min){
       const c = this.#p.getCapacity();
       return (c < min) ? this.#p.addCapacity(min - c) : c;
@@ -839,20 +874,17 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
 
     importDb(name, bytes){ return this.#p.importDb(name,bytes) }
 
-    async wipeFiles(){return this.#p.reset(true)}
+    async wipeFiles(){ return this.#p.reset(true) }
 
-    unlink(filename){
-      return this.#p.deletePath(filename);
-    }
+    unlink(filename){ return this.#p.deletePath(filename) }
 
-    async removeVfs(){return this.#p.removeVfs()}
+    async removeVfs(){ return this.#p.removeVfs() }
 
-  }/* class SAHPoolUtil */;
+  }/* class OpfsSAHPoolUtil */;
 
   /**
-     Ensure that the client has a "fully-sync" SAH impl,
-     else reject the promise. Returns true on success,
-     throws on error.
+     Returns a resolved Promise if the current environment
+     has a "fully-sync" SAH impl, else a rejected Promise.
   */
   const apiVersionCheck = async ()=>{
     const dh = await navigator.storage.getDirectory();
@@ -1087,7 +1119,7 @@ globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){
       return thePool.isReady.then(async()=>{
         /** The poolUtil object will be the result of the
             resolved Promise. */
-        const poolUtil = new SAHPoolUtil(thePool);
+        const poolUtil = new OpfsSAHPoolUtil(thePool);
 
         if(sqlite3.oo1){
           const oo1 = sqlite3.oo1;
index 46c9678ff82409c7b4d15b56d1fb99b1734c818b..9bf3bd22cd811dcd85297d4c8b6eae7dd9e8b2de 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Update\sthe\sdevelopment-over-ssh\sdocs\sfor\sthe\swasm\sbuild.
-D 2023-07-19T17:46:28.936
+C More\sinternal\srefactoring\sand\sdocs\sfor\sopfs-sahpool.
+D 2023-07-19T17:47:02.768
 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
 F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -502,7 +502,7 @@ F ext/wasm/api/sqlite3-api-worker1.js 9f32af64df1a031071912eea7a201557fe39b17386
 F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89
 F ext/wasm/api/sqlite3-opfs-async-proxy.js 8cf8a897726f14071fae6be6648125162b256dfb4f96555b865dbb7a6b65e379
 F ext/wasm/api/sqlite3-v-helper.js 7daa0eab0a513a25b05e9abae7b5beaaa39209b3ed12f86aeae9ef8d2719ed25
-F ext/wasm/api/sqlite3-vfs-opfs-sahpool.js d3e41757230c8a41fccc4db077d029546f0ebccd13d4ba0111c52ca77779ab70
+F ext/wasm/api/sqlite3-vfs-opfs-sahpool.js 05b5646b91faa947833d43a840e8b94abb441afa953ee5a11cc7f07f4e01361a
 F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 4946af0d6fbd395aa39966562ca85900664605a5f0cc10fff50146dee527812c
 F ext/wasm/api/sqlite3-wasm.c 8867f1d41c112fb4a2cfe22ff224eccaf309fcdea266cee0ec554f85db72ef0f
 F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bc06df0d599e625bde6a10a394e326dc68da9ff07fa5404354580f81566e591f
@@ -2044,8 +2044,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
 F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
 F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
 F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 534481cd0c2e6f62dd0a82f25d4b78fdcc671eb70d6966693c98212a6420891c
-R 3098985ac29097adbc0d24d2b5daf2dc
+P 500109bd0a4c134b91c37f397ff1ee828e09c17f7ecd153f975ede748caee7bb
+R 44dc85544ec440f7c21f7b899d57ed02
 U stephan
-Z 78455e14df71dd2dbc1be007d9b53932
+Z e1c9bd04ae7a0c44d52816708800bbbb
 # Remove this line to create a well-formed Fossil manifest.
index 7bb3f99caeda45c4873da5d7f6f79490654102ef..d4e846dedcee2bf7311e08520ac8cccb15fb1684 100644 (file)
@@ -1 +1 @@
-500109bd0a4c134b91c37f397ff1ee828e09c17f7ecd153f975ede748caee7bb
\ No newline at end of file
+64ccf6177a019eab46fb3345ad1e8ba80eaf2c9da55767031f9f04ccd16afb4d
\ No newline at end of file