mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-07 02:42:48 +03:00
Remove the timing and counter metrics from the OPFS VFS, as they're long-since unused so are just wasted CPU cycles.
FossilOrigin-Name: 67c035c34fb916e66bfe115a132660771e8fa2921e6d46756975c5df3ebcd73c
This commit is contained in:
@@ -87,35 +87,6 @@ const installAsyncProxy = function(){
|
||||
const log = (...args)=>logImpl(2, ...args);
|
||||
const warn = (...args)=>logImpl(1, ...args);
|
||||
const error = (...args)=>logImpl(0, ...args);
|
||||
const metrics = Object.create(null);
|
||||
metrics.reset = ()=>{
|
||||
let k;
|
||||
const r = (m)=>(m.count = m.time = m.wait = 0);
|
||||
for(k in state.opIds){
|
||||
r(metrics[k] = Object.create(null));
|
||||
}
|
||||
let s = metrics.s11n = Object.create(null);
|
||||
s = s.serialize = Object.create(null);
|
||||
s.count = s.time = 0;
|
||||
s = metrics.s11n.deserialize = Object.create(null);
|
||||
s.count = s.time = 0;
|
||||
};
|
||||
metrics.dump = ()=>{
|
||||
let k, n = 0, t = 0, w = 0;
|
||||
for(k in state.opIds){
|
||||
const m = metrics[k];
|
||||
n += m.count;
|
||||
t += m.time;
|
||||
w += m.wait;
|
||||
m.avgTime = (m.count && m.time) ? (m.time / m.count) : 0;
|
||||
}
|
||||
console.log(globalThis?.location?.href,
|
||||
"metrics for",globalThis?.location?.href,":\n",
|
||||
metrics,
|
||||
"\nTotal of",n,"op(s) for",t,"ms",
|
||||
"approx",w,"ms spent waiting on OPFS APIs.");
|
||||
console.log("Serialization metrics:",metrics.s11n);
|
||||
};
|
||||
|
||||
/**
|
||||
__openFiles is a map of sqlite3_file pointers (integers) to
|
||||
@@ -372,37 +343,6 @@ const installAsyncProxy = function(){
|
||||
if(fh.readOnly) toss(opName+"(): File is read-only: "+fh.filenameAbs);
|
||||
};
|
||||
|
||||
/**
|
||||
We track 2 different timers: the "metrics" timer records how much
|
||||
time we spend performing work. The "wait" timer records how much
|
||||
time we spend waiting on the underlying OPFS timer. See the calls
|
||||
to mTimeStart(), mTimeEnd(), wTimeStart(), and wTimeEnd()
|
||||
throughout this file to see how they're used.
|
||||
*/
|
||||
const __mTimer = Object.create(null);
|
||||
__mTimer.op = undefined;
|
||||
__mTimer.start = undefined;
|
||||
const mTimeStart = (op)=>{
|
||||
__mTimer.start = performance.now();
|
||||
__mTimer.op = op;
|
||||
//metrics[op] || toss("Maintenance required: missing metrics for",op);
|
||||
++metrics[op].count;
|
||||
};
|
||||
const mTimeEnd = ()=>(
|
||||
metrics[__mTimer.op].time += performance.now() - __mTimer.start
|
||||
);
|
||||
const __wTimer = Object.create(null);
|
||||
__wTimer.op = undefined;
|
||||
__wTimer.start = undefined;
|
||||
const wTimeStart = (op)=>{
|
||||
__wTimer.start = performance.now();
|
||||
__wTimer.op = op;
|
||||
//metrics[op] || toss("Maintenance required: missing metrics for",op);
|
||||
};
|
||||
const wTimeEnd = ()=>(
|
||||
metrics[__wTimer.op].wait += performance.now() - __wTimer.start
|
||||
);
|
||||
|
||||
/**
|
||||
Gets set to true by the 'opfs-async-shutdown' command to quit the
|
||||
wait loop. This is only intended for debugging purposes: we cannot
|
||||
@@ -413,37 +353,24 @@ const installAsyncProxy = function(){
|
||||
|
||||
/**
|
||||
Asynchronous wrappers for sqlite3_vfs and sqlite3_io_methods
|
||||
methods, as well as helpers like mkdir(). Maintenance reminder:
|
||||
members are in alphabetical order to simplify finding them.
|
||||
methods, as well as helpers like mkdir().
|
||||
*/
|
||||
const vfsAsyncImpls = {
|
||||
'opfs-async-metrics': async ()=>{
|
||||
mTimeStart('opfs-async-metrics');
|
||||
metrics.dump();
|
||||
storeAndNotify('opfs-async-metrics', 0);
|
||||
mTimeEnd();
|
||||
},
|
||||
'opfs-async-shutdown': async ()=>{
|
||||
flagAsyncShutdown = true;
|
||||
storeAndNotify('opfs-async-shutdown', 0);
|
||||
},
|
||||
mkdir: async (dirname)=>{
|
||||
mTimeStart('mkdir');
|
||||
let rc = 0;
|
||||
wTimeStart('mkdir');
|
||||
try {
|
||||
await getDirForFilename(dirname+"/filepart", true);
|
||||
}catch(e){
|
||||
state.s11n.storeException(2,e);
|
||||
rc = state.sq3Codes.SQLITE_IOERR;
|
||||
}finally{
|
||||
wTimeEnd();
|
||||
}
|
||||
storeAndNotify('mkdir', rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xAccess: async (filename)=>{
|
||||
mTimeStart('xAccess');
|
||||
/* OPFS cannot support the full range of xAccess() queries
|
||||
sqlite3 calls for. We can essentially just tell if the file
|
||||
is accessible, but if it is then it's automatically writable
|
||||
@@ -456,26 +383,20 @@ const installAsyncProxy = function(){
|
||||
accessible, non-0 means not accessible.
|
||||
*/
|
||||
let rc = 0;
|
||||
wTimeStart('xAccess');
|
||||
try{
|
||||
const [dh, fn] = await getDirForFilename(filename);
|
||||
await dh.getFileHandle(fn);
|
||||
}catch(e){
|
||||
state.s11n.storeException(2,e);
|
||||
rc = state.sq3Codes.SQLITE_IOERR;
|
||||
}finally{
|
||||
wTimeEnd();
|
||||
}
|
||||
storeAndNotify('xAccess', rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xClose: async function(fid/*sqlite3_file pointer*/){
|
||||
const opName = 'xClose';
|
||||
mTimeStart(opName);
|
||||
__implicitLocks.delete(fid);
|
||||
const fh = __openFiles[fid];
|
||||
let rc = 0;
|
||||
wTimeStart(opName);
|
||||
if(fh){
|
||||
delete __openFiles[fid];
|
||||
await closeSyncHandle(fh);
|
||||
@@ -487,15 +408,11 @@ const installAsyncProxy = function(){
|
||||
state.s11n.serialize();
|
||||
rc = state.sq3Codes.SQLITE_NOTFOUND;
|
||||
}
|
||||
wTimeEnd();
|
||||
storeAndNotify(opName, rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xDelete: async function(...args){
|
||||
mTimeStart('xDelete');
|
||||
const rc = await vfsAsyncImpls.xDeleteNoWait(...args);
|
||||
storeAndNotify('xDelete', rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xDeleteNoWait: async function(filename, syncDir = 0, recursive = false){
|
||||
/* The syncDir flag is, for purposes of the VFS API's semantics,
|
||||
@@ -511,7 +428,6 @@ const installAsyncProxy = function(){
|
||||
is false.
|
||||
*/
|
||||
let rc = 0;
|
||||
wTimeStart('xDelete');
|
||||
try {
|
||||
while(filename){
|
||||
const [hDir, filenamePart] = await getDirForFilename(filename, false);
|
||||
@@ -527,14 +443,11 @@ const installAsyncProxy = function(){
|
||||
state.s11n.storeException(2,e);
|
||||
rc = state.sq3Codes.SQLITE_IOERR_DELETE;
|
||||
}
|
||||
wTimeEnd();
|
||||
return rc;
|
||||
},
|
||||
xFileSize: async function(fid/*sqlite3_file pointer*/){
|
||||
mTimeStart('xFileSize');
|
||||
const fh = __openFiles[fid];
|
||||
let rc = 0;
|
||||
wTimeStart('xFileSize');
|
||||
try{
|
||||
const sz = await (await getSyncHandle(fh,'xFileSize')).getSize();
|
||||
state.s11n.serialize(Number(sz));
|
||||
@@ -543,19 +456,15 @@ const installAsyncProxy = function(){
|
||||
rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR);
|
||||
}
|
||||
await releaseImplicitLock(fh);
|
||||
wTimeEnd();
|
||||
storeAndNotify('xFileSize', rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xLock: async function(fid/*sqlite3_file pointer*/,
|
||||
lockType/*SQLITE_LOCK_...*/){
|
||||
mTimeStart('xLock');
|
||||
const fh = __openFiles[fid];
|
||||
let rc = 0;
|
||||
const oldLockType = fh.xLock;
|
||||
fh.xLock = lockType;
|
||||
if( !fh.syncHandle ){
|
||||
wTimeStart('xLock');
|
||||
try {
|
||||
await getSyncHandle(fh,'xLock');
|
||||
__implicitLocks.delete(fid);
|
||||
@@ -564,18 +473,14 @@ const installAsyncProxy = function(){
|
||||
rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR_LOCK);
|
||||
fh.xLock = oldLockType;
|
||||
}
|
||||
wTimeEnd();
|
||||
}
|
||||
storeAndNotify('xLock',rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xOpen: async function(fid/*sqlite3_file pointer*/, filename,
|
||||
flags/*SQLITE_OPEN_...*/,
|
||||
opfsFlags/*OPFS_...*/){
|
||||
const opName = 'xOpen';
|
||||
mTimeStart(opName);
|
||||
const create = (state.sq3Codes.SQLITE_OPEN_CREATE & flags);
|
||||
wTimeStart('xOpen');
|
||||
try{
|
||||
let hDir, filenamePart;
|
||||
try {
|
||||
@@ -583,8 +488,6 @@ const installAsyncProxy = function(){
|
||||
}catch(e){
|
||||
state.s11n.storeException(1,e);
|
||||
storeAndNotify(opName, state.sq3Codes.SQLITE_NOTFOUND);
|
||||
mTimeEnd();
|
||||
wTimeEnd();
|
||||
return;
|
||||
}
|
||||
if( state.opfsFlags.OPFS_UNLINK_BEFORE_OPEN & opfsFlags ){
|
||||
@@ -596,7 +499,6 @@ const installAsyncProxy = function(){
|
||||
}
|
||||
}
|
||||
const hFile = await hDir.getFileHandle(filenamePart, {create});
|
||||
wTimeEnd();
|
||||
const fh = Object.assign(Object.create(null),{
|
||||
fid: fid,
|
||||
filenameAbs: filename,
|
||||
@@ -614,60 +516,47 @@ const installAsyncProxy = function(){
|
||||
__openFiles[fid] = fh;
|
||||
storeAndNotify(opName, 0);
|
||||
}catch(e){
|
||||
wTimeEnd();
|
||||
error(opName,e);
|
||||
state.s11n.storeException(1,e);
|
||||
storeAndNotify(opName, state.sq3Codes.SQLITE_IOERR);
|
||||
}
|
||||
mTimeEnd();
|
||||
},
|
||||
xRead: async function(fid/*sqlite3_file pointer*/,n,offset64){
|
||||
mTimeStart('xRead');
|
||||
let rc = 0, nRead;
|
||||
const fh = __openFiles[fid];
|
||||
try{
|
||||
wTimeStart('xRead');
|
||||
nRead = (await getSyncHandle(fh,'xRead')).read(
|
||||
fh.sabView.subarray(0, n),
|
||||
{at: Number(offset64)}
|
||||
);
|
||||
wTimeEnd();
|
||||
if(nRead < n){/* Zero-fill remaining bytes */
|
||||
fh.sabView.fill(0, nRead, n);
|
||||
rc = state.sq3Codes.SQLITE_IOERR_SHORT_READ;
|
||||
}
|
||||
}catch(e){
|
||||
if(undefined===nRead) wTimeEnd();
|
||||
error("xRead() failed",e,fh);
|
||||
state.s11n.storeException(1,e);
|
||||
rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR_READ);
|
||||
}
|
||||
await releaseImplicitLock(fh);
|
||||
storeAndNotify('xRead',rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xSync: async function(fid/*sqlite3_file pointer*/,flags/*ignored*/){
|
||||
mTimeStart('xSync');
|
||||
const fh = __openFiles[fid];
|
||||
let rc = 0;
|
||||
if(!fh.readOnly && fh.syncHandle){
|
||||
try {
|
||||
wTimeStart('xSync');
|
||||
await fh.syncHandle.flush();
|
||||
}catch(e){
|
||||
state.s11n.storeException(2,e);
|
||||
rc = state.sq3Codes.SQLITE_IOERR_FSYNC;
|
||||
}
|
||||
wTimeEnd();
|
||||
}
|
||||
storeAndNotify('xSync',rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xTruncate: async function(fid/*sqlite3_file pointer*/,size){
|
||||
mTimeStart('xTruncate');
|
||||
let rc = 0;
|
||||
const fh = __openFiles[fid];
|
||||
wTimeStart('xTruncate');
|
||||
try{
|
||||
affirmNotRO('xTruncate', fh);
|
||||
await (await getSyncHandle(fh,'xTruncate')).truncate(size);
|
||||
@@ -677,35 +566,27 @@ const installAsyncProxy = function(){
|
||||
rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR_TRUNCATE);
|
||||
}
|
||||
await releaseImplicitLock(fh);
|
||||
wTimeEnd();
|
||||
storeAndNotify('xTruncate',rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xUnlock: async function(fid/*sqlite3_file pointer*/,
|
||||
lockType/*SQLITE_LOCK_...*/){
|
||||
mTimeStart('xUnlock');
|
||||
let rc = 0;
|
||||
const fh = __openFiles[fid];
|
||||
if( fh.syncHandle
|
||||
&& state.sq3Codes.SQLITE_LOCK_NONE===lockType
|
||||
/* Note that we do not differentiate between lock types in
|
||||
this VFS. We're either locked or unlocked. */ ){
|
||||
wTimeStart('xUnlock');
|
||||
try { await closeSyncHandle(fh) }
|
||||
catch(e){
|
||||
state.s11n.storeException(1,e);
|
||||
rc = state.sq3Codes.SQLITE_IOERR_UNLOCK;
|
||||
}
|
||||
wTimeEnd();
|
||||
}
|
||||
storeAndNotify('xUnlock',rc);
|
||||
mTimeEnd();
|
||||
},
|
||||
xWrite: async function(fid/*sqlite3_file pointer*/,n,offset64){
|
||||
mTimeStart('xWrite');
|
||||
let rc;
|
||||
const fh = __openFiles[fid];
|
||||
wTimeStart('xWrite');
|
||||
try{
|
||||
affirmNotRO('xWrite', fh);
|
||||
rc = (
|
||||
@@ -719,9 +600,7 @@ const installAsyncProxy = function(){
|
||||
rc = GetSyncHandleError.convertRc(e,state.sq3Codes.SQLITE_IOERR_WRITE);
|
||||
}
|
||||
await releaseImplicitLock(fh);
|
||||
wTimeEnd();
|
||||
storeAndNotify('xWrite',rc);
|
||||
mTimeEnd();
|
||||
}
|
||||
}/*vfsAsyncImpls*/;
|
||||
|
||||
@@ -755,8 +634,6 @@ const installAsyncProxy = function(){
|
||||
}
|
||||
};
|
||||
state.s11n.deserialize = function(clear=false){
|
||||
++metrics.s11n.deserialize.count;
|
||||
const t = performance.now();
|
||||
const argc = viewU8[0];
|
||||
const rc = argc ? [] : null;
|
||||
if(argc){
|
||||
@@ -781,12 +658,9 @@ const installAsyncProxy = function(){
|
||||
}
|
||||
if(clear) viewU8[0] = 0;
|
||||
//log("deserialize:",argc, rc);
|
||||
metrics.s11n.deserialize.time += performance.now() - t;
|
||||
return rc;
|
||||
};
|
||||
state.s11n.serialize = function(...args){
|
||||
const t = performance.now();
|
||||
++metrics.s11n.serialize.count;
|
||||
if(args.length){
|
||||
//log("serialize():",args);
|
||||
const typeIds = [];
|
||||
@@ -817,7 +691,6 @@ const installAsyncProxy = function(){
|
||||
}else{
|
||||
viewU8[0] = 0;
|
||||
}
|
||||
metrics.s11n.serialize.time += performance.now() - t;
|
||||
};
|
||||
|
||||
state.s11n.storeException = state.asyncS11nExceptions
|
||||
@@ -899,7 +772,6 @@ const installAsyncProxy = function(){
|
||||
}
|
||||
});
|
||||
initS11n();
|
||||
metrics.reset();
|
||||
log("init state",state);
|
||||
wPost('opfs-async-inited');
|
||||
waitLoop();
|
||||
@@ -912,9 +784,6 @@ const installAsyncProxy = function(){
|
||||
waitLoop();
|
||||
}
|
||||
break;
|
||||
case 'opfs-async-metrics':
|
||||
metrics.dump();
|
||||
break;
|
||||
}
|
||||
};
|
||||
wPost('opfs-async-loaded');
|
||||
|
Reference in New Issue
Block a user