-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathdict.c
91 lines (82 loc) · 1.76 KB
/
dict.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
#include "pgpriv.h"
#include "khashl.h"
KHASHL_CMAP_INIT(KH_LOCAL, pg_strhash_t, pg_sh, const char*, int32_t, kh_hash_str, kh_eq_str)
typedef struct {
pg_strhash_t *h;
int32_t do_copy;
} pg_dict_t;
char *pg_strdup(const char *src)
{
int32_t len;
char *dst;
len = strlen(src);
dst = PG_MALLOC(char, len + 1);
memcpy(dst, src, len + 1);
return dst;
}
char *pg_strndup(const char *src, size_t n)
{
char *dst;
dst = PG_MALLOC(char, n + 1);
strncpy(dst, src, n);
dst[n] = 0;
return dst;
}
void *pg_dict_init(int32_t do_copy)
{
pg_dict_t *d;
d = PG_CALLOC(pg_dict_t, 1);
d->do_copy = !!do_copy;
d->h = pg_sh_init();
return d;
}
void pg_dict_destroy(void *h_)
{
pg_dict_t *d = (pg_dict_t*)h_;
if (d->do_copy) {
khint_t k;
for (k = 0; k < kh_end(d->h); ++k)
if (kh_exist(d->h, k))
free((char*)kh_key(d->h, k));
}
pg_sh_destroy(d->h);
free(d);
}
int32_t pg_dict_size(const void *d)
{
return kh_size(((pg_dict_t*)d)->h);
}
const char **pg_dict_put(void *d_, const char *s, int32_t v0, int32_t *v1, int32_t *absent_)
{
pg_dict_t *d = (pg_dict_t*)d_;
int absent;
khint_t k;
k = pg_sh_put(d->h, s, &absent);
if (absent) {
kh_key(d->h, k) = d->do_copy? pg_strdup(s) : s;
kh_val(d->h, k) = v0;
}
if (absent_) *absent_ = absent;
if (v1) *v1 = kh_val(d->h, k);
return &kh_key(d->h, k);
}
int32_t pg_dict_inc(void *d_, const char *s, int32_t v0)
{
pg_dict_t *d = (pg_dict_t*)d_;
int absent;
khint_t k;
k = pg_sh_put(d->h, s, &absent);
if (absent) {
kh_key(d->h, k) = d->do_copy? pg_strdup(s) : s;
kh_val(d->h, k) = v0;
}
else ++kh_val(d->h, k);
return kh_val(d->h, k);
}
int32_t pg_dict_get(const void *d_, const char *s)
{
const pg_dict_t *d = (const pg_dict_t*)d_;
khint_t k;
k = pg_sh_get(d->h, s);
return k != kh_end(d->h)? kh_val(d->h, k) : -1;
}