]> git.ipfire.org Git - thirdparty/sqlite.git/commitdiff
If all data being sorted fits in memory, avoid writing any data out to temporary...
authordan <dan@noemail.net>
Fri, 2 Sep 2011 11:45:31 +0000 (11:45 +0000)
committerdan <dan@noemail.net>
Fri, 2 Sep 2011 11:45:31 +0000 (11:45 +0000)
FossilOrigin-Name: 71075673c625f243969c3f34c73f28f378924007

manifest
manifest.uuid
src/vdbesort.c

index 9513f2ff2eff9eb2261bce19ae408285219c9ef3..7f37801bfef94e7a49aaf11a497f395da5fe24bb 100644 (file)
--- a/manifest
+++ b/manifest
@@ -1,5 +1,5 @@
-C Instead\sof\sa\stemporary\sb-tree,\suse\sa\slinked-list\sand\smerge-sort\sto\ssort\srecords\sin\smain\smemory\sin\svdbesort.c.
-D 2011-09-02T10:31:11.173
+C If\sall\sdata\sbeing\ssorted\sfits\sin\smemory,\savoid\swriting\sany\sdata\sout\sto\stemporary\sfiles\sin\svdbesort.c.
+D 2011-09-02T11:45:31.600
 F Makefile.arm-wince-mingw32ce-gcc d6df77f1f48d690bd73162294bbba7f59507c72f
 F Makefile.in d314143fa6be24828021d3f583ad37d9afdce505
 F Makefile.linux-gcc 91d710bdc4998cb015f39edf3cb314ec4f4d7e23
@@ -245,7 +245,7 @@ F src/vdbeapi.c 11dc47987abacb76ad016dcf5abc0dc422482a98
 F src/vdbeaux.c e58acbc5ea3823922a0cd8fa21f94f39af51ee88
 F src/vdbeblob.c f024f0bf420f36b070143c32b15cc7287341ffd3
 F src/vdbemem.c 5e6effb96dd53d233361cbfaa3f0a43b9af689e9
-F src/vdbesort.c 9c2e8ca23c2413a5162a4433cb72377588d896f8
+F src/vdbesort.c 1e9d4437c7520e09b18f37d2c520bfa01e638655
 F src/vdbetrace.c 5d0dc3d5fd54878cc8d6d28eb41deb8d5885b114
 F src/vtab.c 901791a47318c0562cd0c676a2c6ff1bc530e582
 F src/wal.c 3154756177d6219e233d84291d5b05f4e06ff5e9
@@ -961,7 +961,7 @@ F tool/symbols.sh caaf6ccc7300fd43353318b44524853e222557d5
 F tool/tostr.awk e75472c2f98dd76e06b8c9c1367f4ab07e122d06
 F tool/vdbe-compress.tcl d70ea6d8a19e3571d7ab8c9b75cba86d1173ff0f
 F tool/warnings.sh b7fdb2cc525f5ef4fa43c80e771636dd3690f9d2
-P ebf819aaa555bd79fddfc0a6f9827a2539095d6c
-R c9d892df81c49366e067933871c3b776
+P 7769fb988d9be0f2d8129aaac19620ac88f9b4a6
+R 023e08b29250dcfb353aa799966d9eeb
 U dan
-Z b3581bd03fb5a181801f57c568eb418b
+Z 052620c5c09aadfa96f446950f8f8dff
index f82002ddab3e49c0efda221a5d2e1ce4f8fe9455..6963963883661bdca47d033a83928a8ff600c707 100644 (file)
@@ -1 +1 @@
-7769fb988d9be0f2d8129aaac19620ac88f9b4a6
\ No newline at end of file
+71075673c625f243969c3f34c73f28f378924007
\ No newline at end of file
index 3ab5d7930a575dd6d8e7b8e1e8f2111dc84499a4..83c1c5d132b5bd81898c01fa2719fbb355f0d852 100644 (file)
@@ -732,13 +732,18 @@ int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){
 
   assert( pSorter );
 
+  /* If no data has been written to disk, then do not do so now. Instead,
+  ** sort the VdbeSorter.pRecord list. The vdbe layer will read data directly
+  ** from the in-memory list.  */
+  if( pSorter->nPMA==0 ){
+    *pbEof = !pSorter->pRecord;
+    assert( pSorter->aTree==0 );
+    return vdbeSorterSort(db, pCsr);
+  }
+
   /* Write the current b-tree to a PMA. Close the b-tree cursor. */
   rc = vdbeSorterListToPMA(db, pCsr);
   if( rc!=SQLITE_OK ) return rc;
-  if( pSorter->nPMA==0 ){
-    *pbEof = 1;
-    return SQLITE_OK;
-  }
 
   /* Allocate space for aIter[] and aTree[]. */
   nIter = pSorter->nPMA;
@@ -826,33 +831,64 @@ int sqlite3VdbeSorterRewind(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){
 */
 int sqlite3VdbeSorterNext(sqlite3 *db, VdbeCursor *pCsr, int *pbEof){
   VdbeSorter *pSorter = pCsr->pSorter;
-  int iPrev = pSorter->aTree[1];  /* Index of iterator to advance */
-  int i;                          /* Index of aTree[] to recalculate */
   int rc;                         /* Return code */
 
-  rc = vdbeSorterIterNext(db, &pSorter->aIter[iPrev]);
-  for(i=(pSorter->nTree+iPrev)/2; rc==SQLITE_OK && i>0; i=i/2){
-    rc = vdbeSorterDoCompare(pCsr, i);
-  }
+  if( pSorter->aTree ){
+    int iPrev = pSorter->aTree[1];/* Index of iterator to advance */
+    int i;                        /* Index of aTree[] to recalculate */
 
-  *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0);
+    rc = vdbeSorterIterNext(db, &pSorter->aIter[iPrev]);
+    for(i=(pSorter->nTree+iPrev)/2; rc==SQLITE_OK && i>0; i=i/2){
+      rc = vdbeSorterDoCompare(pCsr, i);
+    }
+
+    *pbEof = (pSorter->aIter[pSorter->aTree[1]].pFile==0);
+  }else{
+    SorterRecord *pFree = pSorter->pRecord;
+    pSorter->pRecord = pFree->pNext;
+    pFree->pNext = 0;
+    vdbeSorterRecordFree(db, pFree);
+    *pbEof = !pSorter->pRecord;
+    rc = SQLITE_OK;
+  }
   return rc;
 }
 
+/*
+** Return a pointer to a buffer owned by the sorter that contains the 
+** current key.
+*/
+static void *vdbeSorterRowkey(
+  VdbeSorter *pSorter,            /* Sorter object */
+  int *pnKey                      /* OUT: Size of current key in bytes */
+){
+  void *pKey;
+  if( pSorter->aTree ){
+    VdbeSorterIter *pIter;
+    pIter = &pSorter->aIter[ pSorter->aTree[1] ];
+    *pnKey = pIter->nKey;
+    pKey = pIter->aKey;
+  }else{
+    *pnKey = pSorter->pRecord->nVal;
+    pKey = pSorter->pRecord->pVal;
+  }
+  return pKey;
+}
+
 /*
 ** Copy the current sorter key into the memory cell pOut.
 */
 int sqlite3VdbeSorterRowkey(VdbeCursor *pCsr, Mem *pOut){
   VdbeSorter *pSorter = pCsr->pSorter;
-  VdbeSorterIter *pIter;
+  void *pKey; int nKey;           /* Sorter key to copy into pOut */
 
-  pIter = &pSorter->aIter[ pSorter->aTree[1] ];
-  if( sqlite3VdbeMemGrow(pOut, pIter->nKey, 0) ){
+  pKey = vdbeSorterRowkey(pSorter, &nKey);
+  if( sqlite3VdbeMemGrow(pOut, nKey, 0) ){
     return SQLITE_NOMEM;
   }
-  pOut->n = pIter->nKey;
+  pOut->n = nKey;
   MemSetTypeFlag(pOut, MEM_Blob);
-  memcpy(pOut->z, pIter->aKey, pIter->nKey);
+  memcpy(pOut->z, pKey, nKey);
 
   return SQLITE_OK;
 }
@@ -874,11 +910,10 @@ int sqlite3VdbeSorterCompare(
 ){
   int rc;
   VdbeSorter *pSorter = pCsr->pSorter;
-  VdbeSorterIter *pIter;
-  pIter = &pSorter->aIter[ pSorter->aTree[1] ];
-  rc = vdbeSorterCompare(pCsr->pKeyInfo, 1,
-      pVal->z, pVal->n, pIter->aKey, pIter->nKey, pRes
-  );
+  void *pKey; int nKey;           /* Sorter key to compare pVal with */
+
+  pKey = vdbeSorterRowkey(pSorter, &nKey);
+  rc = vdbeSorterCompare(pCsr->pKeyInfo, 1, pVal->z, pVal->n, pKey, nKey, pRes);
   assert( rc!=SQLITE_OK || *pRes<=0 );
   return rc;
 }