+struct node {
+ struct flist_head list;
+ struct rb_node rb;
+ unsigned long long val;
+ unsigned long hits;
+};
+
+static struct flist_head *hash;
+static unsigned long hash_bits = 24;
+static unsigned long hash_size = 1 << 24;
+static struct rb_root rb;
+
+static struct node *hash_lookup(unsigned long long val)
+{
+ struct flist_head *l = &hash[hash_long(val, hash_bits)];
+ struct flist_head *entry;
+ struct node *n;
+
+ flist_for_each(entry, l) {
+ n = flist_entry(entry, struct node, list);
+ if (n->val == val)
+ return n;
+ }
+
+ return NULL;
+}
+
+static void hash_insert(unsigned long long val)
+{
+ struct flist_head *l = &hash[hash_long(val, hash_bits)];
+ struct node *n = malloc(sizeof(*n));
+
+ n->val = val;
+ n->hits = 1;
+ flist_add_tail(&n->list, l);
+}
+
+static void rb_insert(struct node *n)
+{
+ struct rb_node **p, *parent;
+
+ memset(&n->rb, 0, sizeof(n->rb));
+ p = &rb.rb_node;
+ parent = NULL;
+ while (*p) {
+ struct node *__n;
+
+ parent = *p;
+ __n = rb_entry(parent, struct node, rb);
+ if (n->hits > __n->hits)
+ p = &(*p)->rb_left;
+ else
+ p = &(*p)->rb_right;
+ }
+
+ rb_link_node(&n->rb, parent, p);
+ rb_insert_color(&n->rb, &rb);
+}
+
+static unsigned long rb_add(struct flist_head *list)