From: danielk1977 Date: Fri, 17 Oct 2008 19:13:04 +0000 (+0000) Subject: Add the memjournal.c file that should have been with the previous checkin. (CVS 5831) X-Git-Tag: version-3.6.10~346 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=39281b4b42774cf5c678bfe4a3ee11684526cebb;p=thirdparty%2Fsqlite.git Add the memjournal.c file that should have been with the previous checkin. (CVS 5831) FossilOrigin-Name: 0509eff0e6b5cdeeb52c12c0574ea63e9715bcb5 --- diff --git a/manifest b/manifest index 860104d4eb..96c11a4a92 100644 --- a/manifest +++ b/manifest @@ -1,5 +1,5 @@ -C Add\s"pragma\sjournal_mode=memory".\sChange\sthe\sway\srollback\sworks\sfor\sin-memory\sdatabases\sso\sthat\sit\sreuses\sthe\sjournal_mode=memory\scode.\s(CVS\s5830) -D 2008-10-17T18:51:52 +C Add\sthe\smemjournal.c\sfile\sthat\sshould\shave\sbeen\swith\sthe\sprevious\scheckin.\s(CVS\s5831) +D 2008-10-17T19:13:05 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0 F Makefile.in 2014e5a4010ad5ebbcaedff98240b3d14ee83838 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654 @@ -126,6 +126,7 @@ F src/mem3.c 1594f117fde4cf11a6c16521f3f30af8d04bbe68 F src/mem4.c 6703adb1717b26d9d70a1c2586b4b7b7ffee7909 F src/mem5.c 706d462c13a9819dfec7c10d9dccedf8d199960c F src/mem6.c febe4db9ddef73df500989e68a9d4ac68602a075 +F src/memjournal.c b12b20d3441945e590b8dacdc6705d39e02ab33c F src/mutex.c e9cb5fbe94afb4328869afaf3ac49bd1327559eb F src/mutex.h 9e686e83a88838dac8b9c51271c651e833060f1e F src/mutex_noop.c 0004efdbc2fd48d261d5b3416fe537e888c79a54 @@ -648,7 +649,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e -P 5ce2ddffea807d45318619cc9e259a99dfa14346 -R d3d208ea9f507cd99d0a55a9424ad33c +P 39ebf01addf9d0867daafd06a38719e725128f9c +R 1d4a997aeee082e5905b4c1b06561039 U danielk1977 -Z e1e732a777069a84074d19c41d686a93 +Z 721a63141a485df7fdb37e6807d4ec32 diff --git a/manifest.uuid b/manifest.uuid index 48f94588a2..635df36462 100644 --- a/manifest.uuid +++ b/manifest.uuid @@ -1 +1 @@ -39ebf01addf9d0867daafd06a38719e725128f9c \ No newline at end of file +0509eff0e6b5cdeeb52c12c0574ea63e9715bcb5 \ No newline at end of file diff --git a/src/memjournal.c b/src/memjournal.c new file mode 100644 index 0000000000..f8e7d49bef --- /dev/null +++ b/src/memjournal.c @@ -0,0 +1,223 @@ +/* +** 2007 August 22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** @(#) $Id: memjournal.c,v 1.1 2008/10/17 19:13:05 danielk1977 Exp $ +*/ + + +#include "sqliteInt.h" + +typedef struct MemJournal MemJournal; +typedef struct FilePoint FilePoint; +typedef struct FileChunk FileChunk; + +#define JOURNAL_CHUNKSIZE 1024 + +#define MIN(x,y) ((x)<(y)?(x):(y)) + +struct FileChunk { + FileChunk *pNext; + u8 zChunk[JOURNAL_CHUNKSIZE]; +}; + +struct FilePoint { + sqlite3_int64 iOffset; + FileChunk *pChunk; +}; + +struct MemJournal { + sqlite3_io_methods *pMethod; /* I/O methods on journal files */ + FileChunk *pFirst; /* Head of in-memory chunk-list */ + FilePoint endpoint; /* Pointer to the end of the file */ + FilePoint readpoint; /* Pointer to the end of the last xRead() */ +}; + +/* +** Read data from the file. +*/ +static int memjrnlRead( + sqlite3_file *pJfd, /* The journal file from which to read */ + void *zBuf, /* Put the results here */ + int iAmt, /* Number of bytes to read */ + sqlite_int64 iOfst /* Begin reading at this offset */ +){ + MemJournal *p = (MemJournal *)pJfd; + u8 *zOut = zBuf; + int nRead = iAmt; + int iChunkOffset; + FileChunk *pChunk; + + assert( iOfst+iAmt<=p->endpoint.iOffset ); + + if( p->readpoint.iOffset!=iOfst || iOfst==0 ){ + sqlite3_int64 iOff = 0; + for(pChunk=p->pFirst; + pChunk && (iOff+JOURNAL_CHUNKSIZE)<=iOfst; + pChunk=pChunk->pNext + ){ + iOff += JOURNAL_CHUNKSIZE; + } + }else{ + pChunk = p->readpoint.pChunk; + } + + iChunkOffset = (iOfst%JOURNAL_CHUNKSIZE); + do { + int iSpace = JOURNAL_CHUNKSIZE - iChunkOffset; + int nCopy = MIN(nRead, (JOURNAL_CHUNKSIZE - iChunkOffset)); + memcpy(zOut, &pChunk->zChunk[iChunkOffset], nCopy); + zOut += nCopy; + nRead -= iSpace; + iChunkOffset = 0; + } while( nRead>=0 && (pChunk=pChunk->pNext) && nRead>0 ); + p->readpoint.iOffset = iOfst+iAmt; + p->readpoint.pChunk = pChunk; + + return SQLITE_OK; +} + +/* +** Write data to the file. +*/ +static int memjrnlWrite( + sqlite3_file *pJfd, /* The journal file into which to write */ + const void *zBuf, /* Take data to be written from here */ + int iAmt, /* Number of bytes to write */ + sqlite_int64 iOfst /* Begin writing at this offset into the file */ +){ + MemJournal *p = (MemJournal *)pJfd; + int nWrite = iAmt; + u8 *zWrite = (u8 *)zBuf; + + /* An in-memory journal file should only ever be appended to. Random + ** access writes are not required by sqlite. + */ + assert(iOfst==p->endpoint.iOffset); + + while( nWrite>0 ){ + FileChunk *pChunk = p->endpoint.pChunk; + int iChunkOffset = p->endpoint.iOffset%JOURNAL_CHUNKSIZE; + int iSpace = MIN(nWrite, JOURNAL_CHUNKSIZE - iChunkOffset); + + if( iChunkOffset==0 ){ + /* New chunk is required to extend the file. */ + FileChunk *pNew = sqlite3_malloc(sizeof(FileChunk)); + if( !pNew ){ + return SQLITE_IOERR_NOMEM; + } + pNew->pNext = 0; + if( pChunk ){ + assert( p->pFirst ); + pChunk->pNext = pNew; + }else{ + assert( !p->pFirst ); + p->pFirst = pNew; + } + p->endpoint.pChunk = pNew; + } + + memcpy(&p->endpoint.pChunk->zChunk[iChunkOffset], zWrite, iSpace); + zWrite += iSpace; + nWrite -= iSpace; + p->endpoint.iOffset += iSpace; + } + + return SQLITE_OK; +} + +/* +** Truncate the file. +*/ +static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){ + MemJournal *p = (MemJournal *)pJfd; + FileChunk *pChunk; + assert(size==0); + pChunk = p->pFirst; + while( pChunk ){ + FileChunk *pTmp = pChunk; + pChunk = pChunk->pNext; + sqlite3_free(pTmp); + } + sqlite3MemJournalOpen(pJfd); + return SQLITE_OK; +} + +/* +** Close the file. +*/ +static int memjrnlClose(sqlite3_file *pJfd){ + memjrnlTruncate(pJfd, 0); + return SQLITE_OK; +} + + +/* +** Sync the file. +*/ +static int memjrnlSync(sqlite3_file *pJfd, int flags){ + return SQLITE_OK; +} + +/* +** Query the size of the file in bytes. +*/ +static int memjrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){ + MemJournal *p = (MemJournal *)pJfd; + *pSize = (sqlite_int64) p->endpoint.iOffset; + return SQLITE_OK; +} + +/* +** Table of methods for MemJournal sqlite3_file object. +*/ +static struct sqlite3_io_methods MemJournalMethods = { + 1, /* iVersion */ + memjrnlClose, /* xClose */ + memjrnlRead, /* xRead */ + memjrnlWrite, /* xWrite */ + memjrnlTruncate, /* xTruncate */ + memjrnlSync, /* xSync */ + memjrnlFileSize, /* xFileSize */ + 0, /* xLock */ + 0, /* xUnlock */ + 0, /* xCheckReservedLock */ + 0, /* xFileControl */ + 0, /* xSectorSize */ + 0 /* xDeviceCharacteristics */ +}; + +/* +** Open a journal file. +*/ +void sqlite3MemJournalOpen(sqlite3_file *pJfd){ + MemJournal *p = (MemJournal *)pJfd; + memset(p, 0, sqlite3MemJournalSize()); + p->pMethod = &MemJournalMethods; +} + +/* +** Return true if the file-handle passed as an argument is +** an in-memory journal +*/ +int sqlite3IsMemJournal(sqlite3_file *pJfd){ + return pJfd->pMethods==&MemJournalMethods; +} + +/* +** Return the number of bytes required to store a MemJournal that uses vfs +** pVfs to create the underlying on-disk files. +*/ +int sqlite3MemJournalSize(){ + return sizeof(MemJournal); +} + +