/ Check-in [f8ca5622]
Login

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

Overview
Comment:When possible, use memcpy() to and from the mapped region instead of xWrite() and xRead().
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | experimental-mmap
Files: files | file ages | folders
SHA1: f8ca5622d99bedca957caa9ad311d798f63b3ce9
User & Date: dan 2013-03-16 20:19:21
Context
2013-03-19
19:28
Add the sqlite3_io_methods.xMremap() method to the VFS interface. Also "PRAGMA mmap_size". check-in: 6183f1bd user: dan tags: experimental-mmap
2013-03-16
20:19
When possible, use memcpy() to and from the mapped region instead of xWrite() and xRead(). check-in: f8ca5622 user: dan tags: experimental-mmap
2013-03-15
19:13
Fix a dropped error code in pager.c. check-in: 022fdc98 user: dan tags: experimental-mmap
Changes
Hide Diffs Side-by-Side Diffs Show Whitespace Changes Patch

Changes to src/pager.c.

  2861   2861   
  2862   2862     if( pagerUseWal(pPager) ){
  2863   2863       /* Try to pull the page from the write-ahead log. */
  2864   2864       rc = sqlite3WalRead(pPager->pWal, pgno, &isInWal, pgsz, pPg->pData);
  2865   2865     }
  2866   2866     if( rc==SQLITE_OK && !isInWal ){
  2867   2867       i64 iOffset = (pgno-1)*(i64)pPager->pageSize;
         2868  +    if( pPager->pMap && pPager->nMapValid>=iOffset+pPager->pageSize ){
         2869  +      memcpy(pPg->pData, &((u8 *)(pPager->pMap))[iOffset], pPager->pageSize);
         2870  +    }else{
  2868   2871       rc = sqlite3OsRead(pPager->fd, pPg->pData, pgsz, iOffset);
  2869   2872       if( rc==SQLITE_IOERR_SHORT_READ ){
  2870   2873         rc = SQLITE_OK;
  2871   2874       }
  2872   2875     }
         2876  +  }
  2873   2877   
  2874   2878     if( pgno==1 ){
  2875   2879       if( rc ){
  2876   2880         /* If the read is unsuccessful, set the dbFileVers[] to something
  2877   2881         ** that will never be a valid file version.  dbFileVers[] is a copy
  2878   2882         ** of bytes 24..39 of the database.  Bytes 28..31 should always be
  2879   2883         ** zero or the size of the database in page. Bytes 32..35 and 35..39
................................................................................
  3830   3834   static int pagerMap(Pager *pPager){
  3831   3835     int rc;
  3832   3836     i64 sz = 0;
  3833   3837   
  3834   3838     assert( pPager->pMap==0 && pPager->nMap==0 );
  3835   3839   
  3836   3840     rc = sqlite3OsFileSize(pPager->fd, &sz);
         3841  +  sz = sz & ~(4096-1);
         3842  +
  3837   3843     if( rc==SQLITE_OK && sz>0 ){
  3838   3844       int fd;
  3839   3845       rc = sqlite3OsFileControl(pPager->fd, SQLITE_FCNTL_GETFD, (void *)&fd);
  3840   3846       if( rc==SQLITE_OK ){
  3841         -      void *pMap = mmap(0, sz, PROT_READ, MAP_SHARED, fd, 0);
         3847  +      void *pMap = mmap(0, sz, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
  3842   3848         if( pMap==MAP_FAILED ){
  3843         -      assert( 0 );
         3849  +        return SQLITE_IOERR;
         3850  +      }
         3851  +      pPager->pMap = pMap;
         3852  +      pPager->nMapValid = pPager->nMap = sz;
         3853  +    }
         3854  +  }
         3855  +
         3856  +  return rc;
         3857  +}
         3858  +
         3859  +static int pagerRemap(Pager *pPager, Pgno nPage){
         3860  +  i64 sz = (i64)nPage * pPager->pageSize;
         3861  +  sz = sz & ~(4096-1);
         3862  +
         3863  +  if( pPager->nMap!=sz ){
         3864  +    void *pMap = mremap(pPager->pMap, pPager->nMap, sz, MREMAP_MAYMOVE);    
         3865  +    if( pMap==MAP_FAILED ){
  3844   3866           return SQLITE_IOERR;
  3845   3867         }
  3846   3868         pPager->pMap = pMap;
  3847   3869         pPager->nMapValid = pPager->nMap = sz;
  3848   3870       }
  3849         -  }
  3850   3871   
  3851         -  return rc;
         3872  +  return SQLITE_OK;
  3852   3873   }
  3853   3874   
  3854   3875   static int pagerAcquireMapPage(Pager *pPager, Pgno pgno, PgHdr **ppPage){
  3855   3876     int rc;
  3856   3877     *ppPage = 0;
  3857   3878   
  3858   3879     assert( pPager->pWal==0 );
................................................................................
  4221   4242         assert( (pList->flags&PGHDR_NEED_SYNC)==0 );
  4222   4243         if( pList->pgno==1 ) pager_write_changecounter(pList);
  4223   4244   
  4224   4245         /* Encode the database */
  4225   4246         CODEC2(pPager, pList->pData, pgno, 6, return SQLITE_NOMEM, pData);
  4226   4247   
  4227   4248         /* Write out the page data. */
         4249  +      if( pPager->nMapValid>=(offset+pPager->pageSize) ){
         4250  +        memcpy(&((u8 *)(pPager->pMap))[offset], pData, pPager->pageSize);
         4251  +      }else{
  4228   4252         rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset);
         4253  +      }
  4229   4254   
  4230   4255         /* If page 1 was just written, update Pager.dbFileVers to match
  4231   4256         ** the value now stored in the database file. If writing this 
  4232   4257         ** page caused the database file to grow, update dbFileSize. 
  4233   4258         */
  4234   4259         if( pgno==1 ){
  4235   4260           memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers));
................................................................................
  5085   5110           /* Unmap the database file. It is possible that external processes
  5086   5111           ** may have truncated the database file and then extended it back
  5087   5112           ** to its original size while this process was not holding a lock.
  5088   5113           ** In this case there may exist a Pager.pMap mapping that appears
  5089   5114           ** to be the right size but is not actually valid. Avoid this
  5090   5115           ** possibility by unmapping the db here. */
  5091   5116           pagerUnmap(pPager);
  5092         -      }else if( ((i64)nPage*pPager->pageSize)!=pPager->nMap ){
  5093         -        pagerUnmap(pPager);
         5117  +      }else if( pPager->pMap ){
         5118  +        pagerRemap(pPager, nPage);
  5094   5119         }
  5095   5120       }
  5096   5121   
  5097   5122       /* If there is a WAL file in the file-system, open this database in WAL
  5098   5123       ** mode. Otherwise, the following function call is a no-op.
  5099   5124       */
  5100   5125       rc = pagerOpenWalIfPresent(pPager);

Changes to src/test1.c.

  5839   5839         break;
  5840   5840       }
  5841   5841     }
  5842   5842   
  5843   5843     Tcl_ResetResult(interp);
  5844   5844     return TCL_OK;
  5845   5845   }
         5846  +
         5847  +#include <sys/time.h>
         5848  +#include <sys/resource.h>
         5849  +
         5850  +static int test_getrusage(
         5851  +  void * clientData,
         5852  +  Tcl_Interp *interp,
         5853  +  int objc,
         5854  +  Tcl_Obj *CONST objv[]
         5855  +){
         5856  +  char buf[1024];
         5857  +  struct rusage r;
         5858  +  memset(&r, 0, sizeof(r));
         5859  +  getrusage(RUSAGE_SELF, &r);
         5860  +
         5861  +  sprintf(buf, "ru_utime=%d.%06d ru_stime=%d.%06d ru_minflt=%d ru_majflt=%d", 
         5862  +    r.ru_utime.tv_sec, r.ru_utime.tv_usec, 
         5863  +    r.ru_stime.tv_sec, r.ru_stime.tv_usec, 
         5864  +    r.ru_minflt, r.ru_majflt
         5865  +  );
         5866  +  Tcl_SetObjResult(interp, Tcl_NewStringObj(buf, -1));
         5867  +  return TCL_OK;
         5868  +}
  5846   5869   
  5847   5870   #if SQLITE_OS_WIN
  5848   5871   /*
  5849   5872   ** Information passed from the main thread into the windows file locker
  5850   5873   ** background thread.
  5851   5874   */
  5852   5875   struct win32FileLocker {
................................................................................
  6229   6252        { "sqlite3_wal_checkpoint",   test_wal_checkpoint, 0  },
  6230   6253        { "sqlite3_wal_checkpoint_v2",test_wal_checkpoint_v2, 0  },
  6231   6254        { "test_sqlite3_log",         test_sqlite3_log, 0  },
  6232   6255   #ifndef SQLITE_OMIT_EXPLAIN
  6233   6256        { "print_explain_query_plan", test_print_eqp, 0  },
  6234   6257   #endif
  6235   6258        { "sqlite3_test_control", test_test_control },
         6259  +     { "getrusage", test_getrusage },
  6236   6260     };
  6237   6261     static int bitmask_size = sizeof(Bitmask)*8;
  6238   6262     int i;
  6239   6263     extern int sqlite3_sync_count, sqlite3_fullsync_count;
  6240   6264     extern int sqlite3_opentemp_count;
  6241   6265     extern int sqlite3_like_count;
  6242   6266     extern int sqlite3_xferopt_count;