6 #define CNTMIN (1 << 10)
14 int notfound
; /* the value returned for missing keys */
15 int hashlen
; /* the number of characters used for hashing */
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]));
27 * initialise a dictionary
29 * notfound: the value returned for missing keys.
30 * dupkeys: if nonzero, store a copy of keys inserted via dict_put().
31 * hashlen: the number of characters used for hashing
33 struct dict
*dict_make(int notfound
, int dupkeys
, int hashlen
)
35 struct dict
*d
= malloc(sizeof(*d
));
36 memset(d
, 0, sizeof(*d
));
38 d
->hashlen
= hashlen
? hashlen
: 32;
40 d
->notfound
= notfound
;
42 dict_extend(d
, CNTMIN
);
46 void dict_free(struct dict
*d
)
50 for (i
= 0; i
< d
->size
; i
++)
58 static int dict_hash(struct dict
*d
, char *key
)
60 unsigned long hash
= (unsigned char) *key
++;
62 while (--i
> 0 && *key
)
63 hash
= (hash
<< 5) + hash
+ (unsigned char) *key
++;
67 void dict_put(struct dict
*d
, char *key
, int val
)
71 dict_extend(d
, d
->n
+ CNTMIN
);
73 int len
= strlen(key
) + 1;
74 char *dup
= malloc(len
);
75 memcpy(dup
, key
, len
);
81 iset_put(d
->map
, dict_hash(d
, key
), idx
);
84 /* return the index of key in d */
85 int dict_idx(struct dict
*d
, char *key
)
87 int h
= dict_hash(d
, key
);
88 int *b
= iset_get(d
->map
, h
);
89 int *r
= b
+ iset_len(d
->map
, h
);
91 if (!strcmp(d
->key
[*r
], key
))
96 char *dict_key(struct dict
*d
, int idx
)
101 int dict_val(struct dict
*d
, int idx
)
106 int dict_get(struct dict
*d
, char *key
)
108 int idx
= dict_idx(d
, key
);
109 return idx
>= 0 ? d
->val
[idx
] : d
->notfound
;
112 /* match a prefix of key; in the first call, *idx should be -1 */
113 int dict_prefix(struct dict
*d
, char *key
, int *pos
)
115 int *r
= iset_get(d
->map
, dict_hash(d
, key
));
116 while (r
&& r
[++*pos
] >= 0) {
118 int plen
= strlen(d
->key
[idx
]);
119 if (!strncmp(d
->key
[idx
], key
, plen
))