]>
Commit | Line | Data |
---|---|---|
1d73b52f DB |
1 | /* |
2 | * Licensed under a two-clause BSD-style license. | |
3 | * See LICENSE for details. | |
4 | */ | |
5 | ||
6 | #include "git-compat-util.h" | |
7 | #include "trp.h" | |
8 | #include "obj_pool.h" | |
9 | #include "string_pool.h" | |
10 | ||
11 | static struct trp_root tree = { ~0 }; | |
12 | ||
13 | struct node { | |
14 | uint32_t offset; | |
15 | struct trp_node children; | |
16 | }; | |
17 | ||
18 | /* Two memory pools: one for struct node, and another for strings */ | |
19 | obj_pool_gen(node, struct node, 4096) | |
20 | obj_pool_gen(string, char, 4096) | |
21 | ||
22 | static char *node_value(struct node *node) | |
23 | { | |
24 | return node ? string_pointer(node->offset) : NULL; | |
25 | } | |
26 | ||
27 | static int node_cmp(struct node *a, struct node *b) | |
28 | { | |
29 | return strcmp(node_value(a), node_value(b)); | |
30 | } | |
31 | ||
32 | /* Build a Treap from the node structure (a trp_node w/ offset) */ | |
33 | trp_gen(static, tree_, struct node, children, node, node_cmp); | |
34 | ||
35 | const char *pool_fetch(uint32_t entry) | |
36 | { | |
37 | return node_value(node_pointer(entry)); | |
38 | } | |
39 | ||
40 | uint32_t pool_intern(const char *key) | |
41 | { | |
42 | /* Canonicalize key */ | |
43 | struct node *match = NULL, *node; | |
44 | uint32_t key_len; | |
45 | if (key == NULL) | |
46 | return ~0; | |
47 | key_len = strlen(key) + 1; | |
48 | node = node_pointer(node_alloc(1)); | |
49 | node->offset = string_alloc(key_len); | |
50 | strcpy(node_value(node), key); | |
51 | match = tree_search(&tree, node); | |
52 | if (!match) { | |
53 | tree_insert(&tree, node); | |
54 | } else { | |
55 | node_free(1); | |
56 | string_free(key_len); | |
57 | node = match; | |
58 | } | |
59 | return node_offset(node); | |
60 | } | |
61 | ||
62 | uint32_t pool_tok_r(char *str, const char *delim, char **saveptr) | |
63 | { | |
64 | char *token = strtok_r(str, delim, saveptr); | |
65 | return token ? pool_intern(token) : ~0; | |
66 | } | |
67 | ||
68 | void pool_print_seq(uint32_t len, uint32_t *seq, char delim, FILE *stream) | |
69 | { | |
70 | uint32_t i; | |
71 | for (i = 0; i < len && ~seq[i]; i++) { | |
72 | fputs(pool_fetch(seq[i]), stream); | |
73 | if (i < len - 1 && ~seq[i + 1]) | |
74 | fputc(delim, stream); | |
75 | } | |
76 | } | |
77 | ||
78 | uint32_t pool_tok_seq(uint32_t sz, uint32_t *seq, const char *delim, char *str) | |
79 | { | |
80 | char *context = NULL; | |
81 | uint32_t token = ~0; | |
82 | uint32_t length; | |
83 | ||
84 | if (sz == 0) | |
85 | return ~0; | |
86 | if (str) | |
87 | token = pool_tok_r(str, delim, &context); | |
88 | for (length = 0; length < sz; length++) { | |
89 | seq[length] = token; | |
90 | if (token == ~0) | |
91 | return length; | |
92 | token = pool_tok_r(NULL, delim, &context); | |
93 | } | |
94 | seq[sz - 1] = ~0; | |
95 | return sz; | |
96 | } | |
97 | ||
98 | void pool_reset(void) | |
99 | { | |
100 | node_reset(); | |
101 | string_reset(); | |
102 | } |