6 #define DHASH(d, s) ((unsigned char) (s)[0])
7 #define CNTMIN (1 << 10)
15 int notfound
; /* the value returned for missing keys */
16 int dupkeys
; /* duplicate keys if set */
19 static void dict_extend(struct dict
*d
, int size
)
21 d
->key
= mextend(d
->key
, d
->size
, size
, sizeof(d
->key
[0]));
22 d
->val
= mextend(d
->val
, d
->size
, size
, sizeof(d
->val
[0]));
26 struct dict
*dict_make(int notfound
, int dupkeys
)
28 struct dict
*d
= xmalloc(sizeof(*d
));
29 memset(d
, 0, sizeof(*d
));
32 d
->notfound
= notfound
;
34 dict_extend(d
, CNTMIN
);
38 void dict_free(struct dict
*d
)
42 for (i
= 0; i
< d
->size
; i
++)
50 void dict_put(struct dict
*d
, char *key
, int val
)
54 dict_extend(d
, d
->n
+ CNTMIN
);
56 int len
= strlen(key
) + 1;
57 char *dup
= xmalloc(len
);
58 memcpy(dup
, key
, len
);
64 iset_put(d
->map
, DHASH(d
, key
), idx
);
67 /* return the index of key in d */
68 int dict_idx(struct dict
*d
, char *key
)
70 int h
= DHASH(d
, key
);
71 int *b
= iset_get(d
->map
, h
);
72 int *r
= b
+ iset_len(d
->map
, h
);
74 if (!strcmp(d
->key
[*r
], key
))
79 char *dict_key(struct dict
*d
, int idx
)
84 int dict_val(struct dict
*d
, int idx
)
89 int dict_get(struct dict
*d
, char *key
)
91 int idx
= dict_idx(d
, key
);
92 return idx
>= 0 ? d
->val
[idx
] : d
->notfound
;
95 /* match a prefix of key; in the first call, *idx should be -1 */
96 int dict_prefix(struct dict
*d
, char *key
, int *pos
)
98 int *r
= iset_get(d
->map
, DHASH(d
, key
));
99 while (r
&& r
[++*pos
] >= 0) {
101 int plen
= strlen(d
->key
[idx
]);
102 if (!strncmp(d
->key
[idx
], key
, plen
))