summaryrefslogtreecommitdiff
path: root/tools/perf/util/ui/browser.c
diff options
context:
space:
mode:
authorArnaldo Carvalho de Melo <acme@redhat.com>2011-10-14 12:27:54 -0300
committerArnaldo Carvalho de Melo <acme@redhat.com>2011-10-14 12:49:08 -0300
commit250611cfb60ff0c50ca189da7ca727dcd78e8cee (patch)
tree9983dca2ccca7edfb18218099c5bc64dc206ab5f /tools/perf/util/ui/browser.c
parent7296d66aca60a71076a5f0ffab39730e7788590f (diff)
perf ui browser: Add filter method
Its becoming common to allow the user to filter out parts of the data structure being browsed, like already done in the hists browser and in the annotate browser in the next commit, so provide it directly in the ui_browser class list_head helpers. More work required to move the equivalent routines found now in the hists browser to the rb_tree helpers. Cc: David Ahern <dsahern@gmail.com> Cc: Frederic Weisbecker <fweisbec@gmail.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Stephane Eranian <eranian@google.com> Link: http://lkml.kernel.org/n/tip-jk7danyt1d9ji4e3o2xuthpn@git.kernel.org Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/ui/browser.c')
-rw-r--r--tools/perf/util/ui/browser.c51
1 files changed, 42 insertions, 9 deletions
diff --git a/tools/perf/util/ui/browser.c b/tools/perf/util/ui/browser.c
index 078ceaf5f8c1..a54b926efe2b 100644
--- a/tools/perf/util/ui/browser.c
+++ b/tools/perf/util/ui/browser.c
@@ -42,31 +42,62 @@ void ui_browser__gotorc(struct ui_browser *self, int y, int x)
SLsmg_gotorc(self->y + y, self->x + x);
}
+static struct list_head *
+ui_browser__list_head_filter_entries(struct ui_browser *browser,
+ struct list_head *pos)
+{
+ do {
+ if (!browser->filter || !browser->filter(browser, pos))
+ return pos;
+ pos = pos->next;
+ } while (pos != browser->entries);
+
+ return NULL;
+}
+
+static struct list_head *
+ui_browser__list_head_filter_prev_entries(struct ui_browser *browser,
+ struct list_head *pos)
+{
+ do {
+ if (!browser->filter || !browser->filter(browser, pos))
+ return pos;
+ pos = pos->prev;
+ } while (pos != browser->entries);
+
+ return NULL;
+}
+
void ui_browser__list_head_seek(struct ui_browser *self, off_t offset, int whence)
{
struct list_head *head = self->entries;
struct list_head *pos;
+ if (self->nr_entries == 0)
+ return;
+
switch (whence) {
case SEEK_SET:
- pos = head->next;
+ pos = ui_browser__list_head_filter_entries(self, head->next);
break;
case SEEK_CUR:
pos = self->top;
break;
case SEEK_END:
- pos = head->prev;
+ pos = ui_browser__list_head_filter_prev_entries(self, head->prev);
break;
default:
return;
}
+ assert(pos != NULL);
+
if (offset > 0) {
while (offset-- != 0)
- pos = pos->next;
+ pos = ui_browser__list_head_filter_entries(self, pos->next);
} else {
while (offset++ != 0)
- pos = pos->prev;
+ pos = ui_browser__list_head_filter_prev_entries(self, pos->prev);
}
self->top = pos;
@@ -365,15 +396,17 @@ unsigned int ui_browser__list_head_refresh(struct ui_browser *self)
int row = 0;
if (self->top == NULL || self->top == self->entries)
- self->top = head->next;
+ self->top = ui_browser__list_head_filter_entries(self, head->next);
pos = self->top;
list_for_each_from(pos, head) {
- ui_browser__gotorc(self, row, 0);
- self->write(self, pos, row);
- if (++row == self->height)
- break;
+ if (!self->filter || !self->filter(self, pos)) {
+ ui_browser__gotorc(self, row, 0);
+ self->write(self, pos, row);
+ if (++row == self->height)
+ break;
+ }
}
return row;