mirror of https://github.com/sqlite/sqlite
71 lines
1.8 KiB
Plaintext
71 lines
1.8 KiB
Plaintext
How to do a B-Tree insert:
|
|
|
|
insert(data){
|
|
create a new cursor
|
|
move cursor to the entry nearest data
|
|
if( cursor.key == keyof(data) ){
|
|
replace cursor.data with dataof(data)
|
|
return
|
|
}
|
|
childpg = NULL
|
|
add_to_page(cursor, data+childpg)
|
|
delete the cursor
|
|
}
|
|
|
|
add_to_page(cursor, data+childpg ){
|
|
childpg->parent = cursor.page
|
|
if( data+childpg fits on cursor.page ){
|
|
insert data+childpg at cursor
|
|
return
|
|
}
|
|
if( page==root ){
|
|
split page+(data+childpg) into newpage1, center, newpage2
|
|
cursor.page = &newpage1 + center + &newpage2;
|
|
newpage1->parent = cursor.page
|
|
newpage2->parent = cursor.page
|
|
return
|
|
}
|
|
if( move_some_data_left || move_some_data_right ){
|
|
insert data+childpg at cursor
|
|
return
|
|
}
|
|
split page+(data+childpg) into page, center, newpage
|
|
newpage->parent = page->parent
|
|
move cursor to insertion point of center in parent page.
|
|
add_to_page(cursor, center, (newpage));
|
|
}
|
|
|
|
How to do a B-Tree delete:
|
|
|
|
delete(entry){
|
|
if( entry is not a leaf ){
|
|
p = predecessor of entry
|
|
// note: if entry is not a leaf then p must
|
|
// exist and must be a leaf
|
|
free(entry.overflowptr)
|
|
resize entry so that is is big enough to hold p.payload
|
|
entry.payload = p.payload
|
|
entry.overflowptr = p.overflowptr
|
|
p.overflowptr = NULL
|
|
delete(p)
|
|
return
|
|
}
|
|
unlink entry from its page
|
|
refill(page containing entry)
|
|
}
|
|
|
|
refill(page){
|
|
if( page is more than half full ) return
|
|
if( page is the root and contains no entries ){
|
|
copy the one child page into this page thus reducing
|
|
the height of the tree by one.
|
|
return
|
|
}
|
|
if( able to merge page with neighbors ){
|
|
do the merge
|
|
refill(parent page)
|
|
return
|
|
}
|
|
borrow entrys from neighbors
|
|
}
|