|
Blender
V2.59
|
00001 /* 00002 * $Id: BLI_dlrbTree.h 34966 2011-02-18 13:58:08Z jesterking $ 00003 * 00004 * ***** BEGIN GPL LICENSE BLOCK ***** 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License 00008 * as published by the Free Software Foundation; either version 2 00009 * of the License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software Foundation, 00018 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00019 * 00020 * The Original Code is Copyright (C) 2009 Blender Foundation, Joshua Leung 00021 * All rights reserved. 00022 * 00023 * Contributor(s): Joshua Leung (original author) 00024 * 00025 * ***** END GPL LICENSE BLOCK ***** 00026 */ 00027 00028 #ifndef BLI_DLRB_TREE_H 00029 #define BLI_DLRB_TREE_H 00030 00036 /* Double-Linked Red-Black Tree Implementation: 00037 * 00038 * This is simply a Red-Black Tree implementation whose nodes can later 00039 * be arranged + retrieved as elements in a Double-Linked list (i.e. ListBase). 00040 * The Red-Black Tree implementation is based on the methods defined by Wikipedia. 00041 */ 00042 00043 /* ********************************************** */ 00044 /* Data Types and Type Defines */ 00045 00046 /* Base Structs --------------------------------- */ 00047 00048 /* Basic Layout for a Node */ 00049 typedef struct DLRBT_Node { 00050 /* ListBase capabilities */ 00051 struct DLRBT_Node *next, *prev; 00052 00053 /* Tree Associativity settings */ 00054 struct DLRBT_Node *left, *right; 00055 struct DLRBT_Node *parent; 00056 00057 char tree_col; 00058 /* ... for nice alignment, next item should usually be a char too... */ 00059 } DLRBT_Node; 00060 00061 /* Red/Black defines for tree_col */ 00062 typedef enum eDLRBT_Colors { 00063 DLRBT_BLACK= 0, 00064 DLRBT_RED, 00065 } eDLRBT_Colors; 00066 00067 /* -------- */ 00068 00069 /* The Tree Data */ 00070 typedef struct DLRBT_Tree { 00071 /* ListBase capabilities */ 00072 void *first, *last; /* these should be based on DLRBT_Node-s */ 00073 00074 /* Root Node */ 00075 void *root; /* this should be based on DLRBT_Node-s */ 00076 } DLRBT_Tree; 00077 00078 /* Callback Types --------------------------------- */ 00079 00080 /* return -1, 0, 1 for whether the given data is less than, equal to, or greater than the given node 00081 * - node: <DLRBT_Node> the node to compare to 00082 * - data: pointer to the relevant data or values stored in the bitpattern dependant on the function 00083 */ 00084 typedef short (*DLRBT_Comparator_FP)(void *node, void *data); 00085 00086 /* return a new node instance wrapping the given data 00087 * - data: pointer to the relevant data to create a subclass of node from 00088 */ 00089 typedef DLRBT_Node *(*DLRBT_NAlloc_FP)(void *data); 00090 00091 /* update an existing node instance accordingly to be in sync with the given data * 00092 * - node: <DLRBT_Node> the node to update 00093 * - data: pointer to the relevant data or values stored in the bitpattern dependant on the function 00094 */ 00095 typedef void (*DLRBT_NUpdate_FP)(void *node, void *data); 00096 00097 /* ********************************************** */ 00098 /* Public API */ 00099 00100 /* ADT Management ------------------------------- */ 00101 00102 /* Create a new tree, and initialise as necessary */ 00103 DLRBT_Tree *BLI_dlrbTree_new(void); 00104 00105 /* Initialises some given trees */ 00106 void BLI_dlrbTree_init(DLRBT_Tree *tree); 00107 00108 /* Free some tree */ 00109 void BLI_dlrbTree_free(DLRBT_Tree *tree); 00110 00111 /* Make sure the tree's Double-Linked list representation is valid */ 00112 void BLI_dlrbTree_linkedlist_sync(DLRBT_Tree *tree); 00113 00114 00115 /* Searching ------------------------------------ */ 00116 00117 /* Find the node which matches or is the closest to the requested node */ 00118 DLRBT_Node *BLI_dlrbTree_search(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data); 00119 00120 /* Find the node which exactly matches the required data */ 00121 DLRBT_Node *BLI_dlrbTree_search_exact(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data); 00122 00123 /* Find the node which occurs immediately before the best matching node */ 00124 DLRBT_Node *BLI_dlrbTree_search_prev(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data); 00125 00126 /* Find the node which occurs immediately after the best matching node */ 00127 DLRBT_Node *BLI_dlrbTree_search_next(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data); 00128 00129 00130 /* Check whether there is a node matching the requested node */ 00131 short BLI_dlrbTree_contains(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, void *search_data); 00132 00133 00134 /* Node Operations (Managed) --------------------- */ 00135 /* These methods automate the process of adding/removing nodes from the BST, 00136 * using the supplied data and callbacks 00137 */ 00138 00139 /* Add the given data to the tree, and return the node added */ 00140 // NOTE: for duplicates, the update_cb is called (if available), and the existing node is returned 00141 DLRBT_Node *BLI_dlrbTree_add(DLRBT_Tree *tree, DLRBT_Comparator_FP cmp_cb, 00142 DLRBT_NAlloc_FP new_cb, DLRBT_NUpdate_FP update_cb, void *data); 00143 00144 00145 /* Remove the given element from the tree and balance again */ 00146 // FIXME: this is not implemented yet... 00147 void BLI_dlrbTree_remove(DLRBT_Tree *tree, DLRBT_Node *node); 00148 00149 /* Node Operations (Manual) --------------------- */ 00150 /* These methods require custom code for creating BST nodes and adding them to the 00151 * tree in special ways, such that the node can then be balanced. 00152 * 00153 * It is recommended that these methods are only used where the other method is too cumbersome... 00154 */ 00155 00156 /* Balance the tree after the given node has been added to it 00157 * (using custom code, in the Binary Tree way). 00158 */ 00159 void BLI_dlrbTree_insert(DLRBT_Tree *tree, DLRBT_Node *node); 00160 00161 /* ********************************************** */ 00162 00163 #endif // BLI_DLRB_TREE_H