Red-black tree is a kind of balanced binary tree. It has good properties. The nodes in the tree are ordered, and because it is balanced, it is also searched. There is no very bad situation, and the time complexity of binary tree based operations is O(log(N)). The Linux kernel uses a red-black tree to maintain memory blocks when managing vm_area_struct.
First look at the definition of red and black trees in include/linux/rbtree.h, as follows:
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 just a wrapper for struct rb_node* The advantage is that it does not seem to pass the secondary pointer. Yes, very simple. Look at the following important macros. Careful you will find that rb_parent_color is not that simple. Andrea Arcangeli uses a small trick here, but it's great. As the name implies, this member actually contains a pointer to the parent and the color of this node! How did it do it? Very simple, alignment works. Since it is the sizeof (long) size alignment, then on the IA-32, the lower two bits of the address of any rb_node structure must be zero. Instead of being empty, it is better to use them to represent the color. In fact, one is enough.
This way, to extract the parent pointer, just clear the lower two bits of the rb_parent_color member:
#define rb_parent(r) (( Struct rb_node *)((r)->rb_parent_color & ~3))
To take the color, just look at the last bit:
#define rb_color(r) ((r)->rb_parent_color & 1)
Testing colors and setting colors is also a matter of course. Special mention is made to the following inline function:
static inline void rb_link_node(struct rb_node * node, struct rb_node * parent, struct rb_node ** rb_link);
It sets parent to the parent node of node and lets rb_link point to node.
We focus on lib/rbtree.c and look at some of the important algorithms associated with red-black trees. Before we start, let's recall the rules of the red-black tree:
1. Each node is either red or black;
2. The root node must be Black;
3. Red nodes If the child has children, their children 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 a sorting tree to be balanced.
__rb_rotate_left is a left-hand rotation of the node node in the tree rooted at root, and __rb_rotate_right is right-handed. These two functions are for subsequent insert and delete services, rather than providing an interface to the outside.
The newly inserted nodes are set to leaves, dyed red, if the above rules are broken after insertion, the color and rotation can be restored, and the binary tree is rebalanced. The interface function for the insert operation is
void rb_insert_color(struct rb_node *node, struct rb_root *root);
It puts the determined parent node The node node of the point is integrated into the red-black tree rooted at root. The analysis of the specific algorithm can refer to Section 14.3 in [1]. The implementation here is almost exactly the same as the one in the book. How to determine the node's parent node should be done manually by calling rb_insert_color. It is worth pointing out that although the insert operation requires a loop iteration, the total number of rotations will not exceed twice! So the efficiency is still very optimistic.
The deletion operation is more or less troublesome. It must first perform the deletion like "Ordinary Binary Search Tree", and then judge whether to execute further according to the color of the deleted node. Operation. The interface to be deleted is:
void rb_erase(struct rb_node *node, struct rb_root *root);
In fact, it does not actually delete node Instead, just let it break away from the tree rooted at root, and finally it has to decide whether to call __rb_erase_color to adjust. For the explanation of the specific algorithm, refer to Sections 13.3 and 14.4 of [1], RB-DELETE-FIXUP in the corresponding book of __rb_erase_color, and the implementation here is basically the same as that in the book.
The remaining interfaces are simpler.
struct rb_node *rb_first(struct rb_root *root);
Find and return the smallest one in the tree rooted at root Node, as long as you go from the root node to the left.
struct rb_node *rb_last(struct rb_root *root);
is to find and return the largest one, keep going to the right.
struct rb_node *rb_next(struct rb_node *node);
Returning the succession of node in the tree is a bit more complicated. 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 should look up and find the node of the left child of the father of the overlapping node, return Parent node. If the above has reached the root node, it returns NULL.
struct rb_node *rb_prev(struct rb_node *node);
Returns the precursor of node and is symmetric with the operation in rb_next.
void rb_replace_node(struct rb_node *victim, struct rb_node *new, struct rb_root *root);
Replace root with root The victim node in the tree.
A typical example of a red-black tree interface is as follows:
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;
After linux rm deletes the file, recovery is more troublesome. Even if it is restored, the file na
Requirement Description Set SNAT policy using iptables Make hosts on 192.168.100.0/24 network segmen
First install CentOS6 to install rp-pppoe this software, the previous version of centos is installed
According to foreign media reports, many users, like the author, have been intere
Linux/Unix operating system is in the desktop control of the intranet
XXX is not in the sudoers file. This incident will be report
Two ways to install SUSE Linux10 on a hard disk
STM32 uses IAP to update user programs
How to use the SOFTETHER server under the Linux operating system
How to install phpmyadmin under Linux
How to avoid shell scripts being run multiple times at the same time
Linux device driver learning (0)-Hello, world! Module
Install the Linux operating system through the image file on the hard disk
WebLogic installation and configuration on Linux operating system
Why is it time to modify the Linux system with the date command?
Change the Win10 notification box to Win7 "Balloon" type method
IE download error to see if it is the Thunder
Win10 new preview before push User feedback suggestions are deleted
The first time to run Win8 black screen solution under dual system
How to use k treasure? Agricultural Bank k Bao payment transfer graphic tutorial
Win10 system official version of the quick start function how to close (graphic tutorial)
Win8 system windows defender can not start how to do?
u disk system appears how to solve the white screen computer?