aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordrh <>2021-03-16 14:12:26 +0000
committerdrh <>2021-03-16 14:12:26 +0000
commit3fee67533e265be377125faf3c73d26c90914f13 (patch)
tree3e5a3f02a434d12eeb7f9075f87eb7de5d2a7769
parent67d4bbf6c1d75e56d66deb7f34d1521b49b307c1 (diff)
downloadsqlite-3fee67533e265be377125faf3c73d26c90914f13.tar.gz
sqlite-3fee67533e265be377125faf3c73d26c90914f13.zip
Comment and stylistic changes to the appendvfs.c implementation.
FossilOrigin-Name: 25c3186aa143328157fb506a29802e87099cd14be4fa218230484a3212f20621
-rw-r--r--ext/misc/appendvfs.c164
-rw-r--r--manifest14
-rw-r--r--manifest.uuid2
3 files changed, 89 insertions, 91 deletions
diff --git a/ext/misc/appendvfs.c b/ext/misc/appendvfs.c
index 477e1eafc..6975a6abf 100644
--- a/ext/misc/appendvfs.c
+++ b/ext/misc/appendvfs.c
@@ -38,8 +38,8 @@
** (5) Otherwise, SQLITE_CANTOPEN is returned.
**
** To avoid unnecessary complications with the PENDING_BYTE, the size of
-** the file containing the database is limited to 1GB. (1000013824 bytes)
-** This VFS will not read or write past the 1GB mark. This restriction
+** the file containing the database is limited to 1GiB. (1073741824 bytes)
+** This VFS will not read or write past the 1GiB mark. This restriction
** might be lifted in future versions. For now, if you need a larger
** database, then keep it in a separate file.
**
@@ -68,14 +68,16 @@ SQLITE_EXTENSION_INIT1
** Maximum size of the combined prefix + database + append-mark. This
** must be less than 0x40000000 to avoid locking issues on Windows.
*/
-#define APND_MAX_SIZE (65536*15259)
+#define APND_MAX_SIZE (0x40000000)
/*
-** Size of storage page upon which to align appendvfs portion.
+** Try to align the database to an even multiple of APND_ROUNDUP bytes.
*/
-#ifndef APND_ROUNDUP_BITS
-#define APND_ROUNDUP_BITS 12
+#ifndef APND_ROUNDUP
+#define APND_ROUNDUP 4096
#endif
+#define APND_ALIGN_MASK ((sqlite3_int64)(APND_ROUNDUP-1))
+#define APND_START_ROUNDUP(fsz) (((fsz)+APND_ALIGN_MASK) & ~APND_ALIGN_MASK)
/*
** Forward declaration of objects used by this utility
@@ -89,43 +91,45 @@ typedef struct ApndFile ApndFile;
#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
#define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1))
-/* Invariants for an open appendvfs file:
- * Once an appendvfs file is opened, it will be in one of three states:
- * State 0: Never written. Underlying file (if any) is unaltered.
- * State 1: Append mark is persisted, content write is in progress.
- * State 2: Append mark is persisted, content writes are complete.
- *
- * State 0 is persistent in the sense that nothing will have been done
- * to the underlying file, including any attempt to convert it to an
- * appendvfs file.
- *
- * State 1 is normally transitory. However, if a write operation ends
- * abnormally (disk full, power loss, process kill, etc.), then State 1
- * may be persistent on disk with an incomplete content write-out. This
- * is logically equivalent to an interrupted write to an ordinary file,
- * where some unknown portion of to-be-written data is persisted while
- * the remainder is not. Database integrity in such cases is maintained
- * (or not) by the same measures available for ordinary file access.
- *
- * State 2 is persistent under normal circumstances (when there is no
- * abnormal termination of a write operation such that data provided
- * to the underlying VFS write method has not yet reached storage.)
- *
- * In order to maintain the state invariant, the append mark is written
- * in advance of content writes where any part of such content would
- * overwrite an existing (or yet to be written) append mark.
- */
+/* An open appendvfs file
+**
+** An instance of this structure describes the appended database file.
+** A separate sqlite3_file object is always appended. The appended
+** sqlite3_file object (which can be accessed using ORIGFILE()) describes
+** the entire file, including the prefix, the database, and the
+** append-mark.
+**
+** The structure of an AppendVFS database is like this:
+**
+** +-------------+---------+----------+-------------+
+** | prefix-file | padding | database | append-mark |
+** +-------------+---------+----------+-------------+
+** ^ ^
+** | |
+** iPgOne iMark
+**
+**
+** "prefix file" - file onto which the database has been appended.
+** "padding" - zero or more bytes inserted so that "database"
+** starts on an APND_ROUNDUP boundary
+** "database" - The SQLite database file
+** "append-mark" - The 25-byte "Start-Of-SQLite3-NNNNNNNN" that indicates
+** the offset from the start of prefix-file to the start
+** of "database".
+**
+** The size of the database is iMark - iPgOne.
+**
+** The NNNNNNNN in the "Start-Of-SQLite3-NNNNNNNN" suffix is the value
+** of iPgOne stored as a big-ending 64-bit integer.
+**
+** iMark will be the size of the underlying file minus 25 (APND_MARKSIZE).
+** Or, iMark is -1 to indicate that it has not yet been written.
+*/
struct ApndFile {
- /* Access to IO methods of the underlying file */
- sqlite3_file base;
- /* File offset to beginning of appended content (unchanging) */
- sqlite3_int64 iPgOne;
- /* File offset of written append-mark, or -1 if unwritten */
- sqlite3_int64 iMark;
- /* Whenever file is open and .iMark >= 0, and file size changes are
- * not in progress, .iMark + sizeof(append mark) == base file size,
- * and append file size == .iMark - .iPgOne .
- */
+ sqlite3_file base; /* Subclass. MUST BE FIRST! */
+ sqlite3_int64 iPgOne; /* Offset to the start of the database */
+ sqlite3_int64 iMark; /* Offset of the append mark. -1 if unwritten */
+ /* Always followed by another sqlite3_file that describes the whole file */
};
/*
@@ -221,7 +225,6 @@ static const sqlite3_io_methods apnd_io_methods = {
** Close an apnd-file.
*/
static int apndClose(sqlite3_file *pFile){
- assert((ApndFile*)pFile == ORIGFILE(pFile));
pFile = ORIGFILE(pFile);
return pFile->pMethods->xClose(pFile);
}
@@ -255,9 +258,8 @@ static int apndWriteMark(
int i = APND_MARK_FOS_SZ;
int rc;
assert(pFile == ORIGFILE(paf));
- /* assert(pFile == paf->base); */
memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ);
- while (--i >= 0) {
+ while( --i >= 0 ){
a[APND_MARK_PREFIX_SZ+i] = (unsigned char)(iPgOne & 0xff);
iPgOne >>= 8;
}
@@ -282,12 +284,10 @@ static int apndWrite(
sqlite_int64 iWriteEnd = iOfst + iAmt;
if( iWriteEnd>=APND_MAX_SIZE ) return SQLITE_FULL;
pFile = ORIGFILE(pFile);
- /* assert(pFile == paf->base); */
/* If append-mark is absent or will be overwritten, write it. */
if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){
int rc = apndWriteMark(paf, pFile, iWriteEnd);
- if( SQLITE_OK!=rc )
- return rc;
+ if( SQLITE_OK!=rc ) return rc;
}
return pFile->pMethods->xWrite(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
}
@@ -299,8 +299,7 @@ static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){
ApndFile *paf = (ApndFile *)pFile;
pFile = ORIGFILE(pFile);
/* The append mark goes out first so truncate failure does not lose it. */
- if( SQLITE_OK!=apndWriteMark(paf, pFile, size) )
- return SQLITE_IOERR;
+ if( SQLITE_OK!=apndWriteMark(paf, pFile, size) ) return SQLITE_IOERR;
/* Truncate underlying file just past append mark */
return pFile->pMethods->xTruncate(pFile, paf->iMark+APND_MARK_SIZE);
}
@@ -416,8 +415,9 @@ static int apndFetch(
void **pp
){
ApndFile *p = (ApndFile *)pFile;
- if( p->iMark < 0 || iOfst+iAmt > p->iMark)
+ if( p->iMark < 0 || iOfst+iAmt > p->iMark ){
return SQLITE_IOERR; /* Cannot read what is not yet there. */
+ }
pFile = ORIGFILE(pFile);
return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp);
}
@@ -468,14 +468,18 @@ static int apndIsAppendvfsDatabase(sqlite3_int64 sz, sqlite3_file *pFile){
char zHdr[16];
sqlite3_int64 iMark = apndReadMark(sz, pFile);
if( iMark>=0 ){
- /* If file has right end-marker, the expected odd size, and the
- * SQLite DB type marker where the end-marker puts it, then it
- * is an appendvfs database (to be treated as such.)
- */
+ /* If file has the correct end-marker, the expected odd size, and the
+ ** SQLite DB type marker where the end-marker puts it, then it
+ ** is an appendvfs database.
+ */
rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), iMark);
- if( SQLITE_OK==rc && memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))==0
- && (sz & 0x1ff)== APND_MARK_SIZE && sz>=512+APND_MARK_SIZE )
+ if( SQLITE_OK==rc
+ && memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))==0
+ && (sz & 0x1ff) == APND_MARK_SIZE
+ && sz>=512+APND_MARK_SIZE
+ ){
return 1; /* It's an appendvfs database */
+ }
}
return 0;
}
@@ -497,11 +501,6 @@ static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){
}
}
-/* Round-up used to get appendvfs portion to begin at a page boundary. */
-#define APND_ALIGN_MASK(nbits) ((1<<nbits)-1)
-#define APND_START_ROUNDUP(fsz, nbits) \
- ( ((fsz)+APND_ALIGN_MASK(nbits)) & ~(sqlite3_int64)APND_ALIGN_MASK(nbits) )
-
/*
** Open an apnd file handle.
*/
@@ -519,49 +518,48 @@ static int apndOpen(
sqlite3_int64 sz;
if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
/* The appendvfs is not to be used for transient or temporary databases.
- * Just use the base VFS open to initialize the given file object and
- * open the underlying file. (Appendvfs is then unused for this file.)
- */
+ ** Just use the base VFS open to initialize the given file object and
+ ** open the underlying file. (Appendvfs is then unused for this file.)
+ */
return pBaseVfs->xOpen(pBaseVfs, zName, pFile, flags, pOutFlags);
}
memset(pApndFile, 0, sizeof(ApndFile));
pFile->pMethods = &apnd_io_methods;
- /* Record that append mark has not been written until seen otherwise. */
- pApndFile->iMark = -1;
+ pApndFile->iMark = -1; /* Append mark not yet written */
rc = pBaseVfs->xOpen(pBaseVfs, zName, pBaseFile, flags, pOutFlags);
- if( rc ) goto apnd_open_done;
- rc = pBaseFile->pMethods->xFileSize(pBaseFile, &sz);
+ if( rc==SQLITE_OK ){
+ rc = pBaseFile->pMethods->xFileSize(pBaseFile, &sz);
+ }
if( rc ){
pBaseFile->pMethods->xClose(pBaseFile);
- goto apnd_open_done;
+ pFile->pMethods = 0;
+ return rc;
}
if( apndIsOrdinaryDatabaseFile(sz, pBaseFile) ){
/* The file being opened appears to be just an ordinary DB. Copy
- * the base dispatch-table so this instance mimics the base VFS.
- */
+ ** the base dispatch-table so this instance mimics the base VFS.
+ */
memmove(pApndFile, pBaseFile, pBaseVfs->szOsFile);
return SQLITE_OK;
}
pApndFile->iPgOne = apndReadMark(sz, pFile);
if( pApndFile->iPgOne>=0 ){
- /* Append mark was found, infer its offset */
- pApndFile->iMark = sz - APND_MARK_SIZE;
- /* pApndFile->base = pBaseFile; */
+ pApndFile->iMark = sz - APND_MARK_SIZE; /* Append mark found */
return SQLITE_OK;
}
if( (flags & SQLITE_OPEN_CREATE)==0 ){
pBaseFile->pMethods->xClose(pBaseFile);
rc = SQLITE_CANTOPEN;
+ pFile->pMethods = 0;
+ }else{
+ /* Round newly added appendvfs location to #define'd page boundary.
+ ** Note that nothing has yet been written to the underlying file.
+ ** The append mark will be written along with first content write.
+ ** Until then, paf->iMark value indicates it is not yet written.
+ */
+ pApndFile->iPgOne = APND_START_ROUNDUP(sz);
}
- /* Round newly added appendvfs location to #define'd page boundary.
- * Note that nothing has yet been written to the underlying file.
- * The append mark will be written along with first content write.
- * Until then, paf->iMark value indicates it is not yet written.
- */
- pApndFile->iPgOne = APND_START_ROUNDUP(sz, APND_ROUNDUP_BITS);
-apnd_open_done:
- if( rc ) pFile->pMethods = 0;
return rc;
}
diff --git a/manifest b/manifest
index 869781322..57975f75a 100644
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Fix\sassert\stypo.
-D 2021-03-16T07:06:29.878
+C Comment\sand\sstylistic\schanges\sto\sthe\sappendvfs.c\simplementation.
+D 2021-03-16T14:12:26.803
F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1
F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea
F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724
@@ -286,7 +286,7 @@ F ext/lsm1/tool/mklsm1c.tcl f31561bbee5349f0a554d1ad7236ac1991fc09176626f529f607
F ext/misc/README.md d6dd0fe1d8af77040216798a6a2b0c46c73054d2f0ea544fbbcdccf6f238c240
F ext/misc/amatch.c e3ad5532799cee9a97647f483f67f43b38796b84b5a8c60594fe782a4338f358
F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb
-F ext/misc/appendvfs.c 1dad6e7dc162ad36367513c1f985a1b474c3f3517f53ba22a6a89ce980843098
+F ext/misc/appendvfs.c 390c411f14e66abb2f30b9023ebc57334288780c9388cdc6e0a25deb5d40e3b2
F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0edb2a
F ext/misc/btreeinfo.c d28ce349b40054eaa9473e835837bad7a71deec33ba13e39f963d50933bfa0f9
F ext/misc/carray.c b75a0f207391038bf1540d3372f482a95c3613511c7c474db51ede1196321c7c
@@ -1910,7 +1910,7 @@ F vsixtest/vsixtest.tcl 6a9a6ab600c25a91a7acc6293828957a386a8a93
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P eae8236f3b9bc326648d1c8fca61cb3c38f821d06fe915fd0978cffeb1f6152b
-R 32b396e0e85126b3386d72e2bc6e8e4c
-U larrybr
-Z f8d4366505c35a746a63af41266ec4f5
+P 3aedf818c1cfc88ee1103abd8b20e787f6be1bcc4c9350963f0cd52f5ac04154
+R d4d0d407c45719772ccdc3772a06a769
+U drh
+Z 2e9ac8f611b5ac99207230cf538d46c9
diff --git a/manifest.uuid b/manifest.uuid
index b9d2df6bb..283bb8a43 100644
--- a/manifest.uuid
+++ b/manifest.uuid
@@ -1 +1 @@
-3aedf818c1cfc88ee1103abd8b20e787f6be1bcc4c9350963f0cd52f5ac04154 \ No newline at end of file
+25c3186aa143328157fb506a29802e87099cd14be4fa218230484a3212f20621 \ No newline at end of file