@matheusbsbs / matheus-bagliano / commits / 044ad2906a
Fork 0

vcs-svn: implement perfect hash for node-prop keys

Instead of interning property names and comparing their string_pool keys, look them up in a table by string length, which should be about as fast. This is a small step towards removing dependence on string_pool. Signed-off-by: David Barr <david.barr@cordelta.com> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>

David Barr committed Dec 13, 2010 at 19:13 UTC 044ad2906a5e4b805bc8c8d121466d8ff94ecbfb
1 file changed +43 -19
vcs-svn/svndump.c
+43 -19
@@ -14,6 +14,12 @@
14 #include "obj_pool.h"
15 #include "string_pool.h"
16
17 +/*
18 + * Compare start of string to literal of equal length;
19 + * must be guarded by length test.
20 + */
21 +#define constcmp(s, ref) memcmp(s, ref, sizeof(ref) - 1)
22 +
23 #define NODEACT_REPLACE 4
24 #define NODEACT_DELETE 3
25 #define NODEACT_ADD 2
@@ -58,8 +64,7 @@ static struct {
64 } dump_ctx;
65
66 static struct {
61 - uint32_t svn_log, svn_author, svn_date, svn_executable, svn_special, uuid,
62 - revision_number, node_path, node_kind, node_action,
67 + uint32_t uuid, revision_number, node_path, node_kind, node_action,
68 node_copyfrom_path, node_copyfrom_rev, text_content_length,
69 prop_content_length, content_length, svn_fs_dump_format_version,
70 /* version 3 format */
@@ -96,11 +101,6 @@ static void reset_dump_ctx(uint32_t url)
101
102 static void init_keys(void)
103 {
99 - keys.svn_log = pool_intern("svn:log");
100 - keys.svn_author = pool_intern("svn:author");
101 - keys.svn_date = pool_intern("svn:date");
102 - keys.svn_executable = pool_intern("svn:executable");
103 - keys.svn_special = pool_intern("svn:special");
104 keys.uuid = pool_intern("UUID");
105 keys.revision_number = pool_intern("Revision-number");
106 keys.node_path = pool_intern("Node-path");
@@ -117,22 +117,43 @@ static void init_keys(void)
117 keys.prop_delta = pool_intern("Prop-delta");
118 }
119
120 -static void handle_property(uint32_t key, const char *val, uint32_t len,
120 +static void handle_property(const struct strbuf *key_buf,
121 + const char *val, uint32_t len,
122 uint32_t *type_set)
123 {
123 - if (key == keys.svn_log) {
124 + const char *key = key_buf->buf;
125 + size_t keylen = key_buf->len;
126 +
127 + switch (keylen + 1) {
128 + case sizeof("svn:log"):
129 + if (constcmp(key, "svn:log"))
130 + break;
131 if (!val)
132 die("invalid dump: unsets svn:log");
133 /* Value length excludes terminating nul. */
134 rev_ctx.log = log_copy(len + 1, val);
128 - } else if (key == keys.svn_author) {
135 + break;
136 + case sizeof("svn:author"):
137 + if (constcmp(key, "svn:author"))
138 + break;
139 rev_ctx.author = pool_intern(val);
130 - } else if (key == keys.svn_date) {
140 + break;
141 + case sizeof("svn:date"):
142 + if (constcmp(key, "svn:date"))
143 + break;
144 if (!val)
145 die("invalid dump: unsets svn:date");
146 if (parse_date_basic(val, &rev_ctx.timestamp, NULL))
147 warning("invalid timestamp: %s", val);
135 - } else if (key == keys.svn_executable || key == keys.svn_special) {
148 + break;
149 + case sizeof("svn:executable"):
150 + case sizeof("svn:special"):
151 + if (keylen == strlen("svn:executable") &&
152 + constcmp(key, "svn:executable"))
153 + break;
154 + if (keylen == strlen("svn:special") &&
155 + constcmp(key, "svn:special"))
156 + break;
157 if (*type_set) {
158 if (!val)
159 return;
@@ -143,7 +164,7 @@ static void handle_property(uint32_t key, const char *val, uint32_t len,
164 return;
165 }
166 *type_set = 1;
146 - node_ctx.type = key == keys.svn_executable ?
167 + node_ctx.type = keylen == strlen("svn:executable") ?
168 REPO_MODE_EXE :
169 REPO_MODE_LNK;
170 }
@@ -158,7 +179,7 @@ static void die_short_read(void)
179
180 static void read_props(void)
181 {
161 - uint32_t key = ~0;
182 + static struct strbuf key = STRBUF_INIT;
183 const char *t;
184 /*
185 * NEEDSWORK: to support simple mode changes like
@@ -195,16 +216,19 @@ static void read_props(void)
216
217 switch (type) {
218 case 'K':
198 - key = pool_intern(val);
199 - continue;
219 case 'D':
201 - key = pool_intern(val);
220 + strbuf_reset(&key);
221 + if (val)
222 + strbuf_add(&key, val, len);
223 + if (type == 'K')
224 + continue;
225 + assert(type == 'D');
226 val = NULL;
227 len = 0;
228 /* fall through */
229 case 'V':
206 - handle_property(key, val, len, &type_set);
207 - key = ~0;
230 + handle_property(&key, val, len, &type_set);
231 + strbuf_reset(&key);
232 continue;
233 default:
234 die("invalid property line: %s\n", t);