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>
This commit is contained in:
David Barr 2010-12-13 19:56:01 +11:00 committed by Jonathan Nieder
parent 044ad2906a
commit 90c0a3cfe3

View File

@ -63,14 +63,6 @@ static struct {
uint32_t version, uuid, url; uint32_t version, uuid, url;
} dump_ctx; } dump_ctx;
static struct {
uint32_t uuid, revision_number, node_path, node_kind, node_action,
node_copyfrom_path, node_copyfrom_rev, text_content_length,
prop_content_length, content_length, svn_fs_dump_format_version,
/* version 3 format */
text_delta, prop_delta;
} keys;
static void reset_node_ctx(char *fname) static void reset_node_ctx(char *fname)
{ {
node_ctx.type = 0; node_ctx.type = 0;
@ -99,24 +91,6 @@ static void reset_dump_ctx(uint32_t url)
dump_ctx.uuid = ~0; dump_ctx.uuid = ~0;
} }
static void init_keys(void)
{
keys.uuid = pool_intern("UUID");
keys.revision_number = pool_intern("Revision-number");
keys.node_path = pool_intern("Node-path");
keys.node_kind = pool_intern("Node-kind");
keys.node_action = pool_intern("Node-action");
keys.node_copyfrom_path = pool_intern("Node-copyfrom-path");
keys.node_copyfrom_rev = pool_intern("Node-copyfrom-rev");
keys.text_content_length = pool_intern("Text-content-length");
keys.prop_content_length = pool_intern("Prop-content-length");
keys.content_length = pool_intern("Content-length");
keys.svn_fs_dump_format_version = pool_intern("SVN-fs-dump-format-version");
/* version 3 format (Subversion 1.1.0) */
keys.text_delta = pool_intern("Text-delta");
keys.prop_delta = pool_intern("Prop-delta");
}
static void handle_property(const struct strbuf *key_buf, static void handle_property(const struct strbuf *key_buf,
const char *val, uint32_t len, const char *val, uint32_t len,
uint32_t *type_set) uint32_t *type_set)
@ -320,44 +294,61 @@ void svndump_read(const char *url)
char *t; char *t;
uint32_t active_ctx = DUMP_CTX; uint32_t active_ctx = DUMP_CTX;
uint32_t len; uint32_t len;
uint32_t key;
reset_dump_ctx(pool_intern(url)); reset_dump_ctx(pool_intern(url));
while ((t = buffer_read_line(&input))) { while ((t = buffer_read_line(&input))) {
val = strstr(t, ": "); val = strstr(t, ": ");
if (!val) if (!val)
continue; continue;
*val++ = '\0'; val += 2;
*val++ = '\0';
key = pool_intern(t);
if (key == keys.svn_fs_dump_format_version) { /* strlen(key) + 1 */
switch (val - t - 1) {
case sizeof("SVN-fs-dump-format-version"):
if (constcmp(t, "SVN-fs-dump-format-version"))
continue;
dump_ctx.version = atoi(val); dump_ctx.version = atoi(val);
if (dump_ctx.version > 3) if (dump_ctx.version > 3)
die("expected svn dump format version <= 3, found %"PRIu32, die("expected svn dump format version <= 3, found %"PRIu32,
dump_ctx.version); dump_ctx.version);
} else if (key == keys.uuid) { break;
case sizeof("UUID"):
if (constcmp(t, "UUID"))
continue;
dump_ctx.uuid = pool_intern(val); dump_ctx.uuid = pool_intern(val);
} else if (key == keys.revision_number) { break;
case sizeof("Revision-number"):
if (constcmp(t, "Revision-number"))
continue;
if (active_ctx == NODE_CTX) if (active_ctx == NODE_CTX)
handle_node(); handle_node();
if (active_ctx != DUMP_CTX) if (active_ctx != DUMP_CTX)
handle_revision(); handle_revision();
active_ctx = REV_CTX; active_ctx = REV_CTX;
reset_rev_ctx(atoi(val)); reset_rev_ctx(atoi(val));
} else if (key == keys.node_path) { break;
if (active_ctx == NODE_CTX) case sizeof("Node-path"):
handle_node(); if (prefixcmp(t, "Node-"))
active_ctx = NODE_CTX; continue;
reset_node_ctx(val); if (!constcmp(t + strlen("Node-"), "path")) {
} else if (key == keys.node_kind) { if (active_ctx == NODE_CTX)
handle_node();
active_ctx = NODE_CTX;
reset_node_ctx(val);
break;
}
if (constcmp(t + strlen("Node-"), "kind"))
continue;
if (!strcmp(val, "dir")) if (!strcmp(val, "dir"))
node_ctx.type = REPO_MODE_DIR; node_ctx.type = REPO_MODE_DIR;
else if (!strcmp(val, "file")) else if (!strcmp(val, "file"))
node_ctx.type = REPO_MODE_BLB; node_ctx.type = REPO_MODE_BLB;
else else
fprintf(stderr, "Unknown node-kind: %s\n", val); fprintf(stderr, "Unknown node-kind: %s\n", val);
} else if (key == keys.node_action) { break;
case sizeof("Node-action"):
if (constcmp(t, "Node-action"))
continue;
if (!strcmp(val, "delete")) { if (!strcmp(val, "delete")) {
node_ctx.action = NODEACT_DELETE; node_ctx.action = NODEACT_DELETE;
} else if (!strcmp(val, "add")) { } else if (!strcmp(val, "add")) {
@ -370,19 +361,38 @@ void svndump_read(const char *url)
fprintf(stderr, "Unknown node-action: %s\n", val); fprintf(stderr, "Unknown node-action: %s\n", val);
node_ctx.action = NODEACT_UNKNOWN; node_ctx.action = NODEACT_UNKNOWN;
} }
} else if (key == keys.node_copyfrom_path) { break;
case sizeof("Node-copyfrom-path"):
if (constcmp(t, "Node-copyfrom-path"))
continue;
pool_tok_seq(REPO_MAX_PATH_DEPTH, node_ctx.src, "/", val); pool_tok_seq(REPO_MAX_PATH_DEPTH, node_ctx.src, "/", val);
} else if (key == keys.node_copyfrom_rev) { break;
case sizeof("Node-copyfrom-rev"):
if (constcmp(t, "Node-copyfrom-rev"))
continue;
node_ctx.srcRev = atoi(val); node_ctx.srcRev = atoi(val);
} else if (key == keys.text_content_length) { break;
node_ctx.textLength = atoi(val); case sizeof("Text-content-length"):
} else if (key == keys.prop_content_length) { if (!constcmp(t, "Text-content-length")) {
node_ctx.textLength = atoi(val);
break;
}
if (constcmp(t, "Prop-content-length"))
continue;
node_ctx.propLength = atoi(val); node_ctx.propLength = atoi(val);
} else if (key == keys.text_delta) { break;
node_ctx.text_delta = !strcmp(val, "true"); case sizeof("Text-delta"):
} else if (key == keys.prop_delta) { if (!constcmp(t, "Text-delta")) {
node_ctx.text_delta = !strcmp(val, "true");
break;
}
if (constcmp(t, "Prop-delta"))
continue;
node_ctx.prop_delta = !strcmp(val, "true"); node_ctx.prop_delta = !strcmp(val, "true");
} else if (key == keys.content_length) { break;
case sizeof("Content-length"):
if (constcmp(t, "Content-length"))
continue;
len = atoi(val); len = atoi(val);
t = buffer_read_line(&input); t = buffer_read_line(&input);
if (!t) if (!t)
@ -417,7 +427,6 @@ int svndump_init(const char *filename)
reset_dump_ctx(~0); reset_dump_ctx(~0);
reset_rev_ctx(0); reset_rev_ctx(0);
reset_node_ctx(NULL); reset_node_ctx(NULL);
init_keys();
return 0; return 0;
} }