Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Overview
Comment: | Code toward having btree cursors persist when their table is written too. Doesn't work properly yet. (CVS 2097) |
---|---|
Downloads: | Tarball | ZIP archive |
Timelines: | family | ancestors | descendants | both | trunk |
Files: | files | file ages | folders |
SHA1: |
5eaa18d43f2996a9d354bb4fb9c81e26 |
User & Date: | danielk1977 2004-11-13 13:19:56.000 |
Context
2004-11-13
| ||
15:59 | More compile-time options for removing components. (CVS 2098) (check-in: dcbc0c22cf user: drh tags: trunk) | |
13:19 | Code toward having btree cursors persist when their table is written too. Doesn't work properly yet. (CVS 2097) (check-in: 5eaa18d43f user: danielk1977 tags: trunk) | |
03:59 | Fix the keyword generator so that it works with SQLITE_OMIT_ALTERTABLE. (CVS 2096) (check-in: 60ace9985d user: drh tags: trunk) | |
Changes
Changes to src/btree.c.
1 2 3 4 5 6 7 8 9 10 11 | /* ** 2004 April 6 ** ** 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. ** ************************************************************************* | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /* ** 2004 April 6 ** ** 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. ** ************************************************************************* ** $Id: btree.c,v 1.217 2004/11/13 13:19:56 danielk1977 Exp $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to ** ** Donald E. Knuth, THE ART OF COMPUTER PROGRAMMING, Volume 3: ** "Sorting And Searching", pages 473-480. Addison-Wesley ** Publishing Company, Reading, Massachusetts. |
︙ | ︙ | |||
3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 | u8 *apDiv[NB]; /* Divider cells in pParent */ int cntNew[NB+2]; /* Index in aCell[] of cell after i-th page */ int szNew[NB+2]; /* Combined size of cells place on i-th page */ u8 **apCell; /* All cells begin balanced */ int *szCell; /* Local size of all cells in apCell[] */ u8 *aCopy[NB]; /* Space for holding data of apCopy[] */ u8 *aSpace; /* Space to hold copies of dividers cells */ /* ** Find the parent page. */ assert( pPage->isInit ); assert( sqlite3pager_iswriteable(pPage->aData) ); pBt = pPage->pBt; | > | 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 | u8 *apDiv[NB]; /* Divider cells in pParent */ int cntNew[NB+2]; /* Index in aCell[] of cell after i-th page */ int szNew[NB+2]; /* Combined size of cells place on i-th page */ u8 **apCell; /* All cells begin balanced */ int *szCell; /* Local size of all cells in apCell[] */ u8 *aCopy[NB]; /* Space for holding data of apCopy[] */ u8 *aSpace; /* Space to hold copies of dividers cells */ BtCursor *pCur; /* ** Find the parent page. */ assert( pPage->isInit ); assert( sqlite3pager_iswriteable(pPage->aData) ); pBt = pPage->pBt; |
︙ | ︙ | |||
3857 3858 3859 3860 3861 3862 3863 | if( rc ) goto balance_cleanup; apNew[i] = pNew; } nNew++; zeroPage(pNew, pageFlags); } | < < < < < < < < < < | 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 | if( rc ) goto balance_cleanup; apNew[i] = pNew; } nNew++; zeroPage(pNew, pageFlags); } /* ** Put the new pages in accending order. This helps to ** keep entries in the disk file in order so that a scan ** of the table is a linear scan through the file. That ** in turn helps the operating system to deliver pages ** from the disk more rapidly. ** |
︙ | ︙ | |||
3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 | nOld>=3 ? pgnoOld[2] : 0, pgnoNew[0], szNew[0], nNew>=2 ? pgnoNew[1] : 0, nNew>=2 ? szNew[1] : 0, nNew>=3 ? pgnoNew[2] : 0, nNew>=3 ? szNew[2] : 0, nNew>=4 ? pgnoNew[3] : 0, nNew>=4 ? szNew[3] : 0, nNew>=5 ? pgnoNew[4] : 0, nNew>=5 ? szNew[4] : 0)); /* ** Evenly distribute the data in apCell[] across the new pages. ** Insert divider cells into pParent as necessary. */ j = 0; for(i=0; i<nNew; i++){ | > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 | nOld>=3 ? pgnoOld[2] : 0, pgnoNew[0], szNew[0], nNew>=2 ? pgnoNew[1] : 0, nNew>=2 ? szNew[1] : 0, nNew>=3 ? pgnoNew[2] : 0, nNew>=3 ? szNew[2] : 0, nNew>=4 ? pgnoNew[3] : 0, nNew>=4 ? szNew[3] : 0, nNew>=5 ? pgnoNew[4] : 0, nNew>=5 ? szNew[4] : 0)); #if 0 /* The following block shows how cells migrated during the balance op. */ if( sqlite3_btree_trace ){ char zBuf[200]; char *zCsr = zBuf; int a, b, c=0, d=0; *zCsr = '\0'; for(a=0; a<nOld; a++){ int nOldCells = apCopy[a]->nCell+apCopy[a]->nOverflow; for(b=0; b<(nOldCells+((a!=nOld-1&&!leafData)?1:0)); b++){ int x = 0; Pgno iNewPage; Pgno iOldPage; int iNewIndex; int iOldIndex; if( b<nOldCells ){ iOldPage = pgnoOld[a]; iOldIndex = b; }else{ iOldPage = pParent->pgno; iOldIndex = idxDiv[a]; } while( cntNew[x]<=c ) x++; if( x>0 && c==cntNew[x-1] && !leafData ){ iNewPage = pParent->pgno; iNewIndex = nxDiv + a; }else{ assert( x<nNew ); iNewPage = pgnoNew[x]; iNewIndex = c-(x>0?cntNew[x-1]:0)-(leafData?0:1); } if( (&zBuf[sizeof(zBuf)])-zCsr > 100 && (1 || iOldPage!=iNewPage || iOldIndex!=iNewIndex) ){ zCsr += sprintf(zCsr, " %d.%d->%d.%d", iOldPage, iOldIndex, iNewPage, iNewIndex); } c++; if( (d==0 && strlen(zBuf)>35) || strlen(zBuf)>60 ){ TRACE(("%s%s\n", d==0?"BALANCE: Cell migration:":"", zBuf)); zCsr = zBuf; d = 1; } } } assert( c==nCell ); if( zCsr!=zBuf ){ TRACE(("%s%s\n", d==0?"BALANCE: Cell migration":"", zBuf)); } } #endif /* If there are other cursors that refer to one of the pages involved ** in the balancing, then adjust these cursors so that they still ** point to the same cells. */ for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ int nCellCnt = 0; int iCell = -1; Pgno pgno = pCur->pPage->pgno; /* If the cursor is not valid, do not do anything with it. */ if( !pCur->isValid ) continue; for(i=0; iCell<0 && i<nOld; i++){ if( pgno==apCopy[i]->pgno ){ iCell = nCellCnt + pCur->idx; break; } nCellCnt += (apCopy[i]->nCell + apCopy[i]->nOverflow) + (leafData?0:1); } if( pgno==pParent->pgno ){ assert( !leafData ); assert( iCell==-1 ); if( pCur->idx>=nxDiv && pCur->idx<(nxDiv+nOld-1) ){ for(i=0; i<=(pCur->idx-nxDiv); i++){ iCell += (apCopy[i]->nCell + apCopy[i]->nOverflow + 1); } } if( pCur->idx>=(nxDiv+nOld) ){ TRACE(("BALANCE: Cursor %p migrates from %d,%d to %d,%d\n", pCur, pgno, pCur->idx, pgno, pCur->idx+(nNew-nOld))); pCur->idx += (nNew-nOld); pCur->info.nSize = 0; } } if( iCell>=0 ){ int idxNew; Pgno pgnoNew; int x = 0; while( cntNew[x]<=iCell ) x++; if( x>0 && !leafData && cntNew[x-1]==iCell ){ /* The cell that pCur points to is a divider cell in pParent. */ pgnoNew = pParent->pgno; idxNew = nxDiv + x-1; }else{ /* The cell that pCur points to is on page apNew[x]. */ idxNew = iCell-(x>0?cntNew[x-1]:0)-((leafData||x==0)?0:1); pgnoNew = apNew[x]->pgno; } TRACE(("BALANCE: Cursor %p migrates from %d,%d to %d,%d\n", pCur, pgno, pCur->idx, pgnoNew, idxNew)); pCur->idx = idxNew; releasePage(pCur->pPage); rc = getPage(pBt, pgnoNew, &pCur->pPage); assert( rc==SQLITE_OK ); pCur->info.nSize = 0; } } /* Free any old pages that were not reused as new pages. */ for(i=nNew; i<nOld; i++){ rc = freePage(apOld[i]); if( rc ) goto balance_cleanup; releasePage(apOld[i]); apOld[i] = 0; } /* ** Evenly distribute the data in apCell[] across the new pages. ** Insert divider cells into pParent as necessary. */ j = 0; for(i=0; i<nNew; i++){ |
︙ | ︙ | |||
4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 | Pgno pgnoChild; /* Page number of the new child page */ Btree *pBt; /* The BTree */ int usableSize; /* Total usable size of a page */ u8 *data; /* Content of the parent page */ u8 *cdata; /* Content of the child page */ int hdr; /* Offset to page header in parent */ int brk; /* Offset to content of first cell in parent */ assert( pPage->pParent==0 ); assert( pPage->nOverflow>0 ); pBt = pPage->pBt; rc = allocatePage(pBt, &pChild, &pgnoChild, pPage->pgno, 0); if( rc ) return rc; assert( sqlite3pager_iswriteable(pChild->aData) ); | > | 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 | Pgno pgnoChild; /* Page number of the new child page */ Btree *pBt; /* The BTree */ int usableSize; /* Total usable size of a page */ u8 *data; /* Content of the parent page */ u8 *cdata; /* Content of the child page */ int hdr; /* Offset to page header in parent */ int brk; /* Offset to content of first cell in parent */ BtCursor *pCur; assert( pPage->pParent==0 ); assert( pPage->nOverflow>0 ); pBt = pPage->pBt; rc = allocatePage(pBt, &pChild, &pgnoChild, pPage->pgno, 0); if( rc ) return rc; assert( sqlite3pager_iswriteable(pChild->aData) ); |
︙ | ︙ | |||
4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 | if( pChild->nOverflow ){ pChild->nFree = 0; } assert( pChild->nCell==pPage->nCell ); zeroPage(pPage, pChild->aData[0] & ~PTF_LEAF); put4byte(&pPage->aData[pPage->hdrOffset+8], pgnoChild); TRACE(("BALANCE: copy root %d into %d\n", pPage->pgno, pChild->pgno)); rc = balance_nonroot(pChild); releasePage(pChild); return rc; } /* ** Decide if the page pPage needs to be balanced. If balancing is | > > > > > > > > > > > > > > > | 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 | if( pChild->nOverflow ){ pChild->nFree = 0; } assert( pChild->nCell==pPage->nCell ); zeroPage(pPage, pChild->aData[0] & ~PTF_LEAF); put4byte(&pPage->aData[pPage->hdrOffset+8], pgnoChild); TRACE(("BALANCE: copy root %d into %d\n", pPage->pgno, pChild->pgno)); /* If there were cursors pointing at this page, point them at the new ** page instead. Decrement the reference count for the old page and ** increment it for the new one. */ for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ if( pCur->pPage==pPage ){ TRACE(("BALANCE: Cursor %p migrates from %d,%d to %d,%d\n", pCur, pPage->pgno, pCur->idx, pChild->pgno, pCur->idx)); releasePage(pCur->pPage); rc = getPage(pBt, pChild->pgno, &pCur->pPage); assert( rc==SQLITE_OK ); } } rc = balance_nonroot(pChild); releasePage(pChild); return rc; } /* ** Decide if the page pPage needs to be balanced. If balancing is |
︙ | ︙ | |||
4179 4180 4181 4182 4183 4184 4185 | */ static int checkReadLocks(Btree *pBt, Pgno pgnoRoot, BtCursor *pExclude){ BtCursor *p; for(p=pBt->pCursor; p; p=p->pNext){ if( p->pgnoRoot!=pgnoRoot || p==pExclude ) continue; if( p->wrFlag==0 ) return SQLITE_LOCKED; if( p->pPage->pgno!=p->pgnoRoot ){ | | | 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 | */ static int checkReadLocks(Btree *pBt, Pgno pgnoRoot, BtCursor *pExclude){ BtCursor *p; for(p=pBt->pCursor; p; p=p->pNext){ if( p->pgnoRoot!=pgnoRoot || p==pExclude ) continue; if( p->wrFlag==0 ) return SQLITE_LOCKED; if( p->pPage->pgno!=p->pgnoRoot ){ /* moveToRoot(p); */ } } return SQLITE_OK; } /* ** Insert a new record into the BTree. The key is given by (pKey,nKey) |
︙ | ︙ | |||
4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 | int rc; int loc; int szNew; MemPage *pPage; Btree *pBt = pCur->pBt; unsigned char *oldCell; unsigned char *newCell = 0; if( pCur->status ){ return pCur->status; /* A rollback destroyed this cursor */ } if( pBt->inTrans!=TRANS_WRITE ){ /* Must start a transaction before doing an insert */ return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; | > | 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 | int rc; int loc; int szNew; MemPage *pPage; Btree *pBt = pCur->pBt; unsigned char *oldCell; unsigned char *newCell = 0; BtCursor *pCur2; if( pCur->status ){ return pCur->status; /* A rollback destroyed this cursor */ } if( pBt->inTrans!=TRANS_WRITE ){ /* Must start a transaction before doing an insert */ return pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR; |
︙ | ︙ | |||
4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 | assert( pPage->leaf ); pCur->idx++; pCur->info.nSize = 0; }else{ assert( pPage->leaf ); } rc = insertCell(pPage, pCur->idx, newCell, szNew, 0); if( rc!=SQLITE_OK ) goto end_insert; rc = balance(pPage); /* sqlite3BtreePageDump(pCur->pBt, pCur->pgnoRoot, 1); */ /* fflush(stdout); */ if( rc==SQLITE_OK ){ | > > > > > > > > > > > > > > > > > > > > | | 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 | assert( pPage->leaf ); pCur->idx++; pCur->info.nSize = 0; }else{ assert( pPage->leaf ); } rc = insertCell(pPage, pCur->idx, newCell, szNew, 0); pCur->isValid = 1; /* If there are other cursors pointing at this page with a BtCursor.idx ** field greater than or equal to 'i', then the cell they refer to ** has been modified or moved within the page. Fix the cursor. */ for(pCur2=pPage->pBt->pCursor; pCur2; pCur2 = pCur2->pNext){ if( pCur2->pPage==pPage ){ if( pCur2->idx>=pCur->idx && pCur!=pCur2 && loc!=0 ){ /* The cell pointed to by pCur2 was shifted one to the right on it's ** page by this Insert(). */ TRACE(("INSERT: Cursor %p migrates from %d,%d to %d,%d\n", pCur2, pPage->pgno, pCur2->idx, pPage->pgno, pCur2->idx+1)); pCur2->idx++; } pCur2->info.nSize = 0; } } if( rc!=SQLITE_OK ) goto end_insert; rc = balance(pPage); /* sqlite3BtreePageDump(pCur->pBt, pCur->pgnoRoot, 1); */ /* fflush(stdout); */ if( rc==SQLITE_OK ){ /* moveToRoot(pCur); */ } end_insert: sqliteFree(newCell); return rc; } /* |
︙ | ︙ | |||
4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 | szNext = cellSizePtr(leafCur.pPage, pNext); assert( MX_CELL_SIZE(pBt)>=szNext+4 ); tempCell = sqliteMallocRaw( MX_CELL_SIZE(pBt) ); if( tempCell==0 ) return SQLITE_NOMEM; rc = insertCell(pPage, pCur->idx, pNext-4, szNext+4, tempCell); if( rc!=SQLITE_OK ) return rc; put4byte(findOverflowCell(pPage, pCur->idx), pgnoChild); rc = balance(pPage); sqliteFree(tempCell); if( rc ) return rc; dropCell(leafCur.pPage, leafCur.idx, szNext); rc = balance(leafCur.pPage); releaseTempCursor(&leafCur); }else{ TRACE(("DELETE: table=%d delete from leaf %d\n", pCur->pgnoRoot, pPage->pgno)); dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell)); rc = balance(pPage); } moveToRoot(pCur); return rc; } /* | > > | 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 | szNext = cellSizePtr(leafCur.pPage, pNext); assert( MX_CELL_SIZE(pBt)>=szNext+4 ); tempCell = sqliteMallocRaw( MX_CELL_SIZE(pBt) ); if( tempCell==0 ) return SQLITE_NOMEM; rc = insertCell(pPage, pCur->idx, pNext-4, szNext+4, tempCell); if( rc!=SQLITE_OK ) return rc; put4byte(findOverflowCell(pPage, pCur->idx), pgnoChild); pCur->isValid = 0; rc = balance(pPage); sqliteFree(tempCell); if( rc ) return rc; dropCell(leafCur.pPage, leafCur.idx, szNext); rc = balance(leafCur.pPage); releaseTempCursor(&leafCur); }else{ TRACE(("DELETE: table=%d delete from leaf %d\n", pCur->pgnoRoot, pPage->pgno)); dropCell(pPage, pCur->idx, cellSizePtr(pPage, pCell)); pCur->isValid = 0; rc = balance(pPage); } moveToRoot(pCur); return rc; } /* |
︙ | ︙ |
Added test/btree8.test.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 | # 2004 Jun 4 # # 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 implements regression tests for SQLite library. The # focus of this script is btree database backend. # # $Id: btree8.test,v 1.1 2004/11/13 13:19:56 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl # Use the SQL interface to create a couple of btree tables, one using # the flags for an SQL table, the other an SQL index. # do_test btree8-1.0 { execsql { CREATE TABLE t1(a INTEGER PRIMARY KEY, b); CREATE INDEX i1 ON t1(b); } } {} set tnum [execsql {SELECT rootpage FROM sqlite_master where type = 'table'}] set inum [execsql {SELECT rootpage FROM sqlite_master where type = 'index'}] db close # Open the database at the btree level and begin a transaction do_test btree8-1.1 { set ::bt [btree_open test.db 100 0] btree_begin_transaction $::bt expr 0 } {0} # For each element in the list $keys, insert an entry into the SQL table # with the corresponding key value. Check that the cursor used to insert # the key is left pointing to it after the insert. Then save this cursor # in the list $csr_list. # set keys [list 3178 4886 719 1690 443 4113 1618 310 1320 2028] set csr_list [list] set testnum 2 foreach key $keys { do_test btree-8-1.$testnum { set csr [btree_cursor $::bt $::tnum 1] btree_insert $csr $key [string repeat a 10] lappend csr_list $csr btree_key $csr } $key incr testnum } btree_commit $::bt # set btree_trace 1 # Now write more entries to the table (and overwriting the ones that exist). # After each write, check that the cursors created above still point to the # same entries. btree_begin_transaction $::bt set ::write_csr [btree_cursor $::bt $::tnum 1] for {set i $testnum} {$i < 5000 && $nErr==0 } {incr i} { set datalen [expr int(rand()*20.0)] do_test btree8-1.$i.1 { btree_insert $::write_csr $i [string repeat x $datalen] } {} set testnum 1 foreach csr $csr_list key $keys { incr testnum do_test btree8-1.$i.$testnum { btree_key $::csr } $key } } btree_close_cursor $::write_csr btree_commit $::bt if {$::nErr>0} { puts $::csr_list } foreach csr $csr_list { btree_close_cursor $csr } set csr_list [list] # Transform the number $num into a string of length $len by repeating the # string representation of the number as many times as necessary. Repeats # are seperated by a '.' character. Eg: # # [num_to_string 456 10] -> "456.456.45" # proc num_to_string {num len} { return [string range [string repeat "$num." $len] 0 [expr $len-1]] } foreach key $keys { lappend skeys [num_to_string $key 20] } # For each element in the list $skeys, insert an entry into the SQL index # with the corresponding key value. Check that the cursor used to insert # the key is left pointing to it after the insert. Then save this cursor # in the list $csr_list. # btree_begin_transaction $::bt set testnum 0 foreach key $skeys { incr testnum do_test btree-8-2.$testnum { set csr [btree_cursor $::bt $::inum 1] btree_insert $csr $key "" lappend csr_list $csr btree_key $csr } $key } btree_commit $::bt # set btree_trace 1 # Now write more entries to the index (and overwrite the ones that exist). # After each write, check that the cursors created above still point to the # same entries. btree_begin_transaction $::bt set ::write_csr [btree_cursor $::bt $::inum 1] for {set i $testnum} {$i < 5000 && $nErr==0 } {incr i} { set skey [num_to_string $i 20] do_test btree8-2.$i.1 { btree_insert $::write_csr $skey "" } {} set testnum 1 foreach csr $csr_list key $skeys { incr testnum do_test btree8-2.$i.$testnum { btree_key $::csr } $key } } btree_close_cursor $::write_csr btree_commit $::bt if {$::nErr>0} { puts $::csr_list } foreach csr $csr_list { btree_close_cursor $csr } set csr_list [list] finish_test |
Changes to test/quick.test.
1 2 3 4 5 6 7 8 9 10 11 12 | # 2001 September 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 runs all tests. # | | | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # 2001 September 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 runs all tests. # # $Id: quick.test,v 1.33 2004/11/13 13:19:56 danielk1977 Exp $ set testdir [file dirname $argv0] source $testdir/tester.tcl rename finish_test really_finish_test proc finish_test {} {} set ISQUICK 1 |
︙ | ︙ | |||
29 30 31 32 33 34 35 36 37 38 39 40 41 42 | crash.test malloc.test memleak.test misuse.test quick.test utf16.test autovacuum_crash.test } if {[sqlite3 -has-codec]} { # lappend EXCLUDE \ # conflict.test } | > | 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | crash.test malloc.test memleak.test misuse.test quick.test utf16.test autovacuum_crash.test btree8.test } if {[sqlite3 -has-codec]} { # lappend EXCLUDE \ # conflict.test } |
︙ | ︙ |