]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
Remove the rowhash object from the code. Rowset now fills its role. (CVS 6535)
authordrh <drh@noemail.net>
Wed, 22 Apr 2009 02:15:47 +0000 (02:15 +0000)
committerdrh <drh@noemail.net>
Wed, 22 Apr 2009 02:15:47 +0000 (02:15 +0000)
FossilOrigin-Name: e963bed0fe3ce5fa32f04b930e5ed0956dc2aa47

12 files changed:
Makefile.in
main.mk
manifest
manifest.uuid
src/rowhash.c [deleted file]
src/sqliteInt.h
src/vdbe.c
src/vdbeInt.h
src/vdbeaux.c
src/vdbemem.c
src/where.c
tool/mksqlite3c.tcl

index 1e73af6ddde528983901246426c8d4741c374f67..debe2f16dc12a184094fd8ec21e3ccdfd64dae85 100644 (file)
@@ -172,7 +172,7 @@ OBJS0 = alter.lo analyze.lo attach.lo auth.lo backup.lo bitvec.lo btmutex.lo \
         mutex.lo mutex_noop.lo mutex_os2.lo mutex_unix.lo mutex_w32.lo \
         notify.lo opcodes.lo os.lo os_unix.lo os_win.lo os_os2.lo \
         pager.lo parse.lo pcache.lo pcache1.lo pragma.lo prepare.lo printf.lo \
-        random.lo resolve.lo rowhash.lo rowset.lo select.lo status.lo \
+        random.lo resolve.lo rowset.lo select.lo status.lo \
         table.lo tokenize.lo trigger.lo update.lo \
         util.lo vacuum.lo \
         vdbe.lo vdbeapi.lo vdbeaux.lo vdbeblob.lo vdbemem.lo \
@@ -249,7 +249,6 @@ SRC = \
   $(TOP)/src/printf.c \
   $(TOP)/src/random.c \
   $(TOP)/src/resolve.c \
-  $(TOP)/src/rowhash.c \
   $(TOP)/src/rowset.c \
   $(TOP)/src/select.c \
   $(TOP)/src/status.c \
@@ -672,9 +671,6 @@ random.lo:  $(TOP)/src/random.c $(HDR)
 resolve.lo:    $(TOP)/src/resolve.c $(HDR)
        $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/resolve.c
 
-rowhash.lo:    $(TOP)/src/rowhash.c $(HDR)
-       $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/rowhash.c
-
 rowset.lo:     $(TOP)/src/rowset.c $(HDR)
        $(LTCOMPILE) $(TEMP_STORE) -c $(TOP)/src/rowset.c
 
diff --git a/main.mk b/main.mk
index 439fac682badf12014d8f64f1d421df0d1f0d59c..718ba49a8baf4f40496d83507c7341bddd9346c2 100644 (file)
--- a/main.mk
+++ b/main.mk
@@ -61,7 +61,7 @@ LIBOBJ+= alter.o analyze.o attach.o auth.o \
          mutex.o mutex_noop.o mutex_os2.o mutex_unix.o mutex_w32.o \
          notify.o opcodes.o os.o os_os2.o os_unix.o os_win.o \
          pager.o parse.o pcache.o pcache1.o pragma.o prepare.o printf.o \
-         random.o resolve.o rowhash.o rowset.o rtree.o select.o status.o \
+         random.o resolve.o rowset.o rtree.o select.o status.o \
          table.o tokenize.o trigger.o \
          update.o util.o vacuum.o \
          vdbe.o vdbeapi.o vdbeaux.o vdbeblob.o vdbemem.o \
@@ -130,7 +130,6 @@ SRC = \
   $(TOP)/src/printf.c \
   $(TOP)/src/random.c \
   $(TOP)/src/resolve.c \
-  $(TOP)/src/rowhash.c \
   $(TOP)/src/rowset.c \
   $(TOP)/src/select.c \
   $(TOP)/src/status.c \
index a374f13dd6c7b978b370dabb59684f8d871fe9c8..6d41c9a92e3c5ba7ecdeb80d3b7828fed902743e 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,7 +1,7 @@
-C Extend\sthe\sRowset\sobject\sto\scontain\sall\sthe\scapabilities\sof\sRowhash\sin\naddition\sto\sits\slegacy\scapabilities.\s\sUse\sRowset\sto\sreplace\sRowhash.\nIn\saddition\sto\srequiring\sless\scode,\sThis\sremoves\sthe\s2^32\sresult\srow\nlimitation,\suses\sless\smemory,\sand\sgives\sbetter\sbounds\son\sworst-case\nperformance.\s\sThe\sRowhash\simplementation\shas\syet\sto\sbe\sremoved.\s(CVS\s6534)
-D 2009-04-22T00:47:01
+C Remove\sthe\srowhash\sobject\sfrom\sthe\scode.\s\sRowset\snow\sfills\sits\srole.\s(CVS\s6535)
+D 2009-04-22T02:15:48
 F Makefile.arm-wince-mingw32ce-gcc fcd5e9cd67fe88836360bb4f9ef4cb7f8e2fb5a0
-F Makefile.in fa5998fe08bd8c0fdc7f9f66cea16c0279f39da8
+F Makefile.in 583e87706abc3026960ed759aff6371faf84c211
 F Makefile.linux-gcc d53183f4aa6a9192d249731c90dbdffbd2c68654
 F Makefile.vxworks 40c707b2589f61436b89788003b1ccf5679ec3e6
 F README b974cdc3f9f12b87e851b04e75996d720ebf81ac
@@ -83,7 +83,7 @@ F ext/rtree/tkt3363.test 6662237ea75bb431cd5d262dfc9535e1023315fc
 F ext/rtree/viewrtree.tcl 09526398dae87a5a87c5aac2b3854dbaf8376869
 F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895
 F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8
-F main.mk aeaf069e8ec8238ccfab5bdc4219149b16a3ee04
+F main.mk bbb170882a34fe51dbd2d2e9c450c6cc0dad3325
 F mkdll.sh 7d09b23c05d56532e9d44a50868eb4b12ff4f74a
 F mkextu.sh 416f9b7089d80e5590a29692c9d9280a10dbad9f
 F mkextw.sh 4123480947681d9b434a5e7b1ee08135abe409ac
@@ -154,13 +154,12 @@ F src/prepare.c 72d74e6d3b9c8eb0663b33ec6438aa718096ac79
 F src/printf.c ea2d76000cc5f4579d7e9cb2f5460433eec0d384
 F src/random.c 676b9d7ac820fe81e6fb2394ac8c10cff7f38628
 F src/resolve.c 094e44450371fb27869eb8bf679aacbe51fdc56d
-F src/rowhash.c 05179a59fda8494dff033fba16bf653ead96ab37
 F src/rowset.c ee0f774f20bf3fd27470603d2d56d1767bbe1013
 F src/select.c 35225756c247484f473678e5bd191d70a6e4dba0
 F src/shell.c 0a11f831603f17fea20ca97133c0f64e716af4a7
 F src/sqlite.h.in 8e0e256079bac2319380bdfebf403fcbe630510f
 F src/sqlite3ext.h 1db7d63ab5de4b3e6b83dd03d1a4e64fef6d2a17
-F src/sqliteInt.h 7522dc01d59a4e54a01b044c66e21cc6276b03f7
+F src/sqliteInt.h dc64bc8198a2ad3532a996fcecda71ff89a578f0
 F src/sqliteLimit.h ffe93f5a0c4e7bd13e70cd7bf84cfb5c3465f45d
 F src/status.c 237b193efae0cf6ac3f0817a208de6c6c6ef6d76
 F src/table.c cc86ad3d6ad54df7c63a3e807b5783c90411a08d
@@ -201,16 +200,16 @@ F src/update.c 8ededddcde6f7b6da981dd0429a5d34518a475b7
 F src/utf.c 9541d28f40441812c0b40f00334372a0542c00ff
 F src/util.c 828c552a22a1d5b650b8a5ea0009546715c45d93
 F src/vacuum.c 07121a727beeee88f27d704a00313ad6a7c9bef0
-F src/vdbe.c cbef2e1fd232206136cfd94abba0cc64172214f9
+F src/vdbe.c 13f976672cd9d7fce04f9847d74da8c3b869a013
 F src/vdbe.h 35a648bc3279a120da24f34d9a25213ec15daf8a
-F src/vdbeInt.h d3adfeccc750643ae7861f2d29f579d3dad28785
+F src/vdbeInt.h 8726f7b4e3b55c8acf6d304a5b5f727ac1b6c5ab
 F src/vdbeapi.c 015c9d0fb7047657a13a7bb6aa886f75e43db02d
-F src/vdbeaux.c 8b2ecd0ed6fb7e2113c33618ea37f2abafd97717
+F src/vdbeaux.c fdad66c73adb1c6ca6a0cd7a0f9517e5df758122
 F src/vdbeblob.c e67757450ae8581a8b354d9d7e467e41502dfe38
-F src/vdbemem.c 96e57468036638c3de72e2ed8b08f308c5982053
+F src/vdbemem.c 111d8193859d16aefd5d3cb57472808584ea5503
 F src/vtab.c 6118d71c5137e20a7ac51fb5d9beb0361fbedb89
 F src/walker.c 7cdf63223c953d4343c6833e940f110281a378ee
-F src/where.c 894363060378c1828eccd99a36f71e2b81870f1f
+F src/where.c 48f711d293486b43bf87ab3d1eeeebae50cb6839
 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2
 F test/alias.test 597662c5d777a122f9a3df0047ea5c5bd383a911
 F test/all.test 14165b3e32715b700b5f0cbf8f6e3833dda0be45
@@ -707,7 +706,7 @@ F tool/lempar.c aeba88b8566ff66f8a67c96b3eb2dd95e7d8908d
 F tool/mkkeywordhash.c 8e57fbe8c4fe2f1800f9190fd361231cb8558407
 F tool/mkopts.tcl 66ac10d240cc6e86abd37dc908d50382f84ff46e x
 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97
-F tool/mksqlite3c.tcl 2b34be291baff0fdfeb37a970b51cd7ff9891c2a
+F tool/mksqlite3c.tcl 671833bd775e76ebd922b9e82c2508a344562511
 F tool/mksqlite3internalh.tcl 7b43894e21bcb1bb39e11547ce7e38a063357e87
 F tool/omittest.tcl 27d6f6e3b1e95aeb26a1c140e6eb57771c6d794a
 F tool/opcodeDoc.awk b3a2a3d5d3075b8bd90b7afe24283efdd586659c
@@ -721,7 +720,7 @@ F tool/speedtest16.c c8a9c793df96db7e4933f0852abb7a03d48f2e81
 F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff
 F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224
 F tool/speedtest8inst1.c 293327bc76823f473684d589a8160bde1f52c14e
-P 799d31d99fd18a6f99862433384e37d6747ee5b3
-R 1ce70fdfa14fdba2ade8fa79758df61c
+P b101cf70b75c9772aaf50e0eadd0cfa37c84d193
+R 4b293c104cb64e8cb94e481dce760f86
 U drh
-Z c3b824b2829f5e843646dc0fa08d702e
+Z 77e80e656a1a39cdd643ee53416f4c84
index fb5d86070ef0dd76a84522d64e260b654964f0e1..371a0e4cdf0d4e17ef3f7a368b5b9480c9959728 100644 (file)
@@ -1 +1 @@
-b101cf70b75c9772aaf50e0eadd0cfa37c84d193
\ No newline at end of file
+e963bed0fe3ce5fa32f04b930e5ed0956dc2aa47
\ No newline at end of file
diff --git a/src/rowhash.c b/src/rowhash.c
deleted file mode 100644 (file)
index 50559e6..0000000
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
-** 2009 April 15
-**
-** The author disclaims copyright to this source code.  In place of
-** a legal notice, here is a blessing:
-**
-**    May you do good and not evil.
-**    May you find forgiveness for yourself and forgive others.
-**    May you share freely, never taking more than you give.
-**
-*************************************************************************
-**
-** This file contains the implementation of the RowHash data structure.
-** A RowHash has the following properties:
-**
-**   *  A RowHash stores an unordered "bag" of 64-bit integer rowids.
-**      There is no other content.
-**
-**   *  Primative operations are CREATE, INSERT, TEST, and DESTROY.
-**      There is no way to remove individual elements from the RowHash
-**      once they are inserted.
-**
-**   *  INSERT operations are batched.  TEST operation will ignore
-**      elements in the current INSERT batch.  Only elements inserted
-**      in prior batches will be seen by a TEST.
-**
-** The insert batch number is a parameter to the TEST primitive.  The
-** hash table is rebuilt whenever the batch number increases.  TEST
-** operations only look for INSERTs that occurred in prior batches.
-**
-** The caller is responsible for insuring that there are no duplicate
-** INSERTs.
-**
-** $Id: rowhash.c,v 1.5 2009/04/22 00:47:01 drh Exp $
-*/
-#include "sqliteInt.h"
-
-/*
-** An upper bound on the size of heap allocations made by this module.
-** Limiting the size of allocations helps to avoid memory fragmentation.
-*/
-#define ROWHASH_ALLOCATION 1024
-
-/*
-** If there are less than this number of elements in the RowHash, do not
-** bother building a hash-table. Just do a linear search.
-*/
-#define ROWHASH_LINEAR_SEARCH_LIMIT 10
-
-/*
-** This value is what we want the average length of the collision hash
-** chain to be.
-*/
-#define ROWHASH_COLLISION_LENGTH 3
-
-
-/* Forward references to data structures. */
-typedef struct RowHashElem RowHashElem;
-typedef struct RowHashBlock RowHashBlock;
-typedef union RowHashPtr RowHashPtr;
-typedef struct RowHashPage RowHashPage;
-
-/*
-** Number of elements in the RowHashBlock.aElem[] array. This array is
-** sized to make RowHashBlock very close to (without exceeding)
-** ROWHASH_ALLOCATION bytes in size.
-*/
-#define ROWHASH_ELEM_PER_BLOCK (                                            \
-    (ROWHASH_ALLOCATION - ROUND8(sizeof(struct RowHashBlockData))) /        \
-    sizeof(RowHashElem)                                                     \
-)
-
-/*
-** Number of pointers that fit into a single allocation of 
-** ROWHASH_ALLOCATION bytes.
-*/
-#define ROWHASH_POINTER_PER_PAGE (ROWHASH_ALLOCATION/sizeof(RowHashPtr))
-
-/*
-** A page of pointers used to construct a hash table.
-**
-** The hash table is actually a tree composed of instances of this
-** object.  Leaves of the tree use the a[].pElem pointer to point
-** to RowHashElem entries.  Interior nodes of the tree use the
-** a[].pPage element to point to subpages.
-**
-** The hash table is split into a tree in order to avoid having
-** to make large memory allocations, since large allocations can
-** result in unwanted memory fragmentation.
-*/
-struct RowHashPage {
-  union RowHashPtr {
-    RowHashPage *pPage;   /* Used by interior nodes.  Pointer to subtree. */
-    RowHashElem *pElem;   /* Used by leaves.  Pointer to hash entry. */
-  } a[ROWHASH_POINTER_PER_PAGE];
-};
-
-/*
-** Each 64-bit integer in a RowHash is stored as an instance of
-** this object.  
-**
-** Instances of this object are not allocated separately.  They are
-** allocated in large blocks using the RowHashBlock object as a container.
-*/
-struct RowHashElem {
-  i64 iVal;              /* The value being stored.  A rowid. */
-  RowHashElem *pNext;    /* Next element with the same hash */
-};
-
-/*
-** In order to avoid many small allocations of RowHashElem objects,
-** multiple RowHashElem objects are allocated at once, as an instance
-** of this object, and then used as needed.
-**
-** A single RowHash object will allocate one or more of these RowHashBlock
-** objects.  As many are allocated as are needed to store all of the
-** content.  All RowHashBlocks are kept on a linked list formed using
-** RowHashBlock.data.pNext so that they can be freed when the RowHash
-** is destroyed.
-**
-** The linked list of RowHashBlock objects also provides a way to sequentially
-** scan all elements in the RowHash.  This sequential scan is used when
-** rebuilding the hash table.  The hash table is rebuilt after every 
-** batch of inserts.
-*/
-struct RowHashBlock {
-  struct RowHashBlockData {
-    RowHashBlock *pNext;      /* Next RowHashBlock object in list of them all */
-  } data;
-  RowHashElem aElem[ROWHASH_ELEM_PER_BLOCK]; /* Available RowHashElem objects */
-};
-
-/*
-** RowHash structure. References to a structure of this type are passed
-** around and used as opaque handles by code in other modules.
-*/
-struct RowHash {
-  unsigned int nEntry;    /* Number of used entries over all RowHashBlocks */
-  int iBatch;             /* The current insert batch number */
-  u16 nUsed;              /* Number of used entries in first RowHashBlock */
-  u8 nHeight;             /* Height of tree of hash pages */
-  u8 nLinearLimit;        /* Linear search limit (used if pHash==0) */
-  int nBucket;            /* Number of buckets in hash table */
-  RowHashPage *pHash;     /* Pointer to root of hash table tree */
-  RowHashBlock *pBlock;   /* Linked list of RowHashBlocks */
-  sqlite3 *db;            /* Associated database connection */
-};
-
-
-/*
-** Allocate a hash table tree of height nHeight with *pnLeaf leaf pages. 
-** Set *pp to point to the root of the tree.  If the maximum number of leaf 
-** pages in a tree of height nHeight is less than *pnLeaf, allocate only
-** that part of the tree that is necessary to account for all leaves.
-**
-** Before returning, subtract the number of leaves in the tree allocated
-** from *pnLeaf.
-**
-** This routine returns SQLITE_NOMEM if a malloc() fails, or SQLITE_OK
-** otherwise.
-*/
-static int allocHashTable(RowHashPage **pp, int nHeight, int *pnLeaf){
-  RowHashPage *p = (RowHashPage *)sqlite3MallocZero(sizeof(*p));
-  if( !p ){
-    return SQLITE_NOMEM;
-  }
-  *pp = p;
-  if( nHeight==0 ){
-    (*pnLeaf)--;
-  }else{
-    int ii;
-    for(ii=0; ii<ROWHASH_POINTER_PER_PAGE && *pnLeaf>0; ii++){
-      if( allocHashTable(&p->a[ii].pPage, nHeight-1, pnLeaf) ){
-        return SQLITE_NOMEM;
-      }
-    }
-  }
-  return SQLITE_OK;
-}
-
-/*
-** Delete the hash table tree of height nHeight passed as the first argument.
-*/
-static void deleteHashTable(RowHashPage *p, int nHeight){
-  if( p ){
-    if( nHeight>0 ){
-      int ii;
-      for(ii=0; ii<ROWHASH_POINTER_PER_PAGE; ii++){
-        deleteHashTable(p->a[ii].pPage, nHeight-1);
-      }
-    }
-    sqlite3_free(p);
-  }
-}
-
-/*
-** Find the hash-bucket associated with value iVal. Return a pointer to it.
-**
-** By "hash-bucket", we mean the RowHashPage.a[].pElem pointer that
-** corresponds to a particular hash entry.
-*/
-static RowHashElem **findHashBucket(RowHash *pRowHash, i64 iVal){
-  int aOffset[16];
-  int n;
-  RowHashPage *pPage = pRowHash->pHash;
-  int h = (((u64)iVal) % pRowHash->nBucket);
-
-  assert( pRowHash->nHeight < sizeof(aOffset)/sizeof(aOffset[0]) );
-  for(n=0; n<pRowHash->nHeight; n++){
-    int h1 = h / ROWHASH_POINTER_PER_PAGE;
-    aOffset[n] = h - (h1 * ROWHASH_POINTER_PER_PAGE);
-    h = h1;
-  }
-  aOffset[n] = h;
-  for(n=pRowHash->nHeight; n>0; n--){
-    pPage = pPage->a[aOffset[n]].pPage;
-  }
-  return &pPage->a[aOffset[0]].pElem;
-}
-
-/*
-** Build a new hash table tree in p->pHash.  The new hash table should
-** contain all p->nEntry entries in the p->pBlock list.  If there
-** existed a prior tree, delete the old tree first before constructing
-** the new one.
-**
-** If the number of entries (p->nEntry) is less than
-** ROWHASH_LINEAR_SEARCH_LIMIT, then we are guessing that a linear
-** search is going to be faster than a lookup, so do not bother
-** building the hash table.
-*/
-static int makeHashTable(RowHash *p, int iBatch){
-  RowHashBlock *pBlock;
-  int nBucket;
-  int nLeaf, n;
-  
-  /* Delete the old hash table. */
-  deleteHashTable(p->pHash, p->nHeight);
-  assert( p->iBatch!=iBatch );
-  p->iBatch = iBatch;
-
-  /* Skip building the hash table if the number of elements is small */
-  if( p->nEntry<ROWHASH_LINEAR_SEARCH_LIMIT ){
-    p->nLinearLimit = p->nEntry;
-    p->pHash = 0;
-    return SQLITE_OK;
-  }
-
-  /* Determine how many leaves the hash-table will comprise. */
-  nLeaf = 1 + (p->nEntry / (ROWHASH_POINTER_PER_PAGE*ROWHASH_COLLISION_LENGTH));
-  p->nBucket = nBucket = nLeaf*ROWHASH_POINTER_PER_PAGE;
-
-  /* Set nHeight to the height of the tree that contains the leaf pages. If
-  ** RowHash.nHeight is zero, then the whole hash-table fits on a single
-  ** leaf. If RowHash.nHeight is 1, then RowHash.pHash points to an array
-  ** of pointers to leaf pages. If 2, pHash points to an array of pointers
-  ** to arrays of pointers to leaf pages. And so on.
-  */
-  p->nHeight = 0;
-  n = nLeaf;
-  while( n>1 ){
-    n = (n+ROWHASH_POINTER_PER_PAGE-1) / ROWHASH_POINTER_PER_PAGE;
-    p->nHeight++;
-  }
-
-  /* Allocate the hash-table. */
-  if( allocHashTable(&p->pHash, p->nHeight, &nLeaf) ){
-    return SQLITE_NOMEM;
-  }
-
-  /* Insert all values into the hash-table. */
-  for(pBlock=p->pBlock; pBlock; pBlock=pBlock->data.pNext){
-    RowHashElem * const pEnd = &pBlock->aElem[
-      pBlock==p->pBlock?p->nUsed:ROWHASH_ELEM_PER_BLOCK
-    ];
-    RowHashElem *pIter;
-    for(pIter=pBlock->aElem; pIter<pEnd; pIter++){
-      RowHashElem **ppElem = findHashBucket(p, pIter->iVal);
-      pIter->pNext = *ppElem;
-      *ppElem = pIter;
-    }
-  }
-
-  return SQLITE_OK;
-}
-
-/*
-** Check to see if iVal has been inserted into the hash table "p"
-** in some batch prior to iBatch.  If so, set *pExists to 1.
-** If not, set *pExists to 0.
-**
-** The hash table is rebuilt whenever iBatch changes.  A hash table
-** rebuild might encounter an out-of-memory condition.  If that happens,
-** return SQLITE_NOMEM.  If there are no problems, return SQLITE_OK.
-**
-** The initial "batch" is 0.  So, if there were prior calls to
-** sqlite3RowhashInsert() and then this routine is invoked with iBatch==0,
-** because all prior inserts where in the same batch, none of the prior
-** inserts will be visible and this routine will indicate not found.
-** Hence, the first invocation of this routine should probably use
-** a batch number of 1.
-*/
-int sqlite3RowhashTest(
-  RowHash *p,     /* The RowHash to search in */
-  int iBatch,     /* Look for values inserted in batches prior to this batch */
-  i64 iVal,       /* The rowid value we are looking for */
-  int *pExists    /* Store 0 or 1 hear to indicate not-found or found */
-){
-  *pExists = 0;
-  if( p ){
-    assert( p->pBlock );
-    if( iBatch!=p->iBatch && makeHashTable(p, iBatch) ){
-      return SQLITE_NOMEM;
-    }
-    if( p->pHash ){
-      RowHashElem *pElem = *findHashBucket(p, iVal);
-      for(; pElem; pElem=pElem->pNext){
-        if( pElem->iVal==iVal ){
-          *pExists = 1;
-          break;
-        }
-      }
-    }else{
-      int ii;
-      RowHashElem *aElem = p->pBlock->aElem;
-      for(ii=0; ii<p->nLinearLimit; ii++){
-        if( aElem[ii].iVal==iVal ){
-          *pExists = 1;
-          break;
-        }
-      }
-    }
-  }
-  return SQLITE_OK;
-}
-
-/*
-** Insert value iVal into the RowHash object.  Allocate a new RowHash
-** object if necessary.
-**
-** Return SQLITE_OK if all goes as planned. If a malloc() fails, return
-** SQLITE_NOMEM.
-*/
-int sqlite3RowhashInsert(sqlite3 *db, RowHash **pp, i64 iVal){
-  RowHash *p = *pp;
-  
-  /* If the RowHash structure has not been allocated, allocate it now. */
-  if( !p ){
-    p = (RowHash*)sqlite3DbMallocZero(db, sizeof(RowHash));
-    if( !p ){
-      return SQLITE_NOMEM;
-    }
-    p->db = db;
-    *pp = p;
-  }
-
-  /* If the current RowHashBlock is full, or if the first RowHashBlock has
-  ** not yet been allocated, allocate one now. */ 
-  if( !p->pBlock || p->nUsed==ROWHASH_ELEM_PER_BLOCK ){
-    RowHashBlock *pBlock = (RowHashBlock*)sqlite3Malloc(sizeof(RowHashBlock));
-    if( !pBlock ){
-      return SQLITE_NOMEM;
-    }
-    pBlock->data.pNext = p->pBlock;
-    p->pBlock = pBlock;
-    p->nUsed = 0;
-  }
-  assert( p->nUsed==(p->nEntry % ROWHASH_ELEM_PER_BLOCK) );
-
-  /* Add iVal to the current RowHashBlock. */
-  p->pBlock->aElem[p->nUsed].iVal = iVal;
-  p->nUsed++;
-  p->nEntry++;
-  return SQLITE_OK;
-}
-
-/*
-** Destroy the RowHash object passed as the first argument.
-*/
-void sqlite3RowhashDestroy(RowHash *p){
-  if( p ){
-    RowHashBlock *pBlock, *pNext;
-    deleteHashTable(p->pHash, p->nHeight);
-    for(pBlock=p->pBlock; pBlock; pBlock=pNext){
-      pNext = pBlock->data.pNext;
-      sqlite3_free(pBlock);
-    }
-    sqlite3DbFree(p->db, p);
-  }
-}
index 2e51888e002d45bd83227be3d9be6515cf6fb83a..5a61ea5b49055fdd02deae66f2a55e518d4dcae2 100644 (file)
@@ -11,7 +11,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.857 2009/04/22 00:47:01 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.858 2009/04/22 02:15:48 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -557,7 +557,6 @@ struct BusyHandler {
 typedef struct AggInfo AggInfo;
 typedef struct AuthContext AuthContext;
 typedef struct Bitvec Bitvec;
-typedef struct RowHash RowHash;
 typedef struct RowSet RowSet;
 typedef struct CollSeq CollSeq;
 typedef struct Column Column;
@@ -1752,7 +1751,7 @@ struct WhereLevel {
 #define WHERE_FILL_ROWSET      0x0008  /* Save results in a RowSet object */
 #define WHERE_OMIT_OPEN        0x0010  /* Table cursor are already open */
 #define WHERE_OMIT_CLOSE       0x0020  /* Omit close of table & index cursors */
-#define WHERE_FILL_ROWHASH     0x0040  /* Save results in a RowHash object */
+#define WHERE_FILL_ROWTEST     0x0040  /* Save results using OP_RowSetTest */
 
 /*
 ** The WHERE clause processing routine has two halves.  The
@@ -1765,8 +1764,8 @@ struct WhereInfo {
   Parse *pParse;       /* Parsing and code generating context */
   u16 wctrlFlags;      /* Flags originally passed to sqlite3WhereBegin() */
   u8 okOnePass;        /* Ok to use one-pass algorithm for UPDATE or DELETE */
-  int regRowSet;                 /* Store rowids in this rowset/rowhash */
-  int iRowidHandler;             /* Address of OP_RowSet or OP_RowHash */
+  int regRowSet;                 /* Store rowids in this rowset */
+  int iRowidHandler;             /* Address of OP_RowSet or OP_RowSetTest */
   SrcList *pTabList;             /* List of tables in the join */
   int iTop;                      /* The very beginning of the WHERE loop */
   int iContinue;                 /* Jump here to continue with next record */
@@ -2403,10 +2402,6 @@ void sqlite3RowSetInsert(RowSet*, i64);
 int sqlite3RowSetTest(RowSet*, u8 iBatch, i64);
 int sqlite3RowSetNext(RowSet*, i64*);
 
-int sqlite3RowhashInsert(sqlite3*, RowHash **pp, i64 iVal);
-int sqlite3RowhashTest(RowHash *p, int iSet, i64 iVal, int *pExists);
-void sqlite3RowhashDestroy(RowHash *p);
-
 void sqlite3CreateView(Parse*,Token*,Token*,Token*,Select*,int,int);
 
 #if !defined(SQLITE_OMIT_VIEW) || !defined(SQLITE_OMIT_VIRTUALTABLE)
index 8cc33d0be475e843be791aa40ef40c58e2934eeb..a5312fc834e4b0d48cf60a2d5a1f961ee8235f8d 100644 (file)
@@ -43,7 +43,7 @@
 ** in this file for details.  If in doubt, do not deviate from existing
 ** commenting and indentation practices when changing or adding code.
 **
-** $Id: vdbe.c,v 1.836 2009/04/22 00:47:01 drh Exp $
+** $Id: vdbe.c,v 1.837 2009/04/22 02:15:48 drh Exp $
 */
 #include "sqliteInt.h"
 #include "vdbeInt.h"
@@ -4604,34 +4604,35 @@ case OP_RowSetRead: {       /* jump, out3 */
   break;
 }
 
-/* Opcode: RowHash P1 P2 P3 P4
+/* Opcode: RowSetTest P1 P2 P3 P4
 **
 ** Register P3 is assumed to hold a 64-bit integer value. If register P1
-** contains a rowid-hash object and the rowid-hash object contains
+** contains a RowSet object and that RowSet object contains
 ** the value held in P3, jump to register P2. Otherwise, insert the
-** integer in P3 into the rowid-hash container and continue on to the
+** integer in P3 into the RowSet and continue on to the
 ** next opcode.
 **
-** The rowid-hash is optimized for the case where successive sets
+** The RowSet object is optimized for the case where successive sets
 ** of integers, where each set contains no duplicates. Each set
 ** of values is identified by a unique P4 value. The first set
-** must have P4==0, the final set P4=-1.
+** must have P4==0, the final set P4=-1.  P4 must be either -1 or
+** non-negative.  For non-negative values of P4 only the lower 4
+** bits are significant.
 **
 ** This allows optimizations: (a) when P4==0 there is no need to test
-** the row-hash object for P3, as it is guaranteed not to contain it,
+** the rowset object for P3, as it is guaranteed not to contain it,
 ** (b) when P4==-1 there is no need to insert the value, as it will
 ** never be tested for, and (c) when a value that is part of set X is
 ** inserted, there is no need to search to see if the same value was
 ** previously inserted as part of set X (only if it was previously
 ** inserted as part of some other set).
 */
-case OP_RowHash: {                     /* jump, in1, in3 */
+case OP_RowSetTest: {                     /* jump, in1, in3 */
   int iSet = pOp->p4.i;
   assert( pIn3->flags&MEM_Int );
 
-  /* If there is anything other than a row-hash object in memory cell P1,
-  ** delete it now and initialize P1 with an empty row-hash (a null pointer
-  ** is an acceptable representation of an empty row-hash).
+  /* If there is anything other than a rowset object in memory cell P1,
+  ** delete it now and initialize P1 with an empty rowset
   */
   if( (pIn1->flags & MEM_RowSet)==0 ){
     sqlite3VdbeMemSetRowSet(pIn1);
@@ -4639,6 +4640,7 @@ case OP_RowHash: {                     /* jump, in1, in3 */
   }
 
   assert( pOp->p4type==P4_INT32 );
+  assert( iSet==-1 || iSet>=0 );
   if( iSet ){
     int exists;
     exists = sqlite3RowSetTest(pIn1->u.pRowSet, iSet>=0 ? iSet & 0xf : 0xff,
index e5b9f25b29b0306a5669120410affe0040f0ff3e..cbf867dd068a883f38c46e3a444ef41dc6530393 100644 (file)
@@ -15,7 +15,7 @@
 ** 6000 lines long) it was split up into several smaller files and
 ** this header information was factored out.
 **
-** $Id: vdbeInt.h,v 1.168 2009/04/21 09:02:47 danielk1977 Exp $
+** $Id: vdbeInt.h,v 1.169 2009/04/22 02:15:48 drh Exp $
 */
 #ifndef _VDBEINT_H_
 #define _VDBEINT_H_
@@ -115,7 +115,6 @@ struct Mem {
     int nZero;          /* Used when bit MEM_Zero is set in flags */
     FuncDef *pDef;      /* Used only when flags==MEM_Agg */
     RowSet *pRowSet;    /* Used only when flags==MEM_RowSet */
-    RowHash *pRowHash;  /* Used only when flags==MEM_RowHash */
   } u;
   double r;           /* Real value */
   sqlite3 *db;        /* The associated database connection */
@@ -149,7 +148,6 @@ struct Mem {
 #define MEM_Real      0x0008   /* Value is a real number */
 #define MEM_Blob      0x0010   /* Value is a BLOB */
 #define MEM_RowSet    0x0020   /* Value is a RowSet object */
-#define MEM_RowHash   0x0040   /* Value is a RowHash object */
 #define MEM_TypeMask  0x00ff   /* Mask of type bits */
 
 /* Whenever Mem contains a valid string or blob representation, one of
index 697a61bad72b87ee554664ba12c72d3ce74ac0c8..8d16b875c955288d25b7644760f1c819d5c87b7d 100644 (file)
@@ -14,7 +14,7 @@
 ** to version 2.8.7, all this code was combined into the vdbe.c source file.
 ** But that file was getting too big so this subroutines were split out.
 **
-** $Id: vdbeaux.c,v 1.452 2009/04/21 09:02:47 danielk1977 Exp $
+** $Id: vdbeaux.c,v 1.453 2009/04/22 02:15:48 drh Exp $
 */
 #include "sqliteInt.h"
 #include "vdbeInt.h"
@@ -1224,9 +1224,6 @@ static void Cleanup(Vdbe *p){
     if( pMem->flags & MEM_RowSet ){
       sqlite3RowSetClear(pMem->u.pRowSet);
     }
-    if( pMem->flags & MEM_RowHash ){
-      sqlite3RowhashDestroy(pMem->u.pRowHash);
-    }
     MemSetTypeFlag(pMem, MEM_Null);
   }
   releaseMemArray(&p->aMem[1], p->nMem);
index 478ed26646edcc638d0ba2ef24bdf1682a80bcf0..6bc0e1ff81b730460b0d3f1a47572b6d8567b50a 100644 (file)
@@ -15,7 +15,7 @@
 ** only within the VDBE.  Interface routines refer to a Mem using the
 ** name sqlite_value
 **
-** $Id: vdbemem.c,v 1.141 2009/04/21 09:02:47 danielk1977 Exp $
+** $Id: vdbemem.c,v 1.142 2009/04/22 02:15:49 drh Exp $
 */
 #include "sqliteInt.h"
 #include "vdbeInt.h"
@@ -270,7 +270,7 @@ int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){
 */
 void sqlite3VdbeMemReleaseExternal(Mem *p){
   assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) );
-  if( p->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_RowHash) ){
+  if( p->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet) ){
     if( p->flags&MEM_Agg ){
       sqlite3VdbeMemFinalize(p, p->u.pDef);
       assert( (p->flags & MEM_Agg)==0 );
@@ -281,9 +281,6 @@ void sqlite3VdbeMemReleaseExternal(Mem *p){
       p->xDel = 0;
     }else if( p->flags&MEM_RowSet ){
       sqlite3RowSetClear(p->u.pRowSet);
-    }else if( p->flags&MEM_RowHash ){
-      sqlite3RowhashDestroy(p->u.pRowHash);
-      p->u.pRowHash = 0;
     }
   }
 }
index 2ff86374907d6f94ab1bbf1065b5d2a29a7af978..15c3e73650b504472cf58c4dfc7d1cb613fb6839 100644 (file)
@@ -16,7 +16,7 @@
 ** so is applicable.  Because this module is responsible for selecting
 ** indices, you might also think of this module as the "query optimizer".
 **
-** $Id: where.c,v 1.384 2009/04/21 17:23:05 danielk1977 Exp $
+** $Id: where.c,v 1.385 2009/04/22 02:15:49 drh Exp $
 */
 #include "sqliteInt.h"
 
@@ -2414,14 +2414,11 @@ static Bitmask codeOneLoopStart(
   **   1) If pWInfo->regRowSet is non-zero, then the rowid must be inserted
   **      into the RowSet object stored in register pWInfo->regRowSet.
   **
-  **   2) If pWInfo->regRowHash is non-zero, then the rowid must be inserted
-  **      into the RowHash object stored in register pWInfo->regRowHash.
-  **
   ** Extracting a rowid value from a VDBE cursor is not always a cheap
   ** operation, especially if the rowid is being extracted from an index
   ** cursor. If the rowid value is available as a by-product of the code
   ** generated to create the top of the scan loop, then it can be reused
-  ** for either of the two purposes enumerated above without extracting
+  ** without extracting
   ** it from a cursor. The following two variables are used to communicate
   ** the availability of the rowid value to the C-code at the end of this
   ** function that generates the rowid-handling VDBE code.
@@ -2437,7 +2434,7 @@ static Bitmask codeOneLoopStart(
   iCur = pTabItem->iCursor;
   bRev = (pLevel->plan.wsFlags & WHERE_REVERSE)!=0;
   omitTable = (pLevel->plan.wsFlags & WHERE_IDX_ONLY)!=0 
-           && (wctrlFlags & WHERE_FILL_ROWHASH)==0;
+           && (wctrlFlags & WHERE_FILL_ROWTEST)==0;
   regRowSet = pWInfo->regRowSet;
   codeRowSetEarly = 0;
 
@@ -2817,22 +2814,22 @@ static Bitmask codeOneLoopStart(
     ** In the example, there are three indexed terms connected by OR.
     ** The top of the loop looks like this:
     **
-    **          Null       1                # Zero the row-hash in reg 1
+    **          Null       1                # Zero the rowset in reg 1
     **
     ** Then, for each indexed term, the following. The arguments to
-    ** RowHash are such that the rowid of the current row is inserted
-    ** into the row-hash. If it is already present, control skips the
+    ** RowSetTest are such that the rowid of the current row is inserted
+    ** into the RowSet. If it is already present, control skips the
     ** Gosub opcode and jumps straight to the code generated by WhereEnd().
     **
     **        sqlite3WhereBegin(<term>)
-    **          RowHash                     # Insert rowid into rowhash
+    **          RowSetTest                  # Insert rowid into rowset
     **          Gosub      2 A
     **        sqlite3WhereEnd()
     **
     ** Following the above, code to terminate the loop. Label A, the target
     ** of the Gosub above, jumps to the instruction right after the Goto.
     **
-    **          Null       1                # Zero the row-hash in reg 1
+    **          Null       1                # Zero the rowset in reg 1
     **          Goto       B                # The loop is finished.
     **
     **       A: <loop body>                 # Return data, whatever.
@@ -2842,14 +2839,14 @@ static Bitmask codeOneLoopStart(
     **       B: <after the loop>
     **
     */
-    const int f = WHERE_OMIT_OPEN | WHERE_OMIT_CLOSE | WHERE_FILL_ROWHASH;
+    const int f = WHERE_OMIT_OPEN | WHERE_OMIT_CLOSE | WHERE_FILL_ROWTEST;
 
     WhereClause *pOrWc;    /* The OR-clause broken out into subterms */
     WhereTerm *pFinal;     /* Final subterm within the OR-clause. */
     SrcList oneTab;        /* Shortened table list */
 
     int regReturn = ++pParse->nMem;           /* Register used with OP_Gosub */
-    int regRowhash = ++pParse->nMem;          /* Register for RowHash object */
+    int regRowset = ++pParse->nMem;           /* Register for RowSet object */
     int iLoopBody = sqlite3VdbeMakeLabel(v);  /* Start of loop body */
     int iRetInit;                             /* Address of regReturn init */
     int ii;
@@ -2866,8 +2863,8 @@ static Bitmask codeOneLoopStart(
     oneTab.nAlloc = 1;
     oneTab.a[0] = *pTabItem;
 
-    /* Initialize the row-hash register to contain NULL. An SQL NULL is 
-    ** equivalent to an empty row-hash. 
+    /* Initialize the rowset register to contain NULL. An SQL NULL is 
+    ** equivalent to an empty rowset.
     **
     ** Also initialize regReturn to contain the address of the instruction 
     ** immediately following the OP_Return at the bottom of the loop. This
@@ -2877,7 +2874,7 @@ static Bitmask codeOneLoopStart(
     ** fall through to the next instruction, just as an OP_Next does if
     ** called on an uninitialized cursor.
     */
-    sqlite3VdbeAddOp2(v, OP_Null, 0, regRowhash);
+    sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset);
     iRetInit = sqlite3VdbeAddOp2(v, OP_Integer, 0, regReturn);
 
     /* iReleaseReg = iRowidReg = sqlite3GetTempReg(pParse); */
@@ -2888,18 +2885,18 @@ static Bitmask codeOneLoopStart(
 
         /* Loop through table entries that match term pOrTerm. */
         pSubWInfo = sqlite3WhereBegin(
-            pParse, &oneTab, pOrTerm->pExpr, 0, f, regRowhash);
+            pParse, &oneTab, pOrTerm->pExpr, 0, f, regRowset);
         if( pSubWInfo ){
           int iSet = ((ii==pOrWc->nTerm-1)?-1:ii);
-          /* The call to sqlite3WhereBegin has coded an OP_RowHash 
-          ** at instruction iRowHash. Set P2 (the jump target) of this
+          /* The call to sqlite3WhereBegin has coded an OP_RowSetTest
+          ** at instruction iRowSet. Set P2 (the jump target) of this
           ** instruction to jump past the OP_Gosub coded below. This way,
           ** if the rowid is already in the hash-table, the body of the
           ** loop is not executed.
           */
-          int iRowHash = pSubWInfo->iRowidHandler;
-          sqlite3VdbeChangeP2(v, iRowHash, sqlite3VdbeCurrentAddr(v) + 1);
-          sqlite3VdbeChangeP4(v, iRowHash, (char *)iSet, P4_INT32);
+          int iRowSet = pSubWInfo->iRowidHandler;
+          sqlite3VdbeChangeP2(v, iRowSet, sqlite3VdbeCurrentAddr(v) + 1);
+          sqlite3VdbeChangeP4(v, iRowSet, (char *)iSet, P4_INT32);
           sqlite3VdbeAddOp2(v, OP_Gosub, regReturn, iLoopBody);
 
           /* Finish the loop through table entries that match term pOrTerm. */
@@ -2908,7 +2905,7 @@ static Bitmask codeOneLoopStart(
       }
     }
     sqlite3VdbeChangeP1(v, iRetInit, sqlite3VdbeCurrentAddr(v));
-    sqlite3VdbeAddOp2(v, OP_Null, 0, regRowhash);
+    sqlite3VdbeAddOp2(v, OP_Null, 0, regRowset);
     sqlite3VdbeAddOp2(v, OP_Goto, 0, pLevel->addrBrk);
     sqlite3VdbeResolveLabel(v, iLoopBody);
 
@@ -2998,8 +2995,8 @@ static Bitmask codeOneLoopStart(
     if( pWInfo->wctrlFlags&WHERE_FILL_ROWSET ){
       sqlite3VdbeAddOp2(v, OP_RowSetAdd, regRowSet, iRowidReg);
     }else{
-      assert( pWInfo->wctrlFlags&WHERE_FILL_ROWHASH );
-      sqlite3VdbeAddOp3(v, OP_RowHash, regRowSet, 0, iRowidReg);
+      assert( pWInfo->wctrlFlags&WHERE_FILL_ROWTEST );
+      sqlite3VdbeAddOp3(v, OP_RowSetTest, regRowSet, 0, iRowidReg);
     }
   }
   sqlite3ReleaseTempReg(pParse, iReleaseReg);
@@ -3189,7 +3186,7 @@ WhereInfo *sqlite3WhereBegin(
   pWInfo->pWC = pWC = (WhereClause *)&((u8 *)pWInfo)[nByteWInfo];
   pWInfo->wctrlFlags = wctrlFlags;
   pMaskSet = (WhereMaskSet*)&pWC[1];
-  assert( regRowSet==0 || (wctrlFlags&(WHERE_FILL_ROWSET|WHERE_FILL_ROWHASH)) );
+  assert( regRowSet==0 || (wctrlFlags&(WHERE_FILL_ROWSET|WHERE_FILL_ROWTEST)) );
 
   /* Split the WHERE clause into separate subexpressions where each
   ** subexpression is separated by an AND operator.
index 4ad960e2dc4dd085d455812a817f392f07c4048a..857ecfb7f52c8877538b36e9583df61a6708228a 100644 (file)
@@ -239,7 +239,6 @@ foreach file {
    os_unix.c
    os_win.c
 
-   rowhash.c
    bitvec.c
    pcache.c
    pcache1.c