@matheusbsbs / matheus-bagliano / commits / 90c0a3cfe3
Fork 0

vcs-svn: implement perfect hash for top-level 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. Another small step towards removing dependence on string_pool altogether. 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:56 UTC 90c0a3cfe390208c86144bf97ec8fa5610febe0f
1 file changed +59 -50
vcs-svn/svndump.c
+59 -50
@@ -63,14 +63,6 @@ static struct {
63 uint32_t version, uuid, url;
64 } dump_ctx;
65
66 -static struct {
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 */
71 - text_delta, prop_delta;
72 -} keys;
73 -
66 static void reset_node_ctx(char *fname)
67 {
68 node_ctx.type = 0;
@@ -99,24 +91,6 @@ static void reset_dump_ctx(uint32_t url)
91 dump_ctx.uuid = ~0;
92 }
93
102 -static void init_keys(void)
103 -{
104 - keys.uuid = pool_intern("UUID");
105 - keys.revision_number = pool_intern("Revision-number");
106 - keys.node_path = pool_intern("Node-path");
107 - keys.node_kind = pool_intern("Node-kind");
108 - keys.node_action = pool_intern("Node-action");
109 - keys.node_copyfrom_path = pool_intern("Node-copyfrom-path");
110 - keys.node_copyfrom_rev = pool_intern("Node-copyfrom-rev");
111 - keys.text_content_length = pool_intern("Text-content-length");
112 - keys.prop_content_length = pool_intern("Prop-content-length");
113 - keys.content_length = pool_intern("Content-length");
114 - keys.svn_fs_dump_format_version = pool_intern("SVN-fs-dump-format-version");
115 - /* version 3 format (Subversion 1.1.0) */
116 - keys.text_delta = pool_intern("Text-delta");
117 - keys.prop_delta = pool_intern("Prop-delta");
118 -}
119 -
94 static void handle_property(const struct strbuf *key_buf,
95 const char *val, uint32_t len,
96 uint32_t *type_set)
@@ -320,44 +294,61 @@ void svndump_read(const char *url)
294 char *t;
295 uint32_t active_ctx = DUMP_CTX;
296 uint32_t len;
323 - uint32_t key;
297
298 reset_dump_ctx(pool_intern(url));
299 while ((t = buffer_read_line(&input))) {
300 val = strstr(t, ": ");
301 if (!val)
302 continue;
330 - *val++ = '\0';
331 - *val++ = '\0';
332 - key = pool_intern(t);
303 + val += 2;
304
334 - if (key == keys.svn_fs_dump_format_version) {
305 + /* strlen(key) + 1 */
306 + switch (val - t - 1) {
307 + case sizeof("SVN-fs-dump-format-version"):
308 + if (constcmp(t, "SVN-fs-dump-format-version"))
309 + continue;
310 dump_ctx.version = atoi(val);
311 if (dump_ctx.version > 3)
312 die("expected svn dump format version <= 3, found %"PRIu32,
313 dump_ctx.version);
339 - } else if (key == keys.uuid) {
314 + break;
315 + case sizeof("UUID"):
316 + if (constcmp(t, "UUID"))
317 + continue;
318 dump_ctx.uuid = pool_intern(val);
341 - } else if (key == keys.revision_number) {
319 + break;
320 + case sizeof("Revision-number"):
321 + if (constcmp(t, "Revision-number"))
322 + continue;
323 if (active_ctx == NODE_CTX)
324 handle_node();
325 if (active_ctx != DUMP_CTX)
326 handle_revision();
327 active_ctx = REV_CTX;
328 reset_rev_ctx(atoi(val));
348 - } else if (key == keys.node_path) {
349 - if (active_ctx == NODE_CTX)
350 - handle_node();
351 - active_ctx = NODE_CTX;
352 - reset_node_ctx(val);
353 - } else if (key == keys.node_kind) {
329 + break;
330 + case sizeof("Node-path"):
331 + if (prefixcmp(t, "Node-"))
332 + continue;
333 + if (!constcmp(t + strlen("Node-"), "path")) {
334 + if (active_ctx == NODE_CTX)
335 + handle_node();
336 + active_ctx = NODE_CTX;
337 + reset_node_ctx(val);
338 + break;
339 + }
340 + if (constcmp(t + strlen("Node-"), "kind"))
341 + continue;
342 if (!strcmp(val, "dir"))
343 node_ctx.type = REPO_MODE_DIR;
344 else if (!strcmp(val, "file"))
345 node_ctx.type = REPO_MODE_BLB;
346 else
347 fprintf(stderr, "Unknown node-kind: %s\n", val);
360 - } else if (key == keys.node_action) {
348 + break;
349 + case sizeof("Node-action"):
350 + if (constcmp(t, "Node-action"))
351 + continue;
352 if (!strcmp(val, "delete")) {
353 node_ctx.action = NODEACT_DELETE;
354 } else if (!strcmp(val, "add")) {
@@ -370,19 +361,38 @@ void svndump_read(const char *url)
361 fprintf(stderr, "Unknown node-action: %s\n", val);
362 node_ctx.action = NODEACT_UNKNOWN;
363 }
373 - } else if (key == keys.node_copyfrom_path) {
364 + break;
365 + case sizeof("Node-copyfrom-path"):
366 + if (constcmp(t, "Node-copyfrom-path"))
367 + continue;
368 pool_tok_seq(REPO_MAX_PATH_DEPTH, node_ctx.src, "/", val);
375 - } else if (key == keys.node_copyfrom_rev) {
369 + break;
370 + case sizeof("Node-copyfrom-rev"):
371 + if (constcmp(t, "Node-copyfrom-rev"))
372 + continue;
373 node_ctx.srcRev = atoi(val);
377 - } else if (key == keys.text_content_length) {
378 - node_ctx.textLength = atoi(val);
379 - } else if (key == keys.prop_content_length) {
374 + break;
375 + case sizeof("Text-content-length"):
376 + if (!constcmp(t, "Text-content-length")) {
377 + node_ctx.textLength = atoi(val);
378 + break;
379 + }
380 + if (constcmp(t, "Prop-content-length"))
381 + continue;
382 node_ctx.propLength = atoi(val);
381 - } else if (key == keys.text_delta) {
382 - node_ctx.text_delta = !strcmp(val, "true");
383 - } else if (key == keys.prop_delta) {
383 + break;
384 + case sizeof("Text-delta"):
385 + if (!constcmp(t, "Text-delta")) {
386 + node_ctx.text_delta = !strcmp(val, "true");
387 + break;
388 + }
389 + if (constcmp(t, "Prop-delta"))
390 + continue;
391 node_ctx.prop_delta = !strcmp(val, "true");
385 - } else if (key == keys.content_length) {
392 + break;
393 + case sizeof("Content-length"):
394 + if (constcmp(t, "Content-length"))
395 + continue;
396 len = atoi(val);
397 t = buffer_read_line(&input);
398 if (!t)
@@ -417,7 +427,6 @@ int svndump_init(const char *filename)
427 reset_dump_ctx(~0);
428 reset_rev_ctx(0);
429 reset_node_ctx(NULL);
420 - init_keys();
430 return 0;
431 }
432