From: venkatesh.pallipadi@intel.com
To: Ingo Molnar <mingo@elte.hu>, H Peter Anvin <hpa@zytor.com>,
Thomas Gleixner <tglx@linutronix.de>,
Wolfram Strepp <wstrepp@gmx.de>
Cc: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>,
Suresh Siddha <suresh.b.siddha@intel.com>,
linux-kernel@vger.kernel.org
Subject: [patch 1/3] rbtree: Add support for augmented rbtrees
Date: Wed, 10 Feb 2010 11:57:05 -0800 [thread overview]
Message-ID: <20100210195909.648914000@intel.com> (raw)
In-Reply-To: 20100210195704.434039000@intel.com
[-- Attachment #1: 0001-rbtree-Add-support-for-augmented-rbtrees.patch --]
[-- Type: text/plain, Size: 5243 bytes --]
Add support for augmented rbtrees in core rbtree code.
This will be used in subsequent patches, in x86 PAT code, which needs
interval trees to efficiently keep track of PAT ranges.
Signed-off-by: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
Signed-off-by: Suresh Siddha <suresh.b.siddha@intel.com>
---
Documentation/rbtree.txt | 19 ++++++++++++++++++
include/linux/rbtree.h | 5 +++-
lib/rbtree.c | 48 ++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 67 insertions(+), 5 deletions(-)
diff --git a/Documentation/rbtree.txt b/Documentation/rbtree.txt
index aae8355..b2bae0a 100644
--- a/Documentation/rbtree.txt
+++ b/Documentation/rbtree.txt
@@ -190,3 +190,22 @@ Example:
for (node = rb_first(&mytree); node; node = rb_next(node))
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.
+
+Interval tree is an example of augmented rb tree. Reference -
+"Introduction to Algorithms" by Cormen, Leiserson, Rivest and Stein.
+
+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.
+
diff --git a/include/linux/rbtree.h b/include/linux/rbtree.h
index 9c29541..8e33a25 100644
--- a/include/linux/rbtree.h
+++ b/include/linux/rbtree.h
@@ -110,6 +110,7 @@ struct rb_node
struct rb_root
{
struct rb_node *rb_node;
+ void (*augment_cb)(struct rb_node *node);
};
@@ -129,7 +130,9 @@ static inline void rb_set_color(struct rb_node *rb, int color)
rb->rb_parent_color = (rb->rb_parent_color & ~1) | color;
}
-#define RB_ROOT (struct rb_root) { NULL, }
+#define RB_ROOT (struct rb_root) { NULL, NULL, }
+#define RB_AUGMENT_ROOT(x) (struct rb_root) { NULL, x}
+
#define rb_entry(ptr, type, member) container_of(ptr, type, member)
#define RB_EMPTY_ROOT(root) ((root)->rb_node == NULL)
diff --git a/lib/rbtree.c b/lib/rbtree.c
index e2aa3be..15e10b1 100644
--- a/lib/rbtree.c
+++ b/lib/rbtree.c
@@ -44,6 +44,11 @@ static void __rb_rotate_left(struct rb_node *node, struct rb_root *root)
else
root->rb_node = right;
rb_set_parent(node, right);
+
+ if (root->augment_cb) {
+ root->augment_cb(node);
+ root->augment_cb(right);
+ }
}
static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
@@ -67,12 +72,20 @@ static void __rb_rotate_right(struct rb_node *node, struct rb_root *root)
else
root->rb_node = left;
rb_set_parent(node, left);
+
+ if (root->augment_cb) {
+ root->augment_cb(node);
+ root->augment_cb(left);
+ }
}
void rb_insert_color(struct rb_node *node, struct rb_root *root)
{
struct rb_node *parent, *gparent;
+ if (root->augment_cb)
+ root->augment_cb(node);
+
while ((parent = rb_parent(node)) && rb_is_red(parent))
{
gparent = rb_parent(parent);
@@ -227,12 +240,15 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
else
{
struct rb_node *old = node, *left;
+ int old_parent_cb = 0;
+ int successor_parent_cb = 0;
node = node->rb_right;
while ((left = node->rb_left) != NULL)
node = left;
if (rb_parent(old)) {
+ old_parent_cb = 1;
if (rb_parent(old)->rb_left == old)
rb_parent(old)->rb_left = node;
else
@@ -247,8 +263,10 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
if (parent == old) {
parent = node;
} else {
+ successor_parent_cb = 1;
if (child)
rb_set_parent(child, parent);
+
parent->rb_left = child;
node->rb_right = old->rb_right;
@@ -259,6 +277,24 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
node->rb_left = old->rb_left;
rb_set_parent(old->rb_left, node);
+ if (root->augment_cb) {
+ /*
+ * Here, three different nodes can have new children.
+ * The parent of the successor node that was selected
+ * to replace the node to be erased.
+ * The node that is getting erased and is now replaced
+ * by its successor.
+ * The parent of the node getting erased-replaced.
+ */
+ if (successor_parent_cb)
+ root->augment_cb(parent);
+
+ root->augment_cb(node);
+
+ if (old_parent_cb)
+ root->augment_cb(rb_parent(old));
+ }
+
goto color;
}
@@ -267,15 +303,19 @@ void rb_erase(struct rb_node *node, struct rb_root *root)
if (child)
rb_set_parent(child, parent);
- if (parent)
- {
+
+ if (parent) {
if (parent->rb_left == node)
parent->rb_left = child;
else
parent->rb_right = child;
- }
- else
+
+ if (root->augment_cb)
+ root->augment_cb(parent);
+
+ } else {
root->rb_node = child;
+ }
color:
if (color == RB_BLACK)
--
1.6.0.6
--
next prev parent reply other threads:[~2010-02-10 21:34 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-02-10 19:57 [patch 0/3] x86: Use interval tree to keep track of PAT reserve/free venkatesh.pallipadi
2010-02-10 19:57 ` venkatesh.pallipadi [this message]
2010-02-10 23:23 ` [patch 1/3] rbtree: Add support for augmented rbtrees (ver 2) Pallipadi, Venkatesh
2010-02-19 0:21 ` [tip:x86/pat] rbtree: Add support for augmented rbtrees tip-bot for Pallipadi, Venkatesh
2010-05-27 15:29 ` Peter Zijlstra
2010-05-29 12:29 ` [RFC][PATCH] rbtree: undo augmented damage Peter Zijlstra
2010-05-29 13:31 ` [PATCH] rbtree: undo augmented damage -v2 Peter Zijlstra
2010-06-01 17:00 ` Venkatesh Pallipadi
2010-06-01 17:19 ` Peter Zijlstra
2010-06-01 17:34 ` Peter Zijlstra
2010-06-01 17:34 ` Venkatesh Pallipadi
2010-06-01 17:42 ` Peter Zijlstra
2010-06-01 18:09 ` Venkatesh Pallipadi
2010-06-01 18:42 ` Peter Zijlstra
2010-06-01 20:31 ` Venkatesh Pallipadi
2010-06-02 21:11 ` Suresh Siddha
2010-06-03 1:15 ` Venkatesh Pallipadi
2010-06-03 7:13 ` Peter Zijlstra
2010-06-03 7:48 ` Peter Zijlstra
2010-06-03 16:04 ` Suresh Siddha
2010-06-09 10:12 ` [tip:x86/pat] rbtree: Undo augmented trees performance damage tip-bot for Peter Zijlstra
2010-07-05 12:48 ` [tip:x86/urgent] rbtree: Undo augmented trees performance damage and regression tip-bot for Peter Zijlstra
2010-02-10 19:57 ` [patch 2/3] x86: Preparatory changes in pat.c for bigger rbtree change venkatesh.pallipadi
2010-02-19 0:22 ` [tip:x86/pat] x86, pat: " tip-bot for venkatesh.pallipadi@intel.com
2010-02-10 19:57 ` [patch 3/3] x86: Migrate to rbtree only backend for pat memtype management venkatesh.pallipadi
2010-02-10 23:26 ` [patch 3/3] x86: Migrate to rbtree only backend for pat memtype management (ver 2) Pallipadi, Venkatesh
2010-02-19 0:22 ` [tip:x86/pat] x86, pat: Migrate to rbtree only backend for pat memtype management tip-bot for Pallipadi, Venkatesh
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20100210195909.648914000@intel.com \
--to=venkatesh.pallipadi@intel.com \
--cc=hpa@zytor.com \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=suresh.b.siddha@intel.com \
--cc=tglx@linutronix.de \
--cc=wstrepp@gmx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).