6#ifndef RTE_MEMBER_HEAP_H
7#define RTE_MEMBER_HEAP_H
13#define LCHILD(x) (2 * x + 1)
14#define RCHILD(x) (2 * x + 2)
15#define PARENT(x) ((x - 1) / 2)
17#define HASH_BKT_SIZE 16
18#define HASH_HP_MULTI 4
19#define HASH_RESIZE_MULTI 2
22 uint16_t sig[HASH_BKT_SIZE];
23 uint16_t idx[HASH_BKT_SIZE];
30 struct hash_bkt buckets[];
42 struct hash *hashtable;
47hash_table_insert(
const void *key,
int value,
int key_len,
struct hash *table)
49 uint32_t hash = MEMBER_HASH_FUNC(key, key_len, table->seed);
50 uint16_t idx = hash % table->bkt_cnt;
51 uint16_t sig = hash >> 16;
54 for (i = 0; i < HASH_BKT_SIZE; i++) {
55 if (table->buckets[idx].idx[i] == 0) {
56 table->buckets[idx].idx[i] = value;
57 table->buckets[idx].sig[i] = sig;
67hash_table_update(
const void *key,
int old_value,
int value,
int key_len,
struct hash *table)
69 uint32_t hash = MEMBER_HASH_FUNC(key, key_len, table->seed);
70 uint16_t idx = hash % table->bkt_cnt;
71 uint16_t sig = hash >> 16;
74 for (i = 0; i < HASH_BKT_SIZE; i++) {
75 if (table->buckets[idx].sig[i] == sig && table->buckets[idx].idx[i] == old_value) {
76 table->buckets[idx].idx[i] = value;
85hash_table_del(
const void *key, uint16_t value,
int key_len,
struct hash *table)
87 uint32_t hash = MEMBER_HASH_FUNC(key, key_len, table->seed);
88 uint16_t idx = hash % table->bkt_cnt;
89 uint16_t sig = hash >> 16;
92 for (i = 0; i < HASH_BKT_SIZE; i++) {
93 if (table->buckets[idx].sig[i] == sig && table->buckets[idx].idx[i] == value) {
94 table->buckets[idx].idx[i] = 0;
104hash_table_lookup(
const void *key,
int key_len,
struct minheap *hp)
106 struct hash *table = hp->hashtable;
107 uint32_t hash = MEMBER_HASH_FUNC(key, key_len, table->seed);
108 uint16_t idx = hash % table->bkt_cnt;
109 uint16_t sig = hash >> 16;
112 for (i = 0; i < HASH_BKT_SIZE; i++) {
113 if (table->buckets[idx].sig[i] == sig && table->buckets[idx].idx[i] != 0) {
114 uint32_t hp_idx = table->buckets[idx].idx[i] - 1;
116 if (memcmp(hp->elem[hp_idx].key, key, hp->key_len) == 0)
125resize_hash_table(
struct minheap *hp)
128 uint32_t new_bkt_cnt;
131 new_bkt_cnt = hp->hashtable->bkt_cnt * HASH_RESIZE_MULTI;
133 MEMBER_LOG(ERR,
"Sketch Minheap HT load factor is [%f]",
134 hp->hashtable->num_item / ((
float)hp->hashtable->bkt_cnt * HASH_BKT_SIZE));
135 MEMBER_LOG(ERR,
"Sketch Minheap HT resize happen!");
138 new_bkt_cnt *
sizeof(
struct hash_bkt),
139 RTE_CACHE_LINE_SIZE, hp->socket);
141 if (hp->hashtable == NULL) {
142 MEMBER_LOG(ERR,
"Sketch Minheap HT allocation failed");
146 hp->hashtable->bkt_cnt = new_bkt_cnt;
148 for (i = 0; i < hp->size; ++i) {
149 if (hash_table_insert(hp->elem[i].key,
150 i + 1, hp->key_len, hp->hashtable) < 0) {
152 "Sketch Minheap HT resize insert fail!");
165rte_member_minheap_find(
struct minheap *hp,
const void *key)
167 int idx = hash_table_lookup(key, hp->key_len, hp);
172rte_member_minheap_init(
struct minheap *heap,
int size,
173 uint32_t socket, uint32_t seed)
176 RTE_CACHE_LINE_SIZE, socket);
177 if (heap->elem == NULL) {
178 MEMBER_LOG(ERR,
"Sketch Minheap elem allocation failed");
182 uint32_t hash_bkt_cnt =
rte_align32pow2(size * HASH_HP_MULTI) / HASH_BKT_SIZE;
184 if (hash_bkt_cnt == 0)
188 hash_bkt_cnt *
sizeof(
struct hash_bkt),
189 RTE_CACHE_LINE_SIZE, socket);
191 if (heap->hashtable == NULL) {
192 MEMBER_LOG(ERR,
"Sketch Minheap HT allocation failed");
197 heap->hashtable->seed = seed;
198 heap->hashtable->bkt_cnt = hash_bkt_cnt;
199 heap->socket = socket;
206rte_member_heap_swap(
struct node *n1,
struct node *n2)
208 struct node temp = *n1;
215rte_member_heapify(
struct minheap *hp, uint32_t idx,
bool update_hash)
219 if (LCHILD(idx) < hp->size &&
220 hp->elem[LCHILD(idx)].count < hp->elem[idx].count)
221 smallest = LCHILD(idx);
225 if (RCHILD(idx) < hp->size &&
226 hp->elem[RCHILD(idx)].count < hp->elem[smallest].count)
227 smallest = RCHILD(idx);
229 if (smallest != idx) {
230 rte_member_heap_swap(&(hp->elem[idx]), &(hp->elem[smallest]));
233 if (hash_table_update(hp->elem[smallest].key, idx + 1, smallest + 1,
234 hp->key_len, hp->hashtable) < 0) {
235 MEMBER_LOG(ERR,
"Minheap Hash Table update failed");
239 if (hash_table_update(hp->elem[idx].key, smallest + 1, idx + 1,
240 hp->key_len, hp->hashtable) < 0) {
241 MEMBER_LOG(ERR,
"Minheap Hash Table update failed");
245 rte_member_heapify(hp, smallest, update_hash);
251rte_member_minheap_insert_node(
struct minheap *hp,
const void *key,
252 int counter,
void *key_slot,
259 MEMBER_LOG(ERR,
"Minheap get empty keyslot failed");
264 nd.key =
RTE_PTR_ADD(key_slot, slot_id * hp->key_len);
266 memcpy(nd.key, key, hp->key_len);
268 uint32_t i = (hp->size)++;
270 while (i && nd.count < hp->elem[PARENT(i)].count) {
271 hp->elem[i] = hp->elem[PARENT(i)];
272 if (hash_table_update(hp->elem[i].key, PARENT(i) + 1, i + 1,
273 hp->key_len, hp->hashtable) < 0) {
274 MEMBER_LOG(ERR,
"Minheap Hash Table update failed");
281 if (hash_table_insert(key, i + 1, hp->key_len, hp->hashtable) < 0) {
282 if (resize_hash_table(hp) < 0) {
283 MEMBER_LOG(ERR,
"Minheap Hash Table resize failed");
293rte_member_minheap_delete_node(
struct minheap *hp,
const void *key,
294 void *key_slot,
struct rte_ring *free_key_slot)
296 int idx = rte_member_minheap_find(hp, key);
297 uint32_t offset =
RTE_PTR_DIFF(hp->elem[idx].key, key_slot) / hp->key_len;
299 if (hash_table_del(key, idx + 1, hp->key_len, hp->hashtable) < 0) {
300 MEMBER_LOG(ERR,
"Minheap Hash Table delete failed");
306 if (idx == (
int)(hp->size - 1)) {
311 hp->elem[idx] = hp->elem[hp->size - 1];
313 if (hash_table_update(hp->elem[idx].key, hp->size, idx + 1,
314 hp->key_len, hp->hashtable) < 0) {
315 MEMBER_LOG(ERR,
"Minheap Hash Table update failed");
319 rte_member_heapify(hp, idx,
true);
326rte_member_minheap_replace_node(
struct minheap *hp,
331 void *recycle_key = NULL;
333 recycle_key = hp->elem[0].key;
335 if (hash_table_del(recycle_key, 1, hp->key_len, hp->hashtable) < 0) {
336 MEMBER_LOG(ERR,
"Minheap Hash Table delete failed");
340 hp->elem[0] = hp->elem[hp->size - 1];
342 if (hash_table_update(hp->elem[0].key, hp->size, 1,
343 hp->key_len, hp->hashtable) < 0) {
344 MEMBER_LOG(ERR,
"Minheap Hash Table update failed");
349 rte_member_heapify(hp, 0,
true);
351 nd.count = new_counter;
352 nd.key = recycle_key;
354 memcpy(nd.key, new_key, hp->key_len);
356 uint32_t i = (hp->size)++;
358 while (i && nd.count < hp->elem[PARENT(i)].count) {
359 hp->elem[i] = hp->elem[PARENT(i)];
360 if (hash_table_update(hp->elem[i].key, PARENT(i) + 1, i + 1,
361 hp->key_len, hp->hashtable) < 0) {
362 MEMBER_LOG(ERR,
"Minheap Hash Table update failed");
370 if (hash_table_insert(new_key, i + 1, hp->key_len, hp->hashtable) < 0) {
371 MEMBER_LOG(ERR,
"Minheap Hash Table replace insert failed");
372 if (resize_hash_table(hp) < 0) {
373 MEMBER_LOG(ERR,
"Minheap Hash Table replace resize failed");
383rte_member_heapsort(
struct minheap *hp,
struct node *result_array)
385 struct minheap new_hp;
388 new_hp.size = hp->size;
389 new_hp.key_len = hp->key_len;
390 new_hp.elem = result_array;
391 memcpy(result_array, hp->elem, hp->size *
sizeof(
struct node));
394 while (new_hp.size > 1) {
395 rte_member_heap_swap(&(new_hp.elem[0]), &(new_hp.elem[new_hp.size - 1]));
397 rte_member_heapify(&new_hp, 0,
false);
402rte_member_minheap_free(
struct minheap *hp)
412rte_member_minheap_reset(
struct minheap *hp)
417 memset(hp->elem, 0,
sizeof(
struct node) * hp->size);
420 memset((
char *)hp->hashtable +
sizeof(
struct hash), 0,
421 hp->hashtable->bkt_cnt *
sizeof(
struct hash_bkt));
422 hp->hashtable->num_item = 0;
static uint32_t rte_align32pow2(uint32_t x)
#define RTE_PTR_DIFF(ptr1, ptr2)
#define RTE_PTR_ADD(ptr, x)
#define __rte_always_inline
void * rte_zmalloc_socket(const char *type, size_t size, unsigned align, int socket) __rte_alloc_size(2) __rte_alloc_align(3) __rte_malloc __rte_dealloc_free
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)