mirror of
https://github.com/sqlite/sqlite.git
synced 2025-07-29 08:01:23 +03:00
Add an experimental OPFS VFS-specific URI flag, opfs-unlock-asap, which tells the VFS to release implicit locks ASAP. This permits higher concurrency but hurts performance considerably. This may or may not be obsoleted by other concurrency-related experimentation.
FossilOrigin-Name: d23c917013485ec2793125221f3936b05c39d6eca941629fb819b6b4aa714520
This commit is contained in:
@ -355,6 +355,25 @@ const installOpfsVfs = function callee(options){
|
||||
toss("Maintenance required: not found:",k);
|
||||
}
|
||||
});
|
||||
state.opfsFlags = Object.assign(Object.create(null),{
|
||||
/**
|
||||
Flag for use with xOpen(). "opfs-unlock-asap=1" enables
|
||||
this. See defaultUnlockAsap, below.
|
||||
*/
|
||||
OPFS_UNLOCK_ASAP: 0x01,
|
||||
/**
|
||||
If true, any async routine which implicitly acquires a sync
|
||||
access handle (i.e. an OPFS lock) will release that locks at
|
||||
the end of the call which acquires it. If false, such
|
||||
"autolocks" are not released until the VFS is idle for some
|
||||
brief amount of time.
|
||||
|
||||
The benefit of enabling this is much higher concurrency. The
|
||||
down-side is much-reduced performance (as much as a 4x decrease
|
||||
in speedtest1).
|
||||
*/
|
||||
defaultUnlockAsap: false
|
||||
});
|
||||
|
||||
/**
|
||||
Runs the given operation (by name) in the async worker
|
||||
@ -845,9 +864,15 @@ const installOpfsVfs = function callee(options){
|
||||
//xSleep is optionally defined below
|
||||
xOpen: function f(pVfs, zName, pFile, flags, pOutFlags){
|
||||
mTimeStart('xOpen');
|
||||
let opfsFlags = 0;
|
||||
if(0===zName){
|
||||
zName = randomFilename();
|
||||
}else if('number'===typeof zName){
|
||||
if(capi.sqlite3_uri_boolean(zName, "opfs-unlock-asap", 0)){
|
||||
/* -----------------------^^^^^ MUST pass the untranslated
|
||||
C-string here. */
|
||||
opfsFlags |= state.opfsFlags.OPFS_UNLOCK_ASAP;
|
||||
}
|
||||
zName = wasm.cstringToJs(zName);
|
||||
}
|
||||
const fh = Object.create(null);
|
||||
@ -855,7 +880,7 @@ const installOpfsVfs = function callee(options){
|
||||
fh.filename = zName;
|
||||
fh.sab = new SharedArrayBuffer(state.fileBufferSize);
|
||||
fh.flags = flags;
|
||||
const rc = opRun('xOpen', pFile, zName, flags);
|
||||
const rc = opRun('xOpen', pFile, zName, flags, opfsFlags);
|
||||
if(!rc){
|
||||
/* Recall that sqlite3_vfs::xClose() will be called, even on
|
||||
error, unless pFile->pMethods is NULL. */
|
||||
|
@ -201,18 +201,6 @@ const releaseImplicitLocks = async ()=>{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
If true, any routine which implicitly acquires a sync access handle
|
||||
(i.e. an OPFS lock) will release that locks at the end of the call
|
||||
which acquires it. If false, such "autolocks" are not released
|
||||
until the VFS is idle for some brief amount of time.
|
||||
|
||||
The benefit of enabling this is much higher concurrency. The
|
||||
down-side is much-reduced performance (as much as a 4x decrease
|
||||
in speedtest1).
|
||||
*/
|
||||
state.defaultReleaseImplicitLocks = false;
|
||||
|
||||
/**
|
||||
An experiment in improving concurrency by freeing up implicit locks
|
||||
sooner. This is known to impact performance dramatically but it has
|
||||
@ -536,7 +524,8 @@ const vfsAsyncImpls = {
|
||||
mTimeEnd();
|
||||
},
|
||||
xOpen: async function(fid/*sqlite3_file pointer*/, filename,
|
||||
flags/*SQLITE_OPEN_...*/){
|
||||
flags/*SQLITE_OPEN_...*/,
|
||||
opfsFlags/*OPFS_...*/){
|
||||
const opName = 'xOpen';
|
||||
mTimeStart(opName);
|
||||
const create = (state.sq3Codes.SQLITE_OPEN_CREATE & flags);
|
||||
@ -566,13 +555,8 @@ const vfsAsyncImpls = {
|
||||
deleteOnClose: !!(state.sq3Codes.SQLITE_OPEN_DELETEONCLOSE & flags)
|
||||
});
|
||||
fh.releaseImplicitLocks =
|
||||
state.defaultReleaseImplicitLocks
|
||||
/* TODO: check URI flags for "opfs-auto-unlock". First we need to
|
||||
reshape the API a bit to be able to pass those on to here
|
||||
from the other half of the proxy. */;
|
||||
/*if(fh.releaseImplicitLocks){
|
||||
console.warn("releaseImplicitLocks is ON for",fh);
|
||||
}*/
|
||||
(opfsFlags & state.opfsFlags.OPFS_UNLOCK_ASAP)
|
||||
|| state.opfsFlags.defaultUnlockAsap;
|
||||
if(0 /* this block is modelled after something wa-sqlite
|
||||
does but it leads to horrible contention on journal files. */
|
||||
&& (0===(flags & state.sq3Codes.SQLITE_OPEN_MAIN_DB))){
|
||||
@ -887,6 +871,7 @@ navigator.storage.getDirectory().then(function(d){
|
||||
state.sabS11nView = new Uint8Array(state.sabIO, state.sabS11nOffset, state.sabS11nSize);
|
||||
state.opIds = opt.opIds;
|
||||
state.sq3Codes = opt.sq3Codes;
|
||||
state.opfsFlags = opt.opfsFlags;
|
||||
Object.keys(vfsAsyncImpls).forEach((k)=>{
|
||||
if(!Number.isFinite(state.opIds[k])){
|
||||
toss("Maintenance required: missing state.opIds[",k,"]");
|
||||
|
@ -44,7 +44,7 @@ self.sqlite3InitModule().then(async function(sqlite3){
|
||||
};
|
||||
const run = async function(){
|
||||
db = new sqlite3.oo1.DB({
|
||||
filename: 'file:'+dbName,
|
||||
filename: 'file:'+dbName,//+'?opfs-unlock-asap=1'/*EXPERIMENTAL*/,
|
||||
flags: 'c',
|
||||
vfs: 'opfs'
|
||||
});
|
||||
|
Reference in New Issue
Block a user