forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
rblist is the rbtree based code from strlist. It will be the common code for strlist and the to-be-introduced intlist. Signed-off-by: David Ahern <[email protected]> Cc: Frederic Weisbecker <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Link: http://lkml.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
- Loading branch information
Showing
3 changed files
with
156 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
/* | ||
* Based on strlist.c by: | ||
* (c) 2009 Arnaldo Carvalho de Melo <[email protected]> | ||
* | ||
* 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); | ||
rblist->node_delete(rblist, rb_node); | ||
} | ||
|
||
struct rb_node *rblist__find(struct rblist *rblist, const void *entry) | ||
{ | ||
struct rb_node **p = &rblist->entries.rb_node; | ||
struct rb_node *parent = NULL; | ||
|
||
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; | ||
} | ||
|
||
return NULL; | ||
} | ||
|
||
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); | ||
rb_erase(pos, &rblist->entries); | ||
rblist->node_delete(rblist, pos); | ||
} | ||
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; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
#ifndef __PERF_RBLIST_H | ||
#define __PERF_RBLIST_H | ||
|
||
#include <linux/rbtree.h> | ||
#include <stdbool.h> | ||
|
||
/* | ||
* create node structs of the form: | ||
* struct my_node { | ||
* struct rb_node rb_node; | ||
* ... my data ... | ||
* }; | ||
* | ||
* create list structs of the form: | ||
* struct mylist { | ||
* struct rblist rblist; | ||
* ... my data ... | ||
* }; | ||
*/ | ||
|
||
struct rblist { | ||
struct rb_root entries; | ||
unsigned int nr_entries; | ||
|
||
int (*node_cmp)(struct rb_node *rbn, const void *entry); | ||
struct rb_node *(*node_new)(struct rblist *rlist, const void *new_entry); | ||
void (*node_delete)(struct rblist *rblist, struct rb_node *rb_node); | ||
}; | ||
|
||
void rblist__init(struct rblist *rblist); | ||
void rblist__delete(struct rblist *rblist); | ||
int rblist__add_node(struct rblist *rblist, const void *new_entry); | ||
void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node); | ||
struct rb_node *rblist__find(struct rblist *rblist, const void *entry); | ||
struct rb_node *rblist__entry(const struct rblist *rblist, unsigned int idx); | ||
|
||
static inline bool rblist__empty(const struct rblist *rblist) | ||
{ | ||
return rblist->nr_entries == 0; | ||
} | ||
|
||
static inline unsigned int rblist__nr_entries(const struct rblist *rblist) | ||
{ | ||
return rblist->nr_entries; | ||
} | ||
|
||
#endif /* __PERF_RBLIST_H */ |