~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/Documentation/core-api/rbtree.rst

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /Documentation/core-api/rbtree.rst (Version linux-6.11.5) and /Documentation/core-api/rbtree.rst (Version linux-4.9.337)


  1 =================================                 
  2 Red-black Trees (rbtree) in Linux                 
  3 =================================                 
  4                                                   
  5                                                   
  6 :Date: January 18, 2007                           
  7 :Author: Rob Landley <rob@landley.net>             
  8                                                   
  9 What are red-black trees, and what are they fo    
 10 ----------------------------------------------    
 11                                                   
 12 Red-black trees are a type of self-balancing b    
 13 storing sortable key/value data pairs.  This d    
 14 are used to efficiently store sparse arrays an    
 15 to insert/access/delete nodes) and hash tables    
 16 be easily traversed in order, and must be tune    
 17 hash function where rbtrees scale gracefully s    
 18                                                   
 19 Red-black trees are similar to AVL trees, but     
 20 worst case performance for insertion and delet    
 21 three rotations, respectively, to balance the     
 22 (but still O(log n)) lookup time.                 
 23                                                   
 24 To quote Linux Weekly News:                       
 25                                                   
 26     There are a number of red-black trees in u    
 27     The deadline and CFQ I/O schedulers employ    
 28     track requests; the packet CD/DVD driver d    
 29     The high-resolution timer code uses an rbt    
 30     timer requests.  The ext3 filesystem track    
 31     red-black tree.  Virtual memory areas (VMA    
 32     trees, as are epoll file descriptors, cryp    
 33     packets in the "hierarchical token bucket"    
 34                                                   
 35 This document covers use of the Linux rbtree i    
 36 information on the nature and implementation o    
 37                                                   
 38   Linux Weekly News article on red-black trees    
 39     https://lwn.net/Articles/184495/              
 40                                                   
 41   Wikipedia entry on red-black trees              
 42     https://en.wikipedia.org/wiki/Red-black_tr    
 43                                                   
 44 Linux implementation of red-black trees           
 45 ---------------------------------------           
 46                                                   
 47 Linux's rbtree implementation lives in the fil    
 48 "#include <linux/rbtree.h>".                      
 49                                                   
 50 The Linux rbtree implementation is optimized f    
 51 less layer of indirection (and better cache lo    
 52 tree implementations.  Instead of using pointe    
 53 structures, each instance of struct rb_node is    
 54 it organizes.  And instead of using a comparis    
 55 users are expected to write their own tree sea    
 56 which call the provided rbtree functions.  Loc    
 57 user of the rbtree code.                          
 58                                                   
 59 Creating a new rbtree                             
 60 ---------------------                             
 61                                                   
 62 Data nodes in an rbtree tree are structures co    
 63                                                   
 64   struct mytype {                                 
 65         struct rb_node node;                      
 66         char *keystring;                          
 67   };                                              
 68                                                   
 69 When dealing with a pointer to the embedded st    
 70 structure may be accessed with the standard co    
 71 individual members may be accessed directly vi    
 72                                                   
 73 At the root of each rbtree is an rb_root struc    
 74 empty via:                                        
 75                                                   
 76   struct rb_root mytree = RB_ROOT;                
 77                                                   
 78 Searching for a value in an rbtree                
 79 ----------------------------------                
 80                                                   
 81 Writing a search function for your tree is fai    
 82 root, compare each value, and follow the left     
 83                                                   
 84 Example::                                         
 85                                                   
 86   struct mytype *my_search(struct rb_root *roo    
 87   {                                               
 88         struct rb_node *node = root->rb_node;     
 89                                                   
 90         while (node) {                            
 91                 struct mytype *data = containe    
 92                 int result;                       
 93                                                   
 94                 result = strcmp(string, data->    
 95                                                   
 96                 if (result < 0)                   
 97                         node = node->rb_left;     
 98                 else if (result > 0)              
 99                         node = node->rb_right;    
100                 else                              
101                         return data;              
102         }                                         
103         return NULL;                              
104   }                                               
105                                                   
106 Inserting data into an rbtree                     
107 -----------------------------                     
108                                                   
109 Inserting data in the tree involves first sear    
110 new node, then inserting the node and rebalanc    
111                                                   
112 The search for insertion differs from the prev    
113 location of the pointer on which to graft the     
114 needs a link to its parent node for rebalancin    
115                                                   
116 Example::                                         
117                                                   
118   int my_insert(struct rb_root *root, struct m    
119   {                                               
120         struct rb_node **new = &(root->rb_node    
121                                                   
122         /* Figure out where to put new node */    
123         while (*new) {                            
124                 struct mytype *this = containe    
125                 int result = strcmp(data->keys    
126                                                   
127                 parent = *new;                    
128                 if (result < 0)                   
129                         new = &((*new)->rb_lef    
130                 else if (result > 0)              
131                         new = &((*new)->rb_rig    
132                 else                              
133                         return FALSE;             
134         }                                         
135                                                   
136         /* Add new node and rebalance tree. */    
137         rb_link_node(&data->node, parent, new)    
138         rb_insert_color(&data->node, root);       
139                                                   
140         return TRUE;                              
141   }                                               
142                                                   
143 Removing or replacing existing data in an rbtr    
144 ----------------------------------------------    
145                                                   
146 To remove an existing node from a tree, call::    
147                                                   
148   void rb_erase(struct rb_node *victim, struct    
149                                                   
150 Example::                                         
151                                                   
152   struct mytype *data = mysearch(&mytree, "wal    
153                                                   
154   if (data) {                                     
155         rb_erase(&data->node, &mytree);           
156         myfree(data);                             
157   }                                               
158                                                   
159 To replace an existing node in a tree with a n    
160                                                   
161   void rb_replace_node(struct rb_node *old, st    
162                         struct rb_root *tree);    
163                                                   
164 Replacing a node this way does not re-sort the    
165 have the same key as the old node, the rbtree     
166                                                   
167 Iterating through the elements stored in an rb    
168 ----------------------------------------------    
169                                                   
170 Four functions are provided for iterating thro    
171 sorted order.  These work on arbitrary trees,     
172 modified or wrapped (except for locking purpos    
173                                                   
174   struct rb_node *rb_first(struct rb_root *tre    
175   struct rb_node *rb_last(struct rb_root *tree    
176   struct rb_node *rb_next(struct rb_node *node    
177   struct rb_node *rb_prev(struct rb_node *node    
178                                                   
179 To start iterating, call rb_first() or rb_last    
180 of the tree, which will return a pointer to th    
181 the first or last element in the tree.  To con    
182 node by calling rb_next() or rb_prev() on the     
183 NULL when there are no more nodes left.           
184                                                   
185 The iterator functions return a pointer to the    
186 which the containing data structure may be acc    
187 macro, and individual members may be accessed     
188 rb_entry(node, type, member).                     
189                                                   
190 Example::                                         
191                                                   
192   struct rb_node *node;                           
193   for (node = rb_first(&mytree); node; node =     
194         printk("key=%s\n", rb_entry(node, stru    
195                                                   
196 Cached rbtrees                                    
197 --------------                                    
198                                                   
199 Computing the leftmost (smallest) node is quit    
200 search trees, such as for traversals or users     
201 order for their own logic. To this end, users     
202 to optimize O(logN) rb_first() calls to a simp    
203 potentially expensive tree iterations. This is    
204 overhead for maintenance; albeit larger memory    
205                                                   
206 Similar to the rb_root structure, cached rbtre    
207 empty via::                                       
208                                                   
209   struct rb_root_cached mytree = RB_ROOT_CACHE    
210                                                   
211 Cached rbtree is simply a regular rb_root with    
212 leftmost node. This allows rb_root_cached to e    
213 which permits augmented trees to be supported     
214 interfaces::                                      
215                                                   
216   struct rb_node *rb_first_cached(struct rb_ro    
217   void rb_insert_color_cached(struct rb_node *    
218   void rb_erase_cached(struct rb_node *node, s    
219                                                   
220 Both insert and erase calls have their respect    
221 trees::                                           
222                                                   
223   void rb_insert_augmented_cached(struct rb_no    
224                                   bool, struct    
225   void rb_erase_augmented_cached(struct rb_nod    
226                                  struct rb_aug    
227                                                   
228                                                   
229 Support for Augmented rbtrees                     
230 -----------------------------                     
231                                                   
232 Augmented rbtree is an rbtree with "some" addi    
233 each node, where the additional data for node     
234 the contents of all nodes in the subtree roote    
235 be used to augment some new functionality to r    
236 is an optional feature built on top of basic r    
237 An rbtree user who wants this feature will hav    
238 functions with the user provided augmentation     
239 and erasing nodes.                                
240                                                   
241 C files implementing augmented rbtree manipula    
242 <linux/rbtree_augmented.h> instead of <linux/r    
243 linux/rbtree_augmented.h exposes some rbtree i    
244 you are not expected to rely on; please stick     
245 there and do not include <linux/rbtree_augment    
246 either so as to minimize chances of your users    
247 such implementation details.                      
248                                                   
249 On insertion, the user must update the augment    
250 leading to the inserted node, then call rb_lin    
251 rb_augment_inserted() instead of the usual rb_    
252 If rb_augment_inserted() rebalances the rbtree    
253 a user provided function to update the augment    
254 affected subtrees.                                
255                                                   
256 When erasing a node, the user must call rb_era    
257 rb_erase(). rb_erase_augmented() calls back in    
258 to updated the augmented information on affect    
259                                                   
260 In both cases, the callbacks are provided thro    
261 3 callbacks must be defined:                      
262                                                   
263 - A propagation callback, which updates the au    
264   node and its ancestors, up to a given stop p    
265   all the way to the root).                       
266                                                   
267 - A copy callback, which copies the augmented     
268   to a newly assigned subtree root.               
269                                                   
270 - A tree rotation callback, which copies the a    
271   subtree to a newly assigned subtree root AND    
272   information for the former subtree root.        
273                                                   
274 The compiled code for rb_erase_augmented() may    
275 copy callbacks, which results in a large funct    
276 user should have a single rb_erase_augmented()    
277 compiled code size.                               
278                                                   
279                                                   
280 Sample usage                                      
281 ^^^^^^^^^^^^                                      
282                                                   
283 Interval tree is an example of augmented rb tr    
284 "Introduction to Algorithms" by Cormen, Leiser    
285 More details about interval trees:                
286                                                   
287 Classical rbtree has a single key and it canno    
288 interval ranges like [lo:hi] and do a quick lo    
289 lo:hi or to find whether there is an exact mat    
290                                                   
291 However, rbtree can be augmented to store such    
292 way making it possible to do efficient lookup     
293                                                   
294 This "extra information" stored in each node i    
295 (max_hi) value among all the nodes that are it    
296 information can be maintained at each node jus    
297 and its immediate children. And this will be u    
298 for lowest match (lowest start address among a    
299 with something like::                             
300                                                   
301   struct interval_tree_node *                     
302   interval_tree_first_match(struct rb_root *ro    
303                             unsigned long star    
304   {                                               
305         struct interval_tree_node *node;          
306                                                   
307         if (!root->rb_node)                       
308                 return NULL;                      
309         node = rb_entry(root->rb_node, struct     
310                                                   
311         while (true) {                            
312                 if (node->rb.rb_left) {           
313                         struct interval_tree_n    
314                                 rb_entry(node-    
315                                          struc    
316                         if (left->__subtree_la    
317                                 /*                
318                                  * Some nodes     
319                                  * Iterate to     
320                                  * If it also     
321                                  * we are look    
322                                  * matching in    
323                                  * can't satis    
324                                  */               
325                                 node = left;      
326                                 continue;         
327                         }                         
328                 }                                 
329                 if (node->start <= last) {        
330                         if (node->last >= star    
331                                 return node;      
332                         if (node->rb.rb_right)    
333                                 node = rb_entr    
334                                         struct    
335                                 if (node->__su    
336                                         contin    
337                         }                         
338                 }                                 
339                 return NULL;    /* No match */    
340         }                                         
341   }                                               
342                                                   
343 Insertion/removal are defined using the follow    
344                                                   
345   static inline unsigned long                     
346   compute_subtree_last(struct interval_tree_no    
347   {                                               
348         unsigned long max = node->last, subtre    
349         if (node->rb.rb_left) {                   
350                 subtree_last = rb_entry(node->    
351                         struct interval_tree_n    
352                 if (max < subtree_last)           
353                         max = subtree_last;       
354         }                                         
355         if (node->rb.rb_right) {                  
356                 subtree_last = rb_entry(node->    
357                         struct interval_tree_n    
358                 if (max < subtree_last)           
359                         max = subtree_last;       
360         }                                         
361         return max;                               
362   }                                               
363                                                   
364   static void augment_propagate(struct rb_node    
365   {                                               
366         while (rb != stop) {                      
367                 struct interval_tree_node *nod    
368                         rb_entry(rb, struct in    
369                 unsigned long subtree_last = c    
370                 if (node->__subtree_last == su    
371                         break;                    
372                 node->__subtree_last = subtree    
373                 rb = rb_parent(&node->rb);        
374         }                                         
375   }                                               
376                                                   
377   static void augment_copy(struct rb_node *rb_    
378   {                                               
379         struct interval_tree_node *old =          
380                 rb_entry(rb_old, struct interv    
381         struct interval_tree_node *new =          
382                 rb_entry(rb_new, struct interv    
383                                                   
384         new->__subtree_last = old->__subtree_l    
385   }                                               
386                                                   
387   static void augment_rotate(struct rb_node *r    
388   {                                               
389         struct interval_tree_node *old =          
390                 rb_entry(rb_old, struct interv    
391         struct interval_tree_node *new =          
392                 rb_entry(rb_new, struct interv    
393                                                   
394         new->__subtree_last = old->__subtree_l    
395         old->__subtree_last = compute_subtree_    
396   }                                               
397                                                   
398   static const struct rb_augment_callbacks aug    
399         augment_propagate, augment_copy, augme    
400   };                                              
401                                                   
402   void interval_tree_insert(struct interval_tr    
403                             struct rb_root *ro    
404   {                                               
405         struct rb_node **link = &root->rb_node    
406         unsigned long start = node->start, las    
407         struct interval_tree_node *parent;        
408                                                   
409         while (*link) {                           
410                 rb_parent = *link;                
411                 parent = rb_entry(rb_parent, s    
412                 if (parent->__subtree_last < l    
413                         parent->__subtree_last    
414                 if (start < parent->start)        
415                         link = &parent->rb.rb_    
416                 else                              
417                         link = &parent->rb.rb_    
418         }                                         
419                                                   
420         node->__subtree_last = last;              
421         rb_link_node(&node->rb, rb_parent, lin    
422         rb_insert_augmented(&node->rb, root, &    
423   }                                               
424                                                   
425   void interval_tree_remove(struct interval_tr    
426                             struct rb_root *ro    
427   {                                               
428         rb_erase_augmented(&node->rb, root, &a    
429   }                                               
                                                      

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php