Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Enhance kvmem to honor the SQLITE4_KVOPEN_NO_TRANSACTIONS flag. This makes kvmem significantly faster when used to implement ORDER BY with LIMIT. |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
3cb223f975a537145a10d1781e920ecc |
User & Date: | drh 2013-07-31 15:32:34.957 |
Context
2013-07-31
| ||
17:43 | Extra tests for sqlite_kvstore. check-in: 9ce1a04efd user: dan tags: trunk | |
15:32 | Enhance kvmem to honor the SQLITE4_KVOPEN_NO_TRANSACTIONS flag. This makes kvmem significantly faster when used to implement ORDER BY with LIMIT. check-in: 3cb223f975 user: drh tags: trunk | |
14:38 | Allow writing to the sqlite_kvstore if "PRAGMA writable_schema" is set. check-in: 874278817a user: dan tags: trunk | |
Changes
Changes to src/kvmem.c.
︙ | ︙ | |||
251 252 253 254 255 256 257 258 259 260 261 262 263 264 | static void kvmemClearTree(sqlite4_env *pEnv, KVMemNode *pNode){ if( pNode==0 ) return; kvmemClearTree(pEnv, pNode->pBefore); kvmemClearTree(pEnv, pNode->pAfter); kvmemNodeUnref(pEnv, pNode); } /* ** End of utilities *************************************************************************** ** Low-level operations on the tree */ /* Find the first node (the one with the smallest key). | > > > > > > | 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | static void kvmemClearTree(sqlite4_env *pEnv, KVMemNode *pNode){ if( pNode==0 ) return; kvmemClearTree(pEnv, pNode->pBefore); kvmemClearTree(pEnv, pNode->pAfter); kvmemNodeUnref(pEnv, pNode); } /* ** Return true if transactions are preserved */ #define kvmemTransactional(P) \ (((P)->openFlags & SQLITE4_KVOPEN_NO_TRANSACTIONS)==0) /* ** End of utilities *************************************************************************** ** Low-level operations on the tree */ /* Find the first node (the one with the smallest key). |
︙ | ︙ | |||
334 335 336 337 338 339 340 | assert( p->base.iTransLevel>=2 ); pNode = sqlite4_malloc(p->base.pEnv, sizeof(*pNode)+nKey-2 ); if( pNode ){ memset(pNode, 0, sizeof(*pNode)); memcpy(pNode->aKey, aKey, nKey); pNode->nKey = nKey; pNode->nRef = 1; | > | | | | | | > | 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 | assert( p->base.iTransLevel>=2 ); pNode = sqlite4_malloc(p->base.pEnv, sizeof(*pNode)+nKey-2 ); if( pNode ){ memset(pNode, 0, sizeof(*pNode)); memcpy(pNode->aKey, aKey, nKey); pNode->nKey = nKey; pNode->nRef = 1; if( kvmemTransactional(p) ){ pChng = kvmemNewChng(p, pNode); if( pChng==0 ){ sqlite4_free(p->base.pEnv, pNode); pNode = 0; } assert( pChng==0 || pChng->pData==0 ); } } return pNode; } #ifdef SQLITE4_DEBUG /* ** Return the number of times that node pNode occurs in the sub-tree |
︙ | ︙ | |||
483 484 485 486 487 488 489 490 491 492 493 494 495 496 | } static int kvmemCommitPhaseTwo(KVStore *pKVStore, int iLevel){ KVMem *p = (KVMem*)pKVStore; assert( p->iMagicKVMemBase==SQLITE4_KVMEMBASE_MAGIC ); assert( iLevel>=0 ); assert( iLevel<p->base.iTransLevel ); assertUpPointers(p->pRoot); while( p->base.iTransLevel>iLevel && p->base.iTransLevel>1 ){ KVMemChng *pChng, *pNext; if( iLevel<2 ){ for(pChng=p->apLog[p->base.iTransLevel-2]; pChng; pChng=pNext){ KVMemNode *pNode = pChng->pNode; if( pNode->pData ){ | > | 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 | } static int kvmemCommitPhaseTwo(KVStore *pKVStore, int iLevel){ KVMem *p = (KVMem*)pKVStore; assert( p->iMagicKVMemBase==SQLITE4_KVMEMBASE_MAGIC ); assert( iLevel>=0 ); assert( iLevel<p->base.iTransLevel ); assertUpPointers(p->pRoot); if( !kvmemTransactional(p) ) return SQLITE4_OK; while( p->base.iTransLevel>iLevel && p->base.iTransLevel>1 ){ KVMemChng *pChng, *pNext; if( iLevel<2 ){ for(pChng=p->apLog[p->base.iTransLevel-2]; pChng; pChng=pNext){ KVMemNode *pNode = pChng->pNode; if( pNode->pData ){ |
︙ | ︙ | |||
536 537 538 539 540 541 542 543 544 545 546 547 548 549 | ** After this routine returns successfully, the transaction level will be ** equal to iLevel. */ static int kvmemRollback(KVStore *pKVStore, int iLevel){ KVMem *p = (KVMem*)pKVStore; assert( p->iMagicKVMemBase==SQLITE4_KVMEMBASE_MAGIC ); assert( iLevel>=0 ); while( p->base.iTransLevel>iLevel && p->base.iTransLevel>1 ){ KVMemChng *pChng, *pNext; for(pChng=p->apLog[p->base.iTransLevel-2]; pChng; pChng=pNext){ KVMemNode *pNode = pChng->pNode; if( pChng->pData || pChng->oldTrans>0 ){ kvmemDataUnref(p->base.pEnv, pNode->pData); pNode->pData = pChng->pData; | > | 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 | ** After this routine returns successfully, the transaction level will be ** equal to iLevel. */ static int kvmemRollback(KVStore *pKVStore, int iLevel){ KVMem *p = (KVMem*)pKVStore; assert( p->iMagicKVMemBase==SQLITE4_KVMEMBASE_MAGIC ); assert( iLevel>=0 ); if( !kvmemTransactional(p) ) return SQLITE4_OK; while( p->base.iTransLevel>iLevel && p->base.iTransLevel>1 ){ KVMemChng *pChng, *pNext; for(pChng=p->apLog[p->base.iTransLevel-2]; pChng; pChng=pNext){ KVMemNode *pNode = pChng->pNode; if( pChng->pData || pChng->oldTrans>0 ){ kvmemDataUnref(p->base.pEnv, pNode->pData); pNode->pData = pChng->pData; |
︙ | ︙ | |||
623 624 625 626 627 628 629 | if( pNew==0 ) goto KVMemReplace_nomem; pNew->pUp = pNode; break; } }else{ if( pNode->mxTrans==p->base.iTransLevel ){ kvmemDataUnref(p->base.pEnv, pNode->pData); | | | 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 | if( pNew==0 ) goto KVMemReplace_nomem; pNew->pUp = pNode; break; } }else{ if( pNode->mxTrans==p->base.iTransLevel ){ kvmemDataUnref(p->base.pEnv, pNode->pData); }else if( kvmemTransactional(p) ){ pChng = kvmemNewChng(p, pNode); if( pChng==0 ) goto KVMemReplace_nomem; } pNode->pData = pData; return SQLITE4_OK; } } |
︙ | ︙ | |||
826 827 828 829 830 831 832 | pCur = (KVMemCursor*)pKVCursor; assert( pCur->iMagicKVMemCur==SQLITE4_KVMEMCUR_MAGIC ); p = pCur->pOwner; assert( p->iMagicKVMemBase==SQLITE4_KVMEMBASE_MAGIC ); assert( p->base.iTransLevel>=2 ); pNode = pCur->pNode; if( pNode==0 ) return SQLITE4_OK; | > > > | > | | 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 | pCur = (KVMemCursor*)pKVCursor; assert( pCur->iMagicKVMemCur==SQLITE4_KVMEMCUR_MAGIC ); p = pCur->pOwner; assert( p->iMagicKVMemBase==SQLITE4_KVMEMBASE_MAGIC ); assert( p->base.iTransLevel>=2 ); pNode = pCur->pNode; if( pNode==0 ) return SQLITE4_OK; if( !kvmemTransactional(p) ){ pCur->pNode = 0; kvmemRemoveNode(p, pNode); }else if( pNode->pData==0 ){ /* no-op */ }else if( pNode->mxTrans<p->base.iTransLevel ){ pChng = kvmemNewChng(p, pNode); if( pChng==0 ) return SQLITE4_NOMEM; assert( pNode->pData==0 ); }else{ kvmemDataUnref(pCur->base.pEnv, pNode->pData); pNode->pData = 0; } |
︙ | ︙ |