diff options
Diffstat (limited to 'lib/trace-cmd/trace-hash.c')
-rw-r--r-- | lib/trace-cmd/trace-hash.c | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/lib/trace-cmd/trace-hash.c b/lib/trace-cmd/trace-hash.c new file mode 100644 index 00000000..bed97323 --- /dev/null +++ b/lib/trace-cmd/trace-hash.c @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2014, Steven Rostedt <srostedt@redhat.com> + * + */ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <errno.h> + +#include "trace-cmd-private.h" +#include "trace-hash.h" + +int __hidden trace_hash_init(struct trace_hash *hash, int buckets) +{ + memset(hash, 0, sizeof(*hash)); + + hash->buckets = calloc(sizeof(*hash->buckets), buckets); + if (!hash->buckets) + return -ENOMEM; + hash->nr_buckets = buckets; + + /* If a power of two then we can shortcut */ + if (!(buckets & (buckets - 1))) + hash->power = buckets - 1; + + return 0; +} + +void __hidden trace_hash_free(struct trace_hash *hash) +{ + free(hash->buckets); +} + +int __hidden trace_hash_empty(struct trace_hash *hash) +{ + struct trace_hash_item **bucket; + + trace_hash_for_each_bucket(bucket, hash) + if (*bucket) + return 0; + return 1; +} + +int __hidden trace_hash_add(struct trace_hash *hash, struct trace_hash_item *item) +{ + struct trace_hash_item *next; + int bucket = hash->power ? item->key & hash->power : + item->key % hash->nr_buckets; + + if (hash->buckets[bucket]) { + next = hash->buckets[bucket]; + next->prev = item; + } else + next = NULL; + + item->next = next; + item->prev = (struct trace_hash_item *)&hash->buckets[bucket]; + + hash->buckets[bucket] = item; + + return 1; +} + + __hidden struct trace_hash_item * +trace_hash_find(struct trace_hash *hash, unsigned long long key, + trace_hash_func match, void *data) +{ + struct trace_hash_item *item; + int bucket = hash->power ? key & hash->power : + key % hash->nr_buckets; + + for (item = hash->buckets[bucket]; item; item = item->next) { + if (item->key == key) { + if (!match) + return item; + if (match(item, data)) + return item; + } + } + + return NULL; +} |