aboutsummaryrefslogtreecommitdiffstats
path: root/tools/perf/util/strlist.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/perf/util/strlist.c')
-rw-r--r--tools/perf/util/strlist.c130
1 files changed, 79 insertions, 51 deletions
diff --git a/tools/perf/util/strlist.c b/tools/perf/util/strlist.c
index 155d8b7078a..6783a204355 100644
--- a/tools/perf/util/strlist.c
+++ b/tools/perf/util/strlist.c
@@ -10,28 +10,23 @@
10#include <stdlib.h> 10#include <stdlib.h>
11#include <string.h> 11#include <string.h>
12 12
13static 13static struct str_node *str_node__new(const char *s, bool dupstr)
14struct rb_node *strlist__node_new(struct rblist *rblist, const void *entry)
15{ 14{
16 const char *s = entry; 15 struct str_node *self = malloc(sizeof(*self));
17 struct rb_node *rc = NULL;
18 struct strlist *strlist = container_of(rblist, struct strlist, rblist);
19 struct str_node *snode = malloc(sizeof(*snode));
20 16
21 if (snode != NULL) { 17 if (self != NULL) {
22 if (strlist->dupstr) { 18 if (dupstr) {
23 s = strdup(s); 19 s = strdup(s);
24 if (s == NULL) 20 if (s == NULL)
25 goto out_delete; 21 goto out_delete;
26 } 22 }
27 snode->s = s; 23 self->s = s;
28 rc = &snode->rb_node;
29 } 24 }
30 25
31 return rc; 26 return self;
32 27
33out_delete: 28out_delete:
34 free(snode); 29 free(self);
35 return NULL; 30 return NULL;
36} 31}
37 32
@@ -42,26 +37,36 @@ static void str_node__delete(struct str_node *self, bool dupstr)
42 free(self); 37 free(self);
43} 38}
44 39
45static 40int strlist__add(struct strlist *self, const char *new_entry)
46void strlist__node_delete(struct rblist *rblist, struct rb_node *rb_node)
47{ 41{
48 struct strlist *slist = container_of(rblist, struct strlist, rblist); 42 struct rb_node **p = &self->entries.rb_node;
49 struct str_node *snode = container_of(rb_node, struct str_node, rb_node); 43 struct rb_node *parent = NULL;
50 44 struct str_node *sn;
51 str_node__delete(snode, slist->dupstr); 45
52} 46 while (*p != NULL) {
47 int rc;
48
49 parent = *p;
50 sn = rb_entry(parent, struct str_node, rb_node);
51 rc = strcmp(sn->s, new_entry);
52
53 if (rc > 0)
54 p = &(*p)->rb_left;
55 else if (rc < 0)
56 p = &(*p)->rb_right;
57 else
58 return -EEXIST;
59 }
53 60
54static int strlist__node_cmp(struct rb_node *rb_node, const void *entry) 61 sn = str_node__new(new_entry, self->dupstr);
55{ 62 if (sn == NULL)
56 const char *str = entry; 63 return -ENOMEM;
57 struct str_node *snode = container_of(rb_node, struct str_node, rb_node);
58 64
59 return strcmp(snode->s, str); 65 rb_link_node(&sn->rb_node, parent, p);
60} 66 rb_insert_color(&sn->rb_node, &self->entries);
67 ++self->nr_entries;
61 68
62int strlist__add(struct strlist *self, const char *new_entry) 69 return 0;
63{
64 return rblist__add_node(&self->rblist, new_entry);
65} 70}
66 71
67int strlist__load(struct strlist *self, const char *filename) 72int strlist__load(struct strlist *self, const char *filename)
@@ -91,20 +96,34 @@ out:
91 return err; 96 return err;
92} 97}
93 98
94void strlist__remove(struct strlist *slist, struct str_node *snode) 99void strlist__remove(struct strlist *self, struct str_node *sn)
95{ 100{
96 rblist__remove_node(&slist->rblist, &snode->rb_node); 101 rb_erase(&sn->rb_node, &self->entries);
102 str_node__delete(sn, self->dupstr);
97} 103}
98 104
99struct str_node *strlist__find(struct strlist *slist, const char *entry) 105struct str_node *strlist__find(struct strlist *self, const char *entry)
100{ 106{
101 struct str_node *snode = NULL; 107 struct rb_node **p = &self->entries.rb_node;
102 struct rb_node *rb_node = rblist__find(&slist->rblist, entry); 108 struct rb_node *parent = NULL;
103 109
104 if (rb_node) 110 while (*p != NULL) {
105 snode = container_of(rb_node, struct str_node, rb_node); 111 struct str_node *sn;
112 int rc;
113
114 parent = *p;
115 sn = rb_entry(parent, struct str_node, rb_node);
116 rc = strcmp(sn->s, entry);
117
118 if (rc > 0)
119 p = &(*p)->rb_left;
120 else if (rc < 0)
121 p = &(*p)->rb_right;
122 else
123 return sn;
124 }
106 125
107 return snode; 126 return NULL;
108} 127}
109 128
110static int strlist__parse_list_entry(struct strlist *self, const char *s) 129static int strlist__parse_list_entry(struct strlist *self, const char *s)
@@ -137,12 +156,9 @@ struct strlist *strlist__new(bool dupstr, const char *slist)
137 struct strlist *self = malloc(sizeof(*self)); 156 struct strlist *self = malloc(sizeof(*self));
138 157
139 if (self != NULL) { 158 if (self != NULL) {
140 rblist__init(&self->rblist); 159 self->entries = RB_ROOT;
141 self->rblist.node_cmp = strlist__node_cmp;
142 self->rblist.node_new = strlist__node_new;
143 self->rblist.node_delete = strlist__node_delete;
144
145 self->dupstr = dupstr; 160 self->dupstr = dupstr;
161 self->nr_entries = 0;
146 if (slist && strlist__parse_list(self, slist) != 0) 162 if (slist && strlist__parse_list(self, slist) != 0)
147 goto out_error; 163 goto out_error;
148 } 164 }
@@ -155,18 +171,30 @@ out_error:
155 171
156void strlist__delete(struct strlist *self) 172void strlist__delete(struct strlist *self)
157{ 173{
158 if (self != NULL) 174 if (self != NULL) {
159 rblist__delete(&self->rblist); 175 struct str_node *pos;
176 struct rb_node *next = rb_first(&self->entries);
177
178 while (next) {
179 pos = rb_entry(next, struct str_node, rb_node);
180 next = rb_next(&pos->rb_node);
181 strlist__remove(self, pos);
182 }
183 self->entries = RB_ROOT;
184 free(self);
185 }
160} 186}
161 187
162struct str_node *strlist__entry(const struct strlist *slist, unsigned int idx) 188struct str_node *strlist__entry(const struct strlist *self, unsigned int idx)
163{ 189{
164 struct str_node *snode = NULL; 190 struct rb_node *nd;
165 struct rb_node *rb_node;
166 191
167 rb_node = rblist__entry(&slist->rblist, idx); 192 for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) {
168 if (rb_node) 193 struct str_node *pos = rb_entry(nd, struct str_node, rb_node);
169 snode = container_of(rb_node, struct str_node, rb_node);
170 194
171 return snode; 195 if (!idx--)
196 return pos;
197 }
198
199 return NULL;
172} 200}