2007-12-10 15:11:51 +03:00
/*
Red Black Trees
( C ) 1999 Andrea Arcangeli < andrea @ suse . de >
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
linux / include / linux / rbtree . h
To use rbtrees you ' ll have to implement your own insert and search cores .
This will avoid us to use callbacks and to drop drammatically performances .
I know it ' s not the cleaner way , but in C ( not in C + + ) to get
performances and genericity . . .
Some example of insert and search follows here . The search is a plain
normal search over an ordered tree . The insert instead must be implemented
int two steps : as first thing the code must insert the element in
order as a red leaf in the tree , then the support library function
rb_insert_color ( ) must be called . Such function will do the
not trivial work to rebalance the rbtree if necessary .
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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 ;
}
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
# ifndef _LINUX_RBTREE_H
# define _LINUX_RBTREE_H
struct rb_node
{
unsigned long rb_parent_color ;
struct rb_node * rb_right ;
struct rb_node * rb_left ;
2007-12-10 15:20:24 +03:00
} ;
2007-12-10 15:11:51 +03:00
struct rb_root
{
struct rb_node * rb_node ;
} ;
# define RB_ROOT (struct rb_root) { NULL, }
2007-12-10 15:20:24 +03:00
#if 0
# define rb_entry(ptr, type, member) container_of(ptr, type, member)
# endif
2007-12-10 15:11:51 +03:00
2007-12-10 15:20:24 +03:00
void rb_insert_color ( struct rb_node * , struct rb_root * ) ;
void rb_erase ( struct rb_node * , struct rb_root * ) ;
2007-12-10 15:11:51 +03:00
/* Find logical next and previous nodes in a tree */
2007-12-10 15:20:24 +03:00
struct rb_node * rb_next ( struct rb_node * ) ;
struct rb_node * rb_prev ( struct rb_node * ) ;
struct rb_node * rb_first ( struct rb_root * ) ;
struct rb_node * rb_last ( struct rb_root * ) ;
2007-12-10 15:11:51 +03:00
/* Fast replacement of a single node without remove/rebalance/add/rebalance */
2007-12-10 15:20:24 +03:00
extern void rb_replace_node ( struct rb_node * victim , struct rb_node * new_node ,
2007-12-10 15:11:51 +03:00
struct rb_root * root ) ;
2007-12-10 15:20:24 +03:00
void rb_link_node ( struct rb_node * node , struct rb_node * parent ,
struct rb_node * * rb_link ) ;
2007-12-10 15:11:51 +03:00
# endif /* _LINUX_RBTREE_H */