SQLite4
Check-in [89e314d98b]
Not logged in

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

Overview
Comment:Fix lsm_checkpoint() and some lsm_info() calls to match documented behaviour.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 89e314d98b0f7e06ce3b5e779bed67cd32d91761
User & Date: dan 2013-02-05 18:32:16
Context
2013-02-06
11:58
Fix bug to do with block redirection. check-in: 7cc153f523 user: dan tags: trunk
2013-02-05
18:32
Fix lsm_checkpoint() and some lsm_info() calls to match documented behaviour. check-in: 89e314d98b user: dan tags: trunk
18:06
Fixes to lsm_work() to bring it into line with documentation: (a) third argument is a number of KB, not a number of db pages, and (b) passing -1 as the third argument means "do as much work as possible". check-in: 2f8966cd9c user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to lsm-test/lsmtest_tdb3.c.

    11     11   
    12     12   #include <sys/time.h>
    13     13   
    14     14   typedef struct LsmDb LsmDb;
    15     15   typedef struct LsmWorker LsmWorker;
    16     16   typedef struct LsmFile LsmFile;
    17     17   
    18         -#define LSMTEST_DFLT_MT_MAX_CKPT (8*1024*1024)
    19         -#define LSMTEST_DFLT_MT_MIN_CKPT (2*1024*1024)
           18  +#define LSMTEST_DFLT_MT_MAX_CKPT (8*1024)
           19  +#define LSMTEST_DFLT_MT_MIN_CKPT (2*1024)
    20     20   
    21     21   #ifdef LSM_MUTEX_PTHREADS
    22     22   #include <pthread.h>
    23     23   
    24     24   #define LSMTEST_THREAD_CKPT      1
    25     25   #define LSMTEST_THREAD_WORKER    2
    26     26   #define LSMTEST_THREAD_WORKER_AC 3
................................................................................
   496    496     testFree((char *)pDb->pBuf);
   497    497     testFree((char *)pDb);
   498    498     return rc;
   499    499   }
   500    500   
   501    501   static int waitOnCheckpointer(LsmDb *pDb, lsm_db *db){
   502    502     int nSleep = 0;
   503         -  int nByte;
          503  +  int nKB;
   504    504     int rc;
   505    505   
   506    506     do {
   507         -    nByte = 0;
   508         -    rc = lsm_info(db, LSM_INFO_CHECKPOINT_SIZE, &nByte);
   509         -    if( rc!=LSM_OK || nByte<pDb->nMtMaxCkpt ) break;
          507  +    nKB = 0;
          508  +    rc = lsm_info(db, LSM_INFO_CHECKPOINT_SIZE, &nKB);
          509  +    if( rc!=LSM_OK || nKB<pDb->nMtMaxCkpt ) break;
   510    510       usleep(5000);
   511    511       nSleep += 5;
   512    512     }while( 1 );
   513    513   
   514    514   #if 0
   515    515       if( nSleep ) printf("# waitOnCheckpointer(): nSleep=%d\n", nSleep);
   516    516   #endif
................................................................................
   521    521   static int waitOnWorker(LsmDb *pDb){
   522    522     int rc;
   523    523     int nLimit = -1;
   524    524     int nSleep = 0;
   525    525   
   526    526     rc = lsm_config(pDb->db, LSM_CONFIG_AUTOFLUSH, &nLimit);
   527    527     do {
   528         -    int bOld, nNew, rc;
   529         -    rc = lsm_info(pDb->db, LSM_INFO_TREE_SIZE, &bOld, &nNew);
          528  +    int nOld, nNew, rc;
          529  +    rc = lsm_info(pDb->db, LSM_INFO_TREE_SIZE, &nOld, &nNew);
   530    530       if( rc!=LSM_OK ) return rc;
   531         -    if( bOld==0 || nNew<(nLimit/2) ) break;
          531  +    if( nOld==0 || nNew<(nLimit/2) ) break;
   532    532       usleep(5000);
   533    533       nSleep += 5;
   534    534     }while( 1 );
   535    535   
   536    536   #if 0
   537    537     if( nSleep ) printf("# waitOnWorker(): nSleep=%d\n", nSleep);
   538    538   #endif
................................................................................
  1118   1118       int rc = LSM_OK;
  1119   1119       int nCkpt = -1;
  1120   1120   
  1121   1121       /* Do some work. If an error occurs, exit. */
  1122   1122   
  1123   1123       pthread_mutex_unlock(&p->worker_mutex);
  1124   1124       if( p->eType==LSMTEST_THREAD_CKPT ){
  1125         -      int nByte = 0;
  1126         -      rc = lsm_info(pWorker, LSM_INFO_CHECKPOINT_SIZE, &nByte);
  1127         -      if( rc==LSM_OK && nByte>=p->pDb->nMtMinCkpt ){
         1125  +      int nKB = 0;
         1126  +      rc = lsm_info(pWorker, LSM_INFO_CHECKPOINT_SIZE, &nKB);
         1127  +      if( rc==LSM_OK && nKB>=p->pDb->nMtMinCkpt ){
  1128   1128           rc = lsm_checkpoint(pWorker, 0);
  1129   1129         }
  1130   1130       }else{
  1131   1131         int nWrite;
  1132   1132         do {
  1133   1133   
  1134   1134           if( p->eType==LSMTEST_THREAD_WORKER ){

Changes to src/lsm.h.

   392    392   **
   393    393   **   The Tcl structure returned is a list containing one element for each
   394    394   **   free block in the database. The element itself consists of two 
   395    395   **   integers - the block number and the id of the snapshot that freed it.
   396    396   **
   397    397   ** LSM_INFO_CHECKPOINT_SIZE:
   398    398   **   The third argument should be of type (int *). The location pointed to
   399         -**   by this argument is populated with the number of bytes written to the
          399  +**   by this argument is populated with the number of KB written to the
   400    400   **   database file since the most recent checkpoint.
   401    401   **
   402    402   ** LSM_INFO_TREE_SIZE:
   403    403   **   If this value is passed as the second argument to an lsm_info() call, it
   404    404   **   should be followed by two arguments of type (int *) (for a total of four
   405    405   **   arguments).
   406    406   **
................................................................................
   409    409   **   tree structures being used by older clients - this API does not provide
   410    410   **   information on them). One tree structure - the current tree - is used to
   411    411   **   accumulate new data written to the database. The other tree structure -
   412    412   **   the old tree - is a read-only tree holding older data and may be flushed 
   413    413   **   to disk at any time.
   414    414   ** 
   415    415   **   Assuming no error occurs, the location pointed to by the first of the two
   416         -**   (int *) arguments is set to the size of the old in-memory tree in bytes.
          416  +**   (int *) arguments is set to the size of the old in-memory tree in KB.
   417    417   **   The second is set to the size of the current, or live in-memory tree.
   418    418   */
   419    419   #define LSM_INFO_NWRITE           1
   420    420   #define LSM_INFO_NREAD            2
   421    421   #define LSM_INFO_DB_STRUCTURE     3
   422    422   #define LSM_INFO_LOG_STRUCTURE    4
   423    423   #define LSM_INFO_ARRAY_STRUCTURE  5
................................................................................
   496    496   int lsm_flush(lsm_db *pDb);
   497    497   
   498    498   /*
   499    499   ** Attempt to checkpoint the current database snapshot. Return an LSM
   500    500   ** error code if an error occurs or LSM_OK otherwise.
   501    501   **
   502    502   ** If the current snapshot has already been checkpointed, calling this 
   503         -** function is a no-op. In this case if pnByte is not NULL, *pnByte is
          503  +** function is a no-op. In this case if pnKB is not NULL, *pnKB is
   504    504   ** set to 0. Or, if the current snapshot is successfully checkpointed
   505         -** by this function and pbCkpt is not NULL, *pnByte is set to the number
          505  +** by this function and pbKB is not NULL, *pnKB is set to the number
   506    506   ** of bytes written to the database file since the previous checkpoint
   507    507   ** (the same measure as returned by the LSM_INFO_CHECKPOINT_SIZE query).
   508    508   */
   509         -int lsm_checkpoint(lsm_db *pDb, int *pnByte);
          509  +int lsm_checkpoint(lsm_db *pDb, int *pnKB);
   510    510   
   511    511   /*
   512    512   ** CAPI: Opening and Closing Database Cursors
   513    513   **
   514    514   ** Open and close a database cursor.
   515    515   */
   516    516   int lsm_csr_open(lsm_db *pDb, lsm_cursor **ppCsr);

Changes to src/lsm_ckpt.c.

  1182   1182         &pDb->aSnapshot[nCkpt-2], &pDb->aSnapshot[nCkpt-1]
  1183   1183     );
  1184   1184   
  1185   1185     memcpy(pDb->pShmhdr->aSnap1, pDb->aSnapshot, nCkpt*sizeof(u32));
  1186   1186     memcpy(pDb->pShmhdr->aSnap2, pDb->aSnapshot, nCkpt*sizeof(u32));
  1187   1187   }
  1188   1188   
  1189         -int lsmCheckpointSize(lsm_db *db, int *pnByte){
         1189  +/*
         1190  +** Set the output variable to the number of KB of data written into the
         1191  +** database file since the most recent checkpoint.
         1192  +*/
         1193  +int lsmCheckpointSize(lsm_db *db, int *pnKB){
  1190   1194     ShmHeader *pShm = db->pShmhdr;
  1191   1195     int rc = LSM_OK;
  1192   1196     u32 nSynced;
  1193   1197   
         1198  +  /* Set nSynced to the number of pages that had been written when the 
         1199  +  ** database was last checkpointed. */
  1194   1200     rc = lsmCheckpointSynced(db, 0, 0, &nSynced);
         1201  +
  1195   1202     if( rc==LSM_OK ){
  1196   1203       u32 nPgsz = db->pShmhdr->aSnap1[CKPT_HDR_PGSZ];
  1197   1204       u32 nWrite = db->pShmhdr->aSnap1[CKPT_HDR_NWRITE];
  1198         -    *pnByte = (int)((nWrite - nSynced) * nPgsz);
         1205  +    *pnKB = (int)(( ((i64)(nWrite - nSynced) * nPgsz) + 1023) / 1024);
  1199   1206     }
  1200   1207   
  1201   1208     return rc;
  1202   1209   }
  1203   1210   

Changes to src/lsm_main.c.

   451    451     infoFreeWorker(pDb, bUnlock);
   452    452     return rc;
   453    453   }
   454    454   
   455    455   static int infoFreelistSize(lsm_db *pDb, int *pnFree, int *pnWaiting){
   456    456   }
   457    457   
   458         -static int infoTreeSize(lsm_db *db, int *pnOld, int *pnNew){
          458  +static int infoTreeSize(lsm_db *db, int *pnOldKB, int *pnNewKB){
   459    459     ShmHeader *pShm = db->pShmhdr;
   460    460     TreeHeader *p = &pShm->hdr1;
   461    461   
   462    462     /* The following code suffers from two race conditions, as it accesses and
   463    463     ** trusts the contents of shared memory without verifying checksums:
   464    464     **
   465    465     **   * The two values read - TreeHeader.root.nByte and oldroot.nByte - are 
................................................................................
   474    474     **     for the size of the "old" tree may reflect the size of an "old"
   475    475     **     tree that was recently flushed to disk.
   476    476     **
   477    477     ** Given the context in which this function is called (as a result of an
   478    478     ** lsm_info(LSM_INFO_TREE_SIZE) request), neither of these are considered to
   479    479     ** be problems.
   480    480     */
   481         -  *pnNew = (int)p->root.nByte;
          481  +  *pnNewKB = ((int)p->root.nByte + 1023) / 1024;
   482    482     if( p->iOldShmid ){
   483    483       if( p->iOldLog==lsmCheckpointLogOffset(pShm->aSnap1) ){
   484         -      *pnOld = 0;
          484  +      *pnOldKB = 0;
   485    485       }else{
   486         -      *pnOld = (int)p->oldroot.nByte;
          486  +      *pnOldKB = ((int)p->oldroot.nByte + 1023) / 1024;
   487    487       }
   488    488     }else{
   489         -    *pnOld = 0;
          489  +    *pnOldKB = 0;
   490    490     }
   491    491   
   492    492     return LSM_OK;
   493    493   }
   494    494   
   495    495   int lsm_info(lsm_db *pDb, int eParam, ...){
   496    496     int rc = LSM_OK;
................................................................................
   553    553       case LSM_INFO_FREELIST: {
   554    554         char **pzVal = va_arg(ap, char **);
   555    555         rc = lsmInfoFreelist(pDb, pzVal);
   556    556         break;
   557    557       }
   558    558   
   559    559       case LSM_INFO_CHECKPOINT_SIZE: {
   560         -      int *pnByte = va_arg(ap, int *);
   561         -      rc = lsmCheckpointSize(pDb, pnByte);
          560  +      int *pnKB = va_arg(ap, int *);
          561  +      rc = lsmCheckpointSize(pDb, pnKB);
   562    562         break;
   563    563       }
   564    564   
   565    565       case LSM_INFO_TREE_SIZE: {
   566    566         int *pnOld = va_arg(ap, int *);
   567    567         int *pnNew = va_arg(ap, int *);
   568    568         rc = infoTreeSize(pDb, pnOld, pnNew);

Changes to src/lsm_shared.c.

  1580   1580   }
  1581   1581   #endif
  1582   1582   
  1583   1583   void lsmShmBarrier(lsm_db *db){
  1584   1584     lsmEnvShmBarrier(db->pEnv);
  1585   1585   }
  1586   1586   
  1587         -int lsm_checkpoint(lsm_db *pDb, int *pnByte){
         1587  +int lsm_checkpoint(lsm_db *pDb, int *pnKB){
  1588   1588     int rc;                         /* Return code */
  1589   1589     u32 nWrite = 0;                 /* Number of pages checkpointed */
  1590   1590   
  1591   1591     /* Attempt the checkpoint. If successful, nWrite is set to the number of
  1592   1592     ** pages written between this and the previous checkpoint.  */
  1593   1593     rc = lsmCheckpointWrite(pDb, 0, &nWrite);
  1594   1594   
  1595         -  /* If required, calculate the output variable (bytes of data checkpointed). 
         1595  +  /* If required, calculate the output variable (KB of data checkpointed). 
  1596   1596     ** Set it to zero if an error occured.  */
  1597         -  if( pnByte ){
  1598         -    int nByte = 0;
         1597  +  if( pnKB ){
         1598  +    int nKB = 0;
  1599   1599       if( rc==LSM_OK && nWrite ){
  1600         -      nByte = (int)nWrite * lsmFsPageSize(pDb->pFS);
         1600  +      nKB = (((i64)nWrite * lsmFsPageSize(pDb->pFS)) + 1023) / 1024;
  1601   1601       }
  1602         -    *pnByte = nByte;
         1602  +    *pnKB = nKB;
  1603   1603     }
  1604   1604   
  1605   1605     return rc;
  1606   1606   }
  1607   1607