2012-07-31 08:31:32 +04:00
/*
* Based on strlist . c by :
* ( c ) 2009 Arnaldo Carvalho de Melo < acme @ redhat . com >
*
* Licensed under the GPLv2 .
*/
# include <errno.h>
# include <stdio.h>
# include <stdlib.h>
# include "rblist.h"
int rblist__add_node ( struct rblist * rblist , const void * new_entry )
{
struct rb_node * * p = & rblist - > entries . rb_node ;
struct rb_node * parent = NULL , * new_node ;
while ( * p ! = NULL ) {
int rc ;
parent = * p ;
rc = rblist - > node_cmp ( parent , new_entry ) ;
if ( rc > 0 )
p = & ( * p ) - > rb_left ;
else if ( rc < 0 )
p = & ( * p ) - > rb_right ;
else
return - EEXIST ;
}
new_node = rblist - > node_new ( rblist , new_entry ) ;
if ( new_node = = NULL )
return - ENOMEM ;
rb_link_node ( new_node , parent , p ) ;
rb_insert_color ( new_node , & rblist - > entries ) ;
+ + rblist - > nr_entries ;
return 0 ;
}
void rblist__remove_node ( struct rblist * rblist , struct rb_node * rb_node )
{
rb_erase ( rb_node , & rblist - > entries ) ;
2012-08-31 11:09:18 +04:00
- - rblist - > nr_entries ;
2012-07-31 08:31:32 +04:00
rblist - > node_delete ( rblist , rb_node ) ;
}
2013-10-09 07:26:52 +04:00
static struct rb_node * __rblist__findnew ( struct rblist * rblist ,
const void * entry ,
bool create )
2012-07-31 08:31:32 +04:00
{
struct rb_node * * p = & rblist - > entries . rb_node ;
2013-10-09 07:26:52 +04:00
struct rb_node * parent = NULL , * new_node = NULL ;
2012-07-31 08:31:32 +04:00
while ( * p ! = NULL ) {
int rc ;
parent = * p ;
rc = rblist - > node_cmp ( parent , entry ) ;
if ( rc > 0 )
p = & ( * p ) - > rb_left ;
else if ( rc < 0 )
p = & ( * p ) - > rb_right ;
else
return parent ;
}
2013-10-09 07:26:52 +04:00
if ( create ) {
new_node = rblist - > node_new ( rblist , entry ) ;
if ( new_node ) {
rb_link_node ( new_node , parent , p ) ;
rb_insert_color ( new_node , & rblist - > entries ) ;
+ + rblist - > nr_entries ;
}
}
return new_node ;
}
struct rb_node * rblist__find ( struct rblist * rblist , const void * entry )
{
return __rblist__findnew ( rblist , entry , false ) ;
}
struct rb_node * rblist__findnew ( struct rblist * rblist , const void * entry )
{
return __rblist__findnew ( rblist , entry , true ) ;
2012-07-31 08:31:32 +04:00
}
void rblist__init ( struct rblist * rblist )
{
if ( rblist ! = NULL ) {
rblist - > entries = RB_ROOT ;
rblist - > nr_entries = 0 ;
}
return ;
}
void rblist__delete ( struct rblist * rblist )
{
if ( rblist ! = NULL ) {
struct rb_node * pos , * next = rb_first ( & rblist - > entries ) ;
while ( next ) {
pos = next ;
next = rb_next ( pos ) ;
2012-08-31 11:09:18 +04:00
rblist__remove_node ( rblist , pos ) ;
2012-07-31 08:31:32 +04:00
}
free ( rblist ) ;
}
}
struct rb_node * rblist__entry ( const struct rblist * rblist , unsigned int idx )
{
struct rb_node * node ;
for ( node = rb_first ( & rblist - > entries ) ; node ; node = rb_next ( node ) ) {
if ( ! idx - - )
return node ;
}
return NULL ;
}