Blender V2.61 - r43446

BLI_dlrbTree.h

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