]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Removing some surplus files. (CVS 1723)
authordrh <drh@noemail.net>
Sat, 15 Sep 2001 00:59:33 +0000 (00:59 +0000)
committerdrh <drh@noemail.net>
Sat, 15 Sep 2001 00:59:33 +0000 (00:59 +0000)
FossilOrigin-Name: 8ad996fdac6801768e94ca1710a0a3da03e1e7ea

manifest
manifest.uuid
src/ex/README [deleted file]
src/ex/db.c [deleted file]
src/ex/db.h [deleted file]
src/ex/dbbebdb1.c [deleted file]
src/ex/dbbemird.c [deleted file]
src/ex/pg.c [deleted file]
src/ex/pg.h [deleted file]
src/ex/sizes.tcl [deleted file]

index ae357ca530e1f453cc051383e72a926df6e72f0d..56603b0a9e8c639869206af9a9ffd98e34dbe384 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Release\s2.0-alpha-1\s(CVS\s247)
-D 2001-09-15T00:58:00
+C Removing\ssome\ssurplus\sfiles.\s(CVS\s1723)
+D 2001-09-15T00:59:33
 F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
 F Makefile.in 6f4536369ce59b0ee7941f743c65c2c7f703ad2a
 F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
@@ -17,14 +17,6 @@ F src/btree.c 3adf545b8e072000923f7e0f7f91d33072a9f869
 F src/btree.h a3d9c20fa876e837680745ac60500be697026b7b
 F src/build.c 8359e553db8138d09f44957e2d1bcc9b8720117b
 F src/delete.c c84b5a26e29fda3c3de51345073a76bb161271fd
-F src/ex/README b745b00acce2d892f60c40111dacdfc48e0c1c7a
-F src/ex/db.c f1419ae6c93e40b5ac6e39fe7efd95d868e6f9d7
-F src/ex/db.h 3f2933ee20c147fe494835786e4c6f3a562def4e
-F src/ex/dbbebdb1.c 61ed414307f829478614def33de640bbe5b2f770
-F src/ex/dbbemird.c b00aef85656fa0a101dac2c32e12922ad106715a
-F src/ex/pg.c 2bbf6a94f37226d06337868b6bf4d7affc60197f
-F src/ex/pg.h 23a4ac807b0546ec2bb6239ec8bd3e06926572cd
-F src/ex/sizes.tcl f54bad4a2ac567624be59131a6ee42d71b41a3d7
 F src/expr.c bcd91d0487c71cfa44413a46efe5e2c2244901b6
 F src/insert.c 750a44c0d205779b2c42b0791a163937cfb00e74
 F src/main.c 73be8d00a8a9bbec715a6260840a19020a074090
@@ -105,7 +97,7 @@ F www/opcode.tcl cb3a1abf8b7b9be9f3a228d097d6bf8b742c2b6f
 F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f
 F www/tclsqlite.tcl 06f81c401f79a04f2c5ebfb97e7c176225c0aef2
 F www/vdbe.tcl 0c8aaa529dd216ccbf7daaabd80985e413d5f9ad
-P 14474fa144fe7c5dc63e0990d6cc92d769e6013e
-R e56932550882bb08b5533a7aa309b70c
+P 264f23315e682909abb47912f48733f641772a4c
+R b059993507a776d66a3417f913643af9
 U drh
-Z a235c7cc967e6bb6f207b8f3132939fd
+Z 6c5da555882197ba94055adde72070fe
index 5a2fee9d7bdeb235cae6b02b65b03bffd50b5e32..e27bc380e48f7e6811795d80ae76f10199709e2d 100644 (file)
@@ -1 +1 @@
-264f23315e682909abb47912f48733f641772a4c
\ No newline at end of file
+8ad996fdac6801768e94ca1710a0a3da03e1e7ea
\ No newline at end of file
diff --git a/src/ex/README b/src/ex/README
deleted file mode 100644 (file)
index 29f7142..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-This directory is intended to hold "experimental" files.
-
-The code in this directory does not necessary work.  It may
-or may not be added to future SQLite releases.  We just need
-a place to put ideas and works-in-progress and so this 
-directory was created.
-
-If you are interested in the production versions of SQLite,
-you can safely ignore this directory.
diff --git a/src/ex/db.c b/src/ex/db.c
deleted file mode 100644 (file)
index 358ddc9..0000000
+++ /dev/null
@@ -1,1495 +0,0 @@
-/*
-** Copyright (c) 2001 D. Richard Hipp
-**
-** This program is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public
-** License as published by the Free Software Foundation; either
-** version 2 of the License, or (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-** General Public License for more details.
-** 
-** You should have received a copy of the GNU General Public
-** License along with this library; if not, write to the
-** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-** Boston, MA  02111-1307, USA.
-**
-** Author contact information:
-**   drh@hwaci.com
-**   http://www.hwaci.com/drh/
-**
-*************************************************************************
-** $Id: db.c,v 1.1 2001/02/11 16:56:24 drh Exp $
-*/
-#include "sqliteInt.h"
-#include "pg.h"
-
-/*
-** Everything we need to know about an open database
-*/
-struct Db {
-  Pgr *pPgr;            /* The pager for the database */
-  DbCursor *pCursor;    /* All open cursors */
-  int inTransaction;    /* True if a transaction is in progress */
-  u32 freeList;         /* List of free blocks */
-  int nTable;           /* Number of slots in aContent[] */
-  u32 *aTable;          /* Root page numbers for all tables */
-};
-
-/*
-** The maximum depth of a cursor
-*/
-#define MX_LEVEL 10
-
-/*
-** Within a cursor, each level off the search tree is an instance of
-** this structure.
-*/
-typedef struct DbIdxpt DbIdxpt;
-struct DbIdxpt {
-  int pgno;         /* The page number */
-  u32 *aPage;       /* The page data */
-  int idx;          /* Index into pPage[] */
-};
-
-/*
-** Everything we need to know about a cursor
-*/
-struct DbCursor {
-  Db *pDb;                      /* The whole database */
-  DbCursor *pPrev, *pNext;      /* Linked list of all cursors */
-  u32 rootPgno;                 /* Root page of table for this cursor */
-  int onEntry;                  /* True if pointing to a table entry */
-  int nLevel;                   /* Number of levels of indexing used */
-  DbIdxpt aLevel[MX_LEVEL];     /* The index levels */
-};
-
-/*
-** Data layouts
-**
-** LEAF:
-**    x[0]          Magic number: BLOCK_LEAF
-**    x[1]          If root page, total number of entries in this table
-**    ...           One or more entries follow the leaf.
-**
-** Entry:
-**    x[N+0]        Number of u32-sized words in this entry
-**    x[N+1]        Hash value for this entry
-**    x[N+2]        Number of bytes of key in the payload
-**    x[N+3]        Number of bytes of data in the payload
-**    x{N+4]...     The payload area.
-**
-** INDEX:
-**    x[0]          Magic number: BLOCK_INDEX
-**    x[1]          If root page: total number of entries in this table
-**    x[2]          Number of slots in this index (Max value of N)
-**    x[2*N+3]      Page number containing entries with hash <= x[2*N+4]
-**    x[2*N+4]      The maximum hash value for entries on page x[2*N+3].
-**
-** FREE:
-**    x[0]          Magic number: BLOCK_FREE
-**    x[1]          Page number of the next free block on the free list
-**
-** PAGE1:
-**    x[0]          Magic number: BLOCK_PAGE1
-**    x[1]          First page of the freelist
-**    x[2]          Number of tables in this database
-**    x[N+3]        Root page for table N
-
-/*
-** The first word of every page is some combination of these values
-** used to indicate its function.
-*/
-#define BLOCK_PAGE1            0x24e47191
-#define BLOCK_INDEX            0x7ac53b46
-#define BLOCK_LEAF             0x60c45eef
-#define BLOCK_FREE             0x5b2dda47
-
-/*
-** The number of u32-sized objects that will fit on one page.
-*/
-#define U32_PER_PAGE  (SQLITE_PAGE_SIZE/sizeof(u32))
-
-/*
-** Number of direct overflow pages per database entry
-*/
-#define N_DIRECT  10
-
-/*
-** The maximum amount of payload (in bytes) that will fit on on the same
-** page as a leaf.  In other words, the maximum amount of payload
-** that does not require any overflow pages.
-**
-** This size is chosen so that a least 3 entry will fit on every 
-** leaf.  That guarantees it will always be possible to add a new
-** entry after a page split.
-*/
-#define LOCAL_PAYLOAD (((U32_PER_PAGE-2)/3 - (6+N_DIRECT))*sizeof(u32))
-
-/*
-** Allocate a new page.  Return both the page number and a pointer
-** to the page data.  The calling function is responsible for unref-ing
-** the page when it is no longer needed.
-**
-** The page is obtained from the freelist if there is anything there.
-** If the freelist is empty, the new page comes from the end of the
-** database file.
-*/
-int allocPage(Db *pDb, u32 *pPgno, u32 **ppPage){
-  u32 pgno;
-  int rc;
-
-  if( pDb->aTable==0 ) return SQLITE_NOMEM;
-
-  /* Try to reuse a page from the freelist
-  */
-  if( pDb->freeList==0 ){
-    u32 *pPage;
-    rc = sqlitePgGet(pDb->pPgr, pDb->freeList, &pPage);
-    if( rc==SQLITE_OK ){
-      if( pPage[0]==BLOCK_FREE ){
-        *pPgno = pDb->freeList;
-        *ppPage = aPage;
-        pDb->freeList = aPage[1];
-        memset(*ppPage, 0, SQLITE_PAGE_SIZE);
-        return SQLITE_OK;
-      }
-      /* This only happens if we have database corruption */
-      sqlitePgUnref(pPage);
-    }
-  }
-
-  /* If the freelist is empty, or we cannot access it,
-  ** then allocate a new page from the end of the file.
-  */
-  if( (rc = sqlitePgCount(pDb->pPgr, &pgno))==SQLITE_OK &&
-      (rc = sqlitePgGet(pDb->pPgr, pgno, (void**)ppPage))==SQLITE_OK ){
-    *pPgno = pgno;
-    memset(*ppPage, 0, SQLITE_PAGE_SIZE);
-    return SQLITE_OK;
-  }
-  return rc;
-}
-
-/*
-** Return a page to the freelist and dereference the page.
-*/
-static void freePage(DB *pDb, u32 pgno, u32 *aPage){
-  if( pgno==0 ) return
-  if( aPage==0 ){
-    int rc;
-    rc = sqlitePgGet(pDb->pPgr, pgno, &aPage);
-    if( rc!=SQLITE_OK ) return;
-  }
-  assert( sqlitePgNum(aPage)==pgno );
-  aPage[0] = BLOCK_FREE;
-  aPage[1] = pDb->freeList;
-  pDb->freeList = pgno;
-  memset(&aPage[2], 0, SQLITE_PAGE_SIZE - 2*sizeof(u32));
-  sqlitePgTouch(aPage);
-  sqlitePgUnref(aPage);
-}
-
-/*
-** Return the number of bytes of payload storage required on the leaf
-** node to hold the amount of payload specified by the argument.
-** Overflow pages do not count, only memory on the leaf page.
-**
-** Return -1 if nTotal is more than sqlite is able to store.
-*/
-static int payloadLocalSize(int nTotal){
-  int nLocal, i;
-  if( nTotal<0 ) nTotal = 0;
-  if( nTotal <= LOCAL_PAYLOAD ){
-    /* All the data fits on the leaf page */
-    return (nTotal + 3)/4;
-  }
-  nLocal = LOCAL_PAYLOAD;
-  nTotal -= LOCAL_PAYLOAD;
-  if( nTotal < 10*SQLITE_PAGE_SIZE ){
-    return nLocal + ((nTotal+SQLITE_PAGE_SIZE-1)/SQLITE_PAGE_SIZE)*sizeof(u32);
-  }
-  nLocal += N_DIRECT*sizeof(u32);
-  nTotal -= N_DIRECT*SQLITE_PAGE_SIZE;
-  if( nTotal < U32_PER_PAGE*SQLITE_PAGE_SIZE ){
-    return nLocal + sizeof(u32);
-  }
-  nLocal += sizeof(u32);
-  nTotal -= U32_PER_PAGE*SQLITE_PAGE_SIZE;
-  if( nTotal < U32_PER_PAGE*U32_PER_PAGE*SQLITE_PAGE_SIZE ){
-    return nLocal + sizeof(u32);
-  }
-  return -1;  /* This payload will not fit. */
-}
-
-/*
-** Read data from the payload area.
-**
-** aPage points directly at the beginning of the payload.  No bounds 
-** checking is done on offset or amt -- it is assumed that the payload
-** area is big enough to accomodate.
-*/
-static int payloadRead(Db *pDb, u32 *aPage, int offset, int amt, void *pBuf){
-  int rc;
-  int tomove;
-  int i;
-
-  /* First read local data off of the leaf page itself.
-  ** This is all that ever happens in 99% of accesses.
-  */
-  assert( offset>=0 && amt>=0 );
-  if( offset < LOCAL_PAYLOAD ){
-    /* Data stored directly in the leaf block of the BTree */
-    if( amt+offset>LOCAL_PAYLOAD ){
-      tomove = LOCAL_PAYLOAD - offset;
-    }else{
-      tomove = amt;
-    }
-    memcpy(pBuf, &((char*)aPage)[offset], tomove);
-    pBuf = &((char*)pBuf)[tomove];
-    offset += tomove;
-    amt -= tomove;
-    if( amt<=0 ) return SQLITE_OK;
-  }
-  offset -= LOCAL_PAYLOAD;
-  aPage += LOCAL_PAYLOAD/sizeof(aPage[0]);
-
-  /* If not all of the data fits locally, read from the first
-  ** ten direct-access overflow pages.
-  */
-  if( offset < N_DIRECT*SQLITE_PAGE_SIZE ){
-    for(i=offset/SQLITE_PAGE_SIZE; i<N_DIRECT && amt>0; i++){
-      char *aData;
-      base = offset - i*SQLITE_PAGE_SIZE;
-      rc = sqlitePgGet(pDb->pPgr, aPage[i], &aData);
-      if( rc!=SQLITE_OK ) return rc;
-      if( amt+base > SQLITE_PAGE_SIZE ){
-        tomove = SQLITE_PAGE_SIZE - base;
-      }else{
-        tomove = amt;
-      }
-      memcpy(pBuf, &aData[base], tomove);
-      sqlitePgUnref(aData);
-      pBuf = &((char*)pBuf)[tomove];
-      amt -= tomove;
-    }
-  }
-  offset -= N_DIRECT*SQLITE_PAGE_SIZE;
-  aPage += N_DIRECT;
-
-  /* If the first N_DIRECT overflow pages do not contain everything, then
-  ** read from an overflow page that is filled with pointer to
-  ** U32_PER_PAGE more overflow pages.
-  */
-  if( offset < U32_PER_PAGE*SQLITE_PAGE_SIZE ){
-    u32 *indirPage;
-    rc = sqlitePgGet(pDb->pPgr, aPage[0], &indirPage);
-    if( rc!=SQLITE_OK ) return rc;
-    for(i=offset/SQLITE_PAGE_SIZE; i<U32_PER_PAGE && amt>0; i++){
-      int base;
-      char *aData;
-      base = offset - i*SQLITE_PAGE_SIZE;
-      rc = sqlitePgGet(pDb->pPgr, indirPage[idx], &aData);
-      if( rc!=SQLITE_OK ) break;
-      if( amt+base > SQLITE_PAGE_SIZE ){
-        tomove = SQLITE_PAGE_SIZE - base;
-      }else{
-        tomove = amt;
-      }
-      memcpy(pBuf, &aData[base], tomove);
-      sqlitePgUnref(aData);
-      pBuf = &((char*)pBuf)[tomove];
-      amt -= tomove;
-    }
-    sqlitePgUnref(indirPage);
-    if( rc!=SQLITE_OK ) return rc;
-    if( amt<=0 ) return SQLITE_OK;
-  }
-  offset -= U32_PER_PAGE*SQLITE_PAGE_SIZE;
-  aPage++;
-
-  /* If there is still more data, then read using a double-indirect
-  ** overflow.  The overflow page points to U32_PER_PAGE additional
-  ** overflow pages, each of which pointer to U32_PER_PAGE more overflow
-  ** pages which contain data.
-  **
-  ** This is hard to test.  To exercise this code, you have to make
-  ** a database entry of more than 273336 bytes in side, assuming a
-  ** pagesize of 1024 bytes and 10 direct overflow pages.  By the 
-  ** time this code runs, you have already used 267 overflow pages.
-  */
-  if( offset < U32_PER_PAGE*U32_PER_PAGE*SQLITE_PAGE_SIZE ){
-    u32 *dblIndirPage;
-    rc = sqlitePgGet(pDb->pPgr, aPage[0], &dblIndirPage);
-    if( rc!=SQLITE_OK ) return rc;
-    i = offset/(U32_PER_PAGE*SQLITE_PAGE_SIZE);
-    for(; i<U32_PER_PAGE && amt>0; i++){
-      u32 *indirPage;
-      int basis;
-      int j;
-      rc = sqlitePgGet(pDb->pPgr, dblIndirPage[i], &indirPage);
-      if( rc!=SQLITE_OK ) break;
-      basis = i*U32_PER_PAGE*SQLITE_PAGE_SIZE;
-      j = (offset - basis)/SQLITE_PAGE_SIZE;
-      for(; j<U32_PER_PAGE && amt>0; j++){
-        char *aData;
-        base = (offset - basis) - ij*SQLITE_PAGE_SIZE;
-        rc = sqlitePgGet(pDb->pPgr, indirPage[j], &aData);
-        if( rc!=SQLITE_OK ) break;
-        if( amt+base > SQLITE_PAGE_SIZE ){
-          tomove = SQLITE_PAGE_SIZE - base;
-        }else{
-          tomove = amt;
-        }
-        memcpy(pBuf, &aData[base], tomove);
-        sqlitePgUnref(aData);
-        pBuf = &((char*)pBuf)[tomove];
-        amt -= tomove;
-      }
-      sqlitePgUnref(indirPage);
-      if( rc!=SQLITE_OK ) break;
-    }
-    sqlitePgUnref(dblIndirPage);
-  }
-
-  /* Anything beyond the double-indirect pages, just fill in with
-  ** zeros.  You have to write 67382200 bytes to go past the
-  ** double-indirect pages, assuming a 1024 byte page size.
-  */
-  if( amt>0 ) memset(pBuf, 0, amt);
-  return SQLITE_OK;
-}
-
-/*
-** Write data into the payload area.
-**
-** If pages have already been allocated for the payload, they are
-** simply overwritten.  New pages are allocated as necessary to
-** fill in gaps.  sqlitePgTouch() is called on all overflow pages,
-** but the calling function must invoke sqlitePgTouch() for aPage
-** itself.
-*/
-static int payloadWrite(Db *pDb, u32 *aPage, int offset, int amt, void *pBuf){
-  assert( offset>=0 && amt>=0 );
-
-  /* Local data
-  */
-  if( offset < LOCAL_PAYLOAD ){
-    if( amt+offset>LOCAL_PAYLOAD ){
-      tomove = LOCAL_PAYLOAD - offset;
-    }else{
-      tomove = amt;
-    }
-    memcpy(&((char*)aPage)[offset], pBuf, tomove);
-    pBuf = &((char*)pBuf)[tomove];
-    offset += tomove;
-    amt -= tomove;
-    if( amt<=0 ) return SQLITE_OK;
-  }
-  offset -= LOCAL_PAYLOAD;
-  aPage += LOCAL_PAYLOAD/sizeof(aPage[0]);
-
-  /* Direct overflow pages
-  */
-  if( offset < N_DIRECT*SQLITE_PAGE_SIZE ){
-    for(i=offset/SQLITE_PAGE_SIZE; i<N_DIRECT && amt>0; i++){
-      base = offset - i*SQLITE_PAGE_SIZE;
-      if( aPage[i] ){
-        rc = sqlitePgGet(pDb->pPgr, aPage[i], &aData);
-      }else{
-        rc = allocPage(pDb, &aPage[i], &aData);
-      }
-      if( rc!=SQLITE_OK ) return rc;
-      if( amt+base > SQLITE_PAGE_SIZE ){
-        tomove = SQLITE_PAGE_SIZE - base;
-      }else{
-        tomove = amt;
-      }
-      memcpy(&aData[base], pBuf, tomove);
-      sqlitePgTouch(aData);
-      sqlitePgUnref(aData);
-      pBuf = &((char*)pBuf)[tomove];
-      amt -= tomove;
-    }
-    if( amt<=0 ) return SQLITE_OK;
-  }
-  offset -= N_DIRECT*SQLITE_PAGE_SIZE;
-  aPage += N_DIRECT;
-
-  /* Indirect overflow pages
-  */
-  if( offset < U32_PER_PAGE*SQLITE_PAGE_SIZE ){
-    u32 *indirPage;
-    if( aPage[0] ){
-      rc = sqlitePgGet(pDb->pPgr, aPage[0], &indirPage);
-    }else{
-      rc = allocPage(pDb, &aPage[0], &indirPage);
-    }
-    if( rc!=SQLITE_OK ) return rc;
-    for(i=offset/SQLITE_PAGE_SIZE; i<U32_PER_PAGE && amt>0; i++){
-      int base;
-      char *aData;
-      base = offset - i*SQLITE_PAGE_SIZE;
-      if( indirPage[i] ){
-        rc = sqlitePgGet(pDb->pPgr, indirPage[i], &aData);
-      }else{
-        rc = allocPage(pDb, &indirPage[i], &aData);
-        sqlitePgTouch(indirPage);
-      }
-      if( rc!=SQLITE_OK ) break;
-      if( amt+base > SQLITE_PAGE_SIZE ){
-        tomove = SQLITE_PAGE_SIZE - base;
-      }else{
-        tomove = amt;
-      }
-      memcpy(&aData[base], pBuf, tomove);
-      sqlitePgUnref(aData);
-      pBuf = &((char*)pBuf)[tomove];
-      amt -= tomove;
-    }
-    sqlitePgUnref(indirPage);
-    if( rc!=SQLITE_OK ) return rc;
-    if( amt<=0 ) return SQLITE_OK;
-  }
-  offset -= U32_PER_PAGE*SQLITE_PAGE_SIZE;
-  aPage++;
-
-  /* Double-indirect overflow pages
-  */
-  if( offset < U32_PER_PAGE*U32_PER_PAGE*SQLITE_PAGE_SIZE ){
-    u32 *dblIndirPage;
-    if( aPage[0] ){
-      rc = sqlitePgGet(pDb->pPgr, aPage[0], &dblIndirPage);
-    }else{
-      rc = allocPage(pDb, &aPage[0], &dblIndirPage);
-    }
-    if( rc!=SQLITE_OK ) return rc;
-    i = offset/(U32_PER_PAGE*SQLITE_PAGE_SIZE);
-    for(; i<U32_PER_PAGE && amt>0; i++){
-      u32 *indirPage;
-      int basis;
-      int j;
-      if( aPage[0] ){
-        rc = sqlitePgGet(pDb->pPgr, aPage[0], &dblIndirPage);
-      }else{
-        rc = allocPage(pDb, &aPage[0], &dblIndirPage);
-        sqlitePgTouch(dblIndirPage);
-      }
-      rc = sqlitePgGet(pDb->pPgr, dblIndirPage[i], &indirPage);
-      if( rc!=SQLITE_OK ) break;
-      basis = i*U32_PER_PAGE*SQLITE_PAGE_SIZE;
-      j = (offset - basis)/SQLITE_PAGE_SIZE;
-      for(; j<U32_PER_PAGE && amt>0; j++){
-        char *aData;
-        base = (offset - basis) - ij*SQLITE_PAGE_SIZE;
-        if( indirPage[j] ){
-          rc = sqlitePgGet(pDb->pPgr, indirPage[j], &aData);
-        }else{
-          rc = allocPage(pDb, &indirPage[j], &aData);
-          sqlitePgTouch(indirPage);
-        }
-        if( rc!=SQLITE_OK ) break;
-        if( amt+base > SQLITE_PAGE_SIZE ){
-          tomove = SQLITE_PAGE_SIZE - base;
-        }else{
-          tomove = amt;
-        }
-        memcpy(&aData[base], pBuf, tomove);
-        sqlitePgTouch(aData);
-        sqlitePgUnref(aData);
-        pBuf = &((char*)pBuf)[tomove];
-        amt -= tomove;
-      }
-      sqlitePgUnref(indirPage);
-      if( rc!=SQLITE_OK ) break;
-    }
-    sqlitePgUnref(dblIndirPage);
-  }
-
-  return SQLITE_OK;
-}
-
-/*
-** Resize the payload area.  If the payload area descreases in size,
-** this routine deallocates unused overflow pages.  If the payload
-** area increases in size, this routine is a no-op.
-*/
-static int payloadResize(Db *pDb, u32 *aPage, int oldSize, int newSize){
-  int i, j;          /* Loop counters */
-  int first, last;   /* Indices of first and last pages to be freed */
-  int rc;            /* Return code from sqlitePgGet() */
-
-  /* Skip over the local data.  We do not need to free it.
-  */
-  if( newSize>=oldSize ) return SQLITE_OK;
-  oldSize -= LOCAL_PAYLOAD;
-  if( oldSize<=0 ) return SQLITE_OK;
-  newSize -= LOCAL_PAYLOAD;
-  aPage += LOCAL_PAYLOAD/sizeof(u32);
-
-  /* Compute the indices of the first and last overflow pages to
-  ** be freed.
-  */
-  first = (newSize - 1)/SQLITE_PAGE_SIZE + 1;
-  last = (oldSize - 1)/SQLITE_PAGE_SIZE;
-
-  /* Free the direct overflow pages
-  */
-  if( first < N_DIRECT ){
-    for(i=first; i<N_DIRECT && i<=last; i++){
-      freePage(pDb, aPage[i], 0);
-      aPage[i] = 0;
-    }
-  }
-  aPage += N_DIRECT;
-  first -= N_DIRECT;
-  last -= N_DIRECT;
-  if( last<0 ) return SQLITE_OK;
-  if( first<0 ) first = 0;
-  
-  /* Free indirect overflow pages
-  */
-  if( first < U32_PER_PAGE ){
-    u32 *indirPage;
-    rc = sqlitePgGet(pDb->pPgr, aPage[0], &indirPage);
-    if( rc!=SQLITE_OK ) return rc;
-    for(i=first; i<U32_PER_PAGE && i<=last; i++){
-      freePage(pDb, indirPage[i], 0);
-      indirPage[i] = 0;
-      touch = 1;
-    }
-    if( first<=0 ){
-      freepage(pDb, aPage[0], indirPage);
-      aPage[0] = 0;
-    }else{
-      sqlitePgTouch(indirPage);
-      sqlitePgUnref(indirPage);
-    }
-  }
-  aPage++;
-  first -= U32_PER_PAGE;
-  last -= U32_PER_PAGE;
-  if( last<0 ) return SQLITE_OK;
-  if( first<0 ) first = 0;
-
-  /* Free double-indirect overflow pages
-  */
-  if( first < U32_PER_PAGE*U32_PER_PAGE ){
-    u32 *dblIndirPage;
-    rc = sqlitePgGet(pDb->pPgr, aPage[0], &dblIndirPage);
-    if( rc!=SQLITE_OK ) return rc;
-    for(i=first/U32_PER_PAGE; i<U32_PER_PAGE; i++){
-      u32 *indirPage;
-      basis = i*U32_PER_PAGE;
-      if( last < basis ) break;
-      rc = sqlitePgGet(pDb->pPgr, dblIndirPage[i], &indirPage);
-      if( rc!=SQLITE_OK ) return rc;
-      for(j=first>basis?first-basis:0 ; j<U32_PER_PAGE; j++){
-        if( j + basis > last ) break;
-        freePage(pDb, indirPage[j], 0);
-        indirPage[j] = 0;
-      }
-      if( first<=basis ){
-        freepage(pDb, dblIndirPage[i], 0);
-        dblIndirPage[i] = 0;
-      }else{
-        sqlitePgTouch(indirPage);
-        sqlitePgUnref(indirPage);
-      }
-    }
-    if( first<=0 ){
-      freepage(pDb, aPage[0], dblIndirPage);
-      aPage[0] = 0;
-    }else{
-      sqlitePgTouch(dblIndirPage);
-      sqlitePgUnref(dblIndirPage);
-    }
-  }
-
-  return SQLITE_OK;    
-}
-
-/*
-** Allocate space for the content table in the given Db structure.
-** return SQLITE_OK on success and SQLITE_NOMEM if it fails.
-*/
-static int sqliteDbExpandTableArray(Db *pDb){
-  pDb->aTable = sqliteRealloc( pDb->aTable, pDb->nTable*sizeof(u32));
-  if( pDb->aTable==0 ){
-    pDb->inTranaction = 0;
-    return SQLITE_NOMEM;
-  }
-  return SQLITE_OK;
-}
-
-/*
-** Open a database.
-*/
-int sqliteDbOpen(const char *filename, Db **ppDb){
-  Db *pDb = 0;
-  Pgr *pPgr = 0;
-  u32 *aPage1;
-  int rc;
-  u32 nPage;
-
-  rc = sqlitePgOpen(filename, &pPgr);
-  if( rc!=SQLITE_OK ) goto open_err;
-  pDb = sqliteMalloc( sizeof(*pDb) );
-  if( pDb==0 ){
-    rc = SQLITE_NOMEM;
-    goto open_err;
-  }
-  pDb->pPgr = pPgr;
-  pDb->pCursor = 0;
-  pDb->inTransaction = 0;
-  sqlitePgCount(pDb->pPgr, &nPage);
-  rc = sqlitePgGet(pDb->pPgr, 1, &aPage1);
-  if( rc!=0 ) goto open_err;
-  if( nPage==0 ){
-    sqlitePgBeginTransaction(pDb->pPgr);
-    aPage1[0] = BLOCK_PAGE1;
-    sqlitePgTouch(aPage1);
-    sqlitePgCommit(pDb->pPgr);
-  }
-  pDb->freeList = aPage[1];
-  pDb->nTable = aPage[2];
-  rc = sqliteDbExpandTableArray(pDb);
-  if( rc!=SQLITE_OK ) goto open_err;
-  rc = payloadRead(pDb, &aPage1[3], 0, pDb->nTable*sizeof(u32), pDb->aTable);
-  sqlitePgUnref(aPage1);
-  if( rc!=SQLITE_OK ) goto open_err;
-  *ppDb = pDb;
-  return SQLITE_OK;
-
-open_err:
-  *ppDb = 0;
-  if( pPgr ) sqlitePgClose(pPgr);
-  if( pDb ){
-    sqliteFree(pDb->aContent);
-    sqliteFree(pDb);
-  }
-  return rc;
-}
-
-/*
-** Close a database
-*/
-int sqliteDbClose(Db *pDb){
-  while( pDb->pCursor ){
-    sqliteDbCursorClose(pDb->pCursor);
-  }
-  sqlitePgClose(pDb->pPgr);
-  sqliteFree(pDb->aContent);
-  sqliteFree(pDb);
-  return SQLITE_OK;
-}
-
-/*
-** Begin a transaction
-*/
-int sqliteDbBeginTransaction(Db *pDb){
-  int rc;
-  if( pDb->aContent==0 ){
-    return SQLITE_NOMEM;
-  }
-  if( pDb->inTransaction ){
-    return SQLITE_INTERNAL;
-  }
-  rc = sqlitePgBeginTransaction(pDb->pPgr);
-  if( rc!=SQLITE_OK ){
-    return rc;
-  }
-  pDb->inTransaction = 1;
-  return SQLITE_OK;
-}
-
-/*
-** Commit changes to the database
-*/ 
-int sqliteDbCommit(Db *pDb){
-  u32 *aPage1;
-  int rc;
-  if( !pDb->inTransaction ){
-    return SQLITE_OK;
-  }
-  rc = sqlitePgGet(pDb->pPgr, 1, &aPage1);
-  if( rc!=SQLITE_OK ) return rc;
-  aPage1[1] = pDb->freeList;
-  aPage1[2] = pDb->nTable;
-  payloadWrite(pDb, &aPage1[3], 0, pDb->nTable*sizeof(u32), pDb->aTable);
-  sqlitePgUnref(aPage1);
-  rc = sqlitePgCommit(pDb->pPgr);
-  if( rc!=SQLITE_OK ) return rc;
-  pDb->inTransaction = 0;
-  return SQLITE_OK;
-}
-
-/*
-** Rollback the database to its state prior to the beginning of
-** the transaction
-*/
-int sqliteDbRollback(Db *pDb){
-  u32 *aPage1;
-  if( !pDb->inTransaction ) return SQLITE_OK;
-  rc = sqlitePgRollback(pDb->pPgr);
-  if( rc!=SQLITE_OK ) return rc;
-  rc = sqlitePgGet(pDb->pPgr, 1, &aPage1);
-  if( rc!=SQLITE_OK ) return rc;
-  pDb->freeList = aPage1[1];
-  pDb->nTable = aPage1[2];
-  if( sqliteDbExpandTableArray(pDb)!=SQLITE_OK ){
-    return SQLITE_NOMEM;
-  }
-  payloadRead(pDb, &aPage1[3], 0, pDb->nTable*sizeof(u32), pDb->aTable);
-  sqlitePgUnref(aPage1);
-  pDb->inTransaction = 0;
-  return SQLITE_OK;
-}
-
-/*
-** Create a new table in the database.  Write the table number
-** that is used to open a cursor into that table into *pTblno.
-*/
-int sqliteDbCreateTable(Db *pDb, int *pTblno){
-  u32 *aPage;
-  u32 pgno;
-  int rc;
-  int swTblno;
-  int i;
-
-  rc = allocPage(pDb, &pgno, &aPage);
-  if( rc!=SQLITE_OK ){
-    return rc;
-  }
-  tblno = -1;
-  for(i=0; i<pDb->nTable; i++){
-    if( pDb->aTable[i]==0 ){
-      tblno = i;
-      break;
-    }
-  }
-  if( tblno<0 ){
-    pDb->nTable++;
-    rc = sqliteExpandTableArray(pDb);
-    if( rc!=SQLITE_OK ){
-      return rc;
-    }
-  }
-  pDb->aTable[tblno] = pgno;
-  aPage[0] = BLOCK_LEAF;
-  memset(&aPage[1], 0, SQLITE_PAGE_SIZE - sizeof(u32));
-  sqlitePgTouch(aPage);
-  sqlitePgUnref(aPage);
-  return rc;
-}
-
-/*
-** Recursively add a page to the free list
-*/
-static int sqliteDbDropPage(Db *pDb, u32 pgno){
-  u32 *aPage;
-  int rc;
-
-  rc = sqlitePgGet(pDb->pPgr, pgno, (void**)&aPage);
-  if( rc!=SQLITE_OK ) return rc;
-  switch(  aPage[0] ){
-    case BLOCK_INDEX: {
-      int n, i;
-      n = aPage[2];
-      for(i=0; i<n; i++){
-        u32 subpgno = aPage[3 + i*2];
-        if( subpgno>0 ) sqliteDbDropPage(pDb, subpgno);
-      }
-      freePage(pDb, pgno, aPage);
-      break;
-    }
-    case BLOCK_LEAF: {
-      int i = 2;
-      while( i<U32_PER_PAGE ){
-        int entrySize = aPage[i];
-        if( entrySize==0 ) break;
-        payloadResize(pDb, &aPage[i+4], aPage[i+2]+aPage[i+3], 0);
-        i += entrySize;
-      }
-      freePage(pDb, pgno, aPage);
-      break;
-    }
-    default: {
-      /* Do nothing */
-      break;
-    }
-  }
-}
-
-/*
-** Delete the current associate of a cursor and release all the
-** pages it holds.  Except, do not release pages at levels less
-** than N.
-*/
-static void sqliteDbResetCursor(DbCursor *pCur, int N){
-  int i;
-  for(i=pCur->nLevel-1; i>=N; i--){
-    sqlitePgUnref(pCur->aLevel[i].aPage);
-  }
-  pCur->nLevel = N;
-  pCur->onEntry = 0;
-}
-
-/*
-** Delete an entire table.
-*/
-static int sqliteDbDropTable(Db *pDb, int tblno){
-  DbCursor *pCur;
-  u32 pgno;
-
-  /* Find the root page for the table to be dropped.
-  */
-  if( pDb->aTable==0 ){
-    return SQLITE_NOMEM;
-  }
-  if( tblno<0 || tblno>=pDb->nTable || pDb->aTable[tblno]==0 ){
-    return SQLITE_NOTFOUND;
-  }
-  pgno = pDb->aTable[tblno];
-  pDb->aTable[tblno] = 0;
-  if( tblno==pDb->nTable-1 ){
-    pDb->nTable--;
-  }
-
-  /* Reset any cursors pointing to the table that is about to
-  ** be dropped */
-  for(pCur=pDb->pCursor; pCur; pCur=pCur->pNext){
-    if( pCur->rootPgno==pgno ){
-      sqliteDbResetCursor(pCur, 0);
-    }
-  }
-
-  /* Move all pages associated with this table to the freelist
-  */
-  sqliteDbDropPage(pDb, pgno);
-  return SQLITE_OK;
-}
-
-/*
-** Create a new cursor
-*/
-int sqliteDbCursorOpen(Db *pDb, int tblno, DbCursor **ppCur){
-  u32 pgno;
-  DbCursor *pCur;
-
-  /* Translate the table number into a page number
-  */
-  if( pDb->aTable==0 ){
-    *ppCur = 0;
-    return SQLITE_NOMEM;
-  }
-  if( tblno<0 || tblno>=pDb->nContent || pDb->aTable[tblno]==0 ){
-    *ppCur = 0;
-    return SQLITE_NOTFOUND;
-  }
-  pgno = pDb->aTable[tblno];
-  
-  /* Allocate the cursor
-  */
-  pCur = sqliteMalloc( sizeof(*pCur) );
-  pCur->pgno = pgno;
-  pCur->pDb = pDb;
-  pCur->pNext = pDb->pCursor;
-  pCur->pPrev = 0;
-  if( pDb->pCursor ){
-     pDb->pCursor->pPrev = pCur;
-  }
-  pDb->pCursor = pCur;
-  *ppCur = pCur;
-  return SQLITE_OK;
-}
-
-/*
-** Delete a cursor
-*/
-int sqliteDbCursorClose(DbCursor *pCur){
-  int i;
-  if( pCur->pPrev ){
-    pCur->pPrev->pNext = pCur->pNext;
-  }else if( pCur->pDb->pCursor==pCur ){
-    pCur->pDb->pCursor = pCur->pNext;
-  }
-  if( pCur->pNext ){
-    pCur->pNext->pPrev = pCur->pPrev;
-  }
-  sqliteDbResetCursor(pCur, 0);
-  sqliteFree(pCur);
-  return SQLITE_OK; 
-}
-
-/*
-** Beginning at index level "i" (the outer most index is 0), move down 
-** to the first entry of the table.  Levels above i (less than i) are 
-** unchanged.
-*/
-static int sqliteDbGotoFirst(DbCursor *pCur, int i){
-  int rc = -1;
-
-  assert( i>=0 && i<MAX_LEVEL );
-  if( pCur->nLevel > i+1 ){
-    sqliteDbResetCursor(pCur, i+1);
-  }
-  assert( pCur->nLevel==i+1 );
-  while( rc < 0 ){
-    u32 *aPage = pCur->aLevel[i].aPage;
-    assert( aPage!=0 );
-    switch( aPage[0] ){
-      case BLOCK_LEAF: {
-        if( aPage[2]!=0 ){
-          pCur->aLevel[i].idx = 2;
-          pCur->onEntry = 1;
-        }else{
-          sqliteDbResetCursor(pCur, 1);
-        }
-        rc = SQLITE_OK;
-        break;
-      }
-      case BLOCK_INDEX: {
-        int n = aPage[2];
-        if( n<2 || n>=((U32_PER_PAGE - 3)/2) ){
-          sqliteDbResetCur(pCur, 1);
-          rc = SQLITE_CORRUPT;
-          break;
-        }
-        pCur->nLevel++;
-        i++;
-        pCur->aLevel[i].pgno = aPage[3];
-        rc = sqlitePgGet(pCur->pDb->pPgr, pCur->aLevel[i].pgno,
-                    &pCur->aLevel[i].aPage);
-        if( rc != SQLITE_OK ){
-          sqliteDbResetCursor(pCur, 1);
-        }else{
-          rc = -1;
-        }
-        break;
-      }
-      default: {
-        sqliteDbResetCursor(pCur, 1);
-        rc = SQLITE_CORRUPT;
-      }
-    }
-  }
-  return rc;
-}
-
-################
-
-/*
-** Move the cursor to the first entry in the table.
-*/
-int sqliteDbCursorFirst(DbCursor *pCur){
-  if( pCur->nLevel==0 ){
-    int rc;
-    pCur->aLevel[0].pgno = pCur->rootPgno;
-    rc = sqlitePgGet(pCur->pDb->pPgr, pCur->rootPgno, pCur->aLevel[0].aPage);
-    if( rc!=SQLITE_OK ){
-      sqliteDbResetCursor(pCur, 0);
-      return rc;
-    }
-    pCur->nLevel = 1;
-  }
-  return sqliteDbGotoFirst(pCur, 0);
-}
-
-/*
-** Advance the cursor to the next entry in the table.
-*/
-int sqliteDbCursorNext(DbCursor *pCur){
-  int i, idx, n, rc;
-  u32 pgno, *aPage;
-  if( !pCur->onEntry ){
-     return sqliteDbCursorFirst(pCur);
-  }
-  i = pCur->nLevel-1;
-  aPage = pCur->aLevel[i].aPage;
-  idx = pCur->aLevel[i].idx;
-  idx += SWB(aPage[idx]);
-  if( idx >= SQLITE_PAGE_SIZE/sizeof(u32) ){
-    sqliteDbResetCursor(pCur, 1);
-    return SQLITE_CORRUPT;
-  }
-  if( aPage[idx]!=0 ){
-    pCur->aLabel[i].idx = idx;
-    return SQLITE_OK;
-  }
-  rc = SQLITE_OK;
-  while( pCur->nLevel>1 ){
-    pCur->nLevel--;
-    i = pCur->nLevel-1;
-    sqlitePgUnref(pCur->aLevel[pCur->nLevel].aPage);
-    aPage = pCur->aLevel[i].aPage;
-    idx = pCur->aLevel[i].idx;
-    assert( SWB(aPage[0])==BLOCK_MAGIC|BLOCK_INDEX );
-    n = SWB(aPage[2]);
-    idx += 2;
-    if( (idx-3)/2 < n ){
-      pCur->aLevel[i].idx = idx;
-      pCur->nLevel++;
-      i++;
-      pgno = pCur->aLevel[i].pgno = SWB(aPage[idx+1]);
-      rc = sqlitePgGet(pDb->pPgr, pgno, &pCur->aLevel[i].aPage);
-      if( rc!=SQLITE_OK ) break;
-      rc = sqliteDbGotoFirst(pCur, i);
-      break;
-    }
-  }
-  sqliteDbResetCursor(pCur, 0);
-  return SQLITE_OK;
-}
-
-/*
-** Return the amount of data on the entry that the cursor points
-** to.
-*/
-int sqliteDbCursorDatasize(DbCursor *pCur){
-  u32 *aPage;
-  int idx, i;
-  if( !pCur->onEntry ) return 0;
-  i = pCur->nLevel-1;
-  idx = pCur->aLevel[i].idx;
-  aPage = pCur->aLevel[i].aPage;
-  assert( aPage );
-  assert( idx>=2 && idx+4<U32_PER_PAGE );
-  return aPage[idx+3];
-}
-
-/*
-** Return the number of bytes of key on the entry that the cursor points
-** to.
-*/
-int sqliteDbCursorKeysize(DbCursor *pCur){
-  u32 *aPage;
-  int idx, i;
-  if( !pCur->onEntry ) return 0;
-  i = pCur->nLevel-1;
-  idx = pCur->aLevel[i].idx;
-  aPage = pCur->aLevel[i].aPage;
-  assert( aPage );
-  assert( idx>=2 && idx+4<U32_PER_PAGE );
-  return aPage[idx+2];
-}
-
-/*
-** Read data from the cursor.
-*/
-int sqliteDbCursorRead(DbCursor *pCur, int amt, int offset, void *buf){
-  u32 *aPage;
-  int idx, i;
-  int nData;
-  int nKey;
-  if( !pCur->onEntry ){
-    memset(cbuf, 0, amt);
-    return SQLITE_OK;
-  }
-  if( amt<=0 || offset<0 ){
-    return SQLITE_ERR;
-  }
-  i = pCur->nLevel-1;
-  idx = pCur->aLevel[i].idx;
-  aPage = pCur->aLevel[i].aPage;
-  assert( aPage );
-  assert( idx>=2 && idx+4<U32_PER_PAGE );
-  nData = aPage[idx+3];
-  if( offset>=nData ){
-    memset(buf, 0, amt);
-    return SQLITE_OK;
-  }
-  nKey = aPage[idx+2];
-  if( nData<offset+amt ){
-    memset(&((char*)buf)[nData-offset], 0, amt+offset-nData);
-    amt = nData - offset;
-  }
-  payloadRead(pCur->pDb, &aPage[idx+4], amt, offset + nKey, buf);
-  return SQLITE_OK;
-}
-
-/*
-** Read the current key from the cursor.
-*/
-int sqliteDbCursorReadKey(DbCursor *pCur, int amt, int offset, void *buf){
-  u32 *aPage;
-  int idx, i;
-  int nData;
-  int nKey;
-  if( !pCur->onEntry ){
-    memset(cbuf, 0, amt);
-    return SQLITE_OK;
-  }
-  if( amt<=0 || offset<0 ){
-    return SQLITE_ERR;
-  }
-  i = pCur->nLevel-1;
-  idx = pCur->aLevel[i].idx;
-  aPage = pCur->aLevel[i].aPage;
-  assert( aPage );
-  assert( idx>=2 && idx+4<(SQLITE_PAGE_SIZE/sizeof(u32))
-  nKey = aPage[idx+2];
-  if( offset>=nKey ){
-    memset(buf, 0, amt);
-    return SQLITE_OK;
-  }
-  if( nKey<offset+amt ){
-    memset(&((char*)buf)[nKey-offset], 0, amt+offset-nKey);
-    amt = nKey - offset;
-  }
-  payloadRead(pCur->pDb, &aPage[idx+4], amt, offset, buf);
-  return SQLITE_OK;
-}
-
-/*
-** Generate a 32-bit hash from the given key.
-*/
-static u32 sqliteDbHash(int nKey, void *pKey){
-  u32 h;
-  unsigned char *key;
-  if( nKey==4 ){
-    return *(u32*)pKey;
-  }
-  key = pKey;
-  h = 0;
-  while( 0 < nKey-- ){
-    h = (h<<13) ^ (h<<3) ^ h ^ *(key++)
-  }
-  return h;
-}
-
-/*
-** Move the cursor so that the lowest level is the leaf page that
-** contains (or might contain) the given key.
-*/
-static int sqliteDbFindLeaf(DbCursor *pCur, int nKey, void *pKey, u32 h;){
-  int i, j, rc;
-  u32 h;
-
-  h = sqliteDbHash(nKey, pKey);
-  sqliteDbResetCursor(pCur, 1);
-  i = 0;
-  for(;;){
-    u32 nxPgno;
-    u32 *aPage = pCur->aLevel[i].aPage;
-    if( SWB(aPage[0])==BLOCK_MAGIC|BLOCK_LEAF ) break;
-    if( SWB(aPage[0])!=BLOCK_MAGIC|BLOCK_INDEX ){
-      return SQLITE_CORRUPT;
-    }
-    if( i==MAX_LEVEL-1 ){
-      return SQLITE_FULL;
-    }
-    n = SWB(aPage[2]);
-    if( n<2 || n>=(SQLITE_PAGE_SIZE/2*sizeof(u32))-2 ){
-      return SQLITE_CORRUPT;
-    }
-    for(j=0; j<n-1; j++){
-      if( h < SWB(aPage[j*2+3]) ) break;
-    }
-    nxPgno = SWB(aPage[j*2+4]);
-    pCur->aLevel[i].idx = j;
-    pCur->aLevel[i].pgno = nxPgno;
-    rc = sqlitePgGet(pCur->pDb->pPgr, nxPgno, &pCur->aLevel[i].aPage);
-    if( rc!=SQLITE_OK ){
-      return rc;
-    }
-    pCur->nLevel++;
-    i++;
-  }
-  return SQLITE_OK;
-}
-
-/*
-** Position the cursor on the entry that matches the given key.
-*/
-int sqliteDbCursorMoveTo(DbCursor *pCur, int nKey, void *pKey){
-  int rc, i;
-  u32 *aPage;
-  int idx;
-  u32 h;
-
-  h = sqliteDbHash(nKey, pKey);
-  rc = sqliteDbFindLeaf(pCur, nKey, pKey, h);
-  if( rc!=SQLITE_OK ) return rc;
-  i = pCur->nLevel-1;
-  aPage = pCur->aLevel[i].aPage;
-  idx = 2;
-  rc = SQLITE_NOTFOUND;
-  while( idx>=2 && idx<(SQLITE_PAGE_SIZE/sizeof(u32))-3 && aPage[idx]!=0 ){
-    if( sqliteDbKeyMatch(&aPage[idx], nKey, pKey, h) ){
-      pCur->aLevel[i].idx = idx;
-      pCur->onEntry = 1;
-      rc = SQLITE_OK;
-      break;
-    }
-    idx += SWB(aPage[idx]);
-  }
-  return rc;
-}
-
-/*
-** Insert a new entry into the table.  The cursor is left pointing at
-** the new entry.
-*/
-int sqliteDbCursorInsert(   
-   DbCursor *pCur,          /* A cursor on the table in which to insert */
-   int nKey, void *pKey,    /* The insertion key */
-   int nData, void *pData   /* The data to be inserted */
-){
-  int minNeeded, maxNeeded;    /* In u32-sized objects */
-  int rc;
-  u32 h;
-  int available;
-  int i, j, k;
-  int nKeyU, nDataU;
-  u32 *aPage;
-  int incr = 1;
-
-  /* Null data is the same as a delete.
-  */
-  if( nData<=0 || pData==0 ){
-    if( sqliteDbCursorMoveTo(pCur, nKey, pKey);
-      return sqliteDbCursorDelete(pCur);
-    }else{
-      return SQLITE_OK;
-    }
-  }
-
-  /* Figure out how much free space is needed on a leaf block in order
-  ** to hold the new record.
-  */
-  minNeeded = maxNeeded = 6;
-  nKeyU = (nKey+3)/4;
-  nDataU = (nData+3)/4;
-  if( nKeyU + maxNeeded + 2 <= SQLITE_PAGE_SIZE/sizeof(u32) ){
-    maxNeeded += nKeyU;
-  }
-  if( nKeyU < SQLITE_PAGE_SIZE/(3*sizeof(u32)) ){
-    minNeeded += nKeyU;
-  }
-  if( nDataU + maxNeeded + 2 <= SQLITE_PAGE_SIZE/sizeof(u32) ){
-    maxNeeded += nDataU
-  }
-  if( nDataU < SQLITE_PAGE_SIZE/(3*sizeof(u32)) ){
-    minNeeded += nDataU;
-  }
-
-  /* Move the cursor to the leaf block where the new record will be
-  ** inserted.
-  */
-  h = sqliteDbHash(nKey, pKey);
-  rc = sqliteDbFindLeaf(pCur, nKey, pKey, h);
-  if( rc!=SQLITE_OK ) return rc;
-
-  /* Walk thru the leaf once and do two things:
-  **   1.  Remove any prior entry with the same key.
-  **   2.  Figure out how much space is available on this leaf.
-  */
-  i = j = 2;
-  aPage = pCur->aLevel[pCur->nLevel-1].aPage;
-  for(;;){
-    int entrySize = SWB(aPage[i]);
-    if( entrySize<=0 || entrySize + i >= SQLITE_PAGE_SIZE/sizeof(u32) ) break;
-    if( !sqliteDbKeyMatch(&aPage[i], nKey, pKey, h) ){
-      if( j<i ){
-        for(k=0; k<entrySize; k++){
-           aPage[j+k] = aPage[i+k];
-        }
-      }
-      j += entrySize;
-    }else{
-      sqliteDbClearEntry(pCur->pDb, &aPage[i]);
-      incr--;
-    }
-    i += entrySize;
-  }
-  available = SQLITE_PAGE_SIZE/sizeof(u32) - j;
-
-  /* If the new entry will not fit, try to move some of the entries
-  ** from this leaf onto sibling leaves.
-  */
-  if( available<minNeeded ){
-    int newSpace;
-    newSpace = sqliteDbSpreadLoad(pCur, maxNeeded); ############
-    available += newSpace;
-  }
-
-  /* If the new entry still will not fit, try to split this leaf into
-  ** two adjacent leaves.
-  */
-  if( available<minNeeded && pCur->nLevel>1 ){
-    int newAvail;
-    newAvail = sqliteDbSplit(pCur, maxNeeded); ##############
-    if( newAvail>0 ){
-      available += newAvail;
-    }
-  }
-
-  /* If the new entry does not fit after splitting, turn this leaf into
-  ** and index node with one leaf, go down into the new leaf and try 
-  ** to split again.
-  */
-  if( available<minNeeded && pCur->nLevel<MAX_LEVEL-1 ){
-    int newAvail;
-    sqliteDbNewIndexLevel(pCur);  ###############
-    newAvail = sqliteDbSplit(pCur, maxNeeded);
-    if( newAvail>0 ){
-      available = newAvail;
-    }
-  }
-
-  /* If the entry still will not fit, it means the database is full.
-  */
-  if( available<minNeeded ){
-    return SQLITE_FULL;
-  }
-
-  /* Add the new entry to the leaf block.
-  */
-  aPage = pCur->aLevel[pCur->nLevel-1].aPage;
-  i = 2;
-  for(;;){
-    int entrySize = SWB(aPage[i]);
-    if( entrySize<=0 || entrySize + i >= SQLITE_PAGE_SIZE/sizeof(u32) ) break;
-    i += entrySize;
-  }
-  assert( available==SQLITE_PAGE_SIZE/sizeof(u32) - i );
-  aPage[i+1] = SWB(h);
-  available -= 5;
-  if( nKeyU <= available ){
-    aPage[i+2] = SWB(nKey);
-    memcpy(&aPage[i+4], pKey, nKey);
-    j = i + 4 + nKeyU;
-    available -= nKeyU;
-  }else{
-    u32 newPgno, *newPage;
-    aPage[i+2] = SWB(nKey | 0x80000000);
-    rc = allocPage(pCur->pDb, &newPgno, &newPage);
-    if( rc!=SQLITE_OK ) goto write_err;
-    aPage[i+4] = SWB(newPgno);
-    newPage[0] = SWB(BLOCK_MAGIC | BLOCK_OVERFLOW);
-    rc = sqliteDbWriteOvfl(pCur->pDb, newPage, nKey, pKey);
-    if( rc!=SQLITE_OK ) goto write_err;
-    j = i + 5;
-    available -= 1;
-  }
-  if( nDataU <= available ){
-    aPage[i+3] = SWB(nData);
-    memcpy(&aPage[j], pData, nData);
-    available -= nDataU;
-    j += nDataU;
-  }else{
-    u32 newPgno, *newPage;
-    aPage[i+3] = SWB(nData | 0x80000000);
-    rc = allocPage(pCur->pDb, &newPgno, &newPage);
-    if( rc!=SQLITE_OK ) goto write_err;
-    aPage[j] = SWB(newPgno);
-    newPage[0] = SWB(BLOCK_MAGIC | BLOCK_OVERFLOW);
-    rc = sqliteDbWriteOvfl(pCur->pDb, newPage, nData, pData);
-    if( rc!=SQLITE_OK ) goto write_err;
-    available -= 1;
-    j++;
-  }    
-  if( j<SQLITE_PAGE_SIZE/sizeof(u32) ){
-    aPage[j] = 0;
-  }
-  sqlitePgTouch(aPage);
-  pCur->aLevel[pCur->nLevel-1].idx = i;
-  pCur->onEntry = 1;
-
-  /*  Increment the entry count for this table.
-  */
-  if( incr!=0 ){
-    pCur->aLevel[0].aPage[1] = SWB(SWB(pCur->aLevel[0].aPage[1])+incr);
-    sqlitePgTouch(pCur->aLevel[0].aPage);
-  }
-  return SQLITE_OK;
-
-write_err:
-  aPage[i] = 0;
-  pCur->onEntry = 0;
-  return rc;
-}
-
-/*
-** Delete the entry that the cursor points to.
-*/
-int sqliteDbCursorDelete(DbCursor *pCur){
-  int i, idx;
-  int from, to, limit, n;
-  int entrySize;
-  u32 *aPage;
-  if( !pCur->onEntry ) return SQLITE_NOTFOUND;
-
-  /* Delete the entry that the cursor is pointing to.
-  */
-  i = pCur->nLevel - 1;
-  aPage = pCur->aLevel[i].aPage;
-  idx = pCur->aLevel[i].idx;
-  assert( SWB(aPage[0])==BLOCK_MAGIC|BLOCK_LEAF );
-  assert( idx>=2 && idx<SQLITE_PAGE_SIZE/sizeof(u32)-4 );
-  entrySize = SWB(aPage[idx]);
-  assert( entrySize>=6 && idx+entrySize<=SQLITE_PAGE_SIZE/sizeof(u32) );
-  sqliteDbClearEntry(pCur->pDb, &aPage[idx]);
-  to = idx;
-  from = idx + entrySize;
-  while( from<SQLITE_PAGE_SIZE/sizeof(u32) ){
-    int k;
-    entrySize = SWB(aPage[from]);
-    if( entrySize<=0 ) break;
-    for(k=0; k<entrySize; k++){
-      aPage[to++] = aPage[from++]
-    }
-  }
-  aPage[to] = 0;
-
-  /*  Decrement the entry count for this table.
-  */
-  pCur->aLevel[0].aPage[1] = SWB(SWB(pCur->aLevel[0].aPage[1])-1);
-  sqlitePgTouch(pCur->aLevel[0].aPage);
-
-  /* If there are more entries on this leaf or this leaf is the root
-  ** of the table,  then we are done.
-  */
-  if( to>2 || pCur->nLevel==1 ) return SQLITE_OK;
-
-  /* Collapse the tree into a more compact form.
-  */
-  sqliteDbResetCursor(pCur, pCur->nLevel-1);
-
-  i = pCur->nLevel-1;
-  assert( i>=0 && i<MAX_LEVEL );
-  idx = pCur->aLevel[i].idx;
-  aPage = pCur->aLevel[i].aPage;
-  assert( SWB(aPage[0])==BLOCK_MAGIC|BLOCK_INDEX );
-  assert( idx>=3 && idx<SQLITE_PAGE_SIZE/sizeof(u32) );
-  n = SWB(aPage[2]);
-  assert( n>=2 && n<=SQLITE_PAGE_SIZE/2*sizeof(u32)-2 );
-  sqliteDbDropPage(pCur->pDb, SWB(aPage[idx+1]);
-  to = idx;
-  from = idx+2;
-  limit = n*2 + 3;
-  while( from<limit ){
-    aPage[to++] = aPage[from++];
-  }
-  n--;
-  if( n==1 ){
-    u32 oldPgno, *oldPage;
-    oldPgno = SWB(aPage[4]);
-    rc = sqlitePgGet(pCur->pDb->pPgr, oldPgno, &oldPage);
-    if( rc!=SQLITE_OK ){
-      return rc;  /* Do something smarter here */
-    }
-    memcpy(aPage, oldPage, SQLITE_PAGE_SIZE);
-    oldPage[0] = SWB(BLOCK_MAGIC|BLOCK_OVERFLOW);
-    oldPage[1] = 0;
-    sqliteDbDropPage(pCur->pDb, oldPgno);
-    sqlitePgUnref(oldPage);
-  }else{
-    aPage[2] = SWB(n);
-  }
-  sqlitePgTouch(aPage);
-  return SQLITE_OK;
-}
diff --git a/src/ex/db.h b/src/ex/db.h
deleted file mode 100644 (file)
index 67a0906..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
-** Copyright (c) 2001 D. Richard Hipp
-**
-** This program is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public
-** License as published by the Free Software Foundation; either
-** version 2 of the License, or (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-** General Public License for more details.
-** 
-** You should have received a copy of the GNU General Public
-** License along with this library; if not, write to the
-** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-** Boston, MA  02111-1307, USA.
-**
-** Author contact information:
-**   drh@hwaci.com
-**   http://www.hwaci.com/drh/
-**
-*************************************************************************
-** $Id: db.h,v 1.1 2001/02/11 16:56:24 drh Exp $
-*/
-
-typedef struct Db Db;
-typedef struct DbCursor DbCursor;
-
-int sqliteDbOpen(const char *filename, Db**);
-int sqliteDbClose(Db*);
-int sqliteDbBeginTransaction(Db*);
-int sqliteDbCommit(Db*);
-int sqliteDbRollback(Db*);
-
-int sqliteDbCreateTable(Db*, int *pTblno);
-int sqliteDbDropTable(Db*, int tblno);
-
-int sqliteDbCursorOpen(Db*, int tblno, DbCursor**);
-int sqliteDbCursorClose(DbCursor*);
-
-int sqliteDbCursorFirst(DbCursor*);
-int sqliteDbCursorNext(DbCursor*);
-int sqliteDbCursorDatasize(DbCursor*);
-int sqliteDbCursorKeysize(DbCursor*);
-int sqliteDbCursorRead(DbCursor*, int amt, int offset, void *buf);
-int sqliteDbCursorReadKey(DbCursor*, int amt, int offset, void *buf);
-int sqliteDbCursorWrite(DbCursor*, int amt, int offset, const void *buf);
-
-int sqliteDbCursorFind(DbCursor*, int nKey, const void *pKey, int createFlag);
-int sqliteDbCursorResize(DbCursor*, int nData);
diff --git a/src/ex/dbbebdb1.c b/src/ex/dbbebdb1.c
deleted file mode 100644 (file)
index f1d3d9d..0000000
+++ /dev/null
@@ -1,618 +0,0 @@
-/*
-** Copyright (c) 2000 D. Richard Hipp
-**
-** This program is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public
-** License as published by the Free Software Foundation; either
-** version 2 of the License, or (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-** General Public License for more details.
-** 
-** You should have received a copy of the GNU General Public
-** License along with this library; if not, write to the
-** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-** Boston, MA  02111-1307, USA.
-**
-** Author contact information:
-**   drh@hwaci.com
-**   http://www.hwaci.com/drh/
-**
-*************************************************************************
-** This file contains code to implement the database backend (DBBE)
-** for sqlite.  The database backend is the interface between
-** sqlite and the code that does the actually reading and writing
-** of information to the disk.
-**
-** This file uses Berkeley Database version 1.85 as the database backend.
-**
-** $Id: dbbebdb1.c,v 1.1 2001/02/11 16:56:24 drh Exp $
-*/
-#ifdef USE_BDB2
-
-#include "sqliteInt.h"
-#include <sys/types.h>
-#include <limits.h>
-#include <db.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <time.h>
-
-/*
-** Information about each open disk file is an instance of this 
-** structure.  There will only be one such structure for each
-** disk file.  If the VDBE opens the same file twice (as will happen
-** for a self-join, for example) then two DbbeCursor structures are
-** created but there is only a single BeFile structure with an
-** nRef of 2.
-*/
-typedef struct BeFile BeFile;
-struct BeFile {
-  char *zName;            /* Name of the file */
-  DB dbf;                 /* The file itself */
-  int nRef;               /* Number of references */
-  int delOnClose;         /* Delete when closing */
-  int writeable;          /* Opened for writing */
-  DbbeCursor *pCursor; /* Which of several DbbeCursors has the file cursor */
-  BeFile *pNext, *pPrev;  /* Next and previous on list of open files */
-};
-
-/*
-** The following structure contains all information used by BDB2
-** database driver.  This is a subclass of the Dbbe structure.
-*/
-typedef struct Dbbex Dbbex;
-struct Dbbex {
-  Dbbe dbbe;         /* The base class */
-  int write;         /* True for write permission */
-  BeFile *pOpen;     /* List of open files */
-  char *zDir;        /* Directory hold the database */
-};
-
-/*
-** An cursor into a database file is an instance of the following structure.
-** There can only be a single BeFile structure for each disk file, but
-** there can be multiple DbbeCursor structures.  Each DbbeCursor represents
-** a cursor pointing to a particular part of the open BeFile.  The
-** BeFile.nRef field hold a count of the number of DbbeCursor structures
-** associated with the same disk file.
-*/
-struct DbbeCursor {
-  Dbbex *pBe;        /* The database of which this record is a part */
-  BeFile *pFile;     /* The database file for this table */
-  DBT key;           /* Most recently used key */
-  DBT data;          /* Most recent data */
-  int needRewind;    /* Next key should be the first */
-  int readPending;   /* The fetch hasn't actually been done yet */
-};
-
-/*
-** The "mkdir()" function only takes one argument under Windows.
-*/
-#if OS_WIN
-# define mkdir(A,B) mkdir(A)
-#endif
-
-/*
-** Forward declaration
-*/
-static void sqliteBdb1CloseCursor(DbbeCursor *pCursr);
-
-/*
-** Completely shutdown the given database.  Close all files.  Free all memory.
-*/
-static void sqliteBdb1Close(Dbbe *pDbbe){
-  Dbbex *pBe = (Dbbex*)pDbbe;
-  BeFile *pFile, *pNext;
-  for(pFile=pBe->pOpen; pFile; pFile=pNext){
-    pNext = pFile->pNext;
-    (*pFile->dbf)(pFile->dbf);
-    memset(pFile, 0, sizeof(*pFile));   
-    sqliteFree(pFile);
-  }
-  sqliteDbbeCloseAllTempFiles(pDbbe);
-  memset(pBe, 0, sizeof(*pBe));
-  sqliteFree(pBe);
-}
-
-/*
-** Translate the name of an SQL table (or index) into the name 
-** of a file that holds the key/data pairs for that table or
-** index.  Space to hold the filename is obtained from
-** sqliteMalloc() and must be freed by the calling function.
-*/
-static char *sqliteFileOfTable(Dbbex *pBe, const char *zTable){
-  return sqliteDbbeNameToFile(pBe->zDir, zTable, ".tbl");
-}
-
-/*
-** Open a new table cursor.  Write a pointer to the corresponding
-** DbbeCursor structure into *ppCursr.  Return an integer success
-** code:
-**
-**    SQLITE_OK          It worked!
-**
-**    SQLITE_NOMEM       sqliteMalloc() failed
-**
-**    SQLITE_PERM        Attempt to access a file for which file
-**                       access permission is denied
-**
-**    SQLITE_BUSY        Another thread or process is already using
-**                       the corresponding file and has that file locked.
-**
-**    SQLITE_READONLY    The current thread already has this file open
-**                       readonly but you are trying to open for writing.
-**                       (This can happen if a SELECT callback tries to
-**                       do an UPDATE or DELETE.)
-**
-** If zTable is 0 or "", then a temporary database file is created and
-** a cursor to that temporary file is opened.  The temporary file
-** will be deleted from the disk when it is closed.
-*/
-static int sqliteBdb1OpenCursor(
-  Dbbe *pDbbe,            /* The database the table belongs to */
-  const char *zTable,     /* The SQL name of the file to be opened */
-  int writeable,          /* True to open for writing */
-  int intKeyOnly,         /* True if only integer keys are used */
-  DbbeCursor **ppCursr    /* Write the resulting table pointer here */
-){
-  char *zFile;            /* Name of the table file */
-  DbbeCursor *pCursr;     /* The new table cursor */
-  BeFile *pFile;          /* The underlying data file for this table */
-  int rc = SQLITE_OK;     /* Return value */
-  int open_flags;         /* Flags passed to dbopen() */
-  Dbbex *pBe = (Dbbex*)pDbbe;
-
-  *ppCursr = 0;
-  pCursr = sqliteMalloc( sizeof(*pCursr) );
-  if( pCursr==0 ) return SQLITE_NOMEM;
-  if( zTable ){
-    zFile = sqliteFileOfTable(pBe, zTable);
-    for(pFile=pBe->pOpen; pFile; pFile=pFile->pNext){
-      if( strcmp(pFile->zName,zFile)==0 ) break;
-    }
-  }else{
-    pFile = 0;
-    zFile = 0;
-  }
-  if( pFile==0 ){
-    if( writeable ){
-      open_flags = O_RDWR|O_CREAT
-    }else{
-      open_flags = O_RDONLY;
-    }
-    pFile = sqliteMalloc( sizeof(*pFile) );
-    if( pFile==0 ){
-      sqliteFree(zFile);
-      return SQLITE_NOMEM;
-    }
-    if( zFile ){
-      if( !writeable || pBe->write ){
-        pFile->dbf = dbopen(zFile, open_flags, DB_HASH, 0);
-      }else{
-        pFile->dbf = 0;
-      }
-    }else{
-      int limit;
-      char zRandom[50];
-      zFile = 0;
-      limit = 5;
-      do {
-        sqliteRandomName(zRandom, "_temp_table_");
-        sqliteFree(zFile);
-        zFile = sqliteFileOfTable(pBe, zRandom);
-        pFile->dbf = dbopen(zFile, open_flags, DB_HASH, 0);
-      }while( pFile->dbf==0 && limit-- >= 0);
-      pFile->delOnClose = 1;
-    }
-    pFile->writeable = writeable;
-    pFile->zName = zFile;
-    pFile->nRef = 1;
-    pFile->pPrev = 0;
-    if( pBe->pOpen ){
-      pBe->pOpen->pPrev = pFile;
-    }
-    pFile->pCursor = 0;
-    pFile->pNext = pBe->pOpen;
-    pBe->pOpen = pFile;
-    if( pFile->dbf==0 ){
-      if( !writeable && access(zFile,0) ){
-        /* Trying to read a non-existant file.  This is OK.  All the
-        ** reads will return empty, which is what we want. */
-        rc = SQLITE_OK;   
-      }else if( pBe->write==0 ){
-        rc = SQLITE_READONLY;
-      }else if( access(zFile,W_OK|R_OK) ){
-        rc = SQLITE_PERM;
-      }else{
-        rc = SQLITE_BUSY;
-      }
-    }
-  }else{
-    sqliteFree(zFile);
-    pFile->nRef++;
-    if( writeable && !pFile->writeable ){
-      rc = SQLITE_READONLY;
-    }
-  }
-  pCursr->pBe = pBe;
-  pCursr->pFile = pFile;
-  pCursr->readPending = 0;
-  pCursr->needRewind = 1;
-  if( rc!=SQLITE_OK ){
-    sqliteBdb1CloseCursor(pCursr);
-    *ppCursr = 0;
-  }else{
-    *ppCursr = pCursr;
-  }
-  return rc;
-}
-
-/*
-** Drop a table from the database.  The file on the disk that corresponds
-** to this table is deleted.
-*/
-static void sqliteBdb1DropTable(Dbbe *pBe, const char *zTable){
-  char *zFile;            /* Name of the table file */
-
-  zFile = sqliteFileOfTable((Dbbex*)pBe, zTable);
-  unlink(zFile);
-  sqliteFree(zFile);
-}
-
-/*
-** Close a cursor previously opened by sqliteBdb1OpenCursor().
-**
-** There can be multiple cursors pointing to the same open file.
-** The underlying file is not closed until all cursors have been
-** closed.  This routine decrements the BeFile.nref field of the
-** underlying file and closes the file when nref reaches 0.
-*/
-static void sqliteBdb1CloseCursor(DbbeCursor *pCursr){
-  BeFile *pFile;
-  Dbbex *pBe;
-  if( pCursr==0 ) return;
-  pFile = pCursr->pFile;
-  pBe = pCursr->pBe;
-  if( pFile->pCursor==pCursr ){
-    pFile->pCursor = 0;
-  }
-  pFile->nRef--;
-  if( pFile->dbf!=NULL ){
-    (*pFile->dbf->sync)(pFile->dbf, 0);
-  }
-  if( pFile->nRef<=0 ){
-    if( pFile->dbf!=NULL ){
-      (*pFile->dbf->close)(pFile->dbf);
-    }
-    if( pFile->pPrev ){
-      pFile->pPrev->pNext = pFile->pNext;
-    }else{
-      pBe->pOpen = pFile->pNext;
-    }
-    if( pFile->pNext ){
-      pFile->pNext->pPrev = pFile->pPrev;
-    }
-    if( pFile->delOnClose ){
-      unlink(pFile->zName);
-    }
-    sqliteFree(pFile->zName);
-    memset(pFile, 0, sizeof(*pFile));
-    sqliteFree(pFile);
-  }
-  if( pCursr->key.dptr ) free(pCursr->key.dptr); ######
-  if( pCursr->data.dptr ) free(pCursr->data.dptr); ######
-  memset(pCursr, 0, sizeof(*pCursr));
-  sqliteFree(pCursr);
-}
-
-/*
-** Reorganize a table to reduce search times and disk usage.
-*/
-static int sqliteBdb1ReorganizeTable(Dbbe *pBe, const char *zTable){
-  /* No-op */
-  return SQLITE_OK;
-}
-
-/*
-** Clear the given datum
-*/
-static void datumClear(datum *p){
-  if( p->dptr ) free(p->dptr); ########
-  p->data = 0;
-  p->size = 0;
-}
-
-/*
-** Fetch a single record from an open cursor.  Return 1 on success
-** and 0 on failure.
-*/
-static int sqliteBdb1Fetch(DbbeCursor *pCursr, int nKey, char *pKey){
-  DBT key;
-  key.size = nKey;
-  key.data = pKey;
-  datumClear(&pCursr->key);
-  datumClear(&pCursr->data);
-  if( pCursr->pFile && pCursr->pFile->dbf ){
-    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, key);
-  }
-  return pCursr->data.dptr!=0;
-}
-
-/*
-** Return 1 if the given key is already in the table.  Return 0
-** if it is not.
-*/
-static int sqliteBdb1Test(DbbeCursor *pCursr, int nKey, char *pKey){
-  DBT key;
-  int result = 0;
-  key.dsize = nKey;
-  key.dptr = pKey;
-  if( pCursr->pFile && pCursr->pFile->dbf ){
-    result = gdbm_exists(pCursr->pFile->dbf, key);
-  }
-  return result;
-}
-
-/*
-** Copy bytes from the current key or data into a buffer supplied by
-** the calling function.  Return the number of bytes copied.
-*/
-static
-int sqliteBdb1CopyKey(DbbeCursor *pCursr, int offset, int size, char *zBuf){
-  int n;
-  if( offset>=pCursr->key.dsize ) return 0;
-  if( offset+size>pCursr->key.dsize ){
-    n = pCursr->key.dsize - offset;
-  }else{
-    n = size;
-  }
-  memcpy(zBuf, &pCursr->key.dptr[offset], n);
-  return n;
-}
-static
-int sqliteBdb1CopyData(DbbeCursor *pCursr, int offset, int size, char *zBuf){
-  int n;
-  if( pCursr->readPending && pCursr->pFile && pCursr->pFile->dbf ){
-    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, pCursr->key);
-    pCursr->readPending = 0;
-  }
-  if( offset>=pCursr->data.dsize ) return 0;
-  if( offset+size>pCursr->data.dsize ){
-    n = pCursr->data.dsize - offset;
-  }else{
-    n = size;
-  }
-  memcpy(zBuf, &pCursr->data.dptr[offset], n);
-  return n;
-}
-
-/*
-** Return a pointer to bytes from the key or data.  The data returned
-** is ephemeral.
-*/
-static char *sqliteBdb1ReadKey(DbbeCursor *pCursr, int offset){
-  if( offset<0 || offset>=pCursr->key.dsize ) return "";
-  return &pCursr->key.dptr[offset];
-}
-static char *sqliteBdb1ReadData(DbbeCursor *pCursr, int offset){
-  if( pCursr->readPending && pCursr->pFile && pCursr->pFile->dbf ){
-    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, pCursr->key);
-    pCursr->readPending = 0;
-  }
-  if( offset<0 || offset>=pCursr->data.dsize ) return "";
-  return &pCursr->data.dptr[offset];
-}
-
-/*
-** Return the total number of bytes in either data or key.
-*/
-static int sqliteBdb1KeyLength(DbbeCursor *pCursr){
-  return pCursr->key.dsize;
-}
-static int sqliteBdb1DataLength(DbbeCursor *pCursr){
-  if( pCursr->readPending && pCursr->pFile && pCursr->pFile->dbf ){
-    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, pCursr->key);
-    pCursr->readPending = 0;
-  }
-  return pCursr->data.dsize;
-}
-
-/*
-** Make is so that the next call to sqliteNextKey() finds the first
-** key of the table.
-*/
-static int sqliteBdb1Rewind(DbbeCursor *pCursr){
-  pCursr->needRewind = 1;
-  return SQLITE_OK;
-}
-
-/*
-** Read the next key from the table.  Return 1 on success.  Return
-** 0 if there are no more keys.
-*/
-static int sqliteBdb1NextKey(DbbeCursor *pCursr){
-  DBT nextkey;
-  int rc;
-  if( pCursr==0 || pCursr->pFile==0 || pCursr->pFile->dbf==0 ){
-    pCursr->readPending = 0;
-    return 0;
-  }
-  if( pCursr->needRewind ){
-    nextkey = gdbm_firstkey(pCursr->pFile->dbf);
-    pCursr->needRewind = 0;
-  }else{
-    nextkey = gdbm_nextkey(pCursr->pFile->dbf, pCursr->key);
-  }
-  datumClear(&pCursr->key);
-  datumClear(&pCursr->data);
-  pCursr->key = nextkey;
-  if( pCursr->key.dptr ){
-    pCursr->readPending = 1;
-    rc = 1;
-  }else{
-    pCursr->needRewind = 1;
-    pCursr->readPending = 0;
-    rc = 0;
-  }
-  return rc;
-}
-
-/*
-** Get a new integer key.
-*/
-static int sqliteBdb1New(DbbeCursor *pCursr){
-  int iKey;
-  DBT key;
-  int go = 1;
-
-  if( pCursr->pFile==0 || pCursr->pFile->dbf==0 ) return 1;
-  while( go ){
-    iKey = sqliteRandomInteger();
-    if( iKey==0 ) continue;
-    key.dptr = (char*)&iKey;
-    key.dsize = 4;
-    go = gdbm_exists(pCursr->pFile->dbf, key);
-  }
-  return iKey;
-}   
-
-/*
-** Write an entry into the table.  Overwrite any prior entry with the
-** same key.
-*/
-static int sqliteBdb1Put(
-  DbbeCursor *pCursr,  /* Write to the database associated with this cursor */
-  int nKey,            /* Number of bytes in the key */
-  char *pKey,          /* The data for the key */
-  int nData,           /* Number of bytes of data */
-  char *pData          /* The data */
-){
-  DBT data, key;
-  int rc;
-  if( pCursr->pFile==0 || pCursr->pFile->dbf==0 ) return SQLITE_ERROR;
-  data.dsize = nData;
-  data.dptr = pData;
-  key.dsize = nKey;
-  key.dptr = pKey;
-  rc = gdbm_store(pCursr->pFile->dbf, key, data, GDBM_REPLACE);
-  if( rc ) rc = SQLITE_ERROR;
-  datumClear(&pCursr->key);
-  datumClear(&pCursr->data);
-  return rc;
-}
-
-/*
-** Remove an entry from a table, if the entry exists.
-*/
-static int sqliteBdb1Delete(DbbeCursor *pCursr, int nKey, char *pKey){
-  DBT key;
-  int rc;
-  datumClear(&pCursr->key);
-  datumClear(&pCursr->data);
-  if( pCursr->pFile==0 || pCursr->pFile->dbf==0 ) return SQLITE_ERROR;
-  key.dsize = nKey;
-  key.dptr = pKey;
-  rc = gdbm_delete(pCursr->pFile->dbf, key);
-  if( rc ) rc = SQLITE_ERROR;
-  return rc;
-}
-
-/*
-** Open a temporary file.  The file is located in the same directory
-** as the rest of the database.
-*/
-static int sqliteBdb1OpenTempFile(Dbbe *pDbbe, FILE **ppFile){
-  Dbbex *pBe = (Dbbex*)pDbbe;
-  return sqliteDbbeOpenTempFile(pBe->zDir, pDbbe, ppFile);
-}
-
-/*
-** This variable contains pointers to all of the access methods
-** used to implement the GDBM backend.
-*/
-static struct DbbeMethods gdbmMethods = {
-  /* n         Close */   sqliteBdb1Close,
-  /*      OpenCursor */   sqliteBdb1OpenCursor,
-  /*       DropTable */   sqliteBdb1DropTable,
-  /* ReorganizeTable */   sqliteBdb1ReorganizeTable,
-  /*     CloseCursor */   sqliteBdb1CloseCursor,
-  /*           Fetch */   sqliteBdb1Fetch,
-  /*            Test */   sqliteBdb1Test,
-  /*         CopyKey */   sqliteBdb1CopyKey,
-  /*        CopyData */   sqliteBdb1CopyData,
-  /*         ReadKey */   sqliteBdb1ReadKey,
-  /*        ReadData */   sqliteBdb1ReadData,
-  /*       KeyLength */   sqliteBdb1KeyLength,
-  /*      DataLength */   sqliteBdb1DataLength,
-  /*         NextKey */   sqliteBdb1NextKey,
-  /*          Rewind */   sqliteBdb1Rewind,
-  /*             New */   sqliteBdb1New,
-  /*             Put */   sqliteBdb1Put,
-  /*          Delete */   sqliteBdb1Delete,
-  /*    OpenTempFile */   sqliteBdb1OpenTempFile,
-  /*   CloseTempFile */   sqliteDbbeCloseTempFile
-};
-
-
-/*
-** This routine opens a new database.  For the GDBM driver
-** implemented here, the database name is the name of the directory
-** containing all the files of the database.
-**
-** If successful, a pointer to the Dbbe structure is returned.
-** If there are errors, an appropriate error message is left
-** in *pzErrMsg and NULL is returned.
-*/
-Dbbe *sqliteBdb1Open(
-  const char *zName,     /* The name of the database */
-  int writeFlag,         /* True if we will be writing to the database */
-  int createFlag,        /* True to create database if it doesn't exist */
-  char **pzErrMsg        /* Write error messages (if any) here */
-){
-  Dbbex *pNew;
-  struct stat statbuf;
-  char *zMaster;
-
-  if( !writeFlag ) createFlag = 0;
-  if( stat(zName, &statbuf)!=0 ){
-    if( createFlag ) mkdir(zName, 0750);
-    if( stat(zName, &statbuf)!=0 ){
-      sqliteSetString(pzErrMsg, createFlag ? 
-         "can't find or create directory \"" : "can't find directory \"",
-         zName, "\"", 0);
-      return 0;
-    }
-  }
-  if( !S_ISDIR(statbuf.st_mode) ){
-    sqliteSetString(pzErrMsg, "not a directory: \"", zName, "\"", 0);
-    return 0;
-  }
-  if( access(zName, writeFlag ? (X_OK|W_OK|R_OK) : (X_OK|R_OK)) ){
-    sqliteSetString(pzErrMsg, "access permission denied", 0);
-    return 0;
-  }
-  zMaster = 0;
-  sqliteSetString(&zMaster, zName, "/" MASTER_NAME ".tbl", 0);
-  if( stat(zMaster, &statbuf)==0
-   && access(zMaster, writeFlag ? (W_OK|R_OK) : R_OK)!=0 ){
-    sqliteSetString(pzErrMsg, "access permission denied for ", zMaster, 0);
-    sqliteFree(zMaster);
-    return 0;
-  }
-  sqliteFree(zMaster);
-  pNew = sqliteMalloc(sizeof(Dbbex) + strlen(zName) + 1);
-  if( pNew==0 ){
-    sqliteSetString(pzErrMsg, "out of memory", 0);
-    return 0;
-  }
-  pNew->dbbe.x = &gdbmMethods;
-  pNew->zDir = (char*)&pNew[1];
-  strcpy(pNew->zDir, zName);
-  pNew->write = writeFlag;
-  pNew->pOpen = 0;
-  return &pNew->dbbe;
-}
diff --git a/src/ex/dbbemird.c b/src/ex/dbbemird.c
deleted file mode 100644 (file)
index 7ca9759..0000000
+++ /dev/null
@@ -1,776 +0,0 @@
-/*
-** Copyright (c) 2000 D. Richard Hipp
-**
-** This program is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public
-** License as published by the Free Software Foundation; either
-** version 2 of the License, or (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-** General Public License for more details.
-** 
-** You should have received a copy of the GNU General Public
-** License along with this library; if not, write to the
-** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-** Boston, MA  02111-1307, USA.
-**
-** Author contact information:
-**   drh@hwaci.com
-**   http://www.hwaci.com/drh/
-**
-*************************************************************************
-** This file contains code to implement the database backend (DBBE)
-** for sqlite.  The database backend is the interface between
-** sqlite and the code that does the actually reading and writing
-** of information to the disk.
-**
-** This file uses GDBM as the database backend.  It should be
-** relatively simple to convert to a different database such
-** as NDBM, SDBM, or BerkeleyDB.
-**
-** $Id: dbbemird.c,v 1.1 2001/02/11 16:56:24 drh Exp $
-*/
-#include "sqliteInt.h"
-#include <gdbm.h>
-#include <sys/stat.h>
-#include <unistd.h>
-#include <ctype.h>
-#include <time.h>
-
-/*
-** Information about each open disk file is an instance of this 
-** structure.  There will only be one such structure for each
-** disk file.  If the VDBE opens the same file twice (as will happen
-** for a self-join, for example) then two DbbeCursor structures are
-** created but there is only a single BeFile structure with an
-** nRef of 2.
-*/
-typedef struct BeFile BeFile;
-struct BeFile {
-  char *zName;            /* Name of the file */
-  GDBM_FILE dbf;          /* The file itself */
-  int nRef;               /* Number of references */
-  int delOnClose;         /* Delete when closing */
-  int writeable;          /* Opened for writing */
-  BeFile *pNext, *pPrev;  /* Next and previous on list of open files */
-};
-
-/*
-** The following structure holds the current state of the RC4 algorithm.
-** We use RC4 as a random number generator.  Each call to RC4 gives
-** a random 8-bit number.
-**
-** Nothing in this file or anywhere else in SQLite does any kind of
-** encryption.  The RC4 algorithm is being used as a PRNG (pseudo-random
-** number generator) not as an encryption device.
-*/
-struct rc4 {
-  int i, j;
-  int s[256];
-};
-
-/*
-** The following structure contains all information used by GDBM
-** database driver.  This is a subclass of the Dbbe structure.
-*/
-typedef struct Dbbex Dbbex;
-struct Dbbex {
-  Dbbe dbbe;         /* The base class */
-  char *zDir;        /* The directory containing the database */
-  int write;         /* True for write permission */
-  BeFile *pOpen;     /* List of open files */
-  int nTemp;         /* Number of temporary files created */
-  FILE **apTemp;     /* Space to hold temporary file pointers */
-  char **azTemp;     /* Names of the temporary files */
-  struct rc4 rc4;    /* The random number generator */
-};
-
-/*
-** An cursor into a database file is an instance of the following structure.
-** There can only be a single BeFile structure for each disk file, but
-** there can be multiple DbbeCursor structures.  Each DbbeCursor represents
-** a cursor pointing to a particular part of the open BeFile.  The
-** BeFile.nRef field hold a count of the number of DbbeCursor structures
-** associated with the same disk file.
-*/
-struct DbbeCursor {
-  Dbbex *pBe;        /* The database of which this record is a part */
-  BeFile *pFile;     /* The database file for this table */
-  datum key;         /* Most recently used key */
-  datum data;        /* Most recent data */
-  int needRewind;    /* Next key should be the first */
-  int readPending;   /* The fetch hasn't actually been done yet */
-};
-
-/*
-** Initialize the RC4 PRNG.  "seed" is a pointer to some random
-** data used to initialize the PRNG.  
-*/
-static void rc4init(struct rc4 *p, char *seed, int seedlen){
-  int i;
-  char k[256];
-  p->j = 0;
-  p->i = 0;
-  for(i=0; i<256; i++){
-    p->s[i] = i;
-    k[i] = seed[i%seedlen];
-  }
-  for(i=0; i<256; i++){
-    int t;
-    p->j = (p->j + p->s[i] + k[i]) & 0xff;
-    t = p->s[p->j];
-    p->s[p->j] = p->s[i];
-    p->s[i] = t;
-  }
-}
-
-/*
-** Get a single 8-bit random value from the RC4 PRNG.
-*/
-static int rc4byte(struct rc4 *p){
-  int t;
-  p->i = (p->i + 1) & 0xff;
-  p->j = (p->j + p->s[p->i]) & 0xff;
-  t = p->s[p->i];
-  p->s[p->i] = p->s[p->j];
-  p->s[p->j] = t;
-  t = p->s[p->i] + p->s[p->j];
-  return t & 0xff;
-}
-
-/*
-** The "mkdir()" function only takes one argument under Windows.
-*/
-#if OS_WIN
-# define mkdir(A,B) mkdir(A)
-#endif
-
-/*
-** Forward declaration
-*/
-static void sqliteGdbmCloseCursor(DbbeCursor *pCursr);
-
-/*
-** Completely shutdown the given database.  Close all files.  Free all memory.
-*/
-static void sqliteGdbmClose(Dbbe *pDbbe){
-  Dbbex *pBe = (Dbbex*)pDbbe;
-  BeFile *pFile, *pNext;
-  int i;
-  for(pFile=pBe->pOpen; pFile; pFile=pNext){
-    pNext = pFile->pNext;
-    gdbm_close(pFile->dbf);
-    memset(pFile, 0, sizeof(*pFile));   
-    sqliteFree(pFile);
-  }
-  for(i=0; i<pBe->nTemp; i++){
-    if( pBe->apTemp[i]!=0 ){
-      unlink(pBe->azTemp[i]);
-      fclose(pBe->apTemp[i]);
-      sqliteFree(pBe->azTemp[i]);
-      pBe->apTemp[i] = 0;
-      pBe->azTemp[i] = 0;
-      break;
-    }
-  }
-  sqliteFree(pBe->azTemp);
-  sqliteFree(pBe->apTemp);
-  memset(pBe, 0, sizeof(*pBe));
-  sqliteFree(pBe);
-}
-
-/*
-** Translate the name of an SQL table (or index) into the name 
-** of a file that holds the key/data pairs for that table or
-** index.  Space to hold the filename is obtained from
-** sqliteMalloc() and must be freed by the calling function.
-*/
-static char *sqliteFileOfTable(Dbbex *pBe, const char *zTable){
-  char *zFile = 0;
-  int i;
-  sqliteSetString(&zFile, pBe->zDir, "/", zTable, ".tbl", 0);
-  if( zFile==0 ) return 0;
-  for(i=strlen(pBe->zDir)+1; zFile[i]; i++){
-    int c = zFile[i];
-    if( isupper(c) ){
-      zFile[i] = tolower(c);
-    }else if( !isalnum(c) && c!='-' && c!='_' && c!='.' ){
-      zFile[i] = '+';
-    }
-  }
-  return zFile;
-}
-
-/*
-** Generate a random filename with the given prefix.  The new filename
-** is written into zBuf[].  The calling function must insure that
-** zBuf[] is big enough to hold the prefix plus 20 or so extra
-** characters.
-**
-** Very random names are chosen so that the chance of a
-** collision with an existing filename is very very small.
-*/
-static void randomName(struct rc4 *pRc4, char *zBuf, char *zPrefix){
-  int i, j;
-  static const char zRandomChars[] = "abcdefghijklmnopqrstuvwxyz0123456789";
-  strcpy(zBuf, zPrefix);
-  j = strlen(zBuf);
-  for(i=0; i<15; i++){
-    int c = rc4byte(pRc4) % (sizeof(zRandomChars) - 1);
-    zBuf[j++] = zRandomChars[c];
-  }
-  zBuf[j] = 0;
-}
-
-/*
-** Open a new table cursor.  Write a pointer to the corresponding
-** DbbeCursor structure into *ppCursr.  Return an integer success
-** code:
-**
-**    SQLITE_OK          It worked!
-**
-**    SQLITE_NOMEM       sqliteMalloc() failed
-**
-**    SQLITE_PERM        Attempt to access a file for which file
-**                       access permission is denied
-**
-**    SQLITE_BUSY        Another thread or process is already using
-**                       the corresponding file and has that file locked.
-**
-**    SQLITE_READONLY    The current thread already has this file open
-**                       readonly but you are trying to open for writing.
-**                       (This can happen if a SELECT callback tries to
-**                       do an UPDATE or DELETE.)
-**
-** If zTable is 0 or "", then a temporary database file is created and
-** a cursor to that temporary file is opened.  The temporary file
-** will be deleted from the disk when it is closed.
-*/
-static int sqliteGdbmOpenCursor(
-  Dbbe *pDbbe,            /* The database the table belongs to */
-  const char *zTable,     /* The SQL name of the file to be opened */
-  int writeable,          /* True to open for writing */
-  DbbeCursor **ppCursr    /* Write the resulting table pointer here */
-){
-  char *zFile;            /* Name of the table file */
-  DbbeCursor *pCursr;     /* The new table cursor */
-  BeFile *pFile;          /* The underlying data file for this table */
-  int rc = SQLITE_OK;     /* Return value */
-  int rw_mask;            /* Permissions mask for opening a table */
-  int mode;               /* Mode for opening a table */
-  Dbbex *pBe = (Dbbex*)pDbbe;
-
-  *ppCursr = 0;
-  pCursr = sqliteMalloc( sizeof(*pCursr) );
-  if( pCursr==0 ) return SQLITE_NOMEM;
-  if( zTable ){
-    zFile = sqliteFileOfTable(pBe, zTable);
-    for(pFile=pBe->pOpen; pFile; pFile=pFile->pNext){
-      if( strcmp(pFile->zName,zFile)==0 ) break;
-    }
-  }else{
-    pFile = 0;
-    zFile = 0;
-  }
-  if( pFile==0 ){
-    if( writeable ){
-      rw_mask = GDBM_WRCREAT | GDBM_FAST;
-      mode = 0640;
-    }else{
-      rw_mask = GDBM_READER;
-      mode = 0640;
-    }
-    pFile = sqliteMalloc( sizeof(*pFile) );
-    if( pFile==0 ){
-      sqliteFree(zFile);
-      return SQLITE_NOMEM;
-    }
-    if( zFile ){
-      if( !writeable || pBe->write ){
-        pFile->dbf = gdbm_open(zFile, 0, rw_mask, mode, 0);
-      }else{
-        pFile->dbf = 0;
-      }
-    }else{
-      int limit;
-      struct rc4 *pRc4;
-      char zRandom[50];
-      pRc4 = &pBe->rc4;
-      zFile = 0;
-      limit = 5;
-      do {
-        randomName(&pBe->rc4, zRandom, "_temp_table_");
-        sqliteFree(zFile);
-        zFile = sqliteFileOfTable(pBe, zRandom);
-        pFile->dbf = gdbm_open(zFile, 0, rw_mask, mode, 0);
-      }while( pFile->dbf==0 && limit-- >= 0);
-      pFile->delOnClose = 1;
-    }
-    pFile->writeable = writeable;
-    pFile->zName = zFile;
-    pFile->nRef = 1;
-    pFile->pPrev = 0;
-    if( pBe->pOpen ){
-      pBe->pOpen->pPrev = pFile;
-    }
-    pFile->pNext = pBe->pOpen;
-    pBe->pOpen = pFile;
-    if( pFile->dbf==0 ){
-      if( !writeable && access(zFile,0) ){
-        /* Trying to read a non-existant file.  This is OK.  All the
-        ** reads will return empty, which is what we want. */
-        rc = SQLITE_OK;   
-      }else if( pBe->write==0 ){
-        rc = SQLITE_READONLY;
-      }else if( access(zFile,W_OK|R_OK) ){
-        rc = SQLITE_PERM;
-      }else{
-        rc = SQLITE_BUSY;
-      }
-    }
-  }else{
-    sqliteFree(zFile);
-    pFile->nRef++;
-    if( writeable && !pFile->writeable ){
-      rc = SQLITE_READONLY;
-    }
-  }
-  pCursr->pBe = pBe;
-  pCursr->pFile = pFile;
-  pCursr->readPending = 0;
-  pCursr->needRewind = 1;
-  if( rc!=SQLITE_OK ){
-    sqliteGdbmCloseCursor(pCursr);
-    *ppCursr = 0;
-  }else{
-    *ppCursr = pCursr;
-  }
-  return rc;
-}
-
-/*
-** Drop a table from the database.  The file on the disk that corresponds
-** to this table is deleted.
-*/
-static void sqliteGdbmDropTable(Dbbe *pBe, const char *zTable){
-  char *zFile;            /* Name of the table file */
-
-  zFile = sqliteFileOfTable((Dbbex*)pBe, zTable);
-  unlink(zFile);
-  sqliteFree(zFile);
-}
-
-/*
-** Close a cursor previously opened by sqliteGdbmOpenCursor().
-**
-** There can be multiple cursors pointing to the same open file.
-** The underlying file is not closed until all cursors have been
-** closed.  This routine decrements the BeFile.nref field of the
-** underlying file and closes the file when nref reaches 0.
-*/
-static void sqliteGdbmCloseCursor(DbbeCursor *pCursr){
-  BeFile *pFile;
-  Dbbex *pBe;
-  if( pCursr==0 ) return;
-  pFile = pCursr->pFile;
-  pBe = pCursr->pBe;
-  pFile->nRef--;
-  if( pFile->dbf!=NULL ){
-    gdbm_sync(pFile->dbf);
-  }
-  if( pFile->nRef<=0 ){
-    if( pFile->dbf!=NULL ){
-      gdbm_close(pFile->dbf);
-    }
-    if( pFile->pPrev ){
-      pFile->pPrev->pNext = pFile->pNext;
-    }else{
-      pBe->pOpen = pFile->pNext;
-    }
-    if( pFile->pNext ){
-      pFile->pNext->pPrev = pFile->pPrev;
-    }
-    if( pFile->delOnClose ){
-      unlink(pFile->zName);
-    }
-    sqliteFree(pFile->zName);
-    memset(pFile, 0, sizeof(*pFile));
-    sqliteFree(pFile);
-  }
-  if( pCursr->key.dptr ) free(pCursr->key.dptr);
-  if( pCursr->data.dptr ) free(pCursr->data.dptr);
-  memset(pCursr, 0, sizeof(*pCursr));
-  sqliteFree(pCursr);
-}
-
-/*
-** Reorganize a table to reduce search times and disk usage.
-*/
-static int sqliteGdbmReorganizeTable(Dbbe *pBe, const char *zTable){
-  DbbeCursor *pCrsr;
-  int rc;
-
-  rc = sqliteGdbmOpenCursor(pBe, zTable, 1, &pCrsr);
-  if( rc!=SQLITE_OK ){
-    return rc;
-  }
-  if( pCrsr && pCrsr->pFile && pCrsr->pFile->dbf ){
-    gdbm_reorganize(pCrsr->pFile->dbf);
-  }
-  if( pCrsr ){
-    sqliteGdbmCloseCursor(pCrsr);
-  }
-  return SQLITE_OK;
-}
-
-/*
-** Clear the given datum
-*/
-static void datumClear(datum *p){
-  if( p->dptr ) free(p->dptr);
-  p->dptr = 0;
-  p->dsize = 0;
-}
-
-/*
-** Fetch a single record from an open cursor.  Return 1 on success
-** and 0 on failure.
-*/
-static int sqliteGdbmFetch(DbbeCursor *pCursr, int nKey, char *pKey){
-  datum key;
-  key.dsize = nKey;
-  key.dptr = pKey;
-  datumClear(&pCursr->key);
-  datumClear(&pCursr->data);
-  if( pCursr->pFile && pCursr->pFile->dbf ){
-    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, key);
-  }
-  return pCursr->data.dptr!=0;
-}
-
-/*
-** Return 1 if the given key is already in the table.  Return 0
-** if it is not.
-*/
-static int sqliteGdbmTest(DbbeCursor *pCursr, int nKey, char *pKey){
-  datum key;
-  int result = 0;
-  key.dsize = nKey;
-  key.dptr = pKey;
-  if( pCursr->pFile && pCursr->pFile->dbf ){
-    result = gdbm_exists(pCursr->pFile->dbf, key);
-  }
-  return result;
-}
-
-/*
-** Copy bytes from the current key or data into a buffer supplied by
-** the calling function.  Return the number of bytes copied.
-*/
-static
-int sqliteGdbmCopyKey(DbbeCursor *pCursr, int offset, int size, char *zBuf){
-  int n;
-  if( offset>=pCursr->key.dsize ) return 0;
-  if( offset+size>pCursr->key.dsize ){
-    n = pCursr->key.dsize - offset;
-  }else{
-    n = size;
-  }
-  memcpy(zBuf, &pCursr->key.dptr[offset], n);
-  return n;
-}
-static
-int sqliteGdbmCopyData(DbbeCursor *pCursr, int offset, int size, char *zBuf){
-  int n;
-  if( pCursr->readPending && pCursr->pFile && pCursr->pFile->dbf ){
-    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, pCursr->key);
-    pCursr->readPending = 0;
-  }
-  if( offset>=pCursr->data.dsize ) return 0;
-  if( offset+size>pCursr->data.dsize ){
-    n = pCursr->data.dsize - offset;
-  }else{
-    n = size;
-  }
-  memcpy(zBuf, &pCursr->data.dptr[offset], n);
-  return n;
-}
-
-/*
-** Return a pointer to bytes from the key or data.  The data returned
-** is ephemeral.
-*/
-static char *sqliteGdbmReadKey(DbbeCursor *pCursr, int offset){
-  if( offset<0 || offset>=pCursr->key.dsize ) return "";
-  return &pCursr->key.dptr[offset];
-}
-static char *sqliteGdbmReadData(DbbeCursor *pCursr, int offset){
-  if( pCursr->readPending && pCursr->pFile && pCursr->pFile->dbf ){
-    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, pCursr->key);
-    pCursr->readPending = 0;
-  }
-  if( offset<0 || offset>=pCursr->data.dsize ) return "";
-  return &pCursr->data.dptr[offset];
-}
-
-/*
-** Return the total number of bytes in either data or key.
-*/
-static int sqliteGdbmKeyLength(DbbeCursor *pCursr){
-  return pCursr->key.dsize;
-}
-static int sqliteGdbmDataLength(DbbeCursor *pCursr){
-  if( pCursr->readPending && pCursr->pFile && pCursr->pFile->dbf ){
-    pCursr->data = gdbm_fetch(pCursr->pFile->dbf, pCursr->key);
-    pCursr->readPending = 0;
-  }
-  return pCursr->data.dsize;
-}
-
-/*
-** Make is so that the next call to sqliteNextKey() finds the first
-** key of the table.
-*/
-static int sqliteGdbmRewind(DbbeCursor *pCursr){
-  pCursr->needRewind = 1;
-  return SQLITE_OK;
-}
-
-/*
-** Read the next key from the table.  Return 1 on success.  Return
-** 0 if there are no more keys.
-*/
-static int sqliteGdbmNextKey(DbbeCursor *pCursr){
-  datum nextkey;
-  int rc;
-  if( pCursr==0 || pCursr->pFile==0 || pCursr->pFile->dbf==0 ){
-    pCursr->readPending = 0;
-    return 0;
-  }
-  if( pCursr->needRewind ){
-    nextkey = gdbm_firstkey(pCursr->pFile->dbf);
-    pCursr->needRewind = 0;
-  }else{
-    nextkey = gdbm_nextkey(pCursr->pFile->dbf, pCursr->key);
-  }
-  datumClear(&pCursr->key);
-  datumClear(&pCursr->data);
-  pCursr->key = nextkey;
-  if( pCursr->key.dptr ){
-    pCursr->readPending = 1;
-    rc = 1;
-  }else{
-    pCursr->needRewind = 1;
-    pCursr->readPending = 0;
-    rc = 0;
-  }
-  return rc;
-}
-
-/*
-** Get a new integer key.
-*/
-static int sqliteGdbmNew(DbbeCursor *pCursr){
-  int iKey;
-  datum key;
-  int go = 1;
-  int i;
-  struct rc4 *pRc4;
-
-  if( pCursr->pFile==0 || pCursr->pFile->dbf==0 ) return 1;
-  pRc4 = &pCursr->pBe->rc4;
-  while( go ){
-    iKey = 0;
-    for(i=0; i<4; i++){
-      iKey = (iKey<<8) + rc4byte(pRc4);
-    }
-    if( iKey==0 ) continue;
-    key.dptr = (char*)&iKey;
-    key.dsize = 4;
-    go = gdbm_exists(pCursr->pFile->dbf, key);
-  }
-  return iKey;
-}   
-
-/*
-** Write an entry into the table.  Overwrite any prior entry with the
-** same key.
-*/
-static int
-sqliteGdbmPut(DbbeCursor *pCursr, int nKey,char *pKey,int nData,char *pData){
-  datum data, key;
-  int rc;
-  if( pCursr->pFile==0 || pCursr->pFile->dbf==0 ) return SQLITE_ERROR;
-  data.dsize = nData;
-  data.dptr = pData;
-  key.dsize = nKey;
-  key.dptr = pKey;
-  rc = gdbm_store(pCursr->pFile->dbf, key, data, GDBM_REPLACE);
-  if( rc ) rc = SQLITE_ERROR;
-  datumClear(&pCursr->key);
-  datumClear(&pCursr->data);
-  return rc;
-}
-
-/*
-** Remove an entry from a table, if the entry exists.
-*/
-static int sqliteGdbmDelete(DbbeCursor *pCursr, int nKey, char *pKey){
-  datum key;
-  int rc;
-  datumClear(&pCursr->key);
-  datumClear(&pCursr->data);
-  if( pCursr->pFile==0 || pCursr->pFile->dbf==0 ) return SQLITE_ERROR;
-  key.dsize = nKey;
-  key.dptr = pKey;
-  rc = gdbm_delete(pCursr->pFile->dbf, key);
-  if( rc ) rc = SQLITE_ERROR;
-  return rc;
-}
-
-/*
-** Open a temporary file.  The file should be deleted when closed.
-**
-** Note that we can't use the old Unix trick of opening the file
-** and then immediately unlinking the file.  That works great
-** under Unix, but fails when we try to port to Windows.
-*/
-static int sqliteGdbmOpenTempFile(Dbbe *pDbbe, FILE **ppFile){
-  char *zFile;         /* Full name of the temporary file */
-  char zBuf[50];       /* Base name of the temporary file */
-  int i;               /* Loop counter */
-  int limit;           /* Prevent an infinite loop */
-  int rc = SQLITE_OK;  /* Value returned by this function */
-  Dbbex *pBe = (Dbbex*)pDbbe;
-
-  for(i=0; i<pBe->nTemp; i++){
-    if( pBe->apTemp[i]==0 ) break;
-  }
-  if( i>=pBe->nTemp ){
-    pBe->nTemp++;
-    pBe->apTemp = sqliteRealloc(pBe->apTemp, pBe->nTemp*sizeof(FILE*) );
-    pBe->azTemp = sqliteRealloc(pBe->azTemp, pBe->nTemp*sizeof(char*) );
-  }
-  if( pBe->apTemp==0 ){
-    *ppFile = 0;
-    return SQLITE_NOMEM;
-  }
-  limit = 4;
-  zFile = 0;
-  do{
-    randomName(&pBe->rc4, zBuf, "/_temp_file_");
-    sqliteFree(zFile);
-    zFile = 0;
-    sqliteSetString(&zFile, pBe->zDir, zBuf, 0);
-  }while( access(zFile,0)==0 && limit-- >= 0 );
-  *ppFile = pBe->apTemp[i] = fopen(zFile, "w+");
-  if( pBe->apTemp[i]==0 ){
-    rc = SQLITE_ERROR;
-    sqliteFree(zFile);
-    pBe->azTemp[i] = 0;
-  }else{
-    pBe->azTemp[i] = zFile;
-  }
-  return rc;
-}
-
-/*
-** Close a temporary file opened using sqliteGdbmOpenTempFile()
-*/
-static void sqliteGdbmCloseTempFile(Dbbe *pDbbe, FILE *f){
-  int i;
-  Dbbex *pBe = (Dbbex*)pDbbe;
-  for(i=0; i<pBe->nTemp; i++){
-    if( pBe->apTemp[i]==f ){
-      unlink(pBe->azTemp[i]);
-      sqliteFree(pBe->azTemp[i]);
-      pBe->apTemp[i] = 0;
-      pBe->azTemp[i] = 0;
-      break;
-    }
-  }
-  fclose(f);
-}
-
-
-/*
-** This routine opens a new database.  For the GDBM driver
-** implemented here, the database name is the name of the directory
-** containing all the files of the database.
-**
-** If successful, a pointer to the Dbbe structure is returned.
-** If there are errors, an appropriate error message is left
-** in *pzErrMsg and NULL is returned.
-*/
-Dbbe *sqliteGdbmOpen(
-  const char *zName,     /* The name of the database */
-  int writeFlag,         /* True if we will be writing to the database */
-  int createFlag,        /* True to create database if it doesn't exist */
-  char **pzErrMsg        /* Write error messages (if any) here */
-){
-  Dbbex *pNew;
-  struct stat statbuf;
-  char *zMaster;
-
-  if( !writeFlag ) createFlag = 0;
-  if( stat(zName, &statbuf)!=0 ){
-    if( createFlag ) mkdir(zName, 0750);
-    if( stat(zName, &statbuf)!=0 ){
-      sqliteSetString(pzErrMsg, createFlag ? 
-         "can't find or create directory \"" : "can't find directory \"",
-         zName, "\"", 0);
-      return 0;
-    }
-  }
-  if( !S_ISDIR(statbuf.st_mode) ){
-    sqliteSetString(pzErrMsg, "not a directory: \"", zName, "\"", 0);
-    return 0;
-  }
-  if( access(zName, writeFlag ? (X_OK|W_OK|R_OK) : (X_OK|R_OK)) ){
-    sqliteSetString(pzErrMsg, "access permission denied", 0);
-    return 0;
-  }
-  zMaster = 0;
-  sqliteSetString(&zMaster, zName, "/" MASTER_NAME ".tbl", 0);
-  if( stat(zMaster, &statbuf)==0
-   && access(zMaster, writeFlag ? (W_OK|R_OK) : R_OK)!=0 ){
-    sqliteSetString(pzErrMsg, "access permission denied for ", zMaster, 0);
-    sqliteFree(zMaster);
-    return 0;
-  }
-  sqliteFree(zMaster);
-  pNew = sqliteMalloc(sizeof(Dbbex) + strlen(zName) + 1);
-  if( pNew==0 ){
-    sqliteSetString(pzErrMsg, "out of memory", 0);
-    return 0;
-  }
-  pNew->dbbe.Close = sqliteGdbmClose;
-  pNew->dbbe.OpenCursor = sqliteGdbmOpenCursor;
-  pNew->dbbe.DropTable = sqliteGdbmDropTable;
-  pNew->dbbe.ReorganizeTable = sqliteGdbmReorganizeTable;
-  pNew->dbbe.CloseCursor = sqliteGdbmCloseCursor;
-  pNew->dbbe.Fetch = sqliteGdbmFetch;
-  pNew->dbbe.Test = sqliteGdbmTest;
-  pNew->dbbe.CopyKey = sqliteGdbmCopyKey;
-  pNew->dbbe.CopyData = sqliteGdbmCopyData;
-  pNew->dbbe.ReadKey = sqliteGdbmReadKey;
-  pNew->dbbe.ReadData = sqliteGdbmReadData;
-  pNew->dbbe.KeyLength = sqliteGdbmKeyLength;
-  pNew->dbbe.DataLength = sqliteGdbmDataLength;
-  pNew->dbbe.NextKey = sqliteGdbmNextKey;
-  pNew->dbbe.Rewind = sqliteGdbmRewind;
-  pNew->dbbe.New = sqliteGdbmNew;
-  pNew->dbbe.Put = sqliteGdbmPut;
-  pNew->dbbe.Delete = sqliteGdbmDelete;
-  pNew->dbbe.OpenTempFile = sqliteGdbmOpenTempFile;
-  pNew->dbbe.CloseTempFile = sqliteGdbmCloseTempFile;
-  pNew->zDir = (char*)&pNew[1];
-  strcpy(pNew->zDir, zName);
-  pNew->write = writeFlag;
-  pNew->pOpen = 0;
-  time(&statbuf.st_ctime);
-  rc4init(&pNew->rc4, (char*)&statbuf, sizeof(statbuf));
-  return &pNew->dbbe;
-}
diff --git a/src/ex/pg.c b/src/ex/pg.c
deleted file mode 100644 (file)
index 5a826c8..0000000
+++ /dev/null
@@ -1,708 +0,0 @@
-/*
-** Copyright (c) 2001 D. Richard Hipp
-**
-** This program is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public
-** License as published by the Free Software Foundation; either
-** version 2 of the License, or (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-** General Public License for more details.
-** 
-** You should have received a copy of the GNU General Public
-** License along with this library; if not, write to the
-** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-** Boston, MA  02111-1307, USA.
-**
-** Author contact information:
-**   drh@hwaci.com
-**   http://www.hwaci.com/drh/
-**
-*************************************************************************
-** $Id: pg.c,v 1.1 2001/02/11 16:56:24 drh Exp $
-*/
-#include <assert.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-#include "sqliteInt.h"
-#include "pg.h"
-
-/*
-** Uncomment the following for a debug trace
-*/
-#if 1
-# define TRACE(X)  printf X; fflush(stdout);
-#endif  
-
-/*
-** Hash table sizes
-*/
-#define J_HASH_SIZE  127  /* Size of the journal page hash table */
-#define PG_HASH_SIZE 349  /* Size of the database page hash table */
-
-/*
-** Forward declaration of structure
-*/
-typedef struct Pghdr Pghdr;
-
-/*
-** All information about a single paging file is contained in an
-** instance of the following structure.
-*/
-struct Pgr {
-  int fdMain;                    /* The main database file */
-  char *zMain;                   /* Name of the database file */
-  int fdJournal;                 /* The journal file */
-  char *zJournal;                /* Name of the journal file */
-  int nMemPg;                    /* Number of memory-resident pages */
-  int nJPg;                      /* Number of pages in the journal */
-  int nDbPg;                     /* Number of pages in the database */
-  int nRefPg;                    /* Number of pages currently in use */
-  Pghdr *pLru, *pMru;            /* Least and most recently used mem-page */
-  Pghdr *pJidx;                  /* List of journal index pages */
-  Pghdr *pAll;                   /* All pages, except journal index pages */
-  u32 aJHash[J_HASH_SIZE];       /* Journal page hash table */
-  Pghdr *aPgHash[PG_HASH_SIZE];  /* Mem-page hash table */
-};
-
-/*
-** Each memory-resident page of the paging file has a header which
-** is an instance of the following structure.
-*/
-struct Pghdr {
-  Pgr *p;            /* Pointer back to the Pgr structure */
-  int nRef;          /* Number of references to this page */
-  int isDirty;       /* TRUE if needs to be written to disk */
-  u32 dbpgno;        /* Page number in the database file */
-  u32 jpgno;         /* Page number in the journal file */
-  Pghdr *pNx;        /* Next page on a list of them all */
-  Pghdr *pLru;       /* Less recently used pages */
-  Pghdr *pMru;       /* More recently used pages */
-  Pghdr *pNxHash;    /* Next with same dbpgno hash */
-  Pghdr *pPvHash;    /* Previous with the same dbpgno hash */
-};
-
-/*
-** For a memory-resident page, the page data comes immediately after
-** the page header.  The following macros can be used to change a 
-** pointer to a page header into a pointer to the data, or vice
-** versa.
-*/
-#define PG_TO_DATA(X)  ((void*)&(X)[1])
-#define DATA_TO_PG(X)  (&((Pghdr*)(X))[-1])
-
-/*
-** The number of in-memory pages that we accumulate before trying
-** to reuse older pages when new ones are requested.
-*/
-#define MX_MEM_PAGE  100
-
-/*
-** The number of journal data pages that come between consecutive 
-** journal index pages.
-*/
-#define N_J_DATAPAGE  (SQLITE_PAGE_SIZE/(2*sizeof(u32)))
-
-/*
-** An index page in the journal consists of an array of N_J_DATAPAGE
-** of the following structures.  There is one instance of the following
-** structure for each of the N_J_DATAPAGE data pages that follow the
-** index.
-**
-** Let the journal page number that a JidxEntry describes be J.  Then
-** the JidxEntry.dbpgno field is the page of the database file that
-** corresponds to the J page in the journal.  The JidxEntry.next_jpgno
-** field hold the number of another journal page that contains
-** a database file page with the same hash as JidxEntry.dbpgno.
-**
-** All information is written to the journal index in big-endian
-** notation.
-*/
-typedef struct JidxEntry JidxEntry;
-struct JidxEntry {
-  char dbpgno[sizeof(u32)];        /* Database page number for this entry */
-  char next_jpgno[sizeof(u32)];    /* Next entry with same hash on dbpgno */
-};
-
-/*
-** Read a page from a file into memory.  Return SQLITE_OK if successful.
-** The "pgno" parameter tells where in the file to read the page.
-** The first page is 1.  Files do not contain a page 0 since a page
-** number of 0 is used to indicate "no such page".
-*/
-static int sqlitePgRead(int fd, char *zBuf, u32 pgno){
-  int got = 0;
-  int amt;
-
-  assert( pgno>0 );
-  assert( fd>=0 );
-  lseek(fd, SEEK_SET, (pgno-1)*SQLITE_PAGE_SIZE);
-  while( got<SQLITE_PAGE_SIZE ){
-    amt = read(fd, &zBuf[got], SQLITE_PAGE_SIZE - got);
-    if( amt<=0 ){
-      memset(&zBuf[got], 0, SQLITE_PAGE_SIZE - got);
-      return amt==0 ? SQLITE_OK : SQLITE_IOERR;
-    }
-    got += amt;
-  }
-  return SQLITE_OK;
-}
-
-/*
-** Read a page from a file into memory.  Return SQLITE_OK if successful.
-** The "pgno" parameter tells where in the file to write the page.
-** The first page is 1.  Files do not contain a page 0 since a page
-** number of 0 is used to indicate "no such page".
-*/
-static int sqlitePgWrite(int fd, char *zBuf, u32 pgno){
-  int done = 0;
-  int amt;
-
-  assert( pgno>0 );
-  assert( fd>=0 );
-  lseek(fd, SEEK_SET, (pgno-1)*SQLITE_PAGE_SIZE);
-  while( done<SQLITE_PAGE_SIZE ){
-    amt = write(fd, &zBuf[done], SQLITE_PAGE_SIZE - done);
-    if( amt<=0 ) return SQLITE_IOERR;
-    done += amt;
-  }
-  return SQLITE_OK;
-}
-
-/*
-** Turn four bytes into an integer.  The first byte is always the
-** most significant 8 bits.
-*/
-static u32 sqlitePgGetInt(const char *p){
-  return ((p[0]&0xff)<<24) | ((p[1]&0xff)<<16) | ((p[2]&0xff)<<8) | (p[3]&0xff);
-}
-
-/*
-** Turn an integer into 4 bytes.  The first byte is always the
-** most significant 8 bits.
-*/
-static void sqlitePgPutInt(u32 v, char *p){
-  p[3] = v & 0xff;
-  v >>= 8;
-  p[2] = v & 0xff;
-  v >>= 8;
-  p[1] = v & 0xff;
-  v >>= 8;
-  p[0] = v & 0xff;
-}
-
-/*
-** Check the hash table for an in-memory page.  Return a pointer to
-** the page header if found.  Return NULL if the page is not in memory.
-*/
-static Pghdr *sqlitePgFind(Pgr *p, u32 pgno){
-  int h;
-  Pghdr *pPg;
-
-  if( pgno==0 ) return 0;
-  h = pgno % PG_HASH_SIZE;
-  for(pPg = p->aPgHash[h]; pPg; pPg=pPg->pNxHash){
-    if( pPg->dbpgno==pgno ) return pPg;
-  }
-  TRACE(("PG: data page %u is %#x\n", pgno, (u32)pPg));
-  return 0;
-}
-
-/*
-** Locate and return an index page from the journal.
-**
-** The first page of a journal is the primary index.  Additional
-** index pages are called secondary indices.  Index pages appear
-** in the journal as often as needed.  (If SQLITE_PAGE_SIZE==1024,
-** then there are 1024/sizeof(int)*2 = 128 database between each
-** pair of index pages.)  Journal index pages are not hashed and
-** do no appear on the Pgr.pAll list.  Index pages are on the
-** Pgr.pJidx list only.  Index pages have Pghdr.dbpgno==0.
-**
-** If the requested index page is not already in memory, then a
-** new memory page is created to hold the index.
-**
-** This routine will return a NULL pointer if we run out of memory.
-*/
-static Pghdr *sqlitePgFindJidx(Pgr *p, u32 pgno){
-  Pghdr *pPg;
-
-  assert( pgno % (N_J_DATAPAGE+1) == 1 );
-  for(pPg=p->pJidx; pPg; pPg=pPg->pNx){
-    if( pPg->jpgno==pgno ){
-      TRACE(("PG: found j-index %u at %#x\n", pgno, (u32)pPg));
-      return pPg;
-    }
-  }
-  pPg = sqliteMalloc( sizeof(Pghdr)+SQLITE_PAGE_SIZE );
-  if( pPg==0 ) return 0;
-  pPg->jpgno = pgno;
-  pPg->pNx = p->pJidx;
-  p->pJidx = pPg;
-  sqlitePgRead(p->fdJournal, PG_TO_DATA(pPg), pgno);
-  TRACE(("PG: create j-index %u at %#x\n", pgno, (u32)pPg));
-  return pPg;
-}
-
-/*
-** Look in the journal to see if the given database page is stored
-** in the journal.  If it is, return its journal page number.  If
-** not, return 0.
-*/
-static u32 sqlitePgJournalPageNumber(Pgr *p, u32 dbpgno){
-  u32 jpgno;
-  
-  if( dbpgno==0 ) return 0;
-  jpgno = p->aJHash[dbpgno % J_HASH_SIZE];
-  while( jpgno!=0 ){
-    int idx_num;     /* Which journal index describes page jpgno */
-    int ipgno;       /* Page number for the journal index */
-    int idx_slot;    /* Which entry in index idx_num describes jpgno */
-    Pghdr *pIdxPg;   /* The index page for jpgno */
-    JidxEntry *aIdx; /* The data for the index page */
-
-    idx_num = (jpgno - 1)/(N_J_DATAPAGE + 1);
-    idx_slot = (jpgno - 1) % (N_J_DATAPAGE + 1) - 2;
-    ipgno = idx_num * (N_J_DATAPAGE + 1) + 1;
-    if( ipgno>p->nJPg ){
-      jpgno = 0;
-      break;
-    }
-    pIdxPg = sqlitePgFindJidx(p, ipgno);
-    assert( pIdxPg!=0 );
-    aIdx = PG_TO_DATA(pIdxPg);
-    if( dbpgno==sqlitePgGetInt(aIdx[idx_slot].dbpgno) ){
-      break;
-    }
-    jpgno = sqlitePgGetInt(aIdx[idx_slot].next_jpgno);
-  }
-  return jpgno;
-}
-
-/*
-** Make a page not dirty by writing it to the journal.
-*/
-static int sqlitePgMakeClean(Pghdr *pPg){
-  Pgr *p = pPg->p;
-  int rc;
-
-  assert( pPg->isDirty );
-  assert( p->fdJournal>=0 );
-  if( pPg->jpgno==0 ){
-    int jpgno;       /* A newly allocate page in the journal */
-    int idx_num;     /* Which journal index describes page jpgno */
-    int idx_slot;    /* Which entry in index idx_num describes jpgno */
-    Pghdr *pIdxPg;   /* The index page for jpgno */
-    JidxEntry *aIdx; /* The data for the index page */
-    int h;           /* The hash value for pPg->dbpgno */
-
-    jpgno = p->nJPg + 1;
-    if( jpgno % (N_J_DATAPAGE + 1) == 1 ){
-      jpgno++;
-    }
-    idx_num = (jpgno - 1)/(N_J_DATAPAGE + 1);
-    idx_slot = (jpgno - 1) % (N_J_DATAPAGE + 1) - 2;
-    pIdxPg = sqlitePgFindJidx(p, idx_num * (N_J_DATAPAGE + 1) + 1);
-    assert( pIdxPg!=0 );
-    aIdx = PG_TO_DATA(pIdxPg);
-    sqlitePgPutInt(pPg->dbpgno, aIdx[idx_slot].dbpgno);
-    h = pPg->dbpgno % J_HASH_SIZE;
-    sqlitePgPutInt(p->aJHash[h], aIdx[idx_slot].next_jpgno);
-    p->aJHash[h] = jpgno;
-    p->nJPg = jpgno;
-    pPg->jpgno = jpgno;
-    TRACE(("PG: assign d-page %u to j-page %u\n", jpgno, pPg->dbpgno));
-  }
-  rc = sqlitePgWrite(p->fdJournal, PG_TO_DATA(pPg), pPg->jpgno);
-  if( rc==SQLITE_OK ){
-    pPg->isDirty = 0;
-  }
-  return rc;
-}
-
-/*
-** Find the number of pages in the given file by measuring the size
-** of the file.  Return 0 if there is any problem.
-*/
-static int sqlitePgPageCount(int fd){
-  struct stat statbuf;
-  if( fstat(fd, &statbuf)!=0 ) return 0;
-  return statbuf.st_size/SQLITE_PAGE_SIZE;
-}
-
-/*
-** This routine reads the journal and transfers pages from the
-** journal to the database.
-*/
-static int sqlitePgJournalPlayback(Pgr *p){
-  Pghdr *pPg;
-  JidxEntry *aIdx;
-  int nJpg;
-  int jpgno = 1;
-  int i;
-  int dbpgno;
-  int rc;
-  char idx[SQLITE_PAGE_SIZE];
-  char pgbuf[SQLITE_PAGE_SIZE];
-  
-  assert( p->fdJournal>=0 );
-  nJpg = sqlitePgPageCount(p->fdJournal);
-  while( jpgno<=nJpg ){
-    if( !sqlitePgRead(p->fdJournal, idx, jpgno++) ) break;
-    aIdx = (JidxEntry*)idx;
-    for(i=0; i<N_J_DATAPAGE; i++){
-      dbpgno = sqlitePgGetInt(&idx[i]);
-      if( dbpgno==0 ){
-        jpgno = nJpg+1;
-        break;
-      }
-      pPg = sqlitePgFind(p, dbpgno);
-      if( pPg ){
-        rc = sqlitePgWrite(p->fdMain, PG_TO_DATA(pPg), dbpgno);
-        TRACE(("PG: commit j-page %u to d-page %u from memory\n",jpgno,dbpgno));
-      }else{
-        rc = sqlitePgRead(p->fdJournal, pgbuf, jpgno);
-        if( rc!=SQLITE_OK ){
-          return rc;
-        }
-        rc = sqlitePgWrite(p->fdMain, pgbuf, dbpgno);
-        TRACE(("PG: commit j-page %u to d-page %u from disk\n",jpgno,dbpgno));
-      }
-      jpgno++;
-      if( rc!=SQLITE_OK ){
-        return rc;
-      }
-    }
-  }
-  TRACE(("PG: commit complete. deleting the journal.\n"));
-  fsync(p->fdMain);
-  close(p->fdJournal);
-  p->fdJournal = -1;
-  unlink(p->zJournal);
-  for(pPg=p->pAll; pPg; pPg=pPg->pNx){
-    pPg->isDirty = 0;
-    pPg->jpgno = 0;
-  }
-  while( (pPg = p->pJidx)!=0 ){
-    p->pAll = pPg->pNx;
-    sqliteFree(pPg);
-  }
-  return SQLITE_OK;
-}
-
-/*
-** Remove the given page from the LRU list.
-*/
-static void sqlitePgUnlinkLru(Pghdr *pPg){
-  Pgr *p = pPg->p;
-  if( pPg->pLru ){
-    pPg->pLru->pMru = pPg->pLru;
-  }
-  if( pPg->pMru ){
-    pPg->pMru->pLru = pPg->pMru;
-  }
-  if( p->pLru==pPg ){
-    p->pLru = pPg->pLru;
-  }
-  if( p->pMru==pPg ){
-    p->pMru = pPg->pMru;
-  }
-  pPg->pLru = pPg->pMru = 0;
-}
-
-/*
-** Open the database file and make *ppPgr pointer to a structure describing it.
-** Return SQLITE_OK on success or an error code if there is a failure.
-**
-** If there was an unfinished commit, complete it before returnning.
-*/
-int sqlitePgOpen(const char *zFilename, Pgr **ppPgr){
-  Pgr *p;
-  int n;
-
-  n = strlen(zFilename);
-  p = sqliteMalloc( sizeof(*p) + n*2 + 4 );
-  if( p==0 ){
-    *ppPgr = 0;
-    return SQLITE_NOMEM;
-  }
-  p->zMain = (char*)&p[1];
-  strcpy(p->zMain, zFilename);
-  p->zJournal = &p->zMain[n+1];
-  strcpy(p->zJournal, p->zMain);
-  p->zJournal[n] = '~';
-  p->zJournal[n+1] = 0;
-  p->fdJournal = -1;
-  p->fdMain = open(p->zMain, O_CREAT|O_RDWR, 0600);
-  if( p->fdMain<0 ){
-    *ppPgr = 0;
-    sqliteFree(p);
-    return SQLITE_PERM;
-  }
-  p->nDbPg = sqlitePgPageCount(p->fdMain);
-  if( access(p->zJournal, R_OK)==0 ){
-    sqlitePgJournalPlayback(p);
-  }
-  *ppPgr = p;
-  return SQLITE_OK;
-}
-
-/*
-** Close the database file.  Any outstanding transactions are abandoned.
-*/
-int sqlitePgClose(Pgr *p){
-  Pghdr *pPg;
-
-  if( p->fdMain ) close(p->fdMain);
-  if( p->fdJournal ) close(p->fdJournal);
-  unlink(p->zJournal);
-  while( (pPg = p->pAll)!=0 ){
-    p->pAll = pPg->pNx;
-    sqliteFree(pPg);
-  }
-  while( (pPg = p->pJidx)!=0 ){
-    p->pAll = pPg->pNx;
-    sqliteFree(pPg);
-  }
-  sqliteFree(p);
-  return SQLITE_OK;
-}
-
-/*
-** Begin a new transaction.  Return SQLITE_OK on success or an error
-** code if something goes wrong.
-*/
-int sqlitePgBeginTransaction(Pgr *p){
-  assert( p->fdJournal<0 );
-  if( p->nRefPg>0 ){
-     /* release the read lock */
-  }
-  /* write lock the database */
-  p->fdJournal = open(p->zJournal, O_CREAT|O_EXCL|O_RDWR, 0600);
-  if( p->fdJournal<0 ){
-    return SQLITE_PERM;
-  }
-  p->nJPg = 0;
-  TRACE(("PG: begin transaction\n"));
-  return SQLITE_OK;
-}
-
-/*
-** Commit the current transaction.  Return SQLITE_OK or an error code.
-*/
-int sqlitePgCommit(Pgr *p){
-  Pghdr *pPrimaryIdx = 0;
-  Pghdr *pPg;
-  int rc;
-
-  for(pPg=p->pAll; pPg; pPg=pPg->pNx){
-    if( pPg->isDirty ){
-      rc = sqlitePgMakeClean(pPg);
-      if( rc!=SQLITE_OK ){
-        return rc;
-      }
-    }
-  }
-  for(pPg=p->pJidx; pPg; pPg=pPg->pNx){
-    if( pPg->jpgno==1 ){
-      pPrimaryIdx = pPg;
-    }else{
-      TRACE(("PG: writing j-index %u\n", pPg->jpgno));
-      rc = sqlitePgMakeClean(pPg);
-      if( rc!=SQLITE_OK ){
-        return rc;
-      }
-    }
-  }
-  assert( pPrimaryIdx!=0 );
-  fsync(p->fdJournal);
-  TRACE(("PG: writing j-index %u\n", pPrimaryIdx->jpgno));
-  rc = sqlitePgMakeClean(pPrimaryIdx);
-  if( rc!=SQLITE_OK ){
-    return rc;
-  }
-  fsync(p->fdJournal);
-  rc = sqlitePgJournalPlayback(p);
-  if( rc!=SQLITE_OK ){
-    return rc;
-  }
-  /* remove write lock from database */
-  if( p->nRefPg>0 ){
-    /* acquire read lock on database */
-  }
-  return SQLITE_OK;
-}
-
-/*
-** Abandon the current transaction.
-*/
-int sqlitePgRollback(Pgr *p){
-  Pghdr *pPg;
-
-  TRACE(("PG: begin rollback\n"));
-  for(pPg=p->pAll; pPg; pPg=pPg->pNx){
-    if( pPg->isDirty || pPg->jpgno!=0 ){
-      pPg->isDirty = 0;
-      pPg->jpgno = 0;
-      if( pPg->nRef>0 ){
-        TRACE(("PG: reloading d-page %u\n", pPg->dbpgno));
-        sqlitePgRead(p->fdMain, PG_TO_DATA(pPg), pPg->dbpgno);
-      }else{
-        sqlitePgUnlinkLru(pPg);
-      }
-    }
-  }
-  close(p->fdJournal);
-  p->fdJournal = -1;
-  unlink(p->zJournal);
-  while( (pPg = p->pJidx)!=0 ){
-    p->pAll = pPg->pNx;
-    sqliteFree(pPg);
-  }
-  p->nDbPg = sqlitePgPageCount(p->fdMain);
-  /* remove write lock from database */
-  if( p->nRefPg>0 ){
-    /* acquire read lock on database */
-  }
-  return SQLITE_OK;
-}
-
-/*
-** Get a page from the database.  Return a pointer to the data for that
-** page.
-**
-** A NULL pointer will be returned if we run out of memory.
-*/
-int sqlitePgGet(Pgr *p, u32 pgno, void **ppData){
-  Pghdr *pPg;
-  int h;
-
-  pPg = sqlitePgFind(p, pgno);
-  if( pPg ){
-    pPg->nRef++;
-    if( pPg->nRef==1 ){
-      sqlitePgUnlinkLru(pPg);
-      TRACE(("PG: d-page %u pulled from cache\n", pgno));
-    }
-    p->nRefPg++;
-    if( p->nRefPg==1 ){
-      /* Acquire a read lock */
-    }
-    *ppData = PG_TO_DATA(pPg);
-    return SQLITE_OK;
-  }
-  if( p->nMemPg<MX_MEM_PAGE || p->pLru==0 ){
-    pPg = sqliteMalloc( sizeof(Pghdr) + SQLITE_PAGE_SIZE );
-    if( pPg==0 ) return SQLITE_NOMEM;
-    p->nMemPg++;
-    pPg->pNx = p->pAll;
-    p->pAll = pPg;
-    pPg->p = p;
-    TRACE(("PG: new page %d created.\n", p->nMemPg));
-  }else{
-    int rc;
-    pPg = p->pLru;
-    if( pPg->isDirty ){
-      rc = sqlitePgMakeClean(pPg);
-      if( rc!=SQLITE_OK ) return rc;
-    }
-    sqlitePgUnlinkLru(pPg);
-    h = pPg->dbpgno % PG_HASH_SIZE;
-    if( pPg->pPvHash ){
-      pPg->pPvHash->pNxHash = pPg->pNxHash;
-    }else{
-      assert( p->aPgHash[h]==pPg );
-      p->aPgHash[h] = pPg->pNxHash;
-    }
-    if( pPg->pNxHash ){
-      pPg->pNxHash->pPvHash = pPg->pPvHash;
-    }
-    TRACE(("PG: recycling d-page %u to d-page %u\n", pPg->dbpgno, pgno));
-  }
-  pPg->dbpgno = pgno;
-  if( pgno>p->nDbPg ){
-    p->nDbPg = pgno;
-  }
-  h = pgno % PG_HASH_SIZE;
-  pPg->pPvHash = 0;
-  pPg->pNxHash = p->aPgHash[h];
-  if( pPg->pNxHash ){
-    pPg->pNxHash->pPvHash = pPg;
-  }
-  p->aPgHash[h] = pPg;
-  pPg->jpgno = sqlitePgJournalPageNumber(p, pgno);
-  if( pPg->jpgno!=0 ){
-    TRACE(("PG: reading d-page %u content from j-page %u\n", pgno, pPg->jpgno));
-    sqlitePgRead(p->fdJournal, PG_TO_DATA(pPg), pPg->jpgno);
-  }else if( pPg->dbpgno!=0 ){
-    TRACE(("PG: reading d-page %u from database\n", pgno));
-    sqlitePgRead(p->fdMain, PG_TO_DATA(pPg), pPg->dbpgno);
-  }else{
-    TRACE(("PG: reading zero page\n");
-    memset(PG_TO_DATA(pPg), 0, SQLITE_PAGE_SIZE);
-  }
-  pPg->isDirty = 0;
-  pPg->nRef = 1;
-  p->nRefPg++;
-  if( p->nRefPg==1 ){
-    /* Acquire a read lock */
-  }
-  *ppData = PG_TO_DATA(pPg);
-  return SQLITE_OK;
-}
-
-/*
-** Release a reference to a database data page.
-*/
-int sqlitePgUnref(void *pData){
-  Pghdr *pPg = DATA_TO_PG(pData);
-  pPg->nRef--;
-  assert( pPg->nRef>=0 );
-  if( pPg->nRef==0 ){
-    Pgr *p = pPg->p;
-    pPg->pMru = 0;
-    pPg->pLru = p->pLru;
-    p->pLru = pPg;
-    TRACE(("PG: d-page %u is unused\n", pPg->dbpgno));
-    p->nRefPg--;
-    if( p->nRefPg==0 ){
-      /* Release the read lock */
-    }
-  }
-  return SQLITE_OK;
-}
-
-/*
-** The database page in the argument has been modified.  Write it back
-** to the database file on the next commit.
-*/
-int sqlitePgTouch(void *pD){
-  Pghdr *pPg = DATA_TO_PG(pD);
-  assert( pPg->p->fdJournal>=0 );
-  if( pPg->isDirty==0 ){
-    pPg->isDirty = 1;
-    TRACE(("PG: d-page %u is dirty\n", pPg->dbpgno));
-  }
-  return SQLITE_OK;
-}
-
-/*
-** Return the number of the first unused page at the end of the
-** database file.
-*/
-int sqlitePgCount(Pgr *p, u32 *pPgno){
-  *pPgno = p->nDbPg;
-  return SQLITE_OK;
-}
-
-/*
-** Return the page number associated with the given page.
-*/
-u32 sqlitePgNum(void *pD){
-  Pghdr *pPg = DATA_TO_PG(pD);
-  return pPg->dbpgno;
-}
diff --git a/src/ex/pg.h b/src/ex/pg.h
deleted file mode 100644 (file)
index f0fd50a..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-** Copyright (c) 2001 D. Richard Hipp
-**
-** This program is free software; you can redistribute it and/or
-** modify it under the terms of the GNU General Public
-** License as published by the Free Software Foundation; either
-** version 2 of the License, or (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-** General Public License for more details.
-** 
-** You should have received a copy of the GNU General Public
-** License along with this library; if not, write to the
-** Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-** Boston, MA  02111-1307, USA.
-**
-** Author contact information:
-**   drh@hwaci.com
-**   http://www.hwaci.com/drh/
-**
-*************************************************************************
-** $Id: pg.h,v 1.1 2001/02/11 16:56:24 drh Exp $
-*/
-
-typedef struct Pgr Pgr;
-#define SQLITE_PAGE_SIZE 1024
-
-
-int sqlitePgOpen(const char *filename, Pgr **pp);
-int sqlitePgClose(Pgr*);
-int sqlitePgBeginTransaction(Pgr*);
-int sqlitePgCommit(Pgr*);
-int sqlitePgRollback(Pgr*);
-int sqlitePgGet(Pgr*, u32 pgno, void **);
-int sqlitePgUnref(void*);
-int sqlitePgTouch(void*);
-int sqlitePgCount(Pgr*, u32*);
-u32 sqlitePgNum(void*);
diff --git a/src/ex/sizes.tcl b/src/ex/sizes.tcl
deleted file mode 100644 (file)
index 4cb6ef6..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-
-set sizes {1024 2048 4096 8192 16384 32768}
-set fmt { %-8s}
-
-puts -nonewline "page size: "
-foreach s $sizes {
-  puts -nonewline [format $fmt $s]
-}
-puts ""
-
-puts -nonewline "on leaf:   "
-foreach s $sizes {
-  set x [expr {$s - 18*4}]
-  set p($s) $x
-  puts -nonewline [format $fmt $x]
-}
-puts ""
-
-puts -nonewline "direct:    "
-foreach s $sizes {
-  set x [expr {$p($s) + 10*$s}]
-  set p($s) $x
-  puts -nonewline [format $fmt $x]
-}
-puts ""
-
-puts -nonewline "indirect:  "
-foreach s $sizes {
-  set x [expr {$p($s) + ($s/4.0)*$s}]
-  set p($s) $x
-  puts -nonewline [format $fmt $x]
-}
-puts ""
-
-puts -nonewline "dbl indir: "
-foreach s $sizes {
-  set x [expr {$p($s) + ($s/4.0)*($s/4)*$s}]
-  set p($s) $x
-  puts -nonewline [format $fmt $x]
-}
-puts ""