Skip to content

Commit b6820d9

Browse files
committed
lib/hash: support RPM for hash
1 parent 2766c37 commit b6820d9

File tree

2 files changed

+68
-24
lines changed

2 files changed

+68
-24
lines changed

lib/hash.c

Lines changed: 55 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,33 @@
2020

2121
#include "hash.h"
2222
#include "../hash_func.h"
23+
#include "../mem/rpm_mem.h"
2324

24-
gen_hash_t *hash_init(unsigned int size)
25+
int hash_init_locks(gen_hash_t *h)
2526
{
2627
unsigned int n;
27-
gen_hash_t *h;
2828
gen_lock_set_t *locks = NULL;
2929

30+
for (n = h->size; n >= 1 && !locks; n/=2) {
31+
locks = lock_set_alloc(n);
32+
if (locks && lock_set_init(locks))
33+
break;
34+
}
35+
36+
if (!locks) {
37+
LM_ERR("could not allocate hash locks\n");
38+
return -1;
39+
}
40+
h->locks = locks;
41+
h->locks_no = n;
42+
return 0;
43+
}
44+
45+
gen_hash_t *hash_init_flags(unsigned int size, unsigned int flags)
46+
{
47+
unsigned int n;
48+
gen_hash_t *h;
49+
3050
/* initialized the hash table */
3151
for (n=0 ; n<(8*sizeof(n) - 1) ; n++) {
3252
if (size==(1<<n))
@@ -39,34 +59,45 @@ gen_hash_t *hash_init(unsigned int size)
3959
break;
4060
}
4161
}
42-
for (n = size; n >= 1 && !locks; n/=2) {
43-
locks = lock_set_alloc(n);
44-
if (locks && lock_set_init(locks))
45-
break;
46-
}
4762

48-
if (!locks) {
49-
LM_ERR("could not allocate hash locks\n");
50-
return NULL;
51-
}
52-
h = shm_malloc(sizeof *h + size * sizeof(*h->entries));
63+
if (flags & HASH_MAP_PERSIST)
64+
h = rpm_malloc(sizeof *h + size * sizeof(*h->entries));
65+
else
66+
h = shm_malloc(sizeof *h + size * sizeof(*h->entries));
5367
if (!h) {
5468
LM_ERR("could not alloc hash of %d elements!\n", size);
5569
return NULL;
5670
}
71+
memset(h, 0, sizeof *h + size * sizeof(*h->entries));
5772
h->entries = (map_t *)(h + 1);
5873
h->size = size;
59-
h->locks = locks;
60-
h->locks_no = n;
74+
h->flags = flags;
75+
if (hash_init_locks(h) < 0) {
76+
LM_ERR("could not alloc locks for hash!\n");
77+
goto error;
78+
}
79+
6180
for (n = 0; n < h->size; n++) {
62-
h->entries[n] = map_create(AVLMAP_SHARED);
81+
h->entries[n] = map_create(
82+
((flags&HASH_MAP_PERSIST)?AVLMAP_PERSISTENT:AVLMAP_SHARED));
6383
if (!h->entries[n]) {
6484
h->size = n; /* we only account for what we've already created */
65-
hash_destroy(h, NULL);
66-
return NULL;
85+
goto error;
6786
}
6887
}
6988
return h;
89+
error:
90+
hash_destroy(h, NULL);
91+
return NULL;
92+
}
93+
94+
void hash_destroy_locks(gen_hash_t *hash)
95+
{
96+
if (!hash->locks)
97+
return;
98+
lock_set_destroy(hash->locks);
99+
lock_set_dealloc(hash->locks);
100+
hash->locks = NULL;
70101
}
71102

72103
void hash_destroy(gen_hash_t *hash, hash_destroy_func destroy)
@@ -76,11 +107,14 @@ void hash_destroy(gen_hash_t *hash, hash_destroy_func destroy)
76107
if (!hash)
77108
return;
78109

79-
lock_set_destroy(hash->locks);
80-
lock_set_dealloc(hash->locks);
110+
hash_destroy_locks(hash);
81111

82112
for (n = 0; n < hash->size; n++)
83-
map_destroy(hash->entries[n], destroy);
113+
if (hash->entries[n])
114+
map_destroy(hash->entries[n], destroy);
84115

85-
shm_free(hash);
116+
if (hash->flags & HASH_MAP_PERSIST)
117+
rpm_free(hash);
118+
else
119+
shm_free(hash);
86120
}

lib/hash.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,11 @@
2424
#include "../map.h"
2525
#include "../locking.h"
2626

27+
#define HASH_MAP_SHARED (1 << 0)
28+
#define HASH_MAP_PERSIST (1 << 1)
29+
2730
typedef struct gen_hash {
28-
unsigned int size, locks_no;
31+
unsigned int size, locks_no, flags;
2932
map_t *entries;
3033
gen_lock_set_t *locks;
3134
} gen_hash_t;
@@ -37,13 +40,20 @@ typedef void (*hash_destroy_func)(void *);
3740
* - a non-sero return code will cause processing to stop */
3841
typedef int (*hash_entry_func)(void *param, str key, void *value);
3942

40-
/* initializes a hash of specified size */
41-
gen_hash_t *hash_init(unsigned int size);
43+
/* initializes a hash of specified size with certain flags */
44+
gen_hash_t *hash_init_flags(unsigned int size, unsigned int flags);
45+
46+
#define hash_init(size) hash_init_flags(size, HASH_MAP_SHARED)
4247

4348
/* destroyes an allocated hash
4449
* - uses the destroy func to call for each value found in hash */
4550
void hash_destroy(gen_hash_t *hash, hash_destroy_func destroy);
4651

52+
/* initializes hash locks */
53+
int hash_init_locks(gen_hash_t *h);
54+
55+
/* releases the hash's locks */
56+
void hash_destroy_locks(gen_hash_t *hash);
4757

4858
/* returns the size of the hash map */
4959
#define hash_size(_h) ((_h)->size)

0 commit comments

Comments
 (0)