/ Check-in [d99ac415]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Modify the memjournal.c code to make it a bit smaller.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | memjournal-exp
Files: files | file ages | folders
SHA1: d99ac4154812065eef26c298de52954d7ee0bd75
User & Date: dan 2016-03-08 17:44:08
Context
2016-03-08
17:59
In memjournal.c, reuse the same sqlite3_file object for both the in-memory phase and the on-disk phase. check-in: e7fbbdc2 user: drh tags: trunk
17:44
Modify the memjournal.c code to make it a bit smaller. Closed-Leaf check-in: d99ac415 user: dan tags: memjournal-exp
15:52
Add a new row type to RBU (a peer of insert, update and delete) - "delete then insert". check-in: 1d9468d2 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to src/memjournal.c.

    65     65     FileChunk *pFirst;              /* Head of in-memory chunk-list */
    66     66     FilePoint endpoint;             /* Pointer to the end of the file */
    67     67     FilePoint readpoint;            /* Pointer to the end of the last xRead() */
    68     68   
    69     69     int flags;                      /* xOpen flags */
    70     70     sqlite3_vfs *pVfs;              /* The "real" underlying VFS */
    71     71     const char *zJournal;           /* Name of the journal file */
    72         -  sqlite3_file *pReal;            /* The "real" underlying file descriptor */
    73     72   };
    74     73   
    75     74   /*
    76     75   ** Read data from the in-memory journal file.  This is the implementation
    77     76   ** of the sqlite3_vfs.xRead method.
    78     77   */
    79     78   static int memjrnlRead(
    80     79     sqlite3_file *pJfd,    /* The journal file from which to read */
    81     80     void *zBuf,            /* Put the results here */
    82     81     int iAmt,              /* Number of bytes to read */
    83     82     sqlite_int64 iOfst     /* Begin reading at this offset */
    84     83   ){
    85     84     MemJournal *p = (MemJournal *)pJfd;
    86         -  if( p->pReal ){
    87         -    return sqlite3OsRead(p->pReal, zBuf, iAmt, iOfst);
    88         -  }else if( (iAmt+iOfst)>p->endpoint.iOffset ){
           85  +  if( (iAmt+iOfst)>p->endpoint.iOffset ){
    89     86       return SQLITE_IOERR_SHORT_READ;
    90     87     }else{
    91     88       u8 *zOut = zBuf;
    92     89       int nRead = iAmt;
    93     90       int iChunkOffset;
    94     91       FileChunk *pChunk;
    95     92   
................................................................................
   134    131     p->pFirst = 0;
   135    132   }
   136    133   
   137    134   /*
   138    135   ** Flush the contents of memory to a real file on disk.
   139    136   */
   140    137   static int memjrnlCreateFile(MemJournal *p){
   141         -  int rc = SQLITE_OK;
   142         -  if( !p->pReal ){
   143         -    sqlite3_file *pReal = (sqlite3_file *)&p[1];
   144         -    rc = sqlite3OsOpen(p->pVfs, p->zJournal, pReal, p->flags, 0);
   145         -    if( rc==SQLITE_OK ){
   146         -      int nChunk = p->nChunkSize;
   147         -      i64 iOff = 0;
   148         -      FileChunk *pIter;
   149         -      p->pReal = pReal;
   150         -      for(pIter=p->pFirst; pIter && rc==SQLITE_OK; pIter=pIter->pNext){
   151         -        int nWrite = nChunk;
   152         -        if( pIter==p->endpoint.pChunk ){
   153         -          nWrite = p->endpoint.iOffset % p->nChunkSize;
   154         -          if( nWrite==0 ) nWrite = p->nChunkSize;
   155         -        }
   156         -        rc = sqlite3OsWrite(pReal, (u8*)pIter->zChunk, nWrite, iOff);
   157         -        iOff += nWrite;
          138  +  int rc;
          139  +  sqlite3_file *pReal = (sqlite3_file*)p;
          140  +  MemJournal copy = *p;
          141  +
          142  +  memset(p, 0, sizeof(MemJournal));
          143  +  rc = sqlite3OsOpen(copy.pVfs, copy.zJournal, pReal, copy.flags, 0);
          144  +  if( rc==SQLITE_OK ){
          145  +    int nChunk = copy.nChunkSize;
          146  +    i64 iOff = 0;
          147  +    FileChunk *pIter;
          148  +    for(pIter=copy.pFirst; pIter && rc==SQLITE_OK; pIter=pIter->pNext){
          149  +      int nWrite = nChunk;
          150  +      if( pIter==copy.endpoint.pChunk ){
          151  +        nWrite = copy.endpoint.iOffset % copy.nChunkSize;
          152  +        if( nWrite==0 ) nWrite = copy.nChunkSize;
   158    153         }
   159         -      if( rc!=SQLITE_OK ){
   160         -        /* If an error occurred while writing to the file, close it before
   161         -        ** returning. This way, SQLite uses the in-memory journal data to 
   162         -        ** roll back changes made to the internal page-cache before this
   163         -        ** function was called.  */
   164         -        sqlite3OsClose(pReal);
   165         -        p->pReal = 0;
   166         -      }else{
   167         -        /* No error has occurred. Free the in-memory buffers. */
   168         -        memjrnlFreeChunks(p);
   169         -      }
          154  +      rc = sqlite3OsWrite(pReal, (u8*)pIter->zChunk, nWrite, iOff);
          155  +      iOff += nWrite;
          156  +    }
          157  +    if( rc==SQLITE_OK ){
          158  +      /* No error has occurred. Free the in-memory buffers. */
          159  +      memjrnlFreeChunks(&copy);
   170    160       }
          161  +  }
          162  +  if( rc!=SQLITE_OK ){
          163  +    /* If an error occurred while creating or writing to the file, restore
          164  +    ** the original before returning. This way, SQLite uses the in-memory
          165  +    ** journal data to roll back changes made to the internal page-cache
          166  +    ** before this function was called.  */
          167  +    sqlite3OsClose(pReal);
          168  +    *p = copy;
   171    169     }
   172    170     return rc;
   173    171   }
   174    172   
   175    173   
   176    174   /*
   177    175   ** Write data to the file.
................................................................................
   182    180     int iAmt,              /* Number of bytes to write */
   183    181     sqlite_int64 iOfst     /* Begin writing at this offset into the file */
   184    182   ){
   185    183     MemJournal *p = (MemJournal *)pJfd;
   186    184     int nWrite = iAmt;
   187    185     u8 *zWrite = (u8 *)zBuf;
   188    186   
   189         -  /* If the file has already been created on disk. */
   190         -  if( p->pReal ){
   191         -    return sqlite3OsWrite(p->pReal, zBuf, iAmt, iOfst);
   192         -  }
   193         -
   194         -  /* If the file should be created now. */
   195         -  else if( p->nSpill>0 && (iAmt+iOfst)>p->nSpill ){
          187  +  /* If the file should be created now, create it and write the new data
          188  +  ** into the file on disk. */
          189  +  if( p->nSpill>0 && (iAmt+iOfst)>p->nSpill ){
   196    190       int rc = memjrnlCreateFile(p);
   197    191       if( rc==SQLITE_OK ){
   198         -      rc = memjrnlWrite(pJfd, zBuf, iAmt, iOfst);
          192  +      rc = sqlite3OsWrite(pJfd, zBuf, iAmt, iOfst);
   199    193       }
   200    194       return rc;
   201    195     }
   202    196   
   203    197     /* If the contents of this write should be stored in memory */
   204    198     else{
   205    199       /* An in-memory journal file should only ever be appended to. Random
................................................................................
   251    245   **
   252    246   ** If the journal file is already on disk, truncate it there. Or, if it
   253    247   ** is still in main memory but is being truncated to zero bytes in size,
   254    248   ** ignore 
   255    249   */
   256    250   static int memjrnlTruncate(sqlite3_file *pJfd, sqlite_int64 size){
   257    251     MemJournal *p = (MemJournal *)pJfd;
   258         -  if( p->pReal ){
   259         -    return sqlite3OsTruncate(p->pReal, size);
   260         -  }else if( size==0 ){
          252  +  if( size==0 ){
   261    253       memjrnlFreeChunks(p);
   262    254       p->nSize = 0;
   263    255       p->endpoint.pChunk = 0;
   264    256       p->endpoint.iOffset = 0;
   265    257       p->readpoint.pChunk = 0;
   266    258       p->readpoint.iOffset = 0;
   267    259     }
................................................................................
   270    262   
   271    263   /*
   272    264   ** Close the file.
   273    265   */
   274    266   static int memjrnlClose(sqlite3_file *pJfd){
   275    267     MemJournal *p = (MemJournal *)pJfd;
   276    268     memjrnlFreeChunks(p);
   277         -  if( p->pReal ) sqlite3OsClose(p->pReal);
   278    269     return SQLITE_OK;
   279    270   }
   280    271   
   281    272   /*
   282    273   ** Sync the file.
   283    274   **
   284    275   ** If the real file has been created, call its xSync method. Otherwise, 
   285    276   ** syncing an in-memory journal is a no-op. 
   286    277   */
   287    278   static int memjrnlSync(sqlite3_file *pJfd, int flags){
   288         -  MemJournal *p = (MemJournal *)pJfd;
   289         -  if( p->pReal ){
   290         -    return sqlite3OsSync(p->pReal, flags);
   291         -  }
          279  +  UNUSED_PARAMETER2(pJfd, flags);
   292    280     return SQLITE_OK;
   293    281   }
   294    282   
   295    283   /*
   296    284   ** Query the size of the file in bytes.
   297    285   */
   298    286   static int memjrnlFileSize(sqlite3_file *pJfd, sqlite_int64 *pSize){
   299    287     MemJournal *p = (MemJournal *)pJfd;
   300         -  if( p->pReal ){
   301         -    return sqlite3OsFileSize(p->pReal, pSize);
   302         -  }
   303    288     *pSize = (sqlite_int64) p->endpoint.iOffset;
   304    289     return SQLITE_OK;
   305    290   }
   306    291   
   307    292   /*
   308    293   ** Table of methods for MemJournal sqlite3_file object.
   309    294   */
................................................................................
   350    335   ){
   351    336     MemJournal *p = (MemJournal*)pJfd;
   352    337   
   353    338     /* Zero the file-handle object. If nSpill was passed zero, initialize
   354    339     ** it using the sqlite3OsOpen() function of the underlying VFS. In this
   355    340     ** case none of the code in this module is executed as a result of calls
   356    341     ** made on the journal file-handle.  */
   357         -  memset(p, 0, sizeof(MemJournal) + (pVfs ? pVfs->szOsFile : 0));
          342  +  memset(p, 0, sizeof(MemJournal));
   358    343     if( nSpill==0 ){
   359    344       return sqlite3OsOpen(pVfs, zName, pJfd, flags, 0);
   360    345     }
   361    346   
   362    347     if( nSpill>0 ){
   363    348       p->nChunkSize = nSpill;
   364    349     }else{
................................................................................
   399    384   
   400    385   /*
   401    386   ** The file-handle passed as the only argument is open on a journal file.
   402    387   ** Return true if this "journal file" is currently stored in heap memory,
   403    388   ** or false otherwise.
   404    389   */
   405    390   int sqlite3JournalIsInMemory(sqlite3_file *p){
   406         -  return p->pMethods==&MemJournalMethods && ((MemJournal*)p)->pReal==0;
          391  +  return p->pMethods==&MemJournalMethods;
   407    392   }
   408    393   
   409    394   /* 
   410    395   ** Return the number of bytes required to store a JournalFile that uses vfs
   411    396   ** pVfs to create the underlying on-disk files.
   412    397   */
   413    398   int sqlite3JournalSize(sqlite3_vfs *pVfs){
   414         -  return pVfs->szOsFile + sizeof(MemJournal);
          399  +  return MAX(pVfs->szOsFile, sizeof(MemJournal));
   415    400   }