CPSC 461: Copyright © 2002 Katrin Becker 1998-2002 Last Modified August 4, 2000 05:34 PM

slides not complete, sorry

B-Trees and Others

Binary Search Trees

you already know this

AVL Trees

height balanced tree where difference in height between any two subtrees is no more than one

Problem:

binary searches require too many seeks in a large file
keeping an index sorted is expensive

- can solve second problem by using a binary tree structure for the index - but the structure can still easily degrade to a linear list so...

try an AVL tree.

- that leaves problem 1... answer paging - divide the tree into subtrees and keep entire subtrees on separate pages
Example: let’s say each page holds 7 nodes - notice the difference in the number of seeks
this creates a new problem though : when we must re-organize the tree we may end up having to reorganize across pages

B-TREES

- build the tree from the leaves instead of the root
- a node (page) consists of a sequence of keys and a set of pointers
- each node contains an ordered list of keys and some pointers - in fact, N keys and N+1 pointers
- the number of pointers defines the order of the tree
- so an order 8 B-tree means 7 keys and 8 pointers
- when a leaf is full and a new key is added, the leaf must be split and the keys are re-distributed as evenly as possible
- when we must split a leaf, we write it to a temporary structure the same as the leaf but with one more key; we copy the full leaf and the new key in their correct order to the temporary structure; split it in two and move one of the middle keys upward (promote it) to the parent node (we use the smallest key of the right leaf
- notice that the tree always remains balanced with respect to height
- notice also that the keys that get promoted are the kinds of keys we would want in a root - they are good separators
B-trees can be built with fixed length records: keep the following information in the record:

KEYS, POINTERS, keycount

this is a paged tree where each page is one record:

keycount | key array | child array

SEARCHING A B-TREE:
RRN = relative record number of the node/page (each node is one record in the index file)
found_RRN = RRN of record(page) where key was found or should be placed
found_POS = position within key array where key was found or should go
FOUND = Boolean true if match; false if no match (i.e. key could be inserted)
function search (RRN, Key, found_RRN, found_POS) : FOUND

if RRN == nil then // hit leaf - go back

return (false)

else

read_page (RRN, PAGE);
look through PAGE for KEY
// find key or place where key should go in the page
if KEY == PAGE.key[i] or KEY < PAGE.key[i] then

POS := i

if KEY == PAGE.key[i] then

found_RRN := RRN
found_POS := POS
return (true)

else // follow appropriate child down to next level

return ( search (PAGE.child[POS], KEY, found_RRN,

found_POS))

end search;
if we are to do an insertion we must first determine that the key doesn’t already exist so the first part of the insertion algorithm is the same as for a search (see slides 5 & 6)
As with binary trees, most algorithms applied to B-trees are recursive
With insertion the routine descends until the leaf is reached; the insertion is done; if the leaf must be split it is and the key to promote is passed back to the previous call to insert (see slide 7)
this still leaves us with a few loose ends
1. Creating the first page (original root)
2. Keeping track of the root when it splits itself (see slide 8)
FORMAL DEFINITION OF A B-TREE:
1. The Order (m) is the maximum number of descendants of a node (= # of pointers).
2. Every node except the root and the leaves must have at least descendants.
3. The root must have at least 2 descendants (except if it is a leaf).
4. All leaves are at the same level.
5. An internal node with x descendants must have x-1 keys.
6. A leaf must have a minimum of - 1 keys if it is not also the root.
A note on Terminology:
order of the tree: some say this is the minimum # of keys a tree can have

some say (including Knuth) it is the maximum # of descendants

leaf : text says lowest existing level; Knuth says it’s one below that
Let’s look at worst case behaviour:
The # descendants at any given level is 1 more than all those in the tree above AND at the current level (like binary trees)
EXAMPLE: we have 1,000,000 keys and a tree of order 512 (means 511 keys per page). We need to calculate the minimum possible keys per page to get worst case behaviour:
min # descendants = 2 X d-1 where d is the depth; m = # descendants
A tree with N keys can have N + 1 descendants from its leaf level, so

N + 1 2 X d-1 if we solve for d

d 1 + log ((N + 1) / 2)

This is the upper bound for the depth; if we have 1,000,000 keys and the tree is order 512, we get

d 1 + log256 500,000.5

= d 3.37

which gives us a maximum of three disk accesses!

Deletion, Redistribution, and Concatenation

Remember the rule that says we must maintain a minimum number of keys in a leaf - 1. If we delete keys, sooner or later we will violate this rule so we have to do something about it. (See slides 9 & 10)
case 1 is simple - there’s nothing to do but delete the key
case 2 - delete the root this is tricky so
make a new rule : only delete from leaves

- to make the root into a leaf, swap the key to be deleted with its immediate successor, then delete the leaf key

case 3 - delete a key that causes underflow in the page
since the next page is a sibling which has enough keys, just re-distribute the keys remembering to adjust the parent
case 4 - delete a key that causes underflow but we can’t re-distribute
glue two pages back together (concatenate) and propagate the action upwards

Deletion Rules

1. If the key is not a leaf make it so
2. Delete the key
3. If the leaf is now too small then

if the leaf is too small by 1 then

if the sibling has > min # of keys then

re-distribute

if the sibling has min # keys then

concatenate
apply #3 to the parent

4. If the last key of the root is deleted, then height = height - 1
Redistribution has strictly local effects - it does not propagate up or down
Redistribution involves siblings ONLY (why not cousins? - watch the grandparents)
Redistribution has no other set rules about how to redistribute - usually though we try to spread the keys evenly
What if we redistribute during insertion? What can we gain? (Better use of space i.e. a fuller tree)
B*Trees are B Trees where we postpone splitting by redistribution and when two pages are full and we can no longer redistribute, we split 2 pages into 3 rather than 1 to 2. This way pages remain 2/3 full
Since the root never has a sibling we can’t do a 2-3 split here

VIRTUAL B-TREES

- break up available RAM into pages and keep some in RAM rather than accessing the file each time we need a node
- all accesses require the root so keep it in RAM
- read in other pages as necessary
- notice if we even keep just the root in memory, we have reduced the minimum # seeks in that 1,000,000 record order 512 tree to ) and the maximum to 2
paging in : to read a page from the file into RAM
paging out : to write a page back out to the file
page fault : when a page is required that is not in RAM

- type 1: the page has never been accessed before
- type 2 : the page was there once but isn’t now
can’t do much about type 1 page faults
can reduce the number of type 2 page faults with a good strategy for replacing pages
page replacement strategy : sooner or later all the page slots in RAM will be full so when we need the next page, we need a strategy to decide who goes back to the file
LRU (least recently used) page replacement strategy : replace the oldest page. This can be done by keeping track of the order in which they were paged in.
Variation : keep a count of when they are used and replace the one that hasn’t been used in the longest time
Next Variation: always keep the root and attempt to replace the least recently used leaf

Up till now we have been assuming we only have the keys in this file and that the records themselves are in another file.
Remember that we usually access a key because we want to do something with its record.
We can keep the record with the key if it’s small, or
we can keep the records separate and add the address of the record to the key page
We can also deal with variable length keys and even a variable number of keys/page....

CPSC 461: Copyright © 2002 Katrin Becker 1998-2002 Last Modified August 4, 2000 05:34 PM