More BTree tests and a few bug fixes. (CVS 231)
FossilOrigin-Name: 2c9127943cd5a541613924d2df773c4e8df4c1a6
This commit is contained in:
parent
dd79342e87
commit
9ca7d3b15d
14
manifest
14
manifest
@ -1,5 +1,5 @@
|
||||
C Got\sa\slot\sof\sBTree\stests\sworking.\sStill\slots\smore\sneeded.\s(CVS\s230)
|
||||
D 2001-06-28T01:54:48
|
||||
C More\sBTree\stests\sand\sa\sfew\sbug\sfixes.\s(CVS\s231)
|
||||
D 2001-06-28T11:50:22
|
||||
F COPYRIGHT 74a8a6531a42e124df07ab5599aad63870fa0bd4
|
||||
F Makefile.in 63bc9a6a39b7160ce8d2392ae74eb4ca4ca84c6e
|
||||
F README 51f6a4e7408b34afa5bc1c0485f61b6a4efb6958
|
||||
@ -12,7 +12,7 @@ F notes/notes1.txt b7c0812b704a022e88c621146ae50955c923d464
|
||||
F notes/notes2.txt 7e3fafd5e25906c1fe1e95f13b089aa398ca403e
|
||||
F notes/notes3.txt 985bf688b59f1f52bfe6e4b1f896efdeffac1432
|
||||
F src/TODO 38a68a489e56e9fd4a96263e0ff9404a47368ad4
|
||||
F src/btree.c d55ba210df7625c1edd62a4631bb6d322d9b68ca
|
||||
F src/btree.c 19c77416536851667983be43af62c631fb395a92
|
||||
F src/btree.h d327e9ad671d41d41aa2dd376c9230c8d2167c8e
|
||||
F src/build.c 4f6a2d551c56342cd4a0420654835be3ad179651
|
||||
F src/dbbe.c b18259f99d87240cbe751021cf14dd3aa83a48af
|
||||
@ -53,7 +53,7 @@ F src/vdbe.c f93be4414ba892df9c5589815d2a57c1fb12c820
|
||||
F src/vdbe.h dc1205da434c6a9da03b5d6b089270bbc8e6d437
|
||||
F src/where.c 0c542fc44bd85152dfb8507862cfe2e60c629e9f
|
||||
F test/all.test 21d55a97e39e7ec5776751dc9dd8b1b51ef4a048
|
||||
F test/btree.test dc07031aaa753fb230b0d30166b5f00e467afa49
|
||||
F test/btree.test 6299ba795987b28fddd62e0869211c97ba311bcc
|
||||
F test/copy.test b77a1214bd7756f2849d5c4fa6e715c0ff0c34eb
|
||||
F test/dbbe.test a022fe2d983848f786e17ef1fc6809cfd37fb02c
|
||||
F test/delete.test 50b9b1f06c843d591741dba7869433a105360dbf
|
||||
@ -108,7 +108,7 @@ F www/opcode.tcl cb3a1abf8b7b9be9f3a228d097d6bf8b742c2b6f
|
||||
F www/sqlite.tcl cb0d23d8f061a80543928755ec7775da6e4f362f
|
||||
F www/tclsqlite.tcl 06f81c401f79a04f2c5ebfb97e7c176225c0aef2
|
||||
F www/vdbe.tcl 0c8aaa529dd216ccbf7daaabd80985e413d5f9ad
|
||||
P 6b9b298b2846146b95d7df7f423867976bafa390
|
||||
R 352f1f1690fcb389985c90a80a4e8ed3
|
||||
P 9cfeeb5896d2a17c8c7904136d346a6245c9e497
|
||||
R 143955071809794a38422b6ba77e94d9
|
||||
U drh
|
||||
Z 2f00c60c42da64c07beeccb2fde6cfaa
|
||||
Z c80cdc0e1cd9e727a881d0fcbcd59b2a
|
||||
|
@ -1 +1 @@
|
||||
9cfeeb5896d2a17c8c7904136d346a6245c9e497
|
||||
2c9127943cd5a541613924d2df773c4e8df4c1a6
|
22
src/btree.c
22
src/btree.c
@ -21,7 +21,7 @@
|
||||
** http://www.hwaci.com/drh/
|
||||
**
|
||||
*************************************************************************
|
||||
** $Id: btree.c,v 1.16 2001/06/28 01:54:48 drh Exp $
|
||||
** $Id: btree.c,v 1.17 2001/06/28 11:50:22 drh Exp $
|
||||
**
|
||||
** This file implements a external (disk-based) database using BTrees.
|
||||
** For a detailed discussion of BTrees, refer to
|
||||
@ -1623,6 +1623,7 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){
|
||||
int usedPerPage; /* Memory needed for each page */
|
||||
int freePerPage; /* Average free space per page */
|
||||
int totalSize; /* Total bytes for all cells */
|
||||
MemPage *extraUnref = 0; /* A page that needs to be unref-ed */
|
||||
Pgno pgno; /* Page number */
|
||||
Cell *apCell[MX_CELL*3+5]; /* All cells from pages being balanceed */
|
||||
int szCell[MX_CELL*3+5]; /* Local size of all cells */
|
||||
@ -1693,6 +1694,8 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){
|
||||
if( pCur ){
|
||||
sqlitepager_unref(pCur->pPage);
|
||||
pCur->pPage = pChild;
|
||||
}else{
|
||||
extraUnref = pChild;
|
||||
}
|
||||
zeroPage(pPage);
|
||||
pPage->u.hdr.rightChild = pgnoChild;
|
||||
@ -1767,7 +1770,7 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){
|
||||
*/
|
||||
if( pCur ){
|
||||
iCur = pCur->idx;
|
||||
for(i=0; idxDiv[i]<idx; i++){
|
||||
for(i=0; i<nDiv && idxDiv[i]<idx; i++){
|
||||
iCur += apOld[i]->nCell + 1;
|
||||
}
|
||||
sqlitepager_unref(pCur->pPage);
|
||||
@ -1888,6 +1891,9 @@ static int balance(Btree *pBt, MemPage *pPage, BtCursor *pCur){
|
||||
** Cleanup before returning.
|
||||
*/
|
||||
balance_cleanup:
|
||||
if( extraUnref ){
|
||||
sqlitepager_unref(extraUnref);
|
||||
}
|
||||
for(i=0; i<nOld; i++){
|
||||
if( apOld[i]!=&aOld[i] ) sqlitepager_unref(apOld[i]);
|
||||
}
|
||||
@ -1975,13 +1981,13 @@ int sqliteBtreeDelete(BtCursor *pCur){
|
||||
pCell = pPage->apCell[pCur->idx];
|
||||
pgnoChild = pCell->h.leftChild;
|
||||
clearCell(pCur->pBt, pCell);
|
||||
dropCell(pPage, pCur->idx, cellSize(pCell));
|
||||
if( pgnoChild ){
|
||||
/*
|
||||
** If the entry we just deleted is not a leaf, then we've left a
|
||||
** hole in an internal page. We have to fill the hole by moving
|
||||
** in a cell from a leaf. The next Cell after the one just deleted
|
||||
** is guaranteed to exist and to be a leaf so we can use it.
|
||||
** If the entry we are about to delete is not a leaf so if we do not
|
||||
** do something we will leave a hole on an internal page.
|
||||
** We have to fill the hole by moving in a cell from a leaf. The
|
||||
** next Cell after the one to be deleted is guaranteed to exist and
|
||||
** to be a leaf so we can use it.
|
||||
*/
|
||||
BtCursor leafCur;
|
||||
Cell *pNext;
|
||||
@ -1991,6 +1997,7 @@ int sqliteBtreeDelete(BtCursor *pCur){
|
||||
if( rc!=SQLITE_OK ){
|
||||
return SQLITE_CORRUPT;
|
||||
}
|
||||
dropCell(pPage, pCur->idx, cellSize(pCell));
|
||||
pNext = leafCur.pPage->apCell[leafCur.idx];
|
||||
szNext = cellSize(pNext);
|
||||
pNext->h.leftChild = pgnoChild;
|
||||
@ -2002,6 +2009,7 @@ int sqliteBtreeDelete(BtCursor *pCur){
|
||||
rc = balance(pCur->pBt, leafCur.pPage, 0);
|
||||
releaseTempCursor(&leafCur);
|
||||
}else{
|
||||
dropCell(pPage, pCur->idx, cellSize(pCell));
|
||||
rc = balance(pCur->pBt, pPage, pCur);
|
||||
pCur->bSkipNext = 1;
|
||||
}
|
||||
|
220
test/btree.test
220
test/btree.test
@ -23,7 +23,7 @@
|
||||
# This file implements regression tests for SQLite library. The
|
||||
# focus of this script is btree database backend
|
||||
#
|
||||
# $Id: btree.test,v 1.3 2001/06/28 01:54:50 drh Exp $
|
||||
# $Id: btree.test,v 1.4 2001/06/28 11:50:22 drh Exp $
|
||||
|
||||
|
||||
set testdir [file dirname $argv0]
|
||||
@ -791,6 +791,224 @@ do_test btree-9.7 {
|
||||
lindex [btree_pager_stats $::b1] 1
|
||||
} {0}
|
||||
|
||||
# Create a tree of depth two. That is, there is a single divider entry
|
||||
# on the root pages and two leaf pages. Then delete the divider entry
|
||||
# see what happens.
|
||||
#
|
||||
do_test btree-10.1 {
|
||||
btree_begin_transaction $::b1
|
||||
btree_drop_table $::b1 2
|
||||
lindex [btree_pager_stats $::b1] 1
|
||||
} {1}
|
||||
do_test btree-10.2 {
|
||||
set ::c1 [btree_cursor $::b1 2]
|
||||
lindex [btree_pager_stats $::b1] 1
|
||||
} {2}
|
||||
do_test btree-10.3 {
|
||||
for {set i 1} {$i<=20} {incr i} {
|
||||
set key [format %03d $i]
|
||||
set data "*** $key *** $key *** $key *** $key ***"
|
||||
btree_insert $::c1 $key $data
|
||||
}
|
||||
select_keys $::c1
|
||||
} {001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020}
|
||||
#btree_page_dump $::b1 7
|
||||
#btree_page_dump $::b1 2
|
||||
#btree_page_dump $::b1 6
|
||||
do_test btree-10.4 {
|
||||
btree_move_to $::c1 011
|
||||
btree_delete $::c1
|
||||
select_keys $::c1
|
||||
} {001 002 003 004 005 006 007 008 009 010 012 013 014 015 016 017 018 019 020}
|
||||
#btree_page_dump $::b1 2
|
||||
for {set i 1} {$i<=20} {incr i} {
|
||||
do_test btree-10.5.$i {
|
||||
btree_move_to $::c1 [format %03d $i]
|
||||
lindex [btree_pager_stats $::b1] 1
|
||||
} {2}
|
||||
}
|
||||
|
||||
# Create a tree with lots more pages
|
||||
#
|
||||
catch {unset ::data}
|
||||
catch {unset ::key}
|
||||
for {set i 21} {$i<=1000} {incr i} {
|
||||
do_test btree-11.1.$i.1 {
|
||||
set key [format %03d $i]
|
||||
set ::data "*** $key *** $key *** $key *** $key ***"
|
||||
btree_insert $::c1 $key $data
|
||||
btree_key $::c1
|
||||
} [format %03d $i]
|
||||
do_test btree-11.1.$i.2 {
|
||||
btree_data $::c1
|
||||
} $::data
|
||||
set ::key [format %03d [expr {$i/2}]]
|
||||
if {$::key=="011"} {set ::key 010}
|
||||
do_test btree-11.1.$i.3 {
|
||||
btree_move_to $::c1 $::key
|
||||
btree_key $::c1
|
||||
} $::key
|
||||
}
|
||||
catch {unset ::data}
|
||||
catch {unset ::key}
|
||||
|
||||
# Make sure our reference count is still correct.
|
||||
#
|
||||
do_test btree-11.2 {
|
||||
btree_close_cursor $::c1
|
||||
lindex [btree_pager_stats $::b1] 1
|
||||
} {1}
|
||||
do_test btree-11.3 {
|
||||
set ::c1 [btree_cursor $::b1 2]
|
||||
lindex [btree_pager_stats $::b1] 1
|
||||
} {2}
|
||||
#btree_page_dump $::b1 2
|
||||
|
||||
# Delete the dividers on the root page
|
||||
#
|
||||
do_test btree-11.4 {
|
||||
btree_move_to $::c1 257
|
||||
btree_delete $::c1
|
||||
btree_next $::c1
|
||||
btree_key $::c1
|
||||
} {258}
|
||||
do_test btree-11.4.1 {
|
||||
btree_move_to $::c1 256
|
||||
btree_key $::c1
|
||||
} {256}
|
||||
do_test btree-11.4.2 {
|
||||
btree_move_to $::c1 258
|
||||
btree_key $::c1
|
||||
} {258}
|
||||
do_test btree-11.4.3 {
|
||||
btree_move_to $::c1 259
|
||||
btree_key $::c1
|
||||
} {259}
|
||||
do_test btree-11.4.4 {
|
||||
btree_move_to $::c1 257
|
||||
btree_key $::c1
|
||||
} {256}
|
||||
do_test btree-11.5 {
|
||||
btree_move_to $::c1 513
|
||||
btree_delete $::c1
|
||||
btree_next $::c1
|
||||
btree_key $::c1
|
||||
} {514}
|
||||
do_test btree-11.5.1 {
|
||||
btree_move_to $::c1 512
|
||||
btree_key $::c1
|
||||
} {512}
|
||||
do_test btree-11.5.2 {
|
||||
btree_move_to $::c1 514
|
||||
btree_key $::c1
|
||||
} {514}
|
||||
do_test btree-11.5.3 {
|
||||
btree_move_to $::c1 515
|
||||
btree_key $::c1
|
||||
} {515}
|
||||
do_test btree-11.5.4 {
|
||||
btree_move_to $::c1 513
|
||||
btree_key $::c1
|
||||
} {512}
|
||||
do_test btree-11.6 {
|
||||
btree_move_to $::c1 769
|
||||
btree_delete $::c1
|
||||
btree_next $::c1
|
||||
btree_key $::c1
|
||||
} {770}
|
||||
do_test btree-11.6.1 {
|
||||
btree_move_to $::c1 768
|
||||
btree_key $::c1
|
||||
} {768}
|
||||
do_test btree-11.6.2 {
|
||||
btree_move_to $::c1 771
|
||||
btree_key $::c1
|
||||
} {771}
|
||||
do_test btree-11.6.3 {
|
||||
btree_move_to $::c1 770
|
||||
btree_key $::c1
|
||||
} {770}
|
||||
do_test btree-11.6.4 {
|
||||
btree_move_to $::c1 769
|
||||
btree_key $::c1
|
||||
} {768}
|
||||
#btree_page_dump $::b1 2
|
||||
#btree_page_dump $::b1 25
|
||||
|
||||
# Change the data on an intermediate node such that the node becomes overfull
|
||||
# and has to split. We happen to know that intermediate nodes exist on
|
||||
# 337, 401 and 465 by the btree_page_dumps above
|
||||
#
|
||||
catch {unset ::data}
|
||||
set ::data {This is going to be a very long data segment}
|
||||
append ::data $::data
|
||||
append ::data $::data
|
||||
do_test btree-12.1 {
|
||||
btree_insert $::c1 337 $::data
|
||||
btree_data $::c1
|
||||
} $::data
|
||||
do_test btree-12.2 {
|
||||
btree_insert $::c1 401 $::data
|
||||
btree_data $::c1
|
||||
} $::data
|
||||
do_test btree-12.3 {
|
||||
btree_insert $::c1 465 $::data
|
||||
btree_data $::c1
|
||||
} $::data
|
||||
do_test btree-12.4 {
|
||||
btree_move_to $::c1 337
|
||||
btree_key $::c1
|
||||
} {337}
|
||||
do_test btree-12.5 {
|
||||
btree_data $::c1
|
||||
} $::data
|
||||
do_test btree-12.6 {
|
||||
btree_next $::c1
|
||||
btree_key $::c1
|
||||
} {338}
|
||||
do_test btree-12.7 {
|
||||
btree_move_to $::c1 464
|
||||
btree_key $::c1
|
||||
} {464}
|
||||
do_test btree-12.8 {
|
||||
btree_next $::c1
|
||||
btree_data $::c1
|
||||
} $::data
|
||||
do_test btree-12.9 {
|
||||
btree_next $::c1
|
||||
btree_key $::c1
|
||||
} {466}
|
||||
do_test btree-12.10 {
|
||||
btree_move_to $::c1 400
|
||||
btree_key $::c1
|
||||
} {400}
|
||||
do_test btree-12.11 {
|
||||
btree_next $::c1
|
||||
btree_data $::c1
|
||||
} $::data
|
||||
do_test btree-12.12 {
|
||||
btree_next $::c1
|
||||
btree_key $::c1
|
||||
} {402}
|
||||
|
||||
# To Do:
|
||||
#
|
||||
# 1. Do some deletes from the 3-layer tree
|
||||
# 2. Commit and reopen the database
|
||||
# 3. Read every 15th entry and make sure it works
|
||||
# 4. Implement btree_sanity and put it throughout this script
|
||||
#
|
||||
|
||||
do_test btree-10.98 {
|
||||
btree_close_cursor $::c1
|
||||
lindex [btree_pager_stats $::b1] 1
|
||||
} {1}
|
||||
do_test btree-10.99 {
|
||||
btree_rollback $::b1
|
||||
lindex [btree_pager_stats $::b1] 1
|
||||
} {0}
|
||||
btree_pager_ref_dump $::b1
|
||||
|
||||
do_test btree-99.1 {
|
||||
btree_close $::b1
|
||||
} {}
|
||||
|
Loading…
Reference in New Issue
Block a user