6#ifndef RTE_MEMBER_HEAP_H
7#define RTE_MEMBER_HEAP_H
12#define LCHILD(x) (2 * x + 1)
13#define RCHILD(x) (2 * x + 2)
14#define PARENT(x) ((x - 1) / 2)
16#define HASH_BKT_SIZE 16
17#define HASH_HP_MULTI 4
18#define HASH_RESIZE_MULTI 2
21 uint16_t sig[HASH_BKT_SIZE];
22 uint16_t idx[HASH_BKT_SIZE];
29 struct hash_bkt buckets[0];
41 struct hash *hashtable;
46hash_table_insert(
const void *key,
int value,
int key_len,
struct hash *table)
48 uint32_t hash = MEMBER_HASH_FUNC(key, key_len, table->seed);
49 uint16_t idx = hash % table->bkt_cnt;
50 uint16_t sig = hash >> 16;
53 for (i = 0; i < HASH_BKT_SIZE; i++) {
54 if (table->buckets[idx].idx[i] == 0) {
55 table->buckets[idx].idx[i] = value;
56 table->buckets[idx].sig[i] = sig;
66hash_table_update(
const void *key,
int old_value,
int value,
int key_len,
struct hash *table)
68 uint32_t hash = MEMBER_HASH_FUNC(key, key_len, table->seed);
69 uint16_t idx = hash % table->bkt_cnt;
70 uint16_t sig = hash >> 16;
73 for (i = 0; i < HASH_BKT_SIZE; i++) {
74 if (table->buckets[idx].sig[i] == sig && table->buckets[idx].idx[i] == old_value) {
75 table->buckets[idx].idx[i] = value;
84hash_table_del(
const void *key, uint16_t value,
int key_len,
struct hash *table)
86 uint32_t hash = MEMBER_HASH_FUNC(key, key_len, table->seed);
87 uint16_t idx = hash % table->bkt_cnt;
88 uint16_t sig = hash >> 16;
91 for (i = 0; i < HASH_BKT_SIZE; i++) {
92 if (table->buckets[idx].sig[i] == sig && table->buckets[idx].idx[i] == value) {
93 table->buckets[idx].idx[i] = 0;
103hash_table_lookup(
const void *key,
int key_len,
struct minheap *hp)
105 struct hash *table = hp->hashtable;
106 uint32_t hash = MEMBER_HASH_FUNC(key, key_len, table->seed);
107 uint16_t idx = hash % table->bkt_cnt;
108 uint16_t sig = hash >> 16;
111 for (i = 0; i < HASH_BKT_SIZE; i++) {
112 if (table->buckets[idx].sig[i] == sig && table->buckets[idx].idx[i] != 0) {
113 uint32_t hp_idx = table->buckets[idx].idx[i] - 1;
115 if (memcmp(hp->elem[hp_idx].key, key, hp->key_len) == 0)
124resize_hash_table(
struct minheap *hp)
127 uint32_t new_bkt_cnt;
130 new_bkt_cnt = hp->hashtable->bkt_cnt * HASH_RESIZE_MULTI;
132 RTE_MEMBER_LOG(ERR,
"Sketch Minheap HT load factor is [%f]\n",
133 hp->hashtable->num_item / ((
float)hp->hashtable->bkt_cnt * HASH_BKT_SIZE));
134 RTE_MEMBER_LOG(ERR,
"Sketch Minheap HT resize happen!\n");
137 new_bkt_cnt *
sizeof(
struct hash_bkt),
138 RTE_CACHE_LINE_SIZE, hp->socket);
140 if (hp->hashtable == NULL) {
141 RTE_MEMBER_LOG(ERR,
"Sketch Minheap HT allocation failed\n");
145 hp->hashtable->bkt_cnt = new_bkt_cnt;
147 for (i = 0; i < hp->size; ++i) {
148 if (hash_table_insert(hp->elem[i].key,
149 i + 1, hp->key_len, hp->hashtable) < 0) {
151 "Sketch Minheap HT resize insert fail!\n");
164rte_member_minheap_find(
struct minheap *hp,
const void *key)
166 int idx = hash_table_lookup(key, hp->key_len, hp);
171rte_member_minheap_init(
struct minheap *heap,
int size,
172 uint32_t socket, uint32_t seed)
175 RTE_CACHE_LINE_SIZE, socket);
176 if (heap->elem == NULL) {
177 RTE_MEMBER_LOG(ERR,
"Sketch Minheap elem allocation failed\n");
181 uint32_t hash_bkt_cnt =
rte_align32pow2(size * HASH_HP_MULTI) / HASH_BKT_SIZE;
183 if (hash_bkt_cnt == 0)
187 hash_bkt_cnt *
sizeof(
struct hash_bkt),
188 RTE_CACHE_LINE_SIZE, socket);
190 if (heap->hashtable == NULL) {
191 RTE_MEMBER_LOG(ERR,
"Sketch Minheap HT allocation failed\n");
196 heap->hashtable->seed = seed;
197 heap->hashtable->bkt_cnt = hash_bkt_cnt;
198 heap->socket = socket;
205rte_member_heap_swap(
struct node *n1,
struct node *n2)
207 struct node temp = *n1;
214rte_member_heapify(
struct minheap *hp, uint32_t idx,
bool update_hash)
218 if (LCHILD(idx) < hp->size &&
219 hp->elem[LCHILD(idx)].count < hp->elem[idx].count)
220 smallest = LCHILD(idx);
224 if (RCHILD(idx) < hp->size &&
225 hp->elem[RCHILD(idx)].count < hp->elem[smallest].count)
226 smallest = RCHILD(idx);
228 if (smallest != idx) {
229 rte_member_heap_swap(&(hp->elem[idx]), &(hp->elem[smallest]));
232 if (hash_table_update(hp->elem[smallest].key, idx + 1, smallest + 1,
233 hp->key_len, hp->hashtable) < 0) {
234 RTE_MEMBER_LOG(ERR,
"Minheap Hash Table update failed\n");
238 if (hash_table_update(hp->elem[idx].key, smallest + 1, idx + 1,
239 hp->key_len, hp->hashtable) < 0) {
240 RTE_MEMBER_LOG(ERR,
"Minheap Hash Table update failed\n");
244 rte_member_heapify(hp, smallest, update_hash);
250rte_member_minheap_insert_node(
struct minheap *hp,
const void *key,
251 int counter,
void *key_slot,
258 RTE_MEMBER_LOG(ERR,
"Minheap get empty keyslot failed\n");
263 nd.key =
RTE_PTR_ADD(key_slot, slot_id * hp->key_len);
265 memcpy(nd.key, key, hp->key_len);
267 uint32_t i = (hp->size)++;
269 while (i && nd.count < hp->elem[PARENT(i)].count) {
270 hp->elem[i] = hp->elem[PARENT(i)];
271 if (hash_table_update(hp->elem[i].key, PARENT(i) + 1, i + 1,
272 hp->key_len, hp->hashtable) < 0) {
273 RTE_MEMBER_LOG(ERR,
"Minheap Hash Table update failed\n");
280 if (hash_table_insert(key, i + 1, hp->key_len, hp->hashtable) < 0) {
281 if (resize_hash_table(hp) < 0) {
282 RTE_MEMBER_LOG(ERR,
"Minheap Hash Table resize failed\n");
292rte_member_minheap_delete_node(
struct minheap *hp,
const void *key,
293 void *key_slot,
struct rte_ring *free_key_slot)
295 int idx = rte_member_minheap_find(hp, key);
296 uint32_t offset =
RTE_PTR_DIFF(hp->elem[idx].key, key_slot) / hp->key_len;
298 if (hash_table_del(key, idx + 1, hp->key_len, hp->hashtable) < 0) {
299 RTE_MEMBER_LOG(ERR,
"Minheap Hash Table delete failed\n");
305 if (idx == (
int)(hp->size - 1)) {
310 hp->elem[idx] = hp->elem[hp->size - 1];
312 if (hash_table_update(hp->elem[idx].key, hp->size, idx + 1,
313 hp->key_len, hp->hashtable) < 0) {
314 RTE_MEMBER_LOG(ERR,
"Minheap Hash Table update failed\n");
318 rte_member_heapify(hp, idx,
true);
325rte_member_minheap_replace_node(
struct minheap *hp,
330 void *recycle_key = NULL;
332 recycle_key = hp->elem[0].key;
334 if (hash_table_del(recycle_key, 1, hp->key_len, hp->hashtable) < 0) {
335 RTE_MEMBER_LOG(ERR,
"Minheap Hash Table delete failed\n");
339 hp->elem[0] = hp->elem[hp->size - 1];
341 if (hash_table_update(hp->elem[0].key, hp->size, 1,
342 hp->key_len, hp->hashtable) < 0) {
343 RTE_MEMBER_LOG(ERR,
"Minheap Hash Table update failed\n");
348 rte_member_heapify(hp, 0,
true);
350 nd.count = new_counter;
351 nd.key = recycle_key;
353 memcpy(nd.key, new_key, hp->key_len);
355 uint32_t i = (hp->size)++;
357 while (i && nd.count < hp->elem[PARENT(i)].count) {
358 hp->elem[i] = hp->elem[PARENT(i)];
359 if (hash_table_update(hp->elem[i].key, PARENT(i) + 1, i + 1,
360 hp->key_len, hp->hashtable) < 0) {
361 RTE_MEMBER_LOG(ERR,
"Minheap Hash Table update failed\n");
369 if (hash_table_insert(new_key, i + 1, hp->key_len, hp->hashtable) < 0) {
370 RTE_MEMBER_LOG(ERR,
"Minheap Hash Table replace insert failed\n");
371 if (resize_hash_table(hp) < 0) {
372 RTE_MEMBER_LOG(ERR,
"Minheap Hash Table replace resize failed\n");
382rte_member_heapsort(
struct minheap *hp,
struct node *result_array)
384 struct minheap new_hp;
387 new_hp.size = hp->size;
388 new_hp.key_len = hp->key_len;
389 new_hp.elem = result_array;
390 memcpy(result_array, hp->elem, hp->size *
sizeof(
struct node));
393 while (new_hp.size > 1) {
394 rte_member_heap_swap(&(new_hp.elem[0]), &(new_hp.elem[new_hp.size - 1]));
396 rte_member_heapify(&new_hp, 0,
false);
401rte_member_minheap_free(
struct minheap *hp)
411rte_member_minheap_reset(
struct minheap *hp)
416 memset(hp->elem, 0,
sizeof(
struct node) * hp->size);
419 memset((
char *)hp->hashtable +
sizeof(
struct hash), 0,
420 hp->hashtable->bkt_cnt *
sizeof(
struct hash_bkt));
421 hp->hashtable->num_item = 0;
#define RTE_PTR_DIFF(ptr1, ptr2)
static uint32_t rte_align32pow2(uint32_t x)
#define RTE_PTR_ADD(ptr, x)
#define __rte_always_inline
void void rte_free(void *ptr)
void * rte_zmalloc_socket(const char *type, size_t size, unsigned align, int socket) __rte_alloc_size(2)
static __rte_always_inline int rte_ring_sp_enqueue_elem(struct rte_ring *r, void *obj, unsigned int esize)
static __rte_always_inline int rte_ring_sc_dequeue_elem(struct rte_ring *r, void *obj_p, unsigned int esize)