RB-Tree indexes support in HEAP tables

Renamed _hp_func  ->  hp_func
mi_key_cmp moved to /mysys/my_handler.c
New tests for HEAP tables


heap/_check.c:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/_rectest.c:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/heapdef.h:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/hp_block.c:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/hp_clear.c:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/hp_close.c:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/hp_create.c:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/hp_delete.c:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/hp_hash.c:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/hp_open.c:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/hp_panic.c:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/hp_rename.c:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/hp_rfirst.c:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/hp_rkey.c:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/hp_rlast.c:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/hp_rnext.c:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/hp_rprev.c:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/hp_rrnd.c:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/hp_rsame.c:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/hp_scan.c:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/hp_test1.c:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/hp_test2.c:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/hp_update.c:
  RB-tree index
  Renamed _hp_func -> hp_func
heap/hp_write.c:
  RB-tree index
  Renamed _hp_func -> hp_func
include/Makefile.am:
  New include
include/heap.h:
  RB-Tree index
include/my_tree.h:
  new search functions
  new custom_arg argument
include/myisam.h:
  Removed MI_KEYSEG
isam/isamlog.c:
  Add custom_arg
isam/pack_isam.c:
  Add custom_arg
myisam/ft_nlq_search.c:
  Add custom_arg
myisam/ft_parser.c:
  Add custom_arg
myisam/ft_stopwords.c:
  Add custom_arg
myisam/mi_search.c:
  Remove mi_key_cmp
myisam/mi_write.c:
  Add custom_arg
myisam/myisamdef.h:
  Remove mi_key_cmp
myisam/myisamlog.c:
  Add custom_arg
myisam/myisampack.c:
  Add custom_arg
mysys/Makefile.am:
  New file my_handler.c
mysys/tree.c:
  custom_arg
  new search functions
sql/ha_heap.cc:
  RBTree
sql/ha_myisam.cc:
  RBTree
sql/item_sum.cc:
  custom_arg
sql/sql_analyse.cc:
  custom_arg
sql/sql_class.h:
  custom_arg
sql/sql_table.cc:
  Remove duplicate code
sql/sql_yacc.yy:
  UNDEF by default
sql/table.cc:
  Remove dirty hack
This commit is contained in:
unknown 2002-04-25 13:36:55 +05:00
commit 139a73cade
54 changed files with 2360 additions and 747 deletions

View file

@ -42,6 +42,7 @@
#include "mysys_priv.h"
#include <m_string.h>
#include <my_tree.h>
#include "my_base.h"
#define BLACK 1
#define RED 0
@ -167,7 +168,8 @@ static void delete_tree_element(TREE *tree, TREE_ELEMENT *element)
parent[0] = & parent[-1][0]->right */
TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size)
TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size,
void* custom_arg)
{
int cmp;
TREE_ELEMENT *element,***parent;
@ -177,8 +179,8 @@ TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size)
for (;;)
{
if (element == &tree->null_element ||
(cmp=(*tree->compare)(tree->custom_arg,
ELEMENT_KEY(tree,element),key)) == 0)
(cmp = (*tree->compare)(custom_arg, ELEMENT_KEY(tree,element),
key)) == 0)
break;
if (cmp < 0)
{
@ -198,7 +200,7 @@ TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size)
&& tree->allocated > tree->memory_limit)
{
reset_tree(tree);
return tree_insert(tree, key, key_size);
return tree_insert(tree, key, key_size, custom_arg);
}
key_size+=tree->size_of_element;
@ -234,8 +236,7 @@ TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size)
return element;
}
int tree_delete(TREE *tree, void *key)
int tree_delete(TREE *tree, void *key, void *custom_arg)
{
int cmp,remove_colour;
TREE_ELEMENT *element,***parent, ***org_parent, *nod;
@ -248,8 +249,8 @@ int tree_delete(TREE *tree, void *key)
{
if (element == &tree->null_element)
return 1; /* Was not in tree */
if ((cmp=(*tree->compare)(tree->custom_arg,
ELEMENT_KEY(tree,element),key)) == 0)
if ((cmp = (*tree->compare)(custom_arg, ELEMENT_KEY(tree,element),
key)) == 0)
break;
if (cmp < 0)
{
@ -296,7 +297,7 @@ int tree_delete(TREE *tree, void *key)
}
void *tree_search(TREE *tree, void *key)
void *tree_search(TREE *tree, void *key, void *custom_arg)
{
int cmp;
TREE_ELEMENT *element=tree->root;
@ -305,8 +306,8 @@ void *tree_search(TREE *tree, void *key)
{
if (element == &tree->null_element)
return (void*) 0;
if ((cmp=(*tree->compare)(tree->custom_arg,
ELEMENT_KEY(tree,element),key)) == 0)
if ((cmp = (*tree->compare)(custom_arg, ELEMENT_KEY(tree,element),
key)) == 0)
return ELEMENT_KEY(tree,element);
if (cmp < 0)
element=element->right;
@ -315,6 +316,172 @@ void *tree_search(TREE *tree, void *key)
}
}
void *tree_search_key(TREE *tree, const void *key,
TREE_ELEMENT **parents, TREE_ELEMENT ***last_pos,
enum ha_rkey_function flag, void *custom_arg)
{
int cmp;
TREE_ELEMENT *element = tree->root;
TREE_ELEMENT **last_left_step_parent = NULL;
TREE_ELEMENT **last_equal_element = NULL;
/*
TODO: handle HA_READ_KEY_OR_PREV, HA_READ_BEFORE_KEY, HA_READ_PREFIX,
HA_READ_PREFIX_LAST flags if needed.
*/
*parents = &tree->null_element;
while (element != &tree->null_element)
{
*++parents = element;
if ((cmp = (*tree->compare)(custom_arg, ELEMENT_KEY(tree, element),
key)) == 0)
{
switch (flag) {
case HA_READ_KEY_EXACT:
case HA_READ_KEY_OR_NEXT:
last_equal_element = parents;
cmp = 1;
break;
case HA_READ_AFTER_KEY:
cmp = -1;
break;
default:
return NULL;
}
}
if (cmp < 0) /* element < key */
{
element = element->right;
}
else
{
last_left_step_parent = parents;
element = element->left;
}
}
switch (flag) {
case HA_READ_KEY_EXACT:
*last_pos = last_equal_element;
break;
case HA_READ_KEY_OR_NEXT:
*last_pos = last_equal_element ? last_equal_element : last_left_step_parent;
break;
case HA_READ_AFTER_KEY:
*last_pos = last_left_step_parent;
break;
default:
return NULL;
}
return *last_pos ? ELEMENT_KEY(tree, **last_pos) : NULL;
}
/*
Search first (the most left) or last (the most right) tree element
*/
void *tree_search_edge(TREE *tree, TREE_ELEMENT **parents,
TREE_ELEMENT ***last_pos, int child_offs)
{
TREE_ELEMENT *element = tree->root;
*parents = &tree->null_element;
while (element != &tree->null_element)
{
*++parents = element;
element = ELEMENT_CHILD(element, child_offs);
}
*last_pos = parents;
return **last_pos != &tree->null_element ?
ELEMENT_KEY(tree, **last_pos) : NULL;
}
void *tree_search_next(TREE *tree, TREE_ELEMENT ***last_pos, int l_offs,
int r_offs)
{
TREE_ELEMENT *x = **last_pos;
if (ELEMENT_CHILD(x, r_offs) != &tree->null_element)
{
x = ELEMENT_CHILD(x, r_offs);
*++*last_pos = x;
while (ELEMENT_CHILD(x, l_offs) != &tree->null_element)
{
x = ELEMENT_CHILD(x, l_offs);
*++*last_pos = x;
}
return ELEMENT_KEY(tree, x);
}
else
{
TREE_ELEMENT *y = *--*last_pos;
while (y != &tree->null_element && x == ELEMENT_CHILD(y, r_offs))
{
x = y;
y = *--*last_pos;
}
return y == &tree->null_element ? NULL : ELEMENT_KEY(tree, y);
}
}
/*
Expected that tree is fully balanced
(each path from root to leaf has the same length)
*/
uint tree_record_pos(TREE *tree, const void *key,
enum ha_rkey_function flag, void *custom_arg)
{
int cmp;
TREE_ELEMENT *element = tree->root;
uint left = 1;
uint right = tree->elements_in_tree;
uint last_left_step_pos = tree->elements_in_tree;
uint last_right_step_pos = 1;
uint last_equal_pos = HA_POS_ERROR;
while (element != &tree->null_element)
{
if ((cmp = (*tree->compare)(custom_arg, ELEMENT_KEY(tree, element),
key)) == 0)
{
switch (flag) {
case HA_READ_KEY_EXACT:
last_equal_pos = (left + right) >> 1;
cmp = 1;
break;
case HA_READ_BEFORE_KEY:
cmp = 1;
break;
case HA_READ_AFTER_KEY:
cmp = -1;
break;
default:
return HA_POS_ERROR;
}
}
if (cmp < 0) /* element < key */
{
last_right_step_pos = (left + right) >> 1;
element = element->right;
left = last_right_step_pos;
}
else
{
last_left_step_pos = (left + right) >> 1;
element = element->left;
right = last_left_step_pos;
}
}
switch (flag) {
case HA_READ_KEY_EXACT:
return last_equal_pos;
case HA_READ_BEFORE_KEY:
return last_right_step_pos;
case HA_READ_AFTER_KEY:
return last_left_step_pos;
default:
return HA_POS_ERROR;
}
}
int tree_walk(TREE *tree, tree_walk_action action, void *argument, TREE_WALK visit)
{