00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #pragma once
00017
00018 #include <unistd.h>
00019
00020 #include <drizzled/base.h>
00021 #include <drizzled/memory/root.h>
00022 #include <drizzled/qsort_cmp.h>
00023
00024 namespace drizzled
00025 {
00026
00027
00028 static const int MAX_TREE_HEIGHT= 64;
00029
00030 static const int TREE_NO_DUPS= 1;
00031
00032 typedef enum { left_root_right, right_root_left } TREE_WALK;
00033 typedef int (*tree_walk_action)(void *,uint32_t,void *);
00034
00035 typedef enum { free_init, free_free, free_end } TREE_FREE;
00036 typedef void (*tree_element_free)(void*, TREE_FREE, void *);
00037
00038
00039 class Tree_Element
00040 {
00041 public:
00042 Tree_Element *left,*right;
00043 uint32_t count:31,
00044 colour:1;
00045 };
00046
00047 static const int TREE_ELEMENT_EXTRA_SIZE= (sizeof(Tree_Element) + sizeof(void*));
00048
00054 class Tree
00055 {
00056 private:
00057 Tree_Element *root, null_element;
00058 void *custom_arg;
00059 Tree_Element **parents[MAX_TREE_HEIGHT];
00060 uint32_t offset_to_key, elements_in_tree, size_of_element;
00061 size_t memory_limit;
00062 size_t allocated;
00063 qsort_cmp2 compare;
00064 memory::Root mem_root;
00065 bool with_delete;
00066 tree_element_free free;
00067 uint32_t flag;
00068
00069 public:
00070 void* getCustomArg() {
00071 return custom_arg;
00072 }
00073 Tree_Element* getRoot() {
00074 return root;
00075 }
00076 void setRoot(Tree_Element* root_arg) {
00077 root = root_arg;
00078 }
00079 uint32_t getElementsInTree() {
00080 return elements_in_tree;
00081 }
00082
00083 void init_tree(size_t default_alloc_size, uint32_t memory_limit,
00084 uint32_t size, qsort_cmp2 compare, bool with_delete,
00085 tree_element_free free_element, void *custom_arg);
00086 bool is_inited()
00087 {
00088 return this->root != 0;
00089 }
00090 void delete_tree();
00091 void reset_tree();
00092
00093
00094 Tree_Element *tree_insert(void *key, uint32_t key_size, void *custom_arg);
00095 int tree_walk(tree_walk_action action, void *argument, TREE_WALK visit);
00096
00097 private:
00098 void free_tree(myf free_flags);
00099
00100 void* element_key(Tree_Element* element);
00101 void delete_tree_element(Tree_Element* element);
00102 int tree_walk_left_root_right(Tree_Element* element, tree_walk_action action, void* argument);
00103 int tree_walk_right_root_left(Tree_Element* element, tree_walk_action action, void* argument);
00104
00105 void left_rotate(Tree_Element **parent,Tree_Element *element);
00106 void right_rotate(Tree_Element **parent, Tree_Element *element);
00107 void rb_insert(Tree_Element ***parent, Tree_Element *element);
00108 };
00109
00110 }
00111