mirror of
https://github.com/sqlite/sqlite.git
synced 2025-08-08 14:02:16 +03:00
sqlite3-wasm.c: code legibility and coding style tweaks. Increase SQLITE_DEFAULT_PAGE_SIZE from 4k to 8k, as that improves OPFS speedtest1 performance by roughly 12%.
FossilOrigin-Name: c260895faacb3458c557778630756d02a8520c0f1864bddcf86cdd27ef4a42bd
This commit is contained in:
@@ -32,21 +32,16 @@
|
|||||||
** the same db handle as another thread, thus multi-threading support
|
** the same db handle as another thread, thus multi-threading support
|
||||||
** is unnecessary in the library. Because the filesystems are virtual
|
** is unnecessary in the library. Because the filesystems are virtual
|
||||||
** and local to a given wasm runtime instance, two Workers can never
|
** and local to a given wasm runtime instance, two Workers can never
|
||||||
** access the same db file at once, with the exception of OPFS. As of
|
** access the same db file at once, with the exception of OPFS.
|
||||||
** this writing (2022-09-30), OPFS exclusively locks a file when
|
|
||||||
** opening it, so two Workers can never open the same OPFS-backed file
|
|
||||||
** at once. That situation will change if and when lower-level locking
|
|
||||||
** features are added to OPFS (as is currently planned, per folks
|
|
||||||
** involved with its development).
|
|
||||||
**
|
**
|
||||||
** Summary: except for the case of future OPFS, which supports
|
** Summary: except for the case of OPFS, which supports locking using
|
||||||
** locking, and any similar future filesystems, threading and file
|
** its own API, threading and file locking support are unnecessary in
|
||||||
** locking support are unnecessary in the wasm build.
|
** the wasm build.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** Undefine any SQLITE_... config flags which we specifically do not
|
** Undefine any SQLITE_... config flags which we specifically do not
|
||||||
** want undefined. Please keep these alphabetized.
|
** want defined. Please keep these alphabetized.
|
||||||
*/
|
*/
|
||||||
#undef SQLITE_OMIT_DESERIALIZE
|
#undef SQLITE_OMIT_DESERIALIZE
|
||||||
#undef SQLITE_OMIT_MEMORYDB
|
#undef SQLITE_OMIT_MEMORYDB
|
||||||
@@ -69,9 +64,11 @@
|
|||||||
*/
|
*/
|
||||||
# define SQLITE_DEFAULT_CACHE_SIZE -16384
|
# define SQLITE_DEFAULT_CACHE_SIZE -16384
|
||||||
#endif
|
#endif
|
||||||
#if 0 && !defined(SQLITE_DEFAULT_PAGE_SIZE)
|
#if !defined(SQLITE_DEFAULT_PAGE_SIZE)
|
||||||
/* TODO: experiment with this. */
|
/* OPFS performance is improved with a page size of 8k instead
|
||||||
# define SQLITE_DEFAULT_PAGE_SIZE 8192 /*4096*/
|
** of 4k. kvvfs, OTOH, likely suffers from that. Peformance
|
||||||
|
** with 16k is equivalent to 8k. */
|
||||||
|
# define SQLITE_DEFAULT_PAGE_SIZE 8196 /*4096*/
|
||||||
#endif
|
#endif
|
||||||
#ifndef SQLITE_DEFAULT_UNIX_VFS
|
#ifndef SQLITE_DEFAULT_UNIX_VFS
|
||||||
# define SQLITE_DEFAULT_UNIX_VFS "unix-none"
|
# define SQLITE_DEFAULT_UNIX_VFS "unix-none"
|
||||||
@@ -716,78 +713,78 @@ const char * sqlite3_wasm_enum_json(void){
|
|||||||
|
|
||||||
#define CurrentStruct sqlite3_vfs
|
#define CurrentStruct sqlite3_vfs
|
||||||
StructBinder {
|
StructBinder {
|
||||||
M(iVersion,"i");
|
M(iVersion, "i");
|
||||||
M(szOsFile,"i");
|
M(szOsFile, "i");
|
||||||
M(mxPathname,"i");
|
M(mxPathname, "i");
|
||||||
M(pNext,"p");
|
M(pNext, "p");
|
||||||
M(zName,"s");
|
M(zName, "s");
|
||||||
M(pAppData,"p");
|
M(pAppData, "p");
|
||||||
M(xOpen,"i(pppip)");
|
M(xOpen, "i(pppip)");
|
||||||
M(xDelete,"i(ppi)");
|
M(xDelete, "i(ppi)");
|
||||||
M(xAccess,"i(ppip)");
|
M(xAccess, "i(ppip)");
|
||||||
M(xFullPathname,"i(ppip)");
|
M(xFullPathname, "i(ppip)");
|
||||||
M(xDlOpen,"p(pp)");
|
M(xDlOpen, "p(pp)");
|
||||||
M(xDlError,"p(pip)");
|
M(xDlError, "p(pip)");
|
||||||
M(xDlSym,"p()");
|
M(xDlSym, "p()");
|
||||||
M(xDlClose,"v(pp)");
|
M(xDlClose, "v(pp)");
|
||||||
M(xRandomness,"i(pip)");
|
M(xRandomness, "i(pip)");
|
||||||
M(xSleep,"i(pi)");
|
M(xSleep, "i(pi)");
|
||||||
M(xCurrentTime,"i(pp)");
|
M(xCurrentTime, "i(pp)");
|
||||||
M(xGetLastError,"i(pip)");
|
M(xGetLastError, "i(pip)");
|
||||||
M(xCurrentTimeInt64,"i(pp)");
|
M(xCurrentTimeInt64, "i(pp)");
|
||||||
M(xSetSystemCall,"i(ppp)");
|
M(xSetSystemCall, "i(ppp)");
|
||||||
M(xGetSystemCall,"p(pp)");
|
M(xGetSystemCall, "p(pp)");
|
||||||
M(xNextSystemCall,"p(pp)");
|
M(xNextSystemCall, "p(pp)");
|
||||||
} _StructBinder;
|
} _StructBinder;
|
||||||
#undef CurrentStruct
|
#undef CurrentStruct
|
||||||
|
|
||||||
#define CurrentStruct sqlite3_io_methods
|
#define CurrentStruct sqlite3_io_methods
|
||||||
StructBinder {
|
StructBinder {
|
||||||
M(iVersion,"i");
|
M(iVersion, "i");
|
||||||
M(xClose,"i(p)");
|
M(xClose, "i(p)");
|
||||||
M(xRead,"i(ppij)");
|
M(xRead, "i(ppij)");
|
||||||
M(xWrite,"i(ppij)");
|
M(xWrite, "i(ppij)");
|
||||||
M(xTruncate,"i(pj)");
|
M(xTruncate, "i(pj)");
|
||||||
M(xSync,"i(pi)");
|
M(xSync, "i(pi)");
|
||||||
M(xFileSize,"i(pp)");
|
M(xFileSize, "i(pp)");
|
||||||
M(xLock,"i(pi)");
|
M(xLock, "i(pi)");
|
||||||
M(xUnlock,"i(pi)");
|
M(xUnlock, "i(pi)");
|
||||||
M(xCheckReservedLock,"i(pp)");
|
M(xCheckReservedLock, "i(pp)");
|
||||||
M(xFileControl,"i(pip)");
|
M(xFileControl, "i(pip)");
|
||||||
M(xSectorSize,"i(p)");
|
M(xSectorSize, "i(p)");
|
||||||
M(xDeviceCharacteristics,"i(p)");
|
M(xDeviceCharacteristics, "i(p)");
|
||||||
M(xShmMap,"i(piiip)");
|
M(xShmMap, "i(piiip)");
|
||||||
M(xShmLock,"i(piii)");
|
M(xShmLock, "i(piii)");
|
||||||
M(xShmBarrier,"v(p)");
|
M(xShmBarrier, "v(p)");
|
||||||
M(xShmUnmap,"i(pi)");
|
M(xShmUnmap, "i(pi)");
|
||||||
M(xFetch,"i(pjip)");
|
M(xFetch, "i(pjip)");
|
||||||
M(xUnfetch,"i(pjp)");
|
M(xUnfetch, "i(pjp)");
|
||||||
} _StructBinder;
|
} _StructBinder;
|
||||||
#undef CurrentStruct
|
#undef CurrentStruct
|
||||||
|
|
||||||
#define CurrentStruct sqlite3_file
|
#define CurrentStruct sqlite3_file
|
||||||
StructBinder {
|
StructBinder {
|
||||||
M(pMethods,"p");
|
M(pMethods, "p");
|
||||||
} _StructBinder;
|
} _StructBinder;
|
||||||
#undef CurrentStruct
|
#undef CurrentStruct
|
||||||
|
|
||||||
#define CurrentStruct sqlite3_kvvfs_methods
|
#define CurrentStruct sqlite3_kvvfs_methods
|
||||||
StructBinder {
|
StructBinder {
|
||||||
M(xRead,"i(sspi)");
|
M(xRead, "i(sspi)");
|
||||||
M(xWrite,"i(sss)");
|
M(xWrite, "i(sss)");
|
||||||
M(xDelete,"i(ss)");
|
M(xDelete, "i(ss)");
|
||||||
M(nKeySize,"i");
|
M(nKeySize, "i");
|
||||||
} _StructBinder;
|
} _StructBinder;
|
||||||
#undef CurrentStruct
|
#undef CurrentStruct
|
||||||
|
|
||||||
#if SQLITE_WASM_TESTS
|
#if SQLITE_WASM_TESTS
|
||||||
#define CurrentStruct WasmTestStruct
|
#define CurrentStruct WasmTestStruct
|
||||||
StructBinder {
|
StructBinder {
|
||||||
M(v4,"i");
|
M(v4, "i");
|
||||||
M(cstr,"s");
|
M(cstr, "s");
|
||||||
M(ppV,"p");
|
M(ppV, "p");
|
||||||
M(v8,"j");
|
M(v8, "j");
|
||||||
M(xFunc,"v(p)");
|
M(xFunc, "v(p)");
|
||||||
} _StructBinder;
|
} _StructBinder;
|
||||||
#undef CurrentStruct
|
#undef CurrentStruct
|
||||||
#endif
|
#endif
|
||||||
@@ -820,7 +817,7 @@ const char * sqlite3_wasm_enum_json(void){
|
|||||||
** call is returned.
|
** call is returned.
|
||||||
*/
|
*/
|
||||||
SQLITE_WASM_KEEP
|
SQLITE_WASM_KEEP
|
||||||
int sqlite3_wasm_vfs_unlink(sqlite3_vfs *pVfs, const char * zName){
|
int sqlite3_wasm_vfs_unlink(sqlite3_vfs *pVfs, const char *zName){
|
||||||
int rc = SQLITE_MISUSE /* ??? */;
|
int rc = SQLITE_MISUSE /* ??? */;
|
||||||
if( 0==pVfs && 0!=zName ) pVfs = sqlite3_vfs_find(0);
|
if( 0==pVfs && 0!=zName ) pVfs = sqlite3_vfs_find(0);
|
||||||
if( zName && pVfs && pVfs->xDelete ){
|
if( zName && pVfs && pVfs->xDelete ){
|
||||||
@@ -857,13 +854,15 @@ sqlite3_vfs * sqlite3_wasm_db_vfs(sqlite3 *pDb, const char *zDbName){
|
|||||||
** SQLITE_MISUSE if pDb is NULL.
|
** SQLITE_MISUSE if pDb is NULL.
|
||||||
*/
|
*/
|
||||||
SQLITE_WASM_KEEP
|
SQLITE_WASM_KEEP
|
||||||
int sqlite3_wasm_db_reset(sqlite3*pDb){
|
int sqlite3_wasm_db_reset(sqlite3 *pDb){
|
||||||
int rc = SQLITE_MISUSE;
|
int rc = SQLITE_MISUSE;
|
||||||
if( pDb ){
|
if( pDb ){
|
||||||
rc = sqlite3_db_config(pDb, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
|
rc = sqlite3_db_config(pDb, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);
|
||||||
if( 0==rc ) rc = sqlite3_exec(pDb, "VACUUM", 0, 0, 0);
|
if( 0==rc ){
|
||||||
|
rc = sqlite3_exec(pDb, "VACUUM", 0, 0, 0);
|
||||||
sqlite3_db_config(pDb, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
|
sqlite3_db_config(pDb, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -907,7 +906,7 @@ int sqlite3_wasm_db_export_chunked( sqlite3* pDb,
|
|||||||
}
|
}
|
||||||
for( ; 0==rc && nPos<nSize; nPos += nBuf ){
|
for( ; 0==rc && nPos<nSize; nPos += nBuf ){
|
||||||
rc = pFile->pMethods->xRead(pFile, buf, nBuf, nPos);
|
rc = pFile->pMethods->xRead(pFile, buf, nBuf, nPos);
|
||||||
if(SQLITE_IOERR_SHORT_READ == rc){
|
if( SQLITE_IOERR_SHORT_READ == rc ){
|
||||||
rc = (nPos + nBuf) < nSize ? rc : 0/*assume EOF*/;
|
rc = (nPos + nBuf) < nSize ? rc : 0/*assume EOF*/;
|
||||||
}
|
}
|
||||||
if( 0==rc ) rc = xCallback(buf, nBuf);
|
if( 0==rc ) rc = xCallback(buf, nBuf);
|
||||||
@@ -935,7 +934,7 @@ int sqlite3_wasm_db_serialize( sqlite3 *pDb, const char *zSchema,
|
|||||||
sqlite3_int64 *nOut, unsigned int mFlags ){
|
sqlite3_int64 *nOut, unsigned int mFlags ){
|
||||||
unsigned char * z;
|
unsigned char * z;
|
||||||
if( !pDb || !pOut ) return SQLITE_MISUSE;
|
if( !pDb || !pOut ) return SQLITE_MISUSE;
|
||||||
if(nOut) *nOut = 0;
|
if( nOut ) *nOut = 0;
|
||||||
z = sqlite3_serialize(pDb, zSchema ? zSchema : "main", nOut, mFlags);
|
z = sqlite3_serialize(pDb, zSchema ? zSchema : "main", nOut, mFlags);
|
||||||
if( z || (SQLITE_SERIALIZE_NOCOPY & mFlags) ){
|
if( z || (SQLITE_SERIALIZE_NOCOPY & mFlags) ){
|
||||||
*pOut = z;
|
*pOut = z;
|
||||||
@@ -958,9 +957,8 @@ int sqlite3_wasm_db_serialize( sqlite3 *pDb, const char *zSchema,
|
|||||||
** Emscripten's FS.createDataFile() in a VFS-agnostic way. This
|
** Emscripten's FS.createDataFile() in a VFS-agnostic way. This
|
||||||
** functionality is intended for use in uploading database files.
|
** functionality is intended for use in uploading database files.
|
||||||
**
|
**
|
||||||
** Note that not all VFSes support this operation because they impose
|
** Not all VFSes support this functionality, e.g. the "kvvfs" does
|
||||||
** specific requirements on truncate and write sizes. e.g. kvvfs does
|
** not.
|
||||||
** not work with this.
|
|
||||||
**
|
**
|
||||||
** If pVfs is NULL, sqlite3_vfs_find(0) is used.
|
** If pVfs is NULL, sqlite3_vfs_find(0) is used.
|
||||||
**
|
**
|
||||||
@@ -973,10 +971,7 @@ int sqlite3_wasm_db_serialize( sqlite3 *pDb, const char *zSchema,
|
|||||||
**
|
**
|
||||||
** Whether or not directory components of zFilename are created
|
** Whether or not directory components of zFilename are created
|
||||||
** automatically or not is unspecified: that detail is left to the
|
** automatically or not is unspecified: that detail is left to the
|
||||||
** VFS. The "opfs" VFS, for example, create them.
|
** VFS. The "opfs" VFS, for example, creates them.
|
||||||
**
|
|
||||||
** Not all VFSes support this functionality, e.g. the "kvvfs" does
|
|
||||||
** not.
|
|
||||||
**
|
**
|
||||||
** If an error happens while populating or truncating the file, the
|
** If an error happens while populating or truncating the file, the
|
||||||
** target file will be deleted (if needed) if this function created
|
** target file will be deleted (if needed) if this function created
|
||||||
@@ -1014,7 +1009,8 @@ int sqlite3_wasm_vfs_create_file( sqlite3_vfs *pVfs,
|
|||||||
pVfs->xAccess(pVfs, zFilename, SQLITE_ACCESS_EXISTS, &fileExisted);
|
pVfs->xAccess(pVfs, zFilename, SQLITE_ACCESS_EXISTS, &fileExisted);
|
||||||
rc = sqlite3OsOpenMalloc(pVfs, zFilename, &pFile, openFlags, &flagsOut);
|
rc = sqlite3OsOpenMalloc(pVfs, zFilename, &pFile, openFlags, &flagsOut);
|
||||||
#if 0
|
#if 0
|
||||||
# define RC fprintf(stderr,"create_file(%s,%s) @%d rc=%d\n", pVfs->zName, zFilename, __LINE__, rc);
|
# define RC fprintf(stderr,"create_file(%s,%s) @%d rc=%d\n", \
|
||||||
|
pVfs->zName, zFilename, __LINE__, rc);
|
||||||
#else
|
#else
|
||||||
# define RC
|
# define RC
|
||||||
#endif
|
#endif
|
||||||
@@ -1046,11 +1042,14 @@ int sqlite3_wasm_vfs_create_file( sqlite3_vfs *pVfs,
|
|||||||
}
|
}
|
||||||
if( 0==rc && nData>0 ){
|
if( 0==rc && nData>0 ){
|
||||||
assert( nData<blockSize );
|
assert( nData<blockSize );
|
||||||
rc = pIo->xWrite(pFile, pPos, nData, (sqlite3_int64)(pPos - pData));
|
rc = pIo->xWrite(pFile, pPos, nData,
|
||||||
|
(sqlite3_int64)(pPos - pData));
|
||||||
RC;
|
RC;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if( pIo->xUnlock && doUnlock!=0 ) pIo->xUnlock(pFile, SQLITE_LOCK_NONE);
|
if( pIo->xUnlock && doUnlock!=0 ){
|
||||||
|
pIo->xUnlock(pFile, SQLITE_LOCK_NONE);
|
||||||
|
}
|
||||||
pIo->xClose(pFile);
|
pIo->xClose(pFile);
|
||||||
if( rc!=0 && 0==fileExisted ){
|
if( rc!=0 && 0==fileExisted ){
|
||||||
pVfs->xDelete(pVfs, zFilename, 1);
|
pVfs->xDelete(pVfs, zFilename, 1);
|
||||||
|
12
manifest
12
manifest
@@ -1,5 +1,5 @@
|
|||||||
C Expand\sJS\stests\sfor\sdb\sexport/import\sand\sdocument\sreason\sit\scannot\scurrently\swork\swith\skvvfs.\sFix\sa\sminor\sJS\sbuild\sdependencies\sbug.\sUpdate\spage\stitle\swith\sPASS/FAIL\sprefix\sfor\stester1.js\sto\simprove\soverview\swhen\slaunching\smultiple\stest\stabs.\sAdd\sability\sof\stester1\sshould-run-test\spredicates\sto\sreport\swhy\sa\sgiven\stest\sis\sdisabled.
|
C sqlite3-wasm.c:\scode\slegibility\sand\scoding\sstyle\stweaks.\sIncrease\sSQLITE_DEFAULT_PAGE_SIZE\sfrom\s4k\sto\s8k,\sas\sthat\simproves\sOPFS\sspeedtest1\sperformance\sby\sroughly\s12%.
|
||||||
D 2022-12-02T07:14:56.641
|
D 2022-12-02T08:29:03.564
|
||||||
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
|
||||||
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
|
||||||
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
|
||||||
@@ -512,7 +512,7 @@ F ext/wasm/api/sqlite3-opfs-async-proxy.js 9963c78bf6e5ccb5ba28e8597851bd9d980e8
|
|||||||
F ext/wasm/api/sqlite3-vfs-helper.js 4ad4faf02e1524bf0296be8452c00b5708dce6faf649468d0377e26a0b299263
|
F ext/wasm/api/sqlite3-vfs-helper.js 4ad4faf02e1524bf0296be8452c00b5708dce6faf649468d0377e26a0b299263
|
||||||
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 654f37fd6312d3bb0d067b21ad42f9dcfd629fd34ace892e67e06143a65dc6d0
|
F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 654f37fd6312d3bb0d067b21ad42f9dcfd629fd34ace892e67e06143a65dc6d0
|
||||||
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
|
F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9
|
||||||
F ext/wasm/api/sqlite3-wasm.c edae35c7fe070ae7db5feaf3a7d9ba45708f6f56fdcbb3ad0fb2710e4da3bb05
|
F ext/wasm/api/sqlite3-wasm.c 3fb517065417bfddf9f49b73cf1f8af1d8d50fbb295c484e77359e5ed6e14a21
|
||||||
F ext/wasm/api/sqlite3-worker1-promiser.js 0c7a9826dbf82a5ed4e4f7bf7816e825a52aff253afbf3350431f5773faf0e4b
|
F ext/wasm/api/sqlite3-worker1-promiser.js 0c7a9826dbf82a5ed4e4f7bf7816e825a52aff253afbf3350431f5773faf0e4b
|
||||||
F ext/wasm/api/sqlite3-worker1.js 1e54ea3d540161bcfb2100368a2fc0cad871a207b8336afee1c445715851ec54
|
F ext/wasm/api/sqlite3-worker1.js 1e54ea3d540161bcfb2100368a2fc0cad871a207b8336afee1c445715851ec54
|
||||||
F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8
|
F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8
|
||||||
@@ -2065,8 +2065,8 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
|
|||||||
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
|
||||||
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
|
||||||
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
|
||||||
P 8e4d30ac033a6d9019a7eeedfe788dc0120f565cef2ae8f09d2bf32eb94d8a33
|
P 75f610d3a4cf3d972220f9abc27cdf5990451e3835ceb9cf66973934004dfc5c
|
||||||
R 537bb49fe6ebd23b0d6c90dc722897c8
|
R 476dae20eba5ae2d14fd70169918f0cd
|
||||||
U stephan
|
U stephan
|
||||||
Z eb02f2c4f6198c757ec0df7e4c3e3028
|
Z e6e64ad365153ec68f24a3bd7c94c825
|
||||||
# Remove this line to create a well-formed Fossil manifest.
|
# Remove this line to create a well-formed Fossil manifest.
|
||||||
|
@@ -1 +1 @@
|
|||||||
75f610d3a4cf3d972220f9abc27cdf5990451e3835ceb9cf66973934004dfc5c
|
c260895faacb3458c557778630756d02a8520c0f1864bddcf86cdd27ef4a42bd
|
Reference in New Issue
Block a user