/ Check-in [30bf38d5]
Login
SQLite training in Houston TX on 2019-11-05 (details)
Part of the 2019 Tcl Conference

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

Overview
Comment:Change some LSM code internal typenames from "Blob" and "Pgno" to "LsmBlob" and "LsmPgno". This allows the LSM code to be compiled as a single unit with sqlite3.c.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 30bf38d589adf0b2eb613e184ffb03ed7e625736cb04fd5c341328f72bc5ef4d
User & Date: dan 2017-12-13 15:32:33
Context
2017-12-13
18:01
Correctly invalidate a column cache line when it is overwritten with NULL. Fix for ticket [123c9ba32130a6c9d432]. check-in: 65754dc3 user: drh tags: trunk
15:32
Change some LSM code internal typenames from "Blob" and "Pgno" to "LsmBlob" and "LsmPgno". This allows the LSM code to be compiled as a single unit with sqlite3.c. check-in: 30bf38d5 user: dan tags: trunk
14:22
Add script to amalgamate all LSM files into "lsm1.c". check-in: e32b69d7 user: dan tags: trunk
Changes
Hide Diffs Side-by-Side Diffs Ignore Whitespace Patch

Changes to ext/lsm1/lsmInt.h.

   106    106   typedef unsigned short int u16;
   107    107   typedef unsigned int u32;
   108    108   typedef lsm_i64 i64;
   109    109   typedef unsigned long long int u64;
   110    110   #endif
   111    111   
   112    112   /* A page number is a 64-bit integer. */
   113         -typedef i64 Pgno;
          113  +typedef i64 LsmPgno;
   114    114   
   115    115   #ifdef LSM_DEBUG
   116    116   int lsmErrorBkpt(int);
   117    117   #else
   118    118   # define lsmErrorBkpt(x) (x)
   119    119   #endif
   120    120   
................................................................................
   398    398     void **apShm;                   /* Shared memory chunks */
   399    399     ShmHeader *pShmhdr;             /* Live shared-memory header */
   400    400     TreeHeader treehdr;             /* Local copy of tree-header */
   401    401     u32 aSnapshot[LSM_META_PAGE_SIZE / sizeof(u32)];
   402    402   };
   403    403   
   404    404   struct Segment {
   405         -  Pgno iFirst;                     /* First page of this run */
   406         -  Pgno iLastPg;                    /* Last page of this run */
   407         -  Pgno iRoot;                      /* Root page number (if any) */
          405  +  LsmPgno iFirst;                  /* First page of this run */
          406  +  LsmPgno iLastPg;                 /* Last page of this run */
          407  +  LsmPgno iRoot;                   /* Root page number (if any) */
   408    408     int nSize;                       /* Size of this run in pages */
   409    409   
   410    410     Redirect *pRedirect;             /* Block redirects (or NULL) */
   411    411   };
   412    412   
   413    413   /*
   414    414   ** iSplitTopic/pSplitKey/nSplitKey:
................................................................................
   452    452   ** access to the associated Level struct.
   453    453   **
   454    454   ** iOutputOff:
   455    455   **   The byte offset to write to next within the last page of the 
   456    456   **   output segment.
   457    457   */
   458    458   struct MergeInput {
   459         -  Pgno iPg;                       /* Page on which next input is stored */
          459  +  LsmPgno iPg;                    /* Page on which next input is stored */
   460    460     int iCell;                      /* Cell containing next input to merge */
   461    461   };
   462    462   struct Merge {
   463    463     int nInput;                     /* Number of input runs being merged */
   464    464     MergeInput *aInput;             /* Array nInput entries in size */
   465    465     MergeInput splitkey;            /* Location in file of current splitkey */
   466    466     int nSkip;                      /* Number of separators entries to skip */
   467    467     int iOutputOff;                 /* Write offset on output page */
   468         -  Pgno iCurrentPtr;               /* Current pointer value */
          468  +  LsmPgno iCurrentPtr;            /* Current pointer value */
   469    469   };
   470    470   
   471    471   /* 
   472    472   ** The first argument to this macro is a pointer to a Segment structure.
   473    473   ** Returns true if the structure instance indicates that the separators
   474    474   ** array is valid.
   475    475   */
................................................................................
   575    575     u32 iCmpId;                     /* Id of compression scheme */
   576    576     Level *pLevel;                  /* Pointer to level 0 of snapshot (or NULL) */
   577    577     i64 iId;                        /* Snapshot id */
   578    578     i64 iLogOff;                    /* Log file offset */
   579    579     Redirect redirect;              /* Block redirection array */
   580    580   
   581    581     /* Used by worker snapshots only */
   582         -  int nBlock;                     /* Number of blocks in database file */
   583         -  Pgno aiAppend[LSM_APPLIST_SZ];  /* Append point list */
   584         -  Freelist freelist;              /* Free block list */
   585         -  u32 nWrite;                     /* Total number of pages written to disk */
          582  +  int nBlock;                        /* Number of blocks in database file */
          583  +  LsmPgno aiAppend[LSM_APPLIST_SZ];  /* Append point list */
          584  +  Freelist freelist;                 /* Free block list */
          585  +  u32 nWrite;                        /* Total number of pages written to disk */
   586    586   };
   587    587   #define LSM_INITIAL_SNAPSHOT_ID 11
   588    588   
   589    589   /*
   590    590   ** Functions from file "lsm_ckpt.c".
   591    591   */
   592    592   int lsmCheckpointWrite(lsm_db *, u32 *);
................................................................................
   706    706   
   707    707   int lsmFsPageSize(FileSystem *);
   708    708   void lsmFsSetPageSize(FileSystem *, int);
   709    709   
   710    710   int lsmFsFileid(lsm_db *pDb, void **ppId, int *pnId);
   711    711   
   712    712   /* Creating, populating, gobbling and deleting sorted runs. */
   713         -void lsmFsGobble(lsm_db *, Segment *, Pgno *, int);
          713  +void lsmFsGobble(lsm_db *, Segment *, LsmPgno *, int);
   714    714   int lsmFsSortedDelete(FileSystem *, Snapshot *, int, Segment *);
   715    715   int lsmFsSortedFinish(FileSystem *, Segment *);
   716    716   int lsmFsSortedAppend(FileSystem *, Snapshot *, Level *, int, Page **);
   717    717   int lsmFsSortedPadding(FileSystem *, Snapshot *, Segment *);
   718    718   
   719    719   /* Functions to retrieve the lsm_env pointer from a FileSystem or Page object */
   720    720   lsm_env *lsmFsEnv(FileSystem *);
................................................................................
   723    723   
   724    724   int lsmFsSectorSize(FileSystem *);
   725    725   
   726    726   void lsmSortedSplitkey(lsm_db *, Level *, int *);
   727    727   
   728    728   /* Reading sorted run content. */
   729    729   int lsmFsDbPageLast(FileSystem *pFS, Segment *pSeg, Page **ppPg);
   730         -int lsmFsDbPageGet(FileSystem *, Segment *, Pgno, Page **);
          730  +int lsmFsDbPageGet(FileSystem *, Segment *, LsmPgno, Page **);
   731    731   int lsmFsDbPageNext(Segment *, Page *, int eDir, Page **);
   732    732   
   733    733   u8 *lsmFsPageData(Page *, int *);
   734    734   int lsmFsPageRelease(Page *);
   735    735   int lsmFsPagePersist(Page *);
   736    736   void lsmFsPageRef(Page *);
   737         -Pgno lsmFsPageNumber(Page *);
          737  +LsmPgno lsmFsPageNumber(Page *);
   738    738   
   739    739   int lsmFsNRead(FileSystem *);
   740    740   int lsmFsNWrite(FileSystem *);
   741    741   
   742    742   int lsmFsMetaPageGet(FileSystem *, int, int, MetaPage **);
   743    743   int lsmFsMetaPageRelease(MetaPage *);
   744    744   u8 *lsmFsMetaPageData(MetaPage *, int *);
   745    745   
   746    746   #ifdef LSM_DEBUG
   747    747   int lsmFsDbPageIsLast(Segment *pSeg, Page *pPg);
   748    748   int lsmFsIntegrityCheck(lsm_db *);
   749    749   #endif
   750    750   
   751         -Pgno lsmFsRedirectPage(FileSystem *, Redirect *, Pgno);
          751  +LsmPgno lsmFsRedirectPage(FileSystem *, Redirect *, LsmPgno);
   752    752   
   753    753   int lsmFsPageWritable(Page *);
   754    754   
   755    755   /* Functions to read, write and sync the log file. */
   756    756   int lsmFsWriteLog(FileSystem *pFS, i64 iOff, LsmString *pStr);
   757    757   int lsmFsSyncLog(FileSystem *pFS);
   758    758   int lsmFsReadLog(FileSystem *pFS, i64 iOff, int nRead, LsmString *pStr);
................................................................................
   764    764   
   765    765   /* And to sync the db file */
   766    766   int lsmFsSyncDb(FileSystem *, int);
   767    767   
   768    768   void lsmFsFlushWaiting(FileSystem *, int *);
   769    769   
   770    770   /* Used by lsm_info(ARRAY_STRUCTURE) and lsm_config(MMAP) */
   771         -int lsmInfoArrayStructure(lsm_db *pDb, int bBlock, Pgno iFirst, char **pzOut);
   772         -int lsmInfoArrayPages(lsm_db *pDb, Pgno iFirst, char **pzOut);
          771  +int lsmInfoArrayStructure(lsm_db *pDb, int bBlock, LsmPgno iFirst, char **pz);
          772  +int lsmInfoArrayPages(lsm_db *pDb, LsmPgno iFirst, char **pzOut);
   773    773   int lsmConfigMmap(lsm_db *pDb, int *piParam);
   774    774   
   775    775   int lsmEnvOpen(lsm_env *, const char *, int, lsm_file **);
   776    776   int lsmEnvClose(lsm_env *pEnv, lsm_file *pFile);
   777    777   int lsmEnvLock(lsm_env *pEnv, lsm_file *pFile, int iLock, int eLock);
   778    778   int lsmEnvTestLock(lsm_env *pEnv, lsm_file *pFile, int iLock, int nLock, int);
   779    779   
................................................................................
   781    781   void lsmEnvShmBarrier(lsm_env *);
   782    782   void lsmEnvShmUnmap(lsm_env *, lsm_file *, int);
   783    783   
   784    784   void lsmEnvSleep(lsm_env *, int);
   785    785   
   786    786   int lsmFsReadSyncedId(lsm_db *db, int, i64 *piVal);
   787    787   
   788         -int lsmFsSegmentContainsPg(FileSystem *pFS, Segment *, Pgno, int *);
          788  +int lsmFsSegmentContainsPg(FileSystem *pFS, Segment *, LsmPgno, int *);
   789    789   
   790    790   void lsmFsPurgeCache(FileSystem *);
   791    791   
   792    792   /*
   793    793   ** End of functions from "lsm_file.c".
   794    794   **************************************************************************/
   795    795   
   796    796   /* 
   797    797   ** Functions from file "lsm_sorted.c".
   798    798   */
   799         -int lsmInfoPageDump(lsm_db *, Pgno, int, char **);
          799  +int lsmInfoPageDump(lsm_db *, LsmPgno, int, char **);
   800    800   void lsmSortedCleanup(lsm_db *);
   801    801   int lsmSortedAutoWork(lsm_db *, int nUnit);
   802    802   
   803    803   int lsmSortedWalkFreelist(lsm_db *, int, int (*)(void *, int, i64), void *);
   804    804   
   805    805   int lsmSaveWorker(lsm_db *, int);
   806    806   

Changes to ext/lsm1/lsm_ckpt.c.

   385    385   static void ckptExportAppendlist(
   386    386     lsm_db *db,                     /* Database connection */
   387    387     CkptBuffer *p,                  /* Checkpoint buffer to write to */
   388    388     int *piOut,                     /* IN/OUT: Offset within checkpoint buffer */
   389    389     int *pRc                        /* IN/OUT: Error code */
   390    390   ){
   391    391     int i;
   392         -  Pgno *aiAppend = db->pWorker->aiAppend;
          392  +  LsmPgno *aiAppend = db->pWorker->aiAppend;
   393    393   
   394    394     for(i=0; i<LSM_APPLIST_SZ; i++){
   395    395       ckptAppend64(p, piOut, aiAppend[i], pRc);
   396    396     }
   397    397   };
   398    398   
   399    399   static int ckptExportSnapshot( 

Changes to ext/lsm1/lsm_file.c.

   265    265   **   The lsmFsSortedAppend() function sets the pSeg pointer to point to the
   266    266   **   segment that the new page will be a part of. It is unset by
   267    267   **   lsmFsPagePersist() after the page is written to disk.
   268    268   */
   269    269   struct Page {
   270    270     u8 *aData;                      /* Buffer containing page data */
   271    271     int nData;                      /* Bytes of usable data at aData[] */
   272         -  Pgno iPg;                       /* Page number */
          272  +  LsmPgno iPg;                    /* Page number */
   273    273     int nRef;                       /* Number of outstanding references */
   274    274     int flags;                      /* Combination of PAGE_XXX flags */
   275    275     Page *pHashNext;                /* Next page in hash table slot */
   276    276     Page *pLruNext;                 /* Next page in LRU list */
   277    277     Page *pLruPrev;                 /* Previous page in LRU list */
   278    278     FileSystem *pFS;                /* File system that owns this page */
   279    279   
................................................................................
   328    328   #else
   329    329   # define IOERR_WRAPPER(rc) (rc)
   330    330   #endif
   331    331   
   332    332   #ifdef NDEBUG
   333    333   # define assert_lists_are_ok(x)
   334    334   #else
   335         -static Page *fsPageFindInHash(FileSystem *pFS, Pgno iPg, int *piHash);
          335  +static Page *fsPageFindInHash(FileSystem *pFS, LsmPgno iPg, int *piHash);
   336    336   
   337    337   static void assert_lists_are_ok(FileSystem *pFS){
   338    338   #if 0
   339    339     Page *p;
   340    340   
   341    341     assert( pFS->nMapLimit>=0 );
   342    342   
................................................................................
   528    528     return LSM_OK;
   529    529   }
   530    530   
   531    531   /*
   532    532   ** Return true if page iReal of the database should be accessed using mmap.
   533    533   ** False otherwise.
   534    534   */
   535         -static int fsMmapPage(FileSystem *pFS, Pgno iReal){
          535  +static int fsMmapPage(FileSystem *pFS, LsmPgno iReal){
   536    536     return ((i64)iReal*pFS->nPagesize <= pFS->nMapLimit);
   537    537   }
   538    538   
   539    539   /*
   540    540   ** Given that there are currently nHash slots in the hash table, return 
   541    541   ** the hash key for file iFile, page iPg.
   542    542   */
   543         -static int fsHashKey(int nHash, Pgno iPg){
          543  +static int fsHashKey(int nHash, LsmPgno iPg){
   544    544     return (iPg % nHash);
   545    545   }
   546    546   
   547    547   /*
   548    548   ** This is a helper function for lsmFsOpen(). It opens a single file on
   549    549   ** disk (either the database or log file).
   550    550   */
................................................................................
   876    876   ** Return the page number of the first page on block iBlock. Blocks are
   877    877   ** numbered starting from 1.
   878    878   **
   879    879   ** For a compressed database, page numbers are byte offsets. The first
   880    880   ** page on each block is the byte offset immediately following the 4-byte
   881    881   ** "previous block" pointer at the start of each block.
   882    882   */
   883         -static Pgno fsFirstPageOnBlock(FileSystem *pFS, int iBlock){
   884         -  Pgno iPg;
          883  +static LsmPgno fsFirstPageOnBlock(FileSystem *pFS, int iBlock){
          884  +  LsmPgno iPg;
   885    885     if( pFS->pCompress ){
   886    886       if( iBlock==1 ){
   887    887         iPg = pFS->nMetasize * 2 + 4;
   888    888       }else{
   889         -      iPg = pFS->nBlocksize * (Pgno)(iBlock-1) + 4;
          889  +      iPg = pFS->nBlocksize * (LsmPgno)(iBlock-1) + 4;
   890    890       }
   891    891     }else{
   892    892       const int nPagePerBlock = (pFS->nBlocksize / pFS->nPagesize);
   893    893       if( iBlock==1 ){
   894    894         iPg = 1 + ((pFS->nMetasize*2 + pFS->nPagesize - 1) / pFS->nPagesize);
   895    895       }else{
   896    896         iPg = 1 + (iBlock-1) * nPagePerBlock;
................................................................................
   903    903   ** Return the page number of the last page on block iBlock. Blocks are
   904    904   ** numbered starting from 1.
   905    905   **
   906    906   ** For a compressed database, page numbers are byte offsets. The first
   907    907   ** page on each block is the byte offset of the byte immediately before 
   908    908   ** the 4-byte "next block" pointer at the end of each block.
   909    909   */
   910         -static Pgno fsLastPageOnBlock(FileSystem *pFS, int iBlock){
          910  +static LsmPgno fsLastPageOnBlock(FileSystem *pFS, int iBlock){
   911    911     if( pFS->pCompress ){
   912         -    return pFS->nBlocksize * (Pgno)iBlock - 1 - 4;
          912  +    return pFS->nBlocksize * (LsmPgno)iBlock - 1 - 4;
   913    913     }else{
   914    914       const int nPagePerBlock = (pFS->nBlocksize / pFS->nPagesize);
   915    915       return iBlock * nPagePerBlock;
   916    916     }
   917    917   }
   918    918   
   919    919   /*
   920    920   ** Return the block number of the block that page iPg is located on. 
   921    921   ** Blocks are numbered starting from 1.
   922    922   */
   923         -static int fsPageToBlock(FileSystem *pFS, Pgno iPg){
          923  +static int fsPageToBlock(FileSystem *pFS, LsmPgno iPg){
   924    924     if( pFS->pCompress ){
   925    925       return (int)((iPg / pFS->nBlocksize) + 1);
   926    926     }else{
   927    927       return (int)(1 + ((iPg-1) / (pFS->nBlocksize / pFS->nPagesize)));
   928    928     }
   929    929   }
   930    930   
   931    931   /*
   932    932   ** Return true if page iPg is the last page on its block.
   933    933   **
   934    934   ** This function is only called in non-compressed database mode.
   935    935   */
   936         -static int fsIsLast(FileSystem *pFS, Pgno iPg){
          936  +static int fsIsLast(FileSystem *pFS, LsmPgno iPg){
   937    937     const int nPagePerBlock = (pFS->nBlocksize / pFS->nPagesize);
   938    938     assert( !pFS->pCompress );
   939    939     return ( iPg && (iPg % nPagePerBlock)==0 );
   940    940   }
   941    941   
   942    942   /*
   943    943   ** Return true if page iPg is the first page on its block.
   944    944   **
   945    945   ** This function is only called in non-compressed database mode.
   946    946   */
   947         -static int fsIsFirst(FileSystem *pFS, Pgno iPg){
          947  +static int fsIsFirst(FileSystem *pFS, LsmPgno iPg){
   948    948     const int nPagePerBlock = (pFS->nBlocksize / pFS->nPagesize);
   949    949     assert( !pFS->pCompress );
   950    950     return ( (iPg % nPagePerBlock)==1
   951    951           || (iPg<nPagePerBlock && iPg==fsFirstPageOnBlock(pFS, 1))
   952    952     );
   953    953   }
   954    954   
................................................................................
   963    963     }
   964    964     return pPage->aData;
   965    965   }
   966    966   
   967    967   /*
   968    968   ** Return the page number of a page.
   969    969   */
   970         -Pgno lsmFsPageNumber(Page *pPage){
          970  +LsmPgno lsmFsPageNumber(Page *pPage){
   971    971     /* assert( (pPage->flags & PAGE_DIRTY)==0 ); */
   972    972     return pPage ? pPage->iPg : 0;
   973    973   }
   974    974   
   975    975   /*
   976    976   ** Page pPg is currently part of the LRU list belonging to pFS. Remove
   977    977   ** it from the list. pPg->pLruNext and pPg->pLruPrev are cleared by this
................................................................................
  1054   1054   /*
  1055   1055   ** Search the hash-table for page iPg. If an entry is round, return a pointer
  1056   1056   ** to it. Otherwise, return NULL.
  1057   1057   **
  1058   1058   ** Either way, if argument piHash is not NULL set *piHash to the hash slot
  1059   1059   ** number that page iPg would be stored in before returning.
  1060   1060   */
  1061         -static Page *fsPageFindInHash(FileSystem *pFS, Pgno iPg, int *piHash){
         1061  +static Page *fsPageFindInHash(FileSystem *pFS, LsmPgno iPg, int *piHash){
  1062   1062     Page *p;                        /* Return value */
  1063   1063     int iHash = fsHashKey(pFS->nHash, iPg);
  1064   1064   
  1065   1065     if( piHash ) *piHash = iHash;
  1066   1066     for(p=pFS->apHash[iHash]; p; p=p->pHashNext){
  1067   1067       if( p->iPg==iPg) break;
  1068   1068     }
................................................................................
  1185   1185   }
  1186   1186   
  1187   1187   /*
  1188   1188   ** If page iPg has been redirected according to the redirections in the
  1189   1189   ** object passed as the second argument, return the destination page to
  1190   1190   ** which it is redirected. Otherwise, return a copy of iPg.
  1191   1191   */
  1192         -Pgno lsmFsRedirectPage(FileSystem *pFS, Redirect *pRedir, Pgno iPg){
  1193         -  Pgno iReal = iPg;
         1192  +LsmPgno lsmFsRedirectPage(FileSystem *pFS, Redirect *pRedir, LsmPgno iPg){
         1193  +  LsmPgno iReal = iPg;
  1194   1194   
  1195   1195     if( pRedir ){
  1196   1196       const int nPagePerBlock = (
  1197   1197           pFS->pCompress ? pFS->nBlocksize : (pFS->nBlocksize / pFS->nPagesize)
  1198   1198       );
  1199   1199       int iBlk = fsPageToBlock(pFS, iPg);
  1200   1200       int i;
  1201   1201       for(i=0; i<pRedir->n; i++){
  1202   1202         int iFrom = pRedir->a[i].iFrom;
  1203   1203         if( iFrom>iBlk ) break;
  1204   1204         if( iFrom==iBlk ){
  1205   1205           int iTo = pRedir->a[i].iTo;
  1206         -        iReal = iPg - (Pgno)(iFrom - iTo) * nPagePerBlock;
         1206  +        iReal = iPg - (LsmPgno)(iFrom - iTo) * nPagePerBlock;
  1207   1207           if( iTo==1 ){
  1208   1208             iReal += (fsFirstPageOnBlock(pFS, 1)-1);
  1209   1209           }
  1210   1210           break;
  1211   1211         }
  1212   1212       }
  1213   1213     }
  1214   1214   
  1215   1215     assert( iReal!=0 );
  1216   1216     return iReal;
  1217   1217   }
  1218   1218   
  1219   1219   /* Required by the circular fsBlockNext<->fsPageGet dependency. */
  1220         -static int fsPageGet(FileSystem *, Segment *, Pgno, int, Page **, int *);
         1220  +static int fsPageGet(FileSystem *, Segment *, LsmPgno, int, Page **, int *);
  1221   1221   
  1222   1222   /*
  1223   1223   ** Parameter iBlock is a database file block. This function reads the value 
  1224   1224   ** stored in the blocks "next block" pointer and stores it in *piNext.
  1225   1225   ** LSM_OK is returned if everything is successful, or an LSM error code
  1226   1226   ** otherwise.
  1227   1227   */
................................................................................
  1265   1265     }
  1266   1266     return rc;
  1267   1267   }
  1268   1268   
  1269   1269   /*
  1270   1270   ** Return the page number of the last page on the same block as page iPg.
  1271   1271   */
  1272         -Pgno fsLastPageOnPagesBlock(FileSystem *pFS, Pgno iPg){
         1272  +LsmPgno fsLastPageOnPagesBlock(FileSystem *pFS, LsmPgno iPg){
  1273   1273     return fsLastPageOnBlock(pFS, fsPageToBlock(pFS, iPg));
  1274   1274   }
  1275   1275   
  1276   1276   /*
  1277   1277   ** Read nData bytes of data from offset iOff of the database file into
  1278   1278   ** buffer aData. If this means reading past the end of a block, follow
  1279   1279   ** the block pointer to the next block and continue reading.
................................................................................
  1533   1533   ** to the total number of free bytes before returning.
  1534   1534   **
  1535   1535   ** If no error occurs, LSM_OK is returned. Otherwise, an lsm error code.
  1536   1536   */
  1537   1537   static int fsPageGet(
  1538   1538     FileSystem *pFS,                /* File-system handle */
  1539   1539     Segment *pSeg,                  /* Block redirection to use (or NULL) */
  1540         -  Pgno iPg,                       /* Page id */
         1540  +  LsmPgno iPg,                    /* Page id */
  1541   1541     int noContent,                  /* True to not load content from disk */
  1542   1542     Page **ppPg,                    /* OUT: New page handle */
  1543   1543     int *pnSpace                    /* OUT: Bytes of free space */
  1544   1544   ){
  1545   1545     Page *p;
  1546   1546     int iHash;
  1547   1547     int rc = LSM_OK;
  1548   1548   
  1549   1549     /* In most cases iReal is the same as iPg. Except, if pSeg->pRedirect is 
  1550   1550     ** not NULL, and the block containing iPg has been redirected, then iReal
  1551   1551     ** is the page number after redirection.  */
  1552         -  Pgno iReal = lsmFsRedirectPage(pFS, (pSeg ? pSeg->pRedirect : 0), iPg);
         1552  +  LsmPgno iReal = lsmFsRedirectPage(pFS, (pSeg ? pSeg->pRedirect : 0), iPg);
  1553   1553   
  1554   1554     assert_lists_are_ok(pFS);
  1555   1555     assert( iPg>=fsFirstPageOnBlock(pFS, 1) );
  1556   1556     assert( iReal>=fsFirstPageOnBlock(pFS, 1) );
  1557   1557     *ppPg = 0;
  1558   1558   
  1559   1559     /* Search the hash-table for the page */
................................................................................
  1685   1685   /*
  1686   1686   ** Return true if the first or last page of segment pRun falls between iFirst
  1687   1687   ** and iLast, inclusive, and pRun is not equal to pIgnore.
  1688   1688   */
  1689   1689   static int fsRunEndsBetween(
  1690   1690     Segment *pRun, 
  1691   1691     Segment *pIgnore, 
  1692         -  Pgno iFirst, 
  1693         -  Pgno iLast
         1692  +  LsmPgno iFirst, 
         1693  +  LsmPgno iLast
  1694   1694   ){
  1695   1695     return (pRun!=pIgnore && (
  1696   1696           (pRun->iFirst>=iFirst && pRun->iFirst<=iLast)
  1697   1697        || (pRun->iLastPg>=iFirst && pRun->iLastPg<=iLast)
  1698   1698     ));
  1699   1699   }
  1700   1700   
................................................................................
  1701   1701   /*
  1702   1702   ** Return true if level pLevel contains a segment other than pIgnore for
  1703   1703   ** which the first or last page is between iFirst and iLast, inclusive.
  1704   1704   */
  1705   1705   static int fsLevelEndsBetween(
  1706   1706     Level *pLevel, 
  1707   1707     Segment *pIgnore, 
  1708         -  Pgno iFirst, 
  1709         -  Pgno iLast
         1708  +  LsmPgno iFirst, 
         1709  +  LsmPgno iLast
  1710   1710   ){
  1711   1711     int i;
  1712   1712   
  1713   1713     if( fsRunEndsBetween(&pLevel->lhs, pIgnore, iFirst, iLast) ){
  1714   1714       return 1;
  1715   1715     }
  1716   1716     for(i=0; i<pLevel->nRight; i++){
................................................................................
  1729   1729   static int fsFreeBlock(
  1730   1730     FileSystem *pFS,                /* File system object */
  1731   1731     Snapshot *pSnapshot,            /* Worker snapshot */
  1732   1732     Segment *pIgnore,               /* Ignore this run when searching */
  1733   1733     int iBlk                        /* Block number of block to free */
  1734   1734   ){
  1735   1735     int rc = LSM_OK;                /* Return code */
  1736         -  Pgno iFirst;                    /* First page on block iBlk */
  1737         -  Pgno iLast;                     /* Last page on block iBlk */
         1736  +  LsmPgno iFirst;                 /* First page on block iBlk */
         1737  +  LsmPgno iLast;                  /* Last page on block iBlk */
  1738   1738     Level *pLevel;                  /* Used to iterate through levels */
  1739   1739   
  1740   1740     int iIn;                        /* Used to iterate through append points */
  1741   1741     int iOut = 0;                   /* Used to output append points */
  1742         -  Pgno *aApp = pSnapshot->aiAppend;
         1742  +  LsmPgno *aApp = pSnapshot->aiAppend;
  1743   1743   
  1744   1744     iFirst = fsFirstPageOnBlock(pFS, iBlk);
  1745   1745     iLast = fsLastPageOnBlock(pFS, iBlk);
  1746   1746   
  1747   1747     /* Check if any other run in the snapshot has a start or end page 
  1748   1748     ** within this block. If there is such a run, return early. */
  1749   1749     for(pLevel=lsmDbSnapshotLevel(pSnapshot); pLevel; pLevel=pLevel->pNext){
................................................................................
  1807   1807   }
  1808   1808   
  1809   1809   /*
  1810   1810   ** aPgno is an array containing nPgno page numbers. Return the smallest page
  1811   1811   ** number from the array that falls on block iBlk. Or, if none of the pages
  1812   1812   ** in aPgno[] fall on block iBlk, return 0.
  1813   1813   */
  1814         -static Pgno firstOnBlock(FileSystem *pFS, int iBlk, Pgno *aPgno, int nPgno){
  1815         -  Pgno iRet = 0;
         1814  +static LsmPgno firstOnBlock(
         1815  +  FileSystem *pFS, 
         1816  +  int iBlk, 
         1817  +  LsmPgno *aPgno, 
         1818  +  int nPgno
         1819  +){
         1820  +  LsmPgno iRet = 0;
  1816   1821     int i;
  1817   1822     for(i=0; i<nPgno; i++){
  1818         -    Pgno iPg = aPgno[i];
         1823  +    LsmPgno iPg = aPgno[i];
  1819   1824       if( fsPageToBlock(pFS, iPg)==iBlk && (iRet==0 || iPg<iRet) ){
  1820   1825         iRet = iPg;
  1821   1826       }
  1822   1827     }
  1823   1828     return iRet;
  1824   1829   }
  1825   1830   
  1826   1831   #ifndef NDEBUG
  1827   1832   /*
  1828   1833   ** Return true if page iPg, which is a part of segment p, lies on
  1829   1834   ** a redirected block. 
  1830   1835   */
  1831         -static int fsPageRedirects(FileSystem *pFS, Segment *p, Pgno iPg){
         1836  +static int fsPageRedirects(FileSystem *pFS, Segment *p, LsmPgno iPg){
  1832   1837     return (iPg!=0 && iPg!=lsmFsRedirectPage(pFS, p->pRedirect, iPg));
  1833   1838   }
  1834   1839   
  1835   1840   /*
  1836   1841   ** Return true if the second argument is not NULL and any of the first
  1837   1842   ** last or root pages lie on a redirected block. 
  1838   1843   */
................................................................................
  1850   1855   ** the segment pRun. This function gobbles from the start of the run to the
  1851   1856   ** first page that appears in aPgno[] (i.e. so that the aPgno[] entry is
  1852   1857   ** the new first page of the run).
  1853   1858   */
  1854   1859   void lsmFsGobble(
  1855   1860     lsm_db *pDb,
  1856   1861     Segment *pRun, 
  1857         -  Pgno *aPgno,
         1862  +  LsmPgno *aPgno,
  1858   1863     int nPgno
  1859   1864   ){
  1860   1865     int rc = LSM_OK;
  1861   1866     FileSystem *pFS = pDb->pFS;
  1862   1867     Snapshot *pSnapshot = pDb->pWorker;
  1863   1868     int iBlk;
  1864   1869   
................................................................................
  1867   1872     assert( nPgno>0 && 0==fsPageRedirects(pFS, pRun, aPgno[0]) );
  1868   1873   
  1869   1874     iBlk = fsPageToBlock(pFS, pRun->iFirst);
  1870   1875     pRun->nSize += (int)(pRun->iFirst - fsFirstPageOnBlock(pFS, iBlk));
  1871   1876   
  1872   1877     while( rc==LSM_OK ){
  1873   1878       int iNext = 0;
  1874         -    Pgno iFirst = firstOnBlock(pFS, iBlk, aPgno, nPgno);
         1879  +    LsmPgno iFirst = firstOnBlock(pFS, iBlk, aPgno, nPgno);
  1875   1880       if( iFirst ){
  1876   1881         pRun->iFirst = iFirst;
  1877   1882         break;
  1878   1883       }
  1879   1884       rc = fsBlockNext(pFS, pRun, iBlk, &iNext);
  1880   1885       if( rc==LSM_OK ) rc = fsFreeBlock(pFS, pSnapshot, pRun, iBlk);
  1881   1886       pRun->nSize -= (int)(
................................................................................
  1901   1906   **   *piNext = iPg + nByte;
  1902   1907   **
  1903   1908   ** But take block overflow and redirection into account.
  1904   1909   */
  1905   1910   static int fsNextPageOffset(
  1906   1911     FileSystem *pFS,                /* File system object */
  1907   1912     Segment *pSeg,                  /* Segment to move within */
  1908         -  Pgno iPg,                       /* Offset of current page */
         1913  +  LsmPgno iPg,                    /* Offset of current page */
  1909   1914     int nByte,                      /* Size of current page including headers */
  1910         -  Pgno *piNext                    /* OUT: Offset of next page. Or zero (EOF) */
         1915  +  LsmPgno *piNext                 /* OUT: Offset of next page. Or zero (EOF) */
  1911   1916   ){
  1912         -  Pgno iNext;
         1917  +  LsmPgno iNext;
  1913   1918     int rc;
  1914   1919   
  1915   1920     assert( pFS->pCompress );
  1916   1921   
  1917   1922     rc = fsAddOffset(pFS, pSeg, iPg, nByte-1, &iNext);
  1918   1923     if( pSeg && iNext==pSeg->iLastPg ){
  1919   1924       iNext = 0;
................................................................................
  1935   1940   ** LSM_OK is returned if no error occurs. Otherwise, an lsm error code.
  1936   1941   ** If any value other than LSM_OK is returned, then the final value of
  1937   1942   ** *piPrev is undefined.
  1938   1943   */
  1939   1944   static int fsGetPageBefore(
  1940   1945     FileSystem *pFS, 
  1941   1946     Segment *pSeg, 
  1942         -  Pgno iPg, 
  1943         -  Pgno *piPrev
         1947  +  LsmPgno iPg, 
         1948  +  LsmPgno *piPrev
  1944   1949   ){
  1945   1950     u8 aSz[3];
  1946   1951     int rc;
  1947   1952     i64 iRead;
  1948   1953   
  1949   1954     assert( pFS->pCompress );
  1950   1955   
................................................................................
  1986   1991   **
  1987   1992   ** Page references returned by this function should be released by the 
  1988   1993   ** caller using lsmFsPageRelease().
  1989   1994   */
  1990   1995   int lsmFsDbPageNext(Segment *pRun, Page *pPg, int eDir, Page **ppNext){
  1991   1996     int rc = LSM_OK;
  1992   1997     FileSystem *pFS = pPg->pFS;
  1993         -  Pgno iPg = pPg->iPg;
         1998  +  LsmPgno iPg = pPg->iPg;
  1994   1999   
  1995   2000     assert( 0==fsSegmentRedirects(pFS, pRun) );
  1996   2001     if( pFS->pCompress ){
  1997   2002       int nSpace = pPg->nCompress + 2*3;
  1998   2003   
  1999   2004       do {
  2000   2005         if( eDir>0 ){
................................................................................
  2058   2063   ** already allocated block. If it is possible, the page number of the first
  2059   2064   ** page to use for the new segment is returned. Otherwise zero.
  2060   2065   **
  2061   2066   ** If argument pLvl is not NULL, then this function will not attempt to
  2062   2067   ** start the new segment immediately following any segment that is part
  2063   2068   ** of the right-hand-side of pLvl.
  2064   2069   */
  2065         -static Pgno findAppendPoint(FileSystem *pFS, Level *pLvl){
         2070  +static LsmPgno findAppendPoint(FileSystem *pFS, Level *pLvl){
  2066   2071     int i;
  2067         -  Pgno *aiAppend = pFS->pDb->pWorker->aiAppend;
  2068         -  Pgno iRet = 0;
         2072  +  LsmPgno *aiAppend = pFS->pDb->pWorker->aiAppend;
         2073  +  LsmPgno iRet = 0;
  2069   2074   
  2070   2075     for(i=LSM_APPLIST_SZ-1; iRet==0 && i>=0; i--){
  2071   2076       if( (iRet = aiAppend[i]) ){
  2072   2077         if( pLvl ){
  2073   2078           int iBlk = fsPageToBlock(pFS, iRet);
  2074   2079           int j;
  2075   2080           for(j=0; iRet && j<pLvl->nRight; j++){
................................................................................
  2094   2099     Snapshot *pSnapshot,
  2095   2100     Level *pLvl,
  2096   2101     int bDefer,
  2097   2102     Page **ppOut
  2098   2103   ){
  2099   2104     int rc = LSM_OK;
  2100   2105     Page *pPg = 0;
  2101         -  Pgno iApp = 0;
  2102         -  Pgno iNext = 0;
         2106  +  LsmPgno iApp = 0;
         2107  +  LsmPgno iNext = 0;
  2103   2108     Segment *p = &pLvl->lhs;
  2104         -  Pgno iPrev = p->iLastPg;
         2109  +  LsmPgno iPrev = p->iLastPg;
  2105   2110   
  2106   2111     *ppOut = 0;
  2107   2112     assert( p->pRedirect==0 );
  2108   2113   
  2109   2114     if( pFS->pCompress || bDefer ){
  2110   2115       /* In compressed database mode the page is not assigned a page number
  2111   2116       ** or location in the database file at this point. This will be done
................................................................................
  2191   2196       ** Shift this extra block back to the free-block list. 
  2192   2197       **
  2193   2198       ** Otherwise, add the first free page in the last block used by the run
  2194   2199       ** to the lAppend list.
  2195   2200       */
  2196   2201       if( fsLastPageOnPagesBlock(pFS, p->iLastPg)!=p->iLastPg ){
  2197   2202         int i;
  2198         -      Pgno *aiAppend = pFS->pDb->pWorker->aiAppend;
         2203  +      LsmPgno *aiAppend = pFS->pDb->pWorker->aiAppend;
  2199   2204         for(i=0; i<LSM_APPLIST_SZ; i++){
  2200   2205           if( aiAppend[i]==0 ){
  2201   2206             aiAppend[i] = p->iLastPg+1;
  2202   2207             break;
  2203   2208           }
  2204   2209         }
  2205   2210       }else if( pFS->pCompress==0 ){
................................................................................
  2222   2227   }
  2223   2228   
  2224   2229   /*
  2225   2230   ** Obtain a reference to page number iPg.
  2226   2231   **
  2227   2232   ** Return LSM_OK if successful, or an lsm error code if an error occurs.
  2228   2233   */
  2229         -int lsmFsDbPageGet(FileSystem *pFS, Segment *pSeg, Pgno iPg, Page **ppPg){
         2234  +int lsmFsDbPageGet(FileSystem *pFS, Segment *pSeg, LsmPgno iPg, Page **ppPg){
  2230   2235     return fsPageGet(pFS, pSeg, iPg, 0, ppPg, 0);
  2231   2236   }
  2232   2237   
  2233   2238   /*
  2234   2239   ** Obtain a reference to the last page in the segment passed as the 
  2235   2240   ** second argument.
  2236   2241   **
  2237   2242   ** Return LSM_OK if successful, or an lsm error code if an error occurs.
  2238   2243   */
  2239   2244   int lsmFsDbPageLast(FileSystem *pFS, Segment *pSeg, Page **ppPg){
  2240   2245     int rc;
  2241         -  Pgno iPg = pSeg->iLastPg;
         2246  +  LsmPgno iPg = pSeg->iLastPg;
  2242   2247     if( pFS->pCompress ){
  2243   2248       int nSpace;
  2244   2249       iPg++;
  2245   2250       do {
  2246   2251         nSpace = 0;
  2247   2252         rc = fsGetPageBefore(pFS, pSeg, iPg, &iPg);
  2248   2253         if( rc==LSM_OK ){
................................................................................
  2362   2367   ** number (*piPg) lies on block iFrom, then calculate the equivalent
  2363   2368   ** page on block iTo and set *piPg to this value before returning.
  2364   2369   */
  2365   2370   static void fsMovePage(
  2366   2371     FileSystem *pFS,                /* File system object */
  2367   2372     int iTo,                        /* Destination block */
  2368   2373     int iFrom,                      /* Source block */
  2369         -  Pgno *piPg                      /* IN/OUT: Page number */
         2374  +  LsmPgno *piPg                   /* IN/OUT: Page number */
  2370   2375   ){
  2371         -  Pgno iPg = *piPg;
         2376  +  LsmPgno iPg = *piPg;
  2372   2377     if( iFrom==fsPageToBlock(pFS, iPg) ){
  2373   2378       const int nPagePerBlock = (
  2374   2379           pFS->pCompress ? pFS ->nBlocksize : (pFS->nBlocksize / pFS->nPagesize)
  2375   2380       );
  2376         -    *piPg = iPg - (Pgno)(iFrom - iTo) * nPagePerBlock;
         2381  +    *piPg = iPg - (LsmPgno)(iFrom - iTo) * nPagePerBlock;
  2377   2382     }
  2378   2383   }
  2379   2384   
  2380   2385   /*
  2381   2386   ** Copy the contents of block iFrom to block iTo. 
  2382   2387   **
  2383   2388   ** It is safe to assume that there are no outstanding references to pages 
................................................................................
  2453   2458   /*
  2454   2459   ** Append raw data to a segment. Return the database file offset that the
  2455   2460   ** data is written to (this may be used as the page number if the data
  2456   2461   ** being appended is a new page record).
  2457   2462   **
  2458   2463   ** This function is only used in compressed database mode.
  2459   2464   */
  2460         -static Pgno fsAppendData(
         2465  +static LsmPgno fsAppendData(
  2461   2466     FileSystem *pFS,                /* File-system handle */
  2462   2467     Segment *pSeg,                  /* Segment to append to */
  2463   2468     const u8 *aData,                /* Buffer containing data to write */
  2464   2469     int nData,                      /* Size of buffer aData[] in bytes */
  2465   2470     int *pRc                        /* IN/OUT: Error code */
  2466   2471   ){
  2467         -  Pgno iRet = 0;
         2472  +  LsmPgno iRet = 0;
  2468   2473     int rc = *pRc;
  2469   2474     assert( pFS->pCompress );
  2470   2475     if( rc==LSM_OK ){
  2471   2476       int nRem = 0;
  2472   2477       int nWrite = 0;
  2473         -    Pgno iLastOnBlock;
  2474         -    Pgno iApp = pSeg->iLastPg+1;
         2478  +    LsmPgno iLastOnBlock;
         2479  +    LsmPgno iApp = pSeg->iLastPg+1;
  2475   2480   
  2476   2481       /* If this is the first data written into the segment, find an append-point
  2477   2482       ** or allocate a new block.  */
  2478   2483       if( iApp==1 ){
  2479   2484         pSeg->iFirst = iApp = findAppendPoint(pFS, 0);
  2480   2485         if( iApp==0 ){
  2481   2486           int iBlk;
................................................................................
  2515   2520             assert( iApp==(fsPageToBlock(pFS, iApp)*pFS->nBlocksize)-4 );
  2516   2521             lsmPutU32(aPtr, iBlk);
  2517   2522             rc = lsmEnvWrite(pFS->pEnv, pFS->fdDb, iApp, aPtr, sizeof(aPtr));
  2518   2523           }
  2519   2524   
  2520   2525           /* Set the "prev" pointer on the new block */
  2521   2526           if( rc==LSM_OK ){
  2522         -          Pgno iWrite;
         2527  +          LsmPgno iWrite;
  2523   2528             lsmPutU32(aPtr, fsPageToBlock(pFS, iApp));
  2524   2529             iWrite = fsFirstPageOnBlock(pFS, iBlk);
  2525   2530             rc = lsmEnvWrite(pFS->pEnv, pFS->fdDb, iWrite-4, aPtr, sizeof(aPtr));
  2526   2531             if( nRem>0 ) iApp = iWrite;
  2527   2532           }
  2528   2533         }else{
  2529   2534           /* The next block is already allocated. */
................................................................................
  2584   2589   ** LSM_OK is returned if successful, or an lsm error code otherwise. If
  2585   2590   ** any value other than LSM_OK is returned, then the final value of all
  2586   2591   ** output variables is undefined.
  2587   2592   */
  2588   2593   static int fsAppendPage(
  2589   2594     FileSystem *pFS, 
  2590   2595     Segment *pSeg,
  2591         -  Pgno *piNew,
         2596  +  LsmPgno *piNew,
  2592   2597     int *piPrev,
  2593   2598     int *piNext
  2594   2599   ){
  2595         -  Pgno iPrev = pSeg->iLastPg;
         2600  +  LsmPgno iPrev = pSeg->iLastPg;
  2596   2601     int rc;
  2597   2602     assert( iPrev!=0 );
  2598   2603   
  2599   2604     *piPrev = 0;
  2600   2605     *piNext = 0;
  2601   2606   
  2602   2607     if( fsIsLast(pFS, iPrev) ){
................................................................................
  2646   2651     }
  2647   2652     *pRc = rc;
  2648   2653   }
  2649   2654   
  2650   2655   /*
  2651   2656   ** If there exists a hash-table entry associated with page iPg, remove it.
  2652   2657   */
  2653         -static void fsRemoveHashEntry(FileSystem *pFS, Pgno iPg){
         2658  +static void fsRemoveHashEntry(FileSystem *pFS, LsmPgno iPg){
  2654   2659     Page *p;
  2655   2660     int iHash = fsHashKey(pFS->nHash, iPg);
  2656   2661   
  2657   2662     for(p=pFS->apHash[iHash]; p && p->iPg!=iPg; p=p->pHashNext);
  2658   2663   
  2659   2664     if( p ){
  2660   2665       assert( p->nRef==0 || (p->flags & PAGE_FREE)==0 );
................................................................................
  2800   2805   int lsmFsSortedPadding(
  2801   2806     FileSystem *pFS, 
  2802   2807     Snapshot *pSnapshot,
  2803   2808     Segment *pSeg
  2804   2809   ){
  2805   2810     int rc = LSM_OK;
  2806   2811     if( pFS->pCompress && pSeg->iFirst ){
  2807         -    Pgno iLast2;
  2808         -    Pgno iLast = pSeg->iLastPg;     /* Current last page of segment */
         2812  +    LsmPgno iLast2;
         2813  +    LsmPgno iLast = pSeg->iLastPg;  /* Current last page of segment */
  2809   2814       int nPad;                       /* Bytes of padding required */
  2810   2815       u8 aSz[3];
  2811   2816   
  2812   2817       iLast2 = (1 + iLast/pFS->szSector) * pFS->szSector - 1;
  2813   2818       assert( fsPageToBlock(pFS, iLast)==fsPageToBlock(pFS, iLast2) );
  2814   2819       nPad = (int)(iLast2 - iLast);
  2815   2820   
................................................................................
  2931   2936   int lsmFsSectorSize(FileSystem *pFS){
  2932   2937     return pFS->szSector;
  2933   2938   }
  2934   2939   
  2935   2940   /*
  2936   2941   ** Helper function for lsmInfoArrayStructure().
  2937   2942   */
  2938         -static Segment *startsWith(Segment *pRun, Pgno iFirst){
         2943  +static Segment *startsWith(Segment *pRun, LsmPgno iFirst){
  2939   2944     return (iFirst==pRun->iFirst) ? pRun : 0;
  2940   2945   }
  2941   2946   
  2942   2947   /*
  2943   2948   ** Return the segment that starts with page iFirst, if any. If no such segment
  2944   2949   ** can be found, return NULL.
  2945   2950   */
  2946         -static Segment *findSegment(Snapshot *pWorker, Pgno iFirst){
         2951  +static Segment *findSegment(Snapshot *pWorker, LsmPgno iFirst){
  2947   2952     Level *pLvl;                    /* Used to iterate through db levels */
  2948   2953     Segment *pSeg = 0;              /* Pointer to segment to return */
  2949   2954   
  2950   2955     for(pLvl=lsmDbSnapshotLevel(pWorker); pLvl && pSeg==0; pLvl=pLvl->pNext){
  2951   2956       if( 0==(pSeg = startsWith(&pLvl->lhs, iFirst)) ){
  2952   2957         int i;
  2953   2958         for(i=0; i<pLvl->nRight; i++){
................................................................................
  2966   2971   ** eventually free the string using lsmFree().
  2967   2972   **
  2968   2973   ** If an error occurs, *pzOut is set to NULL and an LSM error code returned.
  2969   2974   */
  2970   2975   int lsmInfoArrayStructure(
  2971   2976     lsm_db *pDb, 
  2972   2977     int bBlock,                     /* True for block numbers only */
  2973         -  Pgno iFirst,
         2978  +  LsmPgno iFirst,
  2974   2979     char **pzOut
  2975   2980   ){
  2976   2981     int rc = LSM_OK;
  2977   2982     Snapshot *pWorker;              /* Worker snapshot */
  2978   2983     Segment *pArray = 0;            /* Array to report on */
  2979   2984     int bUnlock = 0;
  2980   2985   
................................................................................
  3031   3036     }
  3032   3037     return rc;
  3033   3038   }
  3034   3039   
  3035   3040   int lsmFsSegmentContainsPg(
  3036   3041     FileSystem *pFS, 
  3037   3042     Segment *pSeg, 
  3038         -  Pgno iPg, 
         3043  +  LsmPgno iPg, 
  3039   3044     int *pbRes
  3040   3045   ){
  3041   3046     Redirect *pRedir = pSeg->pRedirect;
  3042   3047     int rc = LSM_OK;
  3043   3048     int iBlk;
  3044   3049     int iLastBlk;
  3045   3050     int iPgBlock;                   /* Block containing page iPg */
................................................................................
  3060   3065   ** This function implements the lsm_info(LSM_INFO_ARRAY_PAGES) request.
  3061   3066   ** If successful, *pzOut is set to point to a nul-terminated string 
  3062   3067   ** containing the array structure and LSM_OK is returned. The caller should
  3063   3068   ** eventually free the string using lsmFree().
  3064   3069   **
  3065   3070   ** If an error occurs, *pzOut is set to NULL and an LSM error code returned.
  3066   3071   */
  3067         -int lsmInfoArrayPages(lsm_db *pDb, Pgno iFirst, char **pzOut){
         3072  +int lsmInfoArrayPages(lsm_db *pDb, LsmPgno iFirst, char **pzOut){
  3068   3073     int rc = LSM_OK;
  3069   3074     Snapshot *pWorker;              /* Worker snapshot */
  3070   3075     Segment *pSeg = 0;              /* Array to report on */
  3071   3076     int bUnlock = 0;
  3072   3077   
  3073   3078     *pzOut = 0;
  3074   3079     if( iFirst==0 ) return LSM_ERROR;
................................................................................
  3293   3298   #ifndef NDEBUG
  3294   3299   /*
  3295   3300   ** Return true if pPg happens to be the last page in segment pSeg. Or false
  3296   3301   ** otherwise. This function is only invoked as part of assert() conditions.
  3297   3302   */
  3298   3303   int lsmFsDbPageIsLast(Segment *pSeg, Page *pPg){
  3299   3304     if( pPg->pFS->pCompress ){
  3300         -    Pgno iNext = 0;
         3305  +    LsmPgno iNext = 0;
  3301   3306       int rc;
  3302   3307       rc = fsNextPageOffset(pPg->pFS, pSeg, pPg->iPg, pPg->nCompress+6, &iNext);
  3303   3308       return (rc!=LSM_OK || iNext==0);
  3304   3309     }
  3305   3310     return (pPg->iPg==pSeg->iLastPg);
  3306   3311   }
  3307   3312   #endif

Changes to ext/lsm1/lsm_main.c.

   579    579       case LSM_INFO_DB_STRUCTURE: {
   580    580         char **pzVal = va_arg(ap, char **);
   581    581         rc = lsmStructList(pDb, pzVal);
   582    582         break;
   583    583       }
   584    584   
   585    585       case LSM_INFO_ARRAY_STRUCTURE: {
   586         -      Pgno pgno = va_arg(ap, Pgno);
          586  +      LsmPgno pgno = va_arg(ap, LsmPgno);
   587    587         char **pzVal = va_arg(ap, char **);
   588    588         rc = lsmInfoArrayStructure(pDb, 0, pgno, pzVal);
   589    589         break;
   590    590       }
   591    591   
   592    592       case LSM_INFO_ARRAY_PAGES: {
   593         -      Pgno pgno = va_arg(ap, Pgno);
          593  +      LsmPgno pgno = va_arg(ap, LsmPgno);
   594    594         char **pzVal = va_arg(ap, char **);
   595    595         rc = lsmInfoArrayPages(pDb, pgno, pzVal);
   596    596         break;
   597    597       }
   598    598   
   599    599       case LSM_INFO_PAGE_HEX_DUMP:
   600    600       case LSM_INFO_PAGE_ASCII_DUMP: {
   601         -      Pgno pgno = va_arg(ap, Pgno);
          601  +      LsmPgno pgno = va_arg(ap, LsmPgno);
   602    602         char **pzVal = va_arg(ap, char **);
   603    603         int bUnlock = 0;
   604    604         rc = infoGetWorker(pDb, 0, &bUnlock);
   605    605         if( rc==LSM_OK ){
   606    606           int bHex = (eParam==LSM_INFO_PAGE_HEX_DUMP);
   607    607           rc = lsmInfoPageDump(pDb, pgno, bHex, pzVal);
   608    608         }

Changes to ext/lsm1/lsm_sorted.c.

   100    100   
   101    101   
   102    102   #ifndef LSM_SEGMENTPTR_FREE_THRESHOLD
   103    103   # define LSM_SEGMENTPTR_FREE_THRESHOLD 1024
   104    104   #endif
   105    105   
   106    106   typedef struct SegmentPtr SegmentPtr;
   107         -typedef struct Blob Blob;
          107  +typedef struct LsmBlob LsmBlob;
   108    108   
   109         -struct Blob {
          109  +struct LsmBlob {
   110    110     lsm_env *pEnv;
   111    111     void *pData;
   112    112     int nData;
   113    113     int nAlloc;
   114    114   };
   115    115   
   116    116   /*
................................................................................
   125    125     Level *pLevel;                /* Level object segment is part of */
   126    126     Segment *pSeg;                /* Segment to access */
   127    127   
   128    128     /* Current page. See segmentPtrLoadPage(). */
   129    129     Page *pPg;                    /* Current page */
   130    130     u16 flags;                    /* Copy of page flags field */
   131    131     int nCell;                    /* Number of cells on pPg */
   132         -  Pgno iPtr;                    /* Base cascade pointer */
          132  +  LsmPgno iPtr;                 /* Base cascade pointer */
   133    133   
   134    134     /* Current cell. See segmentPtrLoadCell() */
   135    135     int iCell;                    /* Current record within page pPg */
   136    136     int eType;                    /* Type of current record */
   137         -  Pgno iPgPtr;                  /* Cascade pointer offset */
          137  +  LsmPgno iPgPtr;               /* Cascade pointer offset */
   138    138     void *pKey; int nKey;         /* Key associated with current record */
   139    139     void *pVal; int nVal;         /* Current record value (eType==WRITE only) */
   140    140   
   141    141     /* Blobs used to allocate buffers for pKey and pVal as required */
   142         -  Blob blob1;
   143         -  Blob blob2;
          142  +  LsmBlob blob1;
          143  +  LsmBlob blob2;
   144    144   };
   145    145   
   146    146   /*
   147    147   ** Used to iterate through the keys stored in a b-tree hierarchy from start
   148    148   ** to finish. Only First() and Next() operations are required.
   149    149   **
   150    150   **   btreeCursorNew()
................................................................................
   167    167     int iPg;                        /* Current entry in aPg[]. -1 -> EOF. */
   168    168     BtreePg *aPg;                   /* Pages from root to current location */
   169    169   
   170    170     /* Cache of current entry. pKey==0 for EOF. */
   171    171     void *pKey;
   172    172     int nKey;
   173    173     int eType;
   174         -  Pgno iPtr;
          174  +  LsmPgno iPtr;
   175    175   
   176    176     /* Storage for key, if not local */
   177         -  Blob blob;
          177  +  LsmBlob blob;
   178    178   };
   179    179   
   180    180   
   181    181   /*
   182    182   ** A cursor used for merged searches or iterations through up to one
   183    183   ** Tree structure and any number of sorted files.
   184    184   **
................................................................................
   199    199   */
   200    200   struct MultiCursor {
   201    201     lsm_db *pDb;                    /* Connection that owns this cursor */
   202    202     MultiCursor *pNext;             /* Next cursor owned by connection pDb */
   203    203     int flags;                      /* Mask of CURSOR_XXX flags */
   204    204   
   205    205     int eType;                      /* Cache of current key type */
   206         -  Blob key;                       /* Cache of current key (or NULL) */
   207         -  Blob val;                       /* Cache of current value */
          206  +  LsmBlob key;                    /* Cache of current key (or NULL) */
          207  +  LsmBlob val;                    /* Cache of current value */
   208    208   
   209    209     /* All the component cursors: */
   210    210     TreeCursor *apTreeCsr[2];       /* Up to two tree cursors */
   211    211     int iFree;                      /* Next element of free-list (-ve for eof) */
   212    212     SegmentPtr *aPtr;               /* Array of segment pointers */
   213    213     int nPtr;                       /* Size of array aPtr[] */
   214    214     BtreeCursor *pBtCsr;            /* b-tree cursor (db writes only) */
................................................................................
   217    217     int nTree;                      /* Size of aTree[] array */
   218    218     int *aTree;                     /* Array of comparison results */
   219    219   
   220    220     /* Used by cursors flushing the in-memory tree only */
   221    221     void *pSystemVal;               /* Pointer to buffer to free */
   222    222   
   223    223     /* Used by worker cursors only */
   224         -  Pgno *pPrevMergePtr;
          224  +  LsmPgno *pPrevMergePtr;
   225    225   };
   226    226   
   227    227   /*
   228    228   ** The following constants are used to assign integers to each component
   229    229   ** cursor of a multi-cursor.
   230    230   */
   231    231   #define CURSOR_DATA_TREE0     0   /* Current tree cursor (apTreeCsr[0]) */
................................................................................
   291    291     lsm_db *pDb;                    /* Database handle */
   292    292     Level *pLevel;                  /* Worker snapshot Level being merged */
   293    293     MultiCursor *pCsr;              /* Cursor to read new segment contents from */
   294    294     int bFlush;                     /* True if this is an in-memory tree flush */
   295    295     Hierarchy hier;                 /* B-tree hierarchy under construction */
   296    296     Page *pPage;                    /* Current output page */
   297    297     int nWork;                      /* Number of calls to mergeWorkerNextPage() */
   298         -  Pgno *aGobble;                  /* Gobble point for each input segment */
          298  +  LsmPgno *aGobble;               /* Gobble point for each input segment */
   299    299   
   300         -  Pgno iIndirect;
          300  +  LsmPgno iIndirect;
   301    301     struct SavedPgno {
   302         -    Pgno iPgno;
          302  +    LsmPgno iPgno;
   303    303       int bStore;
   304    304     } aSave[2];
   305    305   };
   306    306   
   307    307   #ifdef LSM_DEBUG_EXPENSIVE
   308    308   static int assertPointersOk(lsm_db *, Segment *, Segment *, int);
   309    309   static int assertBtreeOk(lsm_db *, Segment *);
................................................................................
   367    367     aOut[3] = (u8)((nVal>>32) & 0xFF);
   368    368     aOut[4] = (u8)((nVal>>24) & 0xFF);
   369    369     aOut[5] = (u8)((nVal>>16) & 0xFF);
   370    370     aOut[6] = (u8)((nVal>> 8) & 0xFF);
   371    371     aOut[7] = (u8)((nVal    ) & 0xFF);
   372    372   }
   373    373   
   374         -static int sortedBlobGrow(lsm_env *pEnv, Blob *pBlob, int nData){
          374  +static int sortedBlobGrow(lsm_env *pEnv, LsmBlob *pBlob, int nData){
   375    375     assert( pBlob->pEnv==pEnv || (pBlob->pEnv==0 && pBlob->pData==0) );
   376    376     if( pBlob->nAlloc<nData ){
   377    377       pBlob->pData = lsmReallocOrFree(pEnv, pBlob->pData, nData);
   378    378       if( !pBlob->pData ) return LSM_NOMEM_BKPT;
   379    379       pBlob->nAlloc = nData;
   380    380       pBlob->pEnv = pEnv;
   381    381     }
   382    382     return LSM_OK;
   383    383   }
   384    384   
   385         -static int sortedBlobSet(lsm_env *pEnv, Blob *pBlob, void *pData, int nData){
          385  +static int sortedBlobSet(lsm_env *pEnv, LsmBlob *pBlob, void *pData, int nData){
   386    386     if( sortedBlobGrow(pEnv, pBlob, nData) ) return LSM_NOMEM;
   387    387     memcpy(pBlob->pData, pData, nData);
   388    388     pBlob->nData = nData;
   389    389     return LSM_OK;
   390    390   }
   391    391   
   392    392   #if 0
   393         -static int sortedBlobCopy(Blob *pDest, Blob *pSrc){
          393  +static int sortedBlobCopy(LsmBlob *pDest, LsmBlob *pSrc){
   394    394     return sortedBlobSet(pDest, pSrc->pData, pSrc->nData);
   395    395   }
   396    396   #endif
   397    397   
   398         -static void sortedBlobFree(Blob *pBlob){
          398  +static void sortedBlobFree(LsmBlob *pBlob){
   399    399     assert( pBlob->pEnv || pBlob->pData==0 );
   400    400     if( pBlob->pData ) lsmFree(pBlob->pEnv, pBlob->pData);
   401         -  memset(pBlob, 0, sizeof(Blob));
          401  +  memset(pBlob, 0, sizeof(LsmBlob));
   402    402   }
   403    403   
   404    404   static int sortedReadData(
   405    405     Segment *pSeg,
   406    406     Page *pPg,
   407    407     int iOff,
   408    408     int nByte,
   409    409     void **ppData,
   410         -  Blob *pBlob
          410  +  LsmBlob *pBlob
   411    411   ){
   412    412     int rc = LSM_OK;
   413    413     int iEnd;
   414    414     int nData;
   415    415     int nCell;
   416    416     u8 *aData;
   417    417   
................................................................................
   477    477     return rc;
   478    478   }
   479    479   
   480    480   static int pageGetNRec(u8 *aData, int nData){
   481    481     return (int)lsmGetU16(&aData[SEGMENT_NRECORD_OFFSET(nData)]);
   482    482   }
   483    483   
   484         -static Pgno pageGetPtr(u8 *aData, int nData){
   485         -  return (Pgno)lsmGetU64(&aData[SEGMENT_POINTER_OFFSET(nData)]);
          484  +static LsmPgno pageGetPtr(u8 *aData, int nData){
          485  +  return (LsmPgno)lsmGetU64(&aData[SEGMENT_POINTER_OFFSET(nData)]);
   486    486   }
   487    487   
   488    488   static int pageGetFlags(u8 *aData, int nData){
   489    489     return (int)lsmGetU16(&aData[SEGMENT_FLAGS_OFFSET(nData)]);
   490    490   }
   491    491   
   492    492   static u8 *pageGetCell(u8 *aData, int nData, int iCell){
................................................................................
   502    502     return pageGetNRec(aData, nData);
   503    503   }
   504    504   
   505    505   /*
   506    506   ** Return the decoded (possibly relative) pointer value stored in cell 
   507    507   ** iCell from page aData/nData.
   508    508   */
   509         -static Pgno pageGetRecordPtr(u8 *aData, int nData, int iCell){
   510         -  Pgno iRet;                      /* Return value */
          509  +static LsmPgno pageGetRecordPtr(u8 *aData, int nData, int iCell){
          510  +  LsmPgno iRet;                   /* Return value */
   511    511     u8 *aCell;                      /* Pointer to cell iCell */
   512    512   
   513    513     assert( iCell<pageGetNRec(aData, nData) && iCell>=0 );
   514    514     aCell = pageGetCell(aData, nData, iCell);
   515    515     lsmVarintGet64(&aCell[1], &iRet);
   516    516     return iRet;
   517    517   }
................................................................................
   518    518   
   519    519   static u8 *pageGetKey(
   520    520     Segment *pSeg,                  /* Segment pPg belongs to */
   521    521     Page *pPg,                      /* Page to read from */
   522    522     int iCell,                      /* Index of cell on page to read */
   523    523     int *piTopic,                   /* OUT: Topic associated with this key */
   524    524     int *pnKey,                     /* OUT: Size of key in bytes */
   525         -  Blob *pBlob                     /* If required, use this for dynamic memory */
          525  +  LsmBlob *pBlob                  /* If required, use this for dynamic memory */
   526    526   ){
   527    527     u8 *pKey;
   528    528     int nDummy;
   529    529     int eType;
   530    530     u8 *aData;
   531    531     int nData;
   532    532   
................................................................................
   550    550   
   551    551   static int pageGetKeyCopy(
   552    552     lsm_env *pEnv,                  /* Environment handle */
   553    553     Segment *pSeg,                  /* Segment pPg belongs to */
   554    554     Page *pPg,                      /* Page to read from */
   555    555     int iCell,                      /* Index of cell on page to read */
   556    556     int *piTopic,                   /* OUT: Topic associated with this key */
   557         -  Blob *pBlob                     /* If required, use this for dynamic memory */
          557  +  LsmBlob *pBlob                  /* If required, use this for dynamic memory */
   558    558   ){
   559    559     int rc = LSM_OK;
   560    560     int nKey;
   561    561     u8 *aKey;
   562    562   
   563    563     aKey = pageGetKey(pSeg, pPg, iCell, piTopic, &nKey, pBlob);
   564    564     assert( (void *)aKey!=pBlob->pData || nKey==pBlob->nData );
................................................................................
   565    565     if( (void *)aKey!=pBlob->pData ){
   566    566       rc = sortedBlobSet(pEnv, pBlob, aKey, nKey);
   567    567     }
   568    568   
   569    569     return rc;
   570    570   }
   571    571   
   572         -static Pgno pageGetBtreeRef(Page *pPg, int iKey){
   573         -  Pgno iRef;
          572  +static LsmPgno pageGetBtreeRef(Page *pPg, int iKey){
          573  +  LsmPgno iRef;
   574    574     u8 *aData;
   575    575     int nData;
   576    576     u8 *aCell;
   577    577   
   578    578     aData = fsPageData(pPg, &nData);
   579    579     aCell = pageGetCell(aData, nData, iKey);
   580    580     assert( aCell[0]==0 );
................................................................................
   588    588   #define GETVARINT64(a, i) (((i)=((u8*)(a))[0])<=240?1:lsmVarintGet64((a), &(i)))
   589    589   #define GETVARINT32(a, i) (((i)=((u8*)(a))[0])<=240?1:lsmVarintGet32((a), &(i)))
   590    590   
   591    591   static int pageGetBtreeKey(
   592    592     Segment *pSeg,                  /* Segment page pPg belongs to */
   593    593     Page *pPg,
   594    594     int iKey, 
   595         -  Pgno *piPtr, 
          595  +  LsmPgno *piPtr, 
   596    596     int *piTopic, 
   597    597     void **ppKey,
   598    598     int *pnKey,
   599         -  Blob *pBlob
          599  +  LsmBlob *pBlob
   600    600   ){
   601    601     u8 *aData;
   602    602     int nData;
   603    603     u8 *aCell;
   604    604     int eType;
   605    605   
   606    606     aData = fsPageData(pPg, &nData);
................................................................................
   609    609   
   610    610     aCell = pageGetCell(aData, nData, iKey);
   611    611     eType = *aCell++;
   612    612     aCell += GETVARINT64(aCell, *piPtr);
   613    613   
   614    614     if( eType==0 ){
   615    615       int rc;
   616         -    Pgno iRef;                  /* Page number of referenced page */
          616  +    LsmPgno iRef;               /* Page number of referenced page */
   617    617       Page *pRef;
   618    618       aCell += GETVARINT64(aCell, iRef);
   619    619       rc = lsmFsDbPageGet(lsmPageFS(pPg), pSeg, iRef, &pRef);
   620    620       if( rc!=LSM_OK ) return rc;
   621    621       pageGetKeyCopy(lsmPageEnv(pPg), pSeg, pRef, 0, &eType, pBlob);
   622    622       lsmFsPageRelease(pRef);
   623    623       *ppKey = pBlob->pData;
................................................................................
   634    634   static int btreeCursorLoadKey(BtreeCursor *pCsr){
   635    635     int rc = LSM_OK;
   636    636     if( pCsr->iPg<0 ){
   637    637       pCsr->pKey = 0;
   638    638       pCsr->nKey = 0;
   639    639       pCsr->eType = 0;
   640    640     }else{
   641         -    Pgno dummy;
          641  +    LsmPgno dummy;
   642    642       int iPg = pCsr->iPg;
   643    643       int iCell = pCsr->aPg[iPg].iCell;
   644    644       while( iCell<0 && (--iPg)>=0 ){
   645    645         iCell = pCsr->aPg[iPg].iCell-1;
   646    646       }
   647    647       if( iPg<0 || iCell<0 ) return LSM_CORRUPT_BKPT;
   648    648   
................................................................................
   679    679     assert( pCsr->iPg==pCsr->nDepth-1 );
   680    680   
   681    681     aData = fsPageData(pPg->pPage, &nData);
   682    682     nCell = pageGetNRec(aData, nData);
   683    683     assert( pPg->iCell<=nCell );
   684    684     pPg->iCell++;
   685    685     if( pPg->iCell==nCell ){
   686         -    Pgno iLoad;
          686  +    LsmPgno iLoad;
   687    687   
   688    688       /* Up to parent. */
   689    689       lsmFsPageRelease(pPg->pPage);
   690    690       pPg->pPage = 0;
   691    691       pCsr->iPg--;
   692    692       while( pCsr->iPg>=0 ){
   693    693         pPg = &pCsr->aPg[pCsr->iPg];
................................................................................
   838    838     MergeInput *p
   839    839   ){
   840    840     int rc = LSM_OK;
   841    841   
   842    842     if( p->iPg ){
   843    843       lsm_env *pEnv = lsmFsEnv(pCsr->pFS);
   844    844       int iCell;                    /* Current cell number on leaf page */
   845         -    Pgno iLeaf;                   /* Page number of current leaf page */
          845  +    LsmPgno iLeaf;                /* Page number of current leaf page */
   846    846       int nDepth;                   /* Depth of b-tree structure */
   847    847       Segment *pSeg = pCsr->pSeg;
   848    848   
   849    849       /* Decode the MergeInput structure */
   850    850       iLeaf = p->iPg;
   851    851       nDepth = (p->iCell & 0x00FF);
   852    852       iCell = (p->iCell >> 8) - 1;
................................................................................
   862    862         pCsr->nDepth = nDepth;
   863    863         pCsr->aPg[pCsr->iPg].iCell = iCell;
   864    864         rc = lsmFsDbPageGet(pCsr->pFS, pSeg, iLeaf, pp);
   865    865       }
   866    866   
   867    867       /* Populate any other aPg[] array entries */
   868    868       if( rc==LSM_OK && nDepth>1 ){
   869         -      Blob blob = {0,0,0};
          869  +      LsmBlob blob = {0,0,0};
   870    870         void *pSeek;
   871    871         int nSeek;
   872    872         int iTopicSeek;
   873    873         int iPg = 0;
   874    874         int iLoad = (int)pSeg->iRoot;
   875    875         Page *pPg = pCsr->aPg[nDepth-1].pPage;
   876    876    
................................................................................
   879    879           ** In this case, set the iTopicSeek/pSeek/nSeek key to a value
   880    880           ** greater than any real key.  */
   881    881           assert( iCell==-1 );
   882    882           iTopicSeek = 1000;
   883    883           pSeek = 0;
   884    884           nSeek = 0;
   885    885         }else{
   886         -        Pgno dummy;
          886  +        LsmPgno dummy;
   887    887           rc = pageGetBtreeKey(pSeg, pPg,
   888    888               0, &dummy, &iTopicSeek, &pSeek, &nSeek, &pCsr->blob
   889    889           );
   890    890         }
   891    891   
   892    892         do {
   893    893           Page *pPg2;
................................................................................
   908    908             iMax = iCell2-1;
   909    909             iMin = 0;
   910    910   
   911    911             while( iMax>=iMin ){
   912    912               int iTry = (iMin+iMax)/2;
   913    913               void *pKey; int nKey;         /* Key for cell iTry */
   914    914               int iTopic;                   /* Topic for key pKeyT/nKeyT */
   915         -            Pgno iPtr;                    /* Pointer for cell iTry */
          915  +            LsmPgno iPtr;                 /* Pointer for cell iTry */
   916    916               int res;                      /* (pSeek - pKeyT) */
   917    917   
   918    918               rc = pageGetBtreeKey(
   919    919                   pSeg, pPg2, iTry, &iPtr, &iTopic, &pKey, &nKey, &blob
   920    920               );
   921    921               if( rc!=LSM_OK ) break;
   922    922   
................................................................................
   951    951         u8 *aData;
   952    952         int nData;
   953    953   
   954    954         pBtreePg = &pCsr->aPg[pCsr->iPg];
   955    955         aData = fsPageData(pBtreePg->pPage, &nData);
   956    956         pCsr->iPtr = btreeCursorPtr(aData, nData, pBtreePg->iCell+1);
   957    957         if( pBtreePg->iCell<0 ){
   958         -        Pgno dummy;
          958  +        LsmPgno dummy;
   959    959           int i;
   960    960           for(i=pCsr->iPg-1; i>=0; i--){
   961    961             if( pCsr->aPg[i].iCell>0 ) break;
   962    962           }
   963    963           assert( i>=0 );
   964    964           rc = pageGetBtreeKey(pSeg,
   965    965               pCsr->aPg[i].pPage, pCsr->aPg[i].iCell-1,
................................................................................
  1026   1026   }
  1027   1027   
  1028   1028   static int segmentPtrReadData(
  1029   1029     SegmentPtr *pPtr,
  1030   1030     int iOff,
  1031   1031     int nByte,
  1032   1032     void **ppData,
  1033         -  Blob *pBlob
         1033  +  LsmBlob *pBlob
  1034   1034   ){
  1035   1035     return sortedReadData(pPtr->pSeg, pPtr->pPg, iOff, nByte, ppData, pBlob);
  1036   1036   }
  1037   1037   
  1038   1038   static int segmentPtrNextPage(
  1039   1039     SegmentPtr *pPtr,              /* Load page into this SegmentPtr object */
  1040   1040     int eDir                       /* +1 for next(), -1 for prev() */
................................................................................
  1119   1119   
  1120   1120     pSeg = sortedSplitkeySegment(pLevel);
  1121   1121     if( rc==LSM_OK ){
  1122   1122       rc = lsmFsDbPageGet(pDb->pFS, pSeg, pMerge->splitkey.iPg, &pPg);
  1123   1123     }
  1124   1124     if( rc==LSM_OK ){
  1125   1125       int iTopic;
  1126         -    Blob blob = {0, 0, 0, 0};
         1126  +    LsmBlob blob = {0, 0, 0, 0};
  1127   1127       u8 *aData;
  1128   1128       int nData;
  1129   1129     
  1130   1130       aData = lsmFsPageData(pPg, &nData);
  1131   1131       if( pageGetFlags(aData, nData) & SEGMENT_BTREE_FLAG ){
  1132   1132         void *pKey;
  1133   1133         int nKey;
  1134         -      Pgno dummy;
         1134  +      LsmPgno dummy;
  1135   1135         rc = pageGetBtreeKey(pSeg,
  1136   1136             pPg, pMerge->splitkey.iCell, &dummy, &iTopic, &pKey, &nKey, &blob
  1137   1137         );
  1138   1138         if( rc==LSM_OK && blob.pData!=pKey ){
  1139   1139           rc = sortedBlobSet(pEnv, &blob, pKey, nKey);
  1140   1140         }
  1141   1141       }else{
................................................................................
  1338   1338   */
  1339   1339   static int assertKeyLocation(
  1340   1340     MultiCursor *pCsr, 
  1341   1341     SegmentPtr *pPtr, 
  1342   1342     void *pKey, int nKey
  1343   1343   ){
  1344   1344     lsm_env *pEnv = lsmFsEnv(pCsr->pDb->pFS);
  1345         -  Blob blob = {0, 0, 0};
         1345  +  LsmBlob blob = {0, 0, 0};
  1346   1346     int eDir;
  1347   1347     int iTopic = 0;                 /* TODO: Fix me */
  1348   1348   
  1349   1349     for(eDir=-1; eDir<=1; eDir+=2){
  1350   1350       Page *pTest = pPtr->pPg;
  1351   1351   
  1352   1352       lsmFsPageRef(pTest);
................................................................................
  1484   1484     return rc;
  1485   1485   }
  1486   1486   
  1487   1487   static int ptrFwdPointer(
  1488   1488     Page *pPage,
  1489   1489     int iCell,
  1490   1490     Segment *pSeg,
  1491         -  Pgno *piPtr,
         1491  +  LsmPgno *piPtr,
  1492   1492     int *pbFound
  1493   1493   ){
  1494   1494     Page *pPg = pPage;
  1495   1495     int iFirst = iCell;
  1496   1496     int rc = LSM_OK;
  1497   1497   
  1498   1498     do {
................................................................................
  1569   1569   **   much better if the multi-cursor could do this lazily - only seek to the
  1570   1570   **   level (N+1) page after the user has moved the cursor on level N passed
  1571   1571   **   the big range-delete.
  1572   1572   */
  1573   1573   static int segmentPtrFwdPointer(
  1574   1574     MultiCursor *pCsr,              /* Multi-cursor pPtr belongs to */
  1575   1575     SegmentPtr *pPtr,               /* Segment-pointer to extract FC ptr from */
  1576         -  Pgno *piPtr                     /* OUT: FC pointer value */
         1576  +  LsmPgno *piPtr                  /* OUT: FC pointer value */
  1577   1577   ){
  1578   1578     Level *pLvl = pPtr->pLevel;
  1579   1579     Level *pNext = pLvl->pNext;
  1580   1580     Page *pPg = pPtr->pPg;
  1581   1581     int rc;
  1582   1582     int bFound;
  1583         -  Pgno iOut = 0;
         1583  +  LsmPgno iOut = 0;
  1584   1584   
  1585   1585     if( pPtr->pSeg==&pLvl->lhs || pPtr->pSeg==&pLvl->aRhs[pLvl->nRight-1] ){
  1586   1586       if( pNext==0 
  1587   1587           || (pNext->nRight==0 && pNext->lhs.iRoot)
  1588   1588           || (pNext->nRight!=0 && pNext->aRhs[0].iRoot)
  1589   1589         ){
  1590   1590         /* Do nothing. The pointer will not be used anyway. */
................................................................................
  1637   1637     int *pbStop
  1638   1638   ){
  1639   1639     int (*xCmp)(void *, int, void *, int) = pCsr->pDb->xCmp;
  1640   1640     int res = 0;                        /* Result of comparison operation */
  1641   1641     int rc = LSM_OK;
  1642   1642     int iMin;
  1643   1643     int iMax;
  1644         -  Pgno iPtrOut = 0;
         1644  +  LsmPgno iPtrOut = 0;
  1645   1645   
  1646   1646     /* If the current page contains an oversized entry, then there are no
  1647   1647     ** pointers to one or more of the subsequent pages in the sorted run.
  1648   1648     ** The following call ensures that the segment-ptr points to the correct 
  1649   1649     ** page in this case.  */
  1650   1650     rc = segmentPtrSearchOversized(pCsr, pPtr, iTopic, pKey, nKey);
  1651   1651     iPtrOut = pPtr->iPtr;
................................................................................
  1764   1764   }
  1765   1765   
  1766   1766   static int seekInBtree(
  1767   1767     MultiCursor *pCsr,              /* Multi-cursor object */
  1768   1768     Segment *pSeg,                  /* Seek within this segment */
  1769   1769     int iTopic,
  1770   1770     void *pKey, int nKey,           /* Key to seek to */
  1771         -  Pgno *aPg,                      /* OUT: Page numbers */
         1771  +  LsmPgno *aPg,                   /* OUT: Page numbers */
  1772   1772     Page **ppPg                     /* OUT: Leaf (sorted-run) page reference */
  1773   1773   ){
  1774   1774     int i = 0;
  1775   1775     int rc;
  1776   1776     int iPg;
  1777   1777     Page *pPg = 0;
  1778         -  Blob blob = {0, 0, 0};
         1778  +  LsmBlob blob = {0, 0, 0};
  1779   1779   
  1780   1780     iPg = (int)pSeg->iRoot;
  1781   1781     do {
  1782         -    Pgno *piFirst = 0;
         1782  +    LsmPgno *piFirst = 0;
  1783   1783       if( aPg ){
  1784   1784         aPg[i++] = iPg;
  1785   1785         piFirst = &aPg[i];
  1786   1786       }
  1787   1787   
  1788   1788       rc = lsmFsDbPageGet(pCsr->pDb->pFS, pSeg, iPg, &pPg);
  1789   1789       assert( rc==LSM_OK || pPg==0 );
................................................................................
  1804   1804   
  1805   1805         iMin = 0;
  1806   1806         iMax = nRec-1;
  1807   1807         while( iMax>=iMin ){
  1808   1808           int iTry = (iMin+iMax)/2;
  1809   1809           void *pKeyT; int nKeyT;       /* Key for cell iTry */
  1810   1810           int iTopicT;                  /* Topic for key pKeyT/nKeyT */
  1811         -        Pgno iPtr;                    /* Pointer associated with cell iTry */
         1811  +        LsmPgno iPtr;                 /* Pointer associated with cell iTry */
  1812   1812           int res;                      /* (pKey - pKeyT) */
  1813   1813   
  1814   1814           rc = pageGetBtreeKey(
  1815   1815               pSeg, pPg, iTry, &iPtr, &iTopicT, &pKeyT, &nKeyT, &blob
  1816   1816           );
  1817   1817           if( rc!=LSM_OK ) break;
  1818   1818           if( piFirst && pKeyT==blob.pData ){
................................................................................
  1895   1895   */
  1896   1896   static int seekInLevel(
  1897   1897     MultiCursor *pCsr,              /* Sorted cursor object to seek */
  1898   1898     SegmentPtr *aPtr,               /* Pointer to array of (nRhs+1) SPs */
  1899   1899     int eSeek,                      /* Search bias - see above */
  1900   1900     int iTopic,                     /* Key topic to search for */
  1901   1901     void *pKey, int nKey,           /* Key to search for */
  1902         -  Pgno *piPgno,                   /* IN/OUT: fraction cascade pointer (or 0) */
         1902  +  LsmPgno *piPgno,                /* IN/OUT: fraction cascade pointer (or 0) */
  1903   1903     int *pbStop                     /* OUT: See above */
  1904   1904   ){
  1905   1905     Level *pLvl = aPtr[0].pLevel;   /* Level to seek within */
  1906   1906     int rc = LSM_OK;                /* Return code */
  1907   1907     int iOut = 0;                   /* Pointer to return to caller */
  1908   1908     int res = -1;                   /* Result of xCmp(pKey, split) */
  1909   1909     int nRhs = pLvl->nRight;        /* Number of right-hand-side segments */
................................................................................
  3051   3051     void *pKey, int nKey, 
  3052   3052     int eSeek
  3053   3053   ){
  3054   3054     int eESeek = eSeek;             /* Effective eSeek parameter */
  3055   3055     int bStop = 0;                  /* Set to true to halt search operation */
  3056   3056     int rc = LSM_OK;                /* Return code */
  3057   3057     int iPtr = 0;                   /* Used to iterate through pCsr->aPtr[] */
  3058         -  Pgno iPgno = 0;                 /* FC pointer value */
         3058  +  LsmPgno iPgno = 0;              /* FC pointer value */
  3059   3059   
  3060   3060     assert( pCsr->apTreeCsr[0]==0 || iTopic==0 );
  3061   3061     assert( pCsr->apTreeCsr[1]==0 || iTopic==0 );
  3062   3062   
  3063   3063     if( eESeek==LSM_SEEK_LEFAST ) eESeek = LSM_SEEK_LE;
  3064   3064   
  3065   3065     assert( eESeek==LSM_SEEK_EQ || eESeek==LSM_SEEK_LE || eESeek==LSM_SEEK_GE );
................................................................................
  3533   3533   ** differences are:
  3534   3534   **
  3535   3535   **   1. The record format is (usually, see below) as follows:
  3536   3536   **
  3537   3537   **         + Type byte (always SORTED_SEPARATOR or SORTED_SYSTEM_SEPARATOR),
  3538   3538   **         + Absolute pointer value (varint),
  3539   3539   **         + Number of bytes in key (varint),
  3540         -**         + Blob containing key data.
         3540  +**         + LsmBlob containing key data.
  3541   3541   **
  3542   3542   **   2. All pointer values are stored as absolute values (not offsets 
  3543   3543   **      relative to the footer pointer value).
  3544   3544   **
  3545   3545   **   3. Each pointer that is part of a record points to a page that 
  3546   3546   **      contains keys smaller than the records key (note: not "equal to or
  3547   3547   **      smaller than - smaller than").
................................................................................
  3567   3567   **
  3568   3568   ** See function seekInBtree() for the code that traverses b-tree pages.
  3569   3569   */
  3570   3570   
  3571   3571   static int mergeWorkerBtreeWrite(
  3572   3572     MergeWorker *pMW,
  3573   3573     u8 eType,
  3574         -  Pgno iPtr,
  3575         -  Pgno iKeyPg,
         3574  +  LsmPgno iPtr,
         3575  +  LsmPgno iKeyPg,
  3576   3576     void *pKey,
  3577   3577     int nKey
  3578   3578   ){
  3579   3579     Hierarchy *p = &pMW->hier;
  3580   3580     lsm_db *pDb = pMW->pDb;         /* Database handle */
  3581   3581     int rc = LSM_OK;                /* Return Code */
  3582   3582     int iLevel;                     /* Level of b-tree hierachy to write to */
................................................................................
  3678   3678   
  3679   3679     return rc;
  3680   3680   }
  3681   3681   
  3682   3682   static int mergeWorkerBtreeIndirect(MergeWorker *pMW){
  3683   3683     int rc = LSM_OK;
  3684   3684     if( pMW->iIndirect ){
  3685         -    Pgno iKeyPg = pMW->aSave[1].iPgno;
         3685  +    LsmPgno iKeyPg = pMW->aSave[1].iPgno;
  3686   3686       rc = mergeWorkerBtreeWrite(pMW, 0, pMW->iIndirect, iKeyPg, 0, 0);
  3687   3687       pMW->iIndirect = 0;
  3688   3688     }
  3689   3689     return rc;
  3690   3690   }
  3691   3691   
  3692   3692   /*
................................................................................
  3699   3699   static int mergeWorkerPushHierarchy(
  3700   3700     MergeWorker *pMW,               /* Merge worker object */
  3701   3701     int iTopic,                     /* Topic value for this key */
  3702   3702     void *pKey,                     /* Pointer to key buffer */
  3703   3703     int nKey                        /* Size of pKey buffer in bytes */
  3704   3704   ){
  3705   3705     int rc = LSM_OK;                /* Return Code */
  3706         -  Pgno iPtr;                      /* Pointer value to accompany pKey/nKey */
         3706  +  LsmPgno iPtr;                   /* Pointer value to accompany pKey/nKey */
  3707   3707   
  3708   3708     assert( pMW->aSave[0].bStore==0 );
  3709   3709     assert( pMW->aSave[1].bStore==0 );
  3710   3710     rc = mergeWorkerBtreeIndirect(pMW);
  3711   3711   
  3712   3712     /* Obtain the absolute pointer value to store along with the key in the
  3713   3713     ** page body. This pointer points to a page that contains keys that are
................................................................................
  3730   3730   }
  3731   3731   
  3732   3732   static int mergeWorkerFinishHierarchy(
  3733   3733     MergeWorker *pMW                /* Merge worker object */
  3734   3734   ){
  3735   3735     int i;                          /* Used to loop through apHier[] */
  3736   3736     int rc = LSM_OK;                /* Return code */
  3737         -  Pgno iPtr;                      /* New right-hand-child pointer value */
         3737  +  LsmPgno iPtr;                   /* New right-hand-child pointer value */
  3738   3738   
  3739   3739     iPtr = pMW->aSave[0].iPgno;
  3740   3740     for(i=0; i<pMW->hier.nHier && rc==LSM_OK; i++){
  3741   3741       Page *pPg = pMW->hier.apHier[i];
  3742   3742       int nData;                    /* Size of aData[] in bytes */
  3743   3743       u8 *aData;                    /* Page data for pPg */
  3744   3744   
................................................................................
  3826   3826   ** zero records. The flags field is cleared. The page footer pointer field
  3827   3827   ** is set to iFPtr.
  3828   3828   **
  3829   3829   ** If successful, LSM_OK is returned. Otherwise, an error code.
  3830   3830   */
  3831   3831   static int mergeWorkerNextPage(
  3832   3832     MergeWorker *pMW,               /* Merge worker object to append page to */
  3833         -  Pgno iFPtr                      /* Pointer value for footer of new page */
         3833  +  LsmPgno iFPtr                   /* Pointer value for footer of new page */
  3834   3834   ){
  3835   3835     int rc = LSM_OK;                /* Return code */
  3836   3836     Page *pNext = 0;                /* New page appended to run */
  3837   3837     lsm_db *pDb = pMW->pDb;         /* Database handle */
  3838   3838   
  3839   3839     rc = lsmFsSortedAppend(pDb->pFS, pDb->pWorker, pMW->pLevel, 0, &pNext);
  3840   3840     assert( rc || pMW->pLevel->lhs.iFirst>0 || pMW->pDb->compress.xCompress );
................................................................................
  4214   4214   
  4215   4215   static int mergeWorkerStep(MergeWorker *pMW){
  4216   4216     lsm_db *pDb = pMW->pDb;       /* Database handle */
  4217   4217     MultiCursor *pCsr;            /* Cursor to read input data from */
  4218   4218     int rc = LSM_OK;              /* Return code */
  4219   4219     int eType;                    /* SORTED_SEPARATOR, WRITE or DELETE */
  4220   4220     void *pKey; int nKey;         /* Key */
  4221         -  Pgno iPtr;
         4221  +  LsmPgno iPtr;
  4222   4222     int iVal;
  4223   4223   
  4224   4224     pCsr = pMW->pCsr;
  4225   4225   
  4226   4226     /* Pull the next record out of the source cursor. */
  4227   4227     lsmMCursorKey(pCsr, &pKey, &nKey);
  4228   4228     eType = pCsr->eType;
................................................................................
  4367   4367         multiCursorIgnoreDelete(pCsr);
  4368   4368       }
  4369   4369     }
  4370   4370   
  4371   4371     if( rc!=LSM_OK ){
  4372   4372       lsmMCursorClose(pCsr, 0);
  4373   4373     }else{
  4374         -    Pgno iLeftPtr = 0;
         4374  +    LsmPgno iLeftPtr = 0;
  4375   4375       Merge merge;                  /* Merge object used to create new level */
  4376   4376       MergeWorker mergeworker;      /* MergeWorker object for the same purpose */
  4377   4377   
  4378   4378       memset(&merge, 0, sizeof(Merge));
  4379   4379       memset(&mergeworker, 0, sizeof(MergeWorker));
  4380   4380   
  4381   4381       pNew->pMerge = &merge;
................................................................................
  4544   4544     assert( pDb->pWorker );
  4545   4545     assert( pLevel->pMerge );
  4546   4546     assert( pLevel->nRight>0 );
  4547   4547   
  4548   4548     memset(pMW, 0, sizeof(MergeWorker));
  4549   4549     pMW->pDb = pDb;
  4550   4550     pMW->pLevel = pLevel;
  4551         -  pMW->aGobble = lsmMallocZeroRc(pDb->pEnv, sizeof(Pgno) * pLevel->nRight, &rc);
         4551  +  pMW->aGobble = lsmMallocZeroRc(pDb->pEnv, sizeof(LsmPgno)*pLevel->nRight,&rc);
  4552   4552   
  4553   4553     /* Create a multi-cursor to read the data to write to the new
  4554   4554     ** segment. The new segment contains:
  4555   4555     **
  4556   4556     **   1. Records from LHS of each of the nMerge levels being merged.
  4557   4557     **   2. Separators from either the last level being merged, or the
  4558   4558     **      separators attached to the LHS of the following level, or neither.
................................................................................
  4626   4626     lsm_db *pDb,                    /* Worker connection */
  4627   4627     MultiCursor *pCsr,              /* Multi-cursor being used for a merge */
  4628   4628     int iGobble                     /* pCsr->aPtr[] entry to operate on */
  4629   4629   ){
  4630   4630     int rc = LSM_OK;
  4631   4631     if( rtTopic(pCsr->eType)==0 ){
  4632   4632       Segment *pSeg = pCsr->aPtr[iGobble].pSeg;
  4633         -    Pgno *aPg;
         4633  +    LsmPgno *aPg;
  4634   4634       int nPg;
  4635   4635   
  4636   4636       /* Seek from the root of the b-tree to the segment leaf that may contain
  4637   4637       ** a key equal to the one multi-cursor currently points to. Record the
  4638   4638       ** page number of each b-tree page and the leaf. The segment may be
  4639   4639       ** gobbled up to (but not including) the first of these page numbers.
  4640   4640       */
  4641   4641       assert( pSeg->iRoot>0 );
  4642         -    aPg = lsmMallocZeroRc(pDb->pEnv, sizeof(Pgno)*32, &rc);
         4642  +    aPg = lsmMallocZeroRc(pDb->pEnv, sizeof(LsmPgno)*32, &rc);
  4643   4643       if( rc==LSM_OK ){
  4644   4644         rc = seekInBtree(pCsr, pSeg, 
  4645   4645             rtTopic(pCsr->eType), pCsr->key.pData, pCsr->key.nData, aPg, 0
  4646   4646         ); 
  4647   4647       }
  4648   4648   
  4649   4649       if( rc==LSM_OK ){
................................................................................
  5462   5462   /*
  5463   5463   ** Return a string representation of the segment passed as the only argument.
  5464   5464   ** Space for the returned string is allocated using lsmMalloc(), and should
  5465   5465   ** be freed by the caller using lsmFree().
  5466   5466   */
  5467   5467   static char *segToString(lsm_env *pEnv, Segment *pSeg, int nMin){
  5468   5468     int nSize = pSeg->nSize;
  5469         -  Pgno iRoot = pSeg->iRoot;
  5470         -  Pgno iFirst = pSeg->iFirst;
  5471         -  Pgno iLast = pSeg->iLastPg;
         5469  +  LsmPgno iRoot = pSeg->iRoot;
         5470  +  LsmPgno iFirst = pSeg->iFirst;
         5471  +  LsmPgno iLast = pSeg->iLastPg;
  5472   5472     char *z;
  5473   5473   
  5474   5474     char *z1;
  5475   5475     char *z2;
  5476   5476     int nPad;
  5477   5477   
  5478   5478     z1 = lsmMallocPrintf(pEnv, "%d.%d", iFirst, iLast);
................................................................................
  5523   5523       aBuf[0] = '\0';
  5524   5524     }
  5525   5525   
  5526   5526     return i;
  5527   5527   }
  5528   5528   
  5529   5529   void sortedDumpPage(lsm_db *pDb, Segment *pRun, Page *pPg, int bVals){
  5530         -  Blob blob = {0, 0, 0};         /* Blob used for keys */
         5530  +  LsmBlob blob = {0, 0, 0};       /* LsmBlob used for keys */
  5531   5531     LsmString s;
  5532   5532     int i;
  5533   5533   
  5534   5534     int nRec;
  5535   5535     int iPtr;
  5536   5536     int flags;
  5537   5537     u8 *aData;
................................................................................
  5559   5559   
  5560   5560       aCell = pageGetCell(aData, nData, i);
  5561   5561       eType = *aCell++;
  5562   5562       assert( (flags & SEGMENT_BTREE_FLAG) || eType!=0 );
  5563   5563       aCell += lsmVarintGet32(aCell, &iPgPtr);
  5564   5564   
  5565   5565       if( eType==0 ){
  5566         -      Pgno iRef;                  /* Page number of referenced page */
         5566  +      LsmPgno iRef;               /* Page number of referenced page */
  5567   5567         aCell += lsmVarintGet64(aCell, &iRef);
  5568   5568         lsmFsDbPageGet(pDb->pFS, pRun, iRef, &pRef);
  5569   5569         aKey = pageGetKey(pRun, pRef, 0, &iTopic, &nKey, &blob);
  5570   5570       }else{
  5571   5571         aCell += lsmVarintGet32(aCell, &nKey);
  5572   5572         if( rtIsWrite(eType) ) aCell += lsmVarintGet32(aCell, &nVal);
  5573   5573         sortedReadData(0, pPg, (aCell-aData), nKey+nVal, (void **)&aKey, &blob);
................................................................................
  5603   5603     int bIndirect,                  /* True to follow indirect refs */
  5604   5604     Page *pPg,
  5605   5605     int iCell,
  5606   5606     int *peType,
  5607   5607     int *piPgPtr,
  5608   5608     u8 **paKey, int *pnKey,
  5609   5609     u8 **paVal, int *pnVal,
  5610         -  Blob *pBlob
         5610  +  LsmBlob *pBlob
  5611   5611   ){
  5612   5612     u8 *aData; int nData;           /* Page data */
  5613   5613     u8 *aKey; int nKey = 0;         /* Key */
  5614   5614     u8 *aVal = 0; int nVal = 0;     /* Value */
  5615   5615     int eType;
  5616   5616     int iPgPtr;
  5617   5617     Page *pRef = 0;                 /* Pointer to page iRef */
................................................................................
  5621   5621   
  5622   5622     aCell = pageGetCell(aData, nData, iCell);
  5623   5623     eType = *aCell++;
  5624   5624     aCell += lsmVarintGet32(aCell, &iPgPtr);
  5625   5625   
  5626   5626     if( eType==0 ){
  5627   5627       int dummy;
  5628         -    Pgno iRef;                  /* Page number of referenced page */
         5628  +    LsmPgno iRef;                 /* Page number of referenced page */
  5629   5629       aCell += lsmVarintGet64(aCell, &iRef);
  5630   5630       if( bIndirect ){
  5631   5631         lsmFsDbPageGet(pDb->pFS, pSeg, iRef, &pRef);
  5632   5632         pageGetKeyCopy(pDb->pEnv, pSeg, pRef, 0, &dummy, pBlob);
  5633   5633         aKey = (u8 *)pBlob->pData;
  5634   5634         nKey = pBlob->nData;
  5635   5635         lsmFsPageRelease(pRef);
................................................................................
  5667   5667   #define INFO_PAGE_DUMP_DATA     0x01
  5668   5668   #define INFO_PAGE_DUMP_VALUES   0x02
  5669   5669   #define INFO_PAGE_DUMP_HEX      0x04
  5670   5670   #define INFO_PAGE_DUMP_INDIRECT 0x08
  5671   5671   
  5672   5672   static int infoPageDump(
  5673   5673     lsm_db *pDb,                    /* Database handle */
  5674         -  Pgno iPg,                       /* Page number of page to dump */
         5674  +  LsmPgno iPg,                    /* Page number of page to dump */
  5675   5675     int flags,
  5676   5676     char **pzOut                    /* OUT: lsmMalloc'd string */
  5677   5677   ){
  5678   5678     int rc = LSM_OK;                /* Return code */
  5679   5679     Page *pPg = 0;                  /* Handle for page iPg */
  5680   5680     int i, j;                       /* Loop counters */
  5681   5681     const int perLine = 16;         /* Bytes per line in the raw hex dump */
................................................................................
  5708   5708     ** to pass a NULL in place of the segment pointer as the second argument
  5709   5709     ** to lsmFsDbPageGet() here.  */
  5710   5710     if( rc==LSM_OK ){
  5711   5711       rc = lsmFsDbPageGet(pDb->pFS, 0, iPg, &pPg);
  5712   5712     }
  5713   5713   
  5714   5714     if( rc==LSM_OK ){
  5715         -    Blob blob = {0, 0, 0, 0};
         5715  +    LsmBlob blob = {0, 0, 0, 0};
  5716   5716       int nKeyWidth = 0;
  5717   5717       LsmString str;
  5718   5718       int nRec;
  5719   5719       int iPtr;
  5720   5720       int flags2;
  5721   5721       int iCell;
  5722   5722       u8 *aData; int nData;         /* Page data and size thereof */
................................................................................
  5743   5743       if( bHex ) nKeyWidth = nKeyWidth * 2;
  5744   5744   
  5745   5745       for(iCell=0; iCell<nRec; iCell++){
  5746   5746         u8 *aKey; int nKey = 0;       /* Key */
  5747   5747         u8 *aVal; int nVal = 0;       /* Value */
  5748   5748         int iPgPtr;
  5749   5749         int eType;
  5750         -      Pgno iAbsPtr;
         5750  +      LsmPgno iAbsPtr;
  5751   5751         char zFlags[8];
  5752   5752   
  5753   5753         infoCellDump(pDb, pSeg, bIndirect, pPg, iCell, &eType, &iPgPtr,
  5754   5754             &aKey, &nKey, &aVal, &nVal, &blob
  5755   5755         );
  5756   5756         iAbsPtr = iPgPtr + ((flags2 & SEGMENT_BTREE_FLAG) ? 0 : iPtr);
  5757   5757   
................................................................................
  5809   5809     }
  5810   5810   
  5811   5811     return rc;
  5812   5812   }
  5813   5813   
  5814   5814   int lsmInfoPageDump(
  5815   5815     lsm_db *pDb,                    /* Database handle */
  5816         -  Pgno iPg,                       /* Page number of page to dump */
         5816  +  LsmPgno iPg,                    /* Page number of page to dump */
  5817   5817     int bHex,                       /* True to output key/value in hex form */
  5818   5818     char **pzOut                    /* OUT: lsmMalloc'd string */
  5819   5819   ){
  5820   5820     int flags = INFO_PAGE_DUMP_DATA | INFO_PAGE_DUMP_VALUES;
  5821   5821     if( bHex ) flags |= INFO_PAGE_DUMP_HEX;
  5822   5822     return infoPageDump(pDb, iPg, flags, pzOut);
  5823   5823   }
................................................................................
  5985   5985     iHdr = SEGMENT_EOF(nOrig, nEntry);
  5986   5986     memmove(&aData[iHdr + (nData-nOrig)], &aData[iHdr], nOrig-iHdr);
  5987   5987   }
  5988   5988   
  5989   5989   #ifdef LSM_DEBUG_EXPENSIVE
  5990   5990   static void assertRunInOrder(lsm_db *pDb, Segment *pSeg){
  5991   5991     Page *pPg = 0;
  5992         -  Blob blob1 = {0, 0, 0, 0};
  5993         -  Blob blob2 = {0, 0, 0, 0};
         5992  +  LsmBlob blob1 = {0, 0, 0, 0};
         5993  +  LsmBlob blob2 = {0, 0, 0, 0};
  5994   5994   
  5995   5995     lsmFsDbPageGet(pDb->pFS, pSeg, pSeg->iFirst, &pPg);
  5996   5996     while( pPg ){
  5997   5997       u8 *aData; int nData;
  5998   5998       Page *pNext;
  5999   5999   
  6000   6000       aData = lsmFsPageData(pPg, &nData);
................................................................................
  6048   6048     Segment *pOne,                  /* Segment containing pointers */
  6049   6049     Segment *pTwo,                  /* Segment containing pointer targets */
  6050   6050     int bRhs                        /* True if pTwo may have been Gobble()d */
  6051   6051   ){
  6052   6052     int rc = LSM_OK;                /* Error code */
  6053   6053     SegmentPtr ptr1;                /* Iterates through pOne */
  6054   6054     SegmentPtr ptr2;                /* Iterates through pTwo */
  6055         -  Pgno iPrev;
         6055  +  LsmPgno iPrev;
  6056   6056   
  6057   6057     assert( pOne && pTwo );
  6058   6058   
  6059   6059     memset(&ptr1, 0, sizeof(ptr1));
  6060   6060     memset(&ptr2, 0, sizeof(ptr1));
  6061   6061     ptr1.pSeg = pOne;
  6062   6062     ptr2.pSeg = pTwo;
................................................................................
  6071   6071     }
  6072   6072   
  6073   6073     if( rc==LSM_OK && ptr1.nCell>0 ){
  6074   6074       rc = segmentPtrLoadCell(&ptr1, 0);
  6075   6075     }
  6076   6076         
  6077   6077     while( rc==LSM_OK && ptr2.pPg ){
  6078         -    Pgno iThis;
         6078  +    LsmPgno iThis;
  6079   6079   
  6080   6080       /* Advance to the next page of segment pTwo that contains at least
  6081   6081       ** one cell. Break out of the loop if the iterator reaches EOF.  */
  6082   6082       do{
  6083   6083         rc = segmentPtrNextPage(&ptr2, 1);
  6084   6084         assert( rc==LSM_OK );
  6085   6085       }while( rc==LSM_OK && ptr2.pPg && ptr2.nCell==0 );
................................................................................
  6133   6133   */
  6134   6134   static int assertBtreeOk(
  6135   6135     lsm_db *pDb,
  6136   6136     Segment *pSeg
  6137   6137   ){
  6138   6138     int rc = LSM_OK;                /* Return code */
  6139   6139     if( pSeg->iRoot ){
  6140         -    Blob blob = {0, 0, 0};        /* Buffer used to cache overflow keys */
         6140  +    LsmBlob blob = {0, 0, 0};     /* Buffer used to cache overflow keys */
  6141   6141       FileSystem *pFS = pDb->pFS;   /* File system to read from */
  6142   6142       Page *pPg = 0;                /* Main run page */
  6143   6143       BtreeCursor *pCsr = 0;        /* Btree cursor */
  6144   6144   
  6145   6145       rc = btreeCursorNew(pDb, pSeg, &pCsr);
  6146   6146       if( rc==LSM_OK ){
  6147   6147         rc = btreeCursorFirst(pCsr);