-C Comment\schanges\sonly:\s\sAdd\sseveral\soptimization\smarks\sin\srowset.c.\s\sAdd\na\sheader\scomment\sthat\sexplains\swhat\sthe\svarious\sspecial\scomments\smean.
-D 2016-04-28T20:11:12.680
+C Further\ssimplifications\sand\simproved\scommentting\son\sthe\srowset.c\smodule,\nincluding\sseveral\soptimization\scomments.
+D 2016-04-28T22:29:31.056
F Makefile.in 9e816d0323e418fbc0f8b2c05fc14e0b3763d9e8
F Makefile.linux-gcc 7bc79876b875010e8c8f9502eb935ca92aa3c434
F Makefile.msc 71b8b16cf9393f68e2e2035486ca104872558836
F src/printf.c 63e6fb12bbe702dd664dc3703776c090383a5a26
F src/random.c ba2679f80ec82c4190062d756f22d0c358180696
F src/resolve.c b8f7174e5f8c33c44ded3a25a973d0bb89228c20
-F src/rowset.c fb413e336e765481e4d8368377c444904cecdf32
+F src/rowset.c 49eb91c588a2bab36647368e031dc5b66928149d
F src/select.c fd4a7ce2937497181063cfedb92058ac89491a5d
F src/shell.c 14ff7f660530a52b117d110ba3390b7b2eb719b6
F src/sqlite.h.in 9984129d86243424b765fcb3f147c697bd20bb54
F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc
F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e
F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0
-P 9f6f17b5c97c9576c340173d068485fdbfd53253
-R 868dfe1770715db047dd242154ff598b
+P 8cdbe89ac6c22d632f677eb293111b3dbae7d6c1
+R 9629e5ecfb28b4deca7492eeb801c3d3
U drh
-Z b6de1d1adc478f4213336a399ac69fc9
+Z f98c64d26c6e12bfaaf00c7f14039634
** of the first SMALLEST is O(NlogN). Second and subsequent SMALLEST
** primitives are constant time. The cost of DESTROY is O(N).
**
-** There is an added cost of O(N) when switching between TEST and
-** SMALLEST primitives.
+** TEST and SMALLEST may not be used by the same RowSet. This used to
+** be possible, but the feature was not used, so it was removed in order
+** to simplify the code.
*/
#include "sqliteInt.h"
return p;
}
-/*
-** Take all the entries on p->pEntry and on the trees in p->pForest and
-** sort them all together into one big ordered list on p->pEntry.
-**
-** This routine should only be called once in the life of a RowSet.
-*/
-static void rowSetToList(RowSet *p){
-
- /* This routine is called only once */
- assert( p!=0 && (p->rsFlags & ROWSET_NEXT)==0 );
-
- if( (p->rsFlags & ROWSET_SORTED)==0 ){
- p->pEntry = rowSetEntrySort(p->pEntry);
- }
-
- /* While this module could theoretically support it, sqlite3RowSetNext()
- ** is never called after sqlite3RowSetText() for the same RowSet. So
- ** there is never a forest to deal with. Should this change, simply
- ** remove the assert() and the #if 0. */
- assert( p->pForest==0 );
-#if 0
- while( p->pForest ){
- struct RowSetEntry *pTree = p->pForest->pLeft;
- if( pTree ){
- struct RowSetEntry *pHead, *pTail;
- rowSetTreeToList(pTree, &pHead, &pTail);
- p->pEntry = rowSetEntryMerge(p->pEntry, pHead);
- }
- p->pForest = p->pForest->pRight;
- }
-#endif
- p->rsFlags |= ROWSET_NEXT; /* Verify this routine is never called again */
-}
-
/*
** Extract the smallest element from the RowSet.
** Write the element into *pRowid. Return 1 on success. Return
** 0 if the RowSet is already empty.
**
** After this routine has been called, the sqlite3RowSetInsert()
-** routine may not be called again.
+** routine may not be called again.
+**
+** This routine may not be called after sqlite3RowSetTest() has
+** been used. Older versions of RowSet allowed that, but as the
+** capability was not used by the code generator, it was removed
+** for code economy.
*/
int sqlite3RowSetNext(RowSet *p, i64 *pRowid){
assert( p!=0 );
+ assert( p->pForest==0 ); /* Cannot be used with sqlite3RowSetText() */
/* Merge the forest into a single sorted list on first call */
- if( (p->rsFlags & ROWSET_NEXT)==0 ) rowSetToList(p);
+ if( (p->rsFlags & ROWSET_NEXT)==0 ){ /*OPTIMIZATION-IF-FALSE*/
+ if( (p->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/
+ p->pEntry = rowSetEntrySort(p->pEntry);
+ }
+ p->rsFlags |= ROWSET_SORTED|ROWSET_NEXT;
+ }
/* Return the next entry on the list */
if( p->pEntry ){
*pRowid = p->pEntry->v;
p->pEntry = p->pEntry->pRight;
- if( p->pEntry==0 ){
+ if( p->pEntry==0 ){ /*OPTIMIZATION-IF-TRUE*/
+ /* Free memory immediately, rather than waiting on sqlite3_finalize() */
sqlite3RowSetClear(p);
}
return 1;
/* This routine is never called after sqlite3RowSetNext() */
assert( pRowSet!=0 && (pRowSet->rsFlags & ROWSET_NEXT)==0 );
- /* Sort entries into the forest on the first test of a new batch
+ /* Sort entries into the forest on the first test of a new batch.
+ ** To save unnecessary work, only do this when the batch number changes.
*/
- if( iBatch!=pRowSet->iBatch ){
+ if( iBatch!=pRowSet->iBatch ){ /*OPTIMIZATION-IF-FALSE*/
p = pRowSet->pEntry;
if( p ){
struct RowSetEntry **ppPrevTree = &pRowSet->pForest;
- if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){
+ if( (pRowSet->rsFlags & ROWSET_SORTED)==0 ){ /*OPTIMIZATION-IF-FALSE*/
+ /* Only sort the current set of entiries if they need it */
p = rowSetEntrySort(p);
}
for(pTree = pRowSet->pForest; pTree; pTree=pTree->pRight){