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