perf tools: Change strlist to use the new rblist

Replaces the direct use of rbtree code with the rblist API. In the end
the patch is a no-op on strlist functionality; the API for strlist is
not changed, only its implementaton.

Signed-off-by: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@redhat.com>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: http://lkml.kernel.org/r/1343709095-7089-3-git-send-email-dsahern@gmail.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
This commit is contained in:
David Ahern 2012-07-30 22:31:33 -06:00 committed by Arnaldo Carvalho de Melo
parent 37bbd3fff1
commit ee8dd3ca43
2 changed files with 58 additions and 85 deletions

View File

@ -10,23 +10,28 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
static struct str_node *str_node__new(const char *s, bool dupstr) static
struct rb_node *strlist__node_new(struct rblist *rblist, const void *entry)
{ {
struct str_node *self = malloc(sizeof(*self)); const char *s = entry;
struct rb_node *rc = NULL;
struct strlist *strlist = container_of(rblist, struct strlist, rblist);
struct str_node *snode = malloc(sizeof(*snode));
if (self != NULL) { if (snode != NULL) {
if (dupstr) { if (strlist->dupstr) {
s = strdup(s); s = strdup(s);
if (s == NULL) if (s == NULL)
goto out_delete; goto out_delete;
} }
self->s = s; snode->s = s;
rc = &snode->rb_node;
} }
return self; return rc;
out_delete: out_delete:
free(self); free(snode);
return NULL; return NULL;
} }
@ -37,36 +42,26 @@ static void str_node__delete(struct str_node *self, bool dupstr)
free(self); free(self);
} }
int strlist__add(struct strlist *self, const char *new_entry) static
void strlist__node_delete(struct rblist *rblist, struct rb_node *rb_node)
{ {
struct rb_node **p = &self->entries.rb_node; struct strlist *slist = container_of(rblist, struct strlist, rblist);
struct rb_node *parent = NULL; struct str_node *snode = container_of(rb_node, struct str_node, rb_node);
struct str_node *sn;
while (*p != NULL) { str_node__delete(snode, slist->dupstr);
int rc;
parent = *p;
sn = rb_entry(parent, struct str_node, rb_node);
rc = strcmp(sn->s, new_entry);
if (rc > 0)
p = &(*p)->rb_left;
else if (rc < 0)
p = &(*p)->rb_right;
else
return -EEXIST;
} }
sn = str_node__new(new_entry, self->dupstr); static int strlist__node_cmp(struct rb_node *rb_node, const void *entry)
if (sn == NULL) {
return -ENOMEM; const char *str = entry;
struct str_node *snode = container_of(rb_node, struct str_node, rb_node);
rb_link_node(&sn->rb_node, parent, p); return strcmp(snode->s, str);
rb_insert_color(&sn->rb_node, &self->entries); }
++self->nr_entries;
return 0; int strlist__add(struct strlist *self, const char *new_entry)
{
return rblist__add_node(&self->rblist, new_entry);
} }
int strlist__load(struct strlist *self, const char *filename) int strlist__load(struct strlist *self, const char *filename)
@ -96,34 +91,20 @@ out:
return err; return err;
} }
void strlist__remove(struct strlist *self, struct str_node *sn) void strlist__remove(struct strlist *slist, struct str_node *snode)
{ {
rb_erase(&sn->rb_node, &self->entries); str_node__delete(snode, slist->dupstr);
str_node__delete(sn, self->dupstr);
} }
struct str_node *strlist__find(struct strlist *self, const char *entry) struct str_node *strlist__find(struct strlist *slist, const char *entry)
{ {
struct rb_node **p = &self->entries.rb_node; struct str_node *snode = NULL;
struct rb_node *parent = NULL; struct rb_node *rb_node = rblist__find(&slist->rblist, entry);
while (*p != NULL) { if (rb_node)
struct str_node *sn; snode = container_of(rb_node, struct str_node, rb_node);
int rc;
parent = *p; return snode;
sn = rb_entry(parent, struct str_node, rb_node);
rc = strcmp(sn->s, entry);
if (rc > 0)
p = &(*p)->rb_left;
else if (rc < 0)
p = &(*p)->rb_right;
else
return sn;
}
return NULL;
} }
static int strlist__parse_list_entry(struct strlist *self, const char *s) static int strlist__parse_list_entry(struct strlist *self, const char *s)
@ -156,9 +137,12 @@ struct strlist *strlist__new(bool dupstr, const char *slist)
struct strlist *self = malloc(sizeof(*self)); struct strlist *self = malloc(sizeof(*self));
if (self != NULL) { if (self != NULL) {
self->entries = RB_ROOT; rblist__init(&self->rblist);
self->rblist.node_cmp = strlist__node_cmp;
self->rblist.node_new = strlist__node_new;
self->rblist.node_delete = strlist__node_delete;
self->dupstr = dupstr; self->dupstr = dupstr;
self->nr_entries = 0;
if (slist && strlist__parse_list(self, slist) != 0) if (slist && strlist__parse_list(self, slist) != 0)
goto out_error; goto out_error;
} }
@ -171,30 +155,18 @@ out_error:
void strlist__delete(struct strlist *self) void strlist__delete(struct strlist *self)
{ {
if (self != NULL) { if (self != NULL)
struct str_node *pos; rblist__delete(&self->rblist);
struct rb_node *next = rb_first(&self->entries);
while (next) {
pos = rb_entry(next, struct str_node, rb_node);
next = rb_next(&pos->rb_node);
strlist__remove(self, pos);
}
self->entries = RB_ROOT;
free(self);
}
} }
struct str_node *strlist__entry(const struct strlist *self, unsigned int idx) struct str_node *strlist__entry(const struct strlist *slist, unsigned int idx)
{ {
struct rb_node *nd; struct str_node *snode = NULL;
struct rb_node *rb_node;
for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { rb_node = rblist__entry(&slist->rblist, idx);
struct str_node *pos = rb_entry(nd, struct str_node, rb_node); if (rb_node)
snode = container_of(rb_node, struct str_node, rb_node);
if (!idx--) return snode;
return pos;
}
return NULL;
} }

View File

@ -4,14 +4,15 @@
#include <linux/rbtree.h> #include <linux/rbtree.h>
#include <stdbool.h> #include <stdbool.h>
#include "rblist.h"
struct str_node { struct str_node {
struct rb_node rb_node; struct rb_node rb_node;
const char *s; const char *s;
}; };
struct strlist { struct strlist {
struct rb_root entries; struct rblist rblist;
unsigned int nr_entries;
bool dupstr; bool dupstr;
}; };
@ -32,18 +33,18 @@ static inline bool strlist__has_entry(struct strlist *self, const char *entry)
static inline bool strlist__empty(const struct strlist *self) static inline bool strlist__empty(const struct strlist *self)
{ {
return self->nr_entries == 0; return rblist__empty(&self->rblist);
} }
static inline unsigned int strlist__nr_entries(const struct strlist *self) static inline unsigned int strlist__nr_entries(const struct strlist *self)
{ {
return self->nr_entries; return rblist__nr_entries(&self->rblist);
} }
/* For strlist iteration */ /* For strlist iteration */
static inline struct str_node *strlist__first(struct strlist *self) static inline struct str_node *strlist__first(struct strlist *self)
{ {
struct rb_node *rn = rb_first(&self->entries); struct rb_node *rn = rb_first(&self->rblist.entries);
return rn ? rb_entry(rn, struct str_node, rb_node) : NULL; return rn ? rb_entry(rn, struct str_node, rb_node) : NULL;
} }
static inline struct str_node *strlist__next(struct str_node *sn) static inline struct str_node *strlist__next(struct str_node *sn)