rbtree: Add support for augmented rbtrees
[sfrench/cifs-2.6.git] / Documentation / rbtree.txt
index 7224459b469e8bf76da4af840468e4dd9d44a520..221f38be98f47be1e682876ef55c2984a8484e76 100644 (file)
@@ -131,8 +131,8 @@ Example:
        }
 
        /* Add new node and rebalance tree. */
-       rb_link_node(data->node, parent, new);
-       rb_insert_color(data->node, root);
+       rb_link_node(&data->node, parent, new);
+       rb_insert_color(&data->node, root);
 
        return TRUE;
   }
@@ -146,10 +146,10 @@ To remove an existing node from a tree, call:
 
 Example:
 
-  struct mytype *data = mysearch(mytree, "walrus");
+  struct mytype *data = mysearch(&mytree, "walrus");
 
   if (data) {
-       rb_erase(data->node, mytree);
+       rb_erase(&data->node, &mytree);
        myfree(data);
   }
 
@@ -188,5 +188,63 @@ Example:
 
   struct rb_node *node;
   for (node = rb_first(&mytree); node; node = rb_next(node))
-       printk("key=%s\n", rb_entry(node, int, keystring));
+       printk("key=%s\n", rb_entry(node, struct mytype, node)->keystring);
 
+Support for Augmented rbtrees
+-----------------------------
+
+Augmented rbtree is an rbtree with "some" additional data stored in each node.
+This data can be used to augment some new functionality to rbtree.
+Augmented rbtree is an optional feature built on top of basic rbtree
+infrastructure. rbtree user who wants this feature will have an augment
+callback function in rb_root initialized.
+
+This callback function will be called from rbtree core routines whenever
+a node has a change in one or both of its children. It is the responsibility
+of the callback function to recalculate the additional data that is in the
+rb node using new children information. Note that if this new additional
+data affects the parent node's additional data, then callback function has
+to handle it and do the recursive updates.
+
+
+Interval tree is an example of augmented rb tree. Reference -
+"Introduction to Algorithms" by Cormen, Leiserson, Rivest and Stein.
+More details about interval trees:
+
+Classical rbtree has a single key and it cannot be directly used to store
+interval ranges like [lo:hi] and do a quick lookup for any overlap with a new
+lo:hi or to find whether there is an exact match for a new lo:hi.
+
+However, rbtree can be augmented to store such interval ranges in a structured
+way making it possible to do efficient lookup and exact match.
+
+This "extra information" stored in each node is the maximum hi
+(max_hi) value among all the nodes that are its descendents. This
+information can be maintained at each node just be looking at the node
+and its immediate children. And this will be used in O(log n) lookup
+for lowest match (lowest start address among all possible matches)
+with something like:
+
+find_lowest_match(lo, hi, node)
+{
+       lowest_match = NULL;
+       while (node) {
+               if (max_hi(node->left) > lo) {
+                       // Lowest overlap if any must be on left side
+                       node = node->left;
+               } else if (overlap(lo, hi, node)) {
+                       lowest_match = node;
+                       break;
+               } else if (lo > node->lo) {
+                       // Lowest overlap if any must be on right side
+                       node = node->right;
+               } else {
+                       break;
+               }
+       }
+       return lowest_match;
+}
+
+Finding exact match will be to first find lowest match and then to follow
+successor nodes looking for exact match, until the start of a node is beyond
+the hi value we are looking for.