0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef _SS_HASHTAB_H_
0012 #define _SS_HASHTAB_H_
0013
0014 #include <linux/types.h>
0015 #include <linux/errno.h>
0016 #include <linux/sched.h>
0017
0018 #define HASHTAB_MAX_NODES U32_MAX
0019
0020 struct hashtab_key_params {
0021 u32 (*hash)(const void *key);
0022 int (*cmp)(const void *key1, const void *key2);
0023
0024 };
0025
0026 struct hashtab_node {
0027 void *key;
0028 void *datum;
0029 struct hashtab_node *next;
0030 };
0031
0032 struct hashtab {
0033 struct hashtab_node **htable;
0034 u32 size;
0035 u32 nel;
0036 };
0037
0038 struct hashtab_info {
0039 u32 slots_used;
0040 u32 max_chain_len;
0041 };
0042
0043
0044
0045
0046
0047
0048 int hashtab_init(struct hashtab *h, u32 nel_hint);
0049
0050 int __hashtab_insert(struct hashtab *h, struct hashtab_node **dst,
0051 void *key, void *datum);
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061 static inline int hashtab_insert(struct hashtab *h, void *key, void *datum,
0062 struct hashtab_key_params key_params)
0063 {
0064 u32 hvalue;
0065 struct hashtab_node *prev, *cur;
0066
0067 cond_resched();
0068
0069 if (!h->size || h->nel == HASHTAB_MAX_NODES)
0070 return -EINVAL;
0071
0072 hvalue = key_params.hash(key) & (h->size - 1);
0073 prev = NULL;
0074 cur = h->htable[hvalue];
0075 while (cur) {
0076 int cmp = key_params.cmp(key, cur->key);
0077
0078 if (cmp == 0)
0079 return -EEXIST;
0080 if (cmp < 0)
0081 break;
0082 prev = cur;
0083 cur = cur->next;
0084 }
0085
0086 return __hashtab_insert(h, prev ? &prev->next : &h->htable[hvalue],
0087 key, datum);
0088 }
0089
0090
0091
0092
0093
0094
0095
0096 static inline void *hashtab_search(struct hashtab *h, const void *key,
0097 struct hashtab_key_params key_params)
0098 {
0099 u32 hvalue;
0100 struct hashtab_node *cur;
0101
0102 if (!h->size)
0103 return NULL;
0104
0105 hvalue = key_params.hash(key) & (h->size - 1);
0106 cur = h->htable[hvalue];
0107 while (cur) {
0108 int cmp = key_params.cmp(key, cur->key);
0109
0110 if (cmp == 0)
0111 return cur->datum;
0112 if (cmp < 0)
0113 break;
0114 cur = cur->next;
0115 }
0116 return NULL;
0117 }
0118
0119
0120
0121
0122 void hashtab_destroy(struct hashtab *h);
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135 int hashtab_map(struct hashtab *h,
0136 int (*apply)(void *k, void *d, void *args),
0137 void *args);
0138
0139 int hashtab_duplicate(struct hashtab *new, struct hashtab *orig,
0140 int (*copy)(struct hashtab_node *new,
0141 struct hashtab_node *orig, void *args),
0142 int (*destroy)(void *k, void *d, void *args),
0143 void *args);
0144
0145
0146 void hashtab_stat(struct hashtab *h, struct hashtab_info *info);
0147
0148 #endif