1 | /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. All rights reserved. |
2 | |
3 | This program is free software; you can redistribute it and/or modify |
4 | it under the terms of the GNU General Public License as published by |
5 | the Free Software Foundation; version 2 of the License. |
6 | |
7 | This program is distributed in the hope that it will be useful, |
8 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
9 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
10 | GNU General Public License for more details. |
11 | |
12 | You should have received a copy of the GNU General Public License |
13 | along with this program; if not, write to the Free Software |
14 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
15 | |
16 | #ifndef _tree_h |
17 | #define _tree_h |
18 | #ifdef __cplusplus |
19 | extern "C" { |
20 | #endif |
21 | |
22 | #include "my_base.h" /* get 'enum ha_rkey_function' */ |
23 | #include "my_alloc.h" /* MEM_ROOT */ |
24 | |
25 | /* Worst case tree is half full. This gives use 2^(MAX_TREE_HEIGHT/2) leafs */ |
26 | #define MAX_TREE_HEIGHT 64 |
27 | |
28 | #define ELEMENT_KEY(tree,element)\ |
29 | (tree->offset_to_key ? (void*)((uchar*) element+tree->offset_to_key) :\ |
30 | *((void**) (element+1))) |
31 | |
32 | #define tree_set_pointer(element,ptr) *((uchar **) (element+1))=((uchar*) (ptr)) |
33 | |
34 | /* |
35 | A tree with its flag set to TREE_ONLY_DUPS behaves differently on inserting |
36 | an element that is not in the tree: |
37 | the element is not added at all, but instead tree_insert() returns a special |
38 | address TREE_ELEMENT_UNIQUE as an indication that the function has not failed |
39 | due to lack of memory. |
40 | */ |
41 | |
42 | #define TREE_ELEMENT_UNIQUE ((TREE_ELEMENT *) 1) |
43 | #define TREE_NO_DUPS 1 |
44 | #define TREE_ONLY_DUPS 2 |
45 | |
46 | typedef enum { left_root_right, right_root_left } TREE_WALK; |
47 | typedef uint32 element_count; |
48 | typedef int (*tree_walk_action)(void *,element_count,void *); |
49 | |
50 | typedef enum { free_init, free_free, free_end } TREE_FREE; |
51 | typedef int (*tree_element_free)(void*, TREE_FREE, void *); |
52 | |
53 | typedef struct st_tree_element { |
54 | struct st_tree_element *left,*right; |
55 | uint32 count:31, |
56 | colour:1; /* black is marked as 1 */ |
57 | } TREE_ELEMENT; |
58 | |
59 | #define ELEMENT_CHILD(element, offs) (*(TREE_ELEMENT**)((char*)element + offs)) |
60 | |
61 | typedef struct st_tree { |
62 | TREE_ELEMENT *root,null_element; |
63 | TREE_ELEMENT **parents[MAX_TREE_HEIGHT]; |
64 | uint offset_to_key,elements_in_tree,size_of_element; |
65 | size_t memory_limit, allocated; |
66 | qsort_cmp2 compare; |
67 | void *custom_arg; |
68 | MEM_ROOT mem_root; |
69 | my_bool with_delete; |
70 | tree_element_free free; |
71 | myf my_flags; |
72 | uint flag; |
73 | } TREE; |
74 | |
75 | /* Functions on whole tree */ |
76 | void init_tree(TREE *tree, size_t default_alloc_size, size_t memory_limit, |
77 | int size, qsort_cmp2 compare, |
78 | tree_element_free free_element, void *custom_arg, |
79 | myf my_flags); |
80 | int delete_tree(TREE*, my_bool abort); |
81 | int reset_tree(TREE*); |
82 | |
83 | /* similar to delete tree, except we do not my_free() blocks in mem_root */ |
84 | #define is_tree_inited(tree) ((tree)->root != 0) |
85 | |
86 | /* Functions on leafs */ |
87 | TREE_ELEMENT *tree_insert(TREE *tree,void *key, uint key_size, |
88 | void *custom_arg); |
89 | void *tree_search(TREE *tree, void *key, void *custom_arg); |
90 | int tree_walk(TREE *tree,tree_walk_action action, |
91 | void *argument, TREE_WALK visit); |
92 | int tree_delete(TREE *tree, void *key, uint key_size, void *custom_arg); |
93 | void *tree_search_key(TREE *tree, const void *key, |
94 | TREE_ELEMENT **parents, TREE_ELEMENT ***last_pos, |
95 | enum ha_rkey_function flag, void *custom_arg); |
96 | void *tree_search_edge(TREE *tree, TREE_ELEMENT **parents, |
97 | TREE_ELEMENT ***last_pos, int child_offs); |
98 | void *tree_search_next(TREE *tree, TREE_ELEMENT ***last_pos, int l_offs, |
99 | int r_offs); |
100 | ha_rows tree_record_pos(TREE *tree, const void *key, |
101 | enum ha_rkey_function search_flag, void *custom_arg); |
102 | #define reset_free_element(tree) (tree)->free= 0 |
103 | |
104 | #define (sizeof(TREE_ELEMENT) + sizeof(void*)) |
105 | |
106 | #ifdef __cplusplus |
107 | } |
108 | #endif |
109 | #endif |
110 | |