Red/black tree in Linux Kernel

Source: Internet
Author: User

The red-black tree is a type of balanced binary tree. It has a good nature. The nodes in the tree are ordered, and because it is a balance, the search will not be very bad, the time complexity of binary tree-based operations is O (log (n )). During vm_area_struct management, the Linux kernel uses a red/black tree to maintain memory blocks.

First go to include/Linux/rbtree. h to see some definitions of the red and black trees, as shown below:

[Copy to clipboard] [-]

Code:

Struct rb_node
{
Unsigned long rb_parent_color;
# Define rb_red 0
# Define rb_black 1
Struct rb_node * rb_right;
Struct rb_node * rb_left;
} _ Attribute _ (aligned (sizeof (long ))));

Struct rb_root is only a package of struct rb_node *. The advantage of this is that it does not seem to have to pass the second-level pointer. Good, very simple. Let's look at the following important macros. You will surely find that rb_parent_color is actually not that simple. Andrea arcangeli uses a small trick here, but it is very good. As the name implies, this member actually contains the pointer to the parent and the color of this node! How does it do it? Very simple. Alignment plays a role. Since it is sizeof (long) size alignment, then on the IA-32, any rb_node struct address of the low two must be zero, rather than empty, it is better to use them to represent the color, there are two colors. In fact, one is enough.

In this way, to extract the parent pointer, you only need to clear the lower two digits of the rb_parent_color member:

[Copy to clipboard] [-]

Code:

# Define rb_parent (R) (struct rb_node *) (R)-> rb_parent_color &~ 3 ))

You only need to check the last digit for the color:

[Copy to clipboard] [-]

Code:

# Define rb_color (R)-> rb_parent_color & 1)

Testing colors and setting colors are also a matter of course. Specifically, the following inline function is required:

[Copy to clipboard] [-]

Code:

Static inline void rb_link_node (struct rb_node * node, struct rb_node * parent, struct rb_node ** rb_link );

It sets the parent as the parent node of the node and points rb_link to the node.

We will focus on lib/rbtree. C and look at some important algorithms related to the red and black trees. Before we start, let's recall the rules of the red and black trees:

1. Each node is either red or black;

2. The root node must be black;

3. If a child has a red node, the child must be black;

4. Each path from the root node to the leaf must contain the same number of black nodes.

These four rules can limit that a sorting tree is balanced.

_ Rb_rotate_left is to left the node in the tree root, __rb_rotate_right is to right. These two functions provide services for insertion and deletion, rather than external interfaces.

The newly inserted nodes are all set to leaves and red. If the above rules are broken after insertion, the color and rotation can be restored, and the binary tree is rebalancing. The interface function of the insert operation is

[Copy to clipboard] [-]

Code:

Void rb_insert_color (struct rb_node * node, struct rb_root * root );

It integrates the node nodes of the identified parent node into the red/black tree with the root node. For more information about the algorithm analysis, see section 14.3 in [1, the implementation here is almost the same as that described in the book. How to determine whether the parent node of a node should be completed through manual overlap before calling rb_insert_color. It is worth noting that although the insert operation requires a loop iteration, the total number of rotations will not exceed two! Therefore, the efficiency is very optimistic.

The delete operation is more or less troublesome. It must first perform a "delete" like a common binary search tree, and then determine whether to perform further operations based on the color of the delete node. The deletion interface is:

[Copy to clipboard] [-]

Code:

Void rb_erase (struct rb_node * node, struct rb_root * root );

In fact, it does not actually Delete the node, but just disconnects it from the root tree. Finally, it also determines whether to call _ rb_erase_color to adjust it. For more information about the specific algorithm, see section 13.3 and section 14.4 in [1]. __rb_erase_color corresponds to the RB-DELETE-FIXUP in the book. The implementation here is basically the same as that in the book.

The remaining several interfaces are relatively simple.

[Copy to clipboard] [-]

Code:

Struct rb_node * rb_first (struct rb_root * root );

Find and return the smallest node in the tree with root as the root node, as long as you keep walking from the root node to the left.

[Copy to clipboard] [-]

Code:

Struct rb_node * rb_last (struct rb_root * root );

Is to find and return the largest one, always to the right.

[Copy to clipboard] [-]

Code:

Struct rb_node * rb_next (struct rb_node * node );

Returns the successor of the node in the tree, which is a little more complex. If the right child of node is not empty, it only needs to return the smallest node in the right subtree of node. If it is empty, it needs to look up, find the child node whose child id is the parent node and return to the parent node. If it reaches the root node, null is returned.

[Copy to clipboard] [-]

Code:

Struct rb_node * rb_prev (struct rb_node * node );

Returns the node precursor, which is symmetric with the operations in rb_next.

[Copy to clipboard] [-]

Code:

Void rb_replace_node (struct rb_node * victim, struct rb_node * New, struct rb_root * root );

Replace the victim node in the tree with "new" as the root.

A typical example of the red/black tree interface is as follows:

[Copy to clipboard] [-]

Code:

Static inline struct page * rb_search_page_cache (struct inode * inode,
Unsigned long offset)
{
Struct rb_node * n = inode-> I _rb_page_cache.rb_node;
Struct page * page;

While (N)
{
Page = rb_entry (n, struct page, rb_page_cache );

If (offset <page-> offset)
N = N-> rb_left;
Else if (Offset> page-> offset)
N = N-> rb_right;
Else
Return page;
}
Return NULL;
}

Static inline struct page * _ rb_insert_page_cache (struct inode * inode,
Unsigned long offset,
Struct rb_node * node)
{
Struct rb_node ** P = & inode-> I _rb_page_cache.rb_node;
Struct rb_node * parent = NULL;
Struct page * page;

While (* P)
{
Parent = * P;
Page = rb_entry (parent, struct page, rb_page_cache );

If (offset <page-> offset)
P = & (* P)-> rb_left;
Else if (Offset> page-> offset)
P = & (* P)-> rb_right;
Else
Return page;
}

Rb_link_node (node, parent, P );

Return NULL;
}

Static inline struct page * rb_insert_page_cache (struct inode * inode,
Unsigned long offset,
Struct rb_node * node)
{
Struct page * ret;
If (ret = _ rb_insert_page_cache (inode, offset, node )))
Goto out;
Rb_insert_color (node, & inode-> I _rb_page_cache );
Out:
Return ret;
}

Because of these good properties and the simplicity of interfaces in implementation, the red/black tree is widely used in kernel programming, greatly improving the efficiency of the kernel.

References:

1. Introduction to algorithms, Thomas H. cormen, Charles E. leiserson, and Ronald L. Rivest, MIT Press.

2. Understanding the Linux kernel, 3rd edition, Daniel P. bovet, Marco cesati, O 'Reilly.

3. Linux kernel 2.6.19 source code.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.