6 #define DHASH(d, s) ((d)->level2 ? (((unsigned char) (s)[1]) << 8) | (unsigned char) (s)[0] : (unsigned char) s[0])
9 * initialise a dictionary
11 * notfound: the value returned for missing keys.
12 * dupkeys: if nonzero, store a copy of keys inserted via dict_put().
13 * level2: use two characters for hasing
15 void dict_init(struct dict
*d
, int size
, long notfound
, int dupkeys
, int level2
)
17 int headsize
= (level2
? 256 * 256 : 256) * sizeof(d
->head
[0]);
18 memset(d
, 0, sizeof(*d
));
22 d
->notfound
= notfound
;
23 d
->key
= xmalloc(size
* sizeof(d
->key
[0]));
24 d
->val
= xmalloc(size
* sizeof(d
->val
[0]));
25 d
->next
= xmalloc(size
* sizeof(d
->next
[0]));
26 d
->head
= xmalloc(headsize
);
27 memset(d
->head
, 0, headsize
);
29 d
->buf
= xmalloc(size
* NMLEN
);
32 void dict_done(struct dict
*d
)
41 void dict_put(struct dict
*d
, char *key
, long val
)
47 int len
= strlen(key
) + 1;
48 if (d
->buflen
+ len
>= d
->size
* NMLEN
)
50 memcpy(d
->buf
+ d
->buflen
, key
, len
);
51 key
= d
->buf
+ d
->buflen
;
57 d
->next
[idx
] = d
->head
[DHASH(d
, key
)];
58 d
->head
[DHASH(d
, key
)] = idx
;
61 /* return the index of key in d */
62 int dict_idx(struct dict
*d
, char *key
)
64 int idx
= d
->head
[DHASH(d
, key
)];
66 if (!strcmp(d
->key
[idx
], key
))
73 char *dict_key(struct dict
*d
, int idx
)
78 long dict_val(struct dict
*d
, int idx
)
83 long dict_get(struct dict
*d
, char *key
)
85 int idx
= dict_idx(d
, key
);
86 return idx
>= 0 ? d
->val
[idx
] : d
->notfound
;
89 /* match a prefix of key; in the first call, *idx should be -1 */
90 long dict_prefix(struct dict
*d
, char *key
, int *idx
)
96 *idx
= d
->head
[DHASH(d
, key
)];
100 plen
= strlen(d
->key
[*idx
]);
101 if (!strncmp(d
->key
[*idx
], key
, plen
))
103 *idx
= d
->next
[*idx
];