From: Jonathan Nieder Date: Tue, 22 Mar 2011 23:44:49 +0000 (-0500) Subject: Merge branch 'db/length-as-hash' into svn-fe X-Git-Tag: v1.7.5-rc0~3^2~8 X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=41b9dd9d4f2f32f8450af59c30f3a7a2fc5a8cc7;p=git.git Merge branch 'db/length-as-hash' into svn-fe * db/length-as-hash: vcs-svn: use strchr to find RFC822 delimiter vcs-svn: implement perfect hash for top-level keys vcs-svn: implement perfect hash for node-prop keys Conflicts: vcs-svn/svndump.c --- 41b9dd9d4f2f32f8450af59c30f3a7a2fc5a8cc7 diff --cc vcs-svn/svndump.c index 7ac74877f,0919a576d..ea5b128e4 --- a/vcs-svn/svndump.c +++ b/vcs-svn/svndump.c @@@ -11,9 -11,15 +11,15 @@@ #include "repo_tree.h" #include "fast_export.h" #include "line_buffer.h" -#include "obj_pool.h" #include "string_pool.h" +#include "strbuf.h" + /* + * Compare start of string to literal of equal length; + * must be guarded by length test. + */ + #define constcmp(s, ref) memcmp(s, ref, sizeof(ref) - 1) + #define NODEACT_REPLACE 4 #define NODEACT_DELETE 3 #define NODEACT_ADD 2 @@@ -42,19 -60,9 +48,10 @@@ static struct } rev_ctx; static struct { - uint32_t version, uuid, url; + uint32_t version; + struct strbuf uuid, url; } dump_ctx; - static struct { - uint32_t svn_log, svn_author, svn_date, svn_executable, svn_special, 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) { node_ctx.type = 0; @@@ -72,55 -80,41 +69,45 @@@ static void reset_rev_ctx(uint32_t revi { rev_ctx.revision = revision; rev_ctx.timestamp = 0; - rev_ctx.log = NULL; - rev_ctx.author = ~0; + strbuf_reset(&rev_ctx.log); + strbuf_reset(&rev_ctx.author); } -static void reset_dump_ctx(uint32_t url) +static void reset_dump_ctx(const char *url) { - dump_ctx.url = url; + strbuf_reset(&dump_ctx.url); + if (url) + strbuf_addstr(&dump_ctx.url, url); dump_ctx.version = 1; - dump_ctx.uuid = ~0; + strbuf_reset(&dump_ctx.uuid); } - static void init_keys(void) - { - keys.svn_log = pool_intern("svn:log"); - keys.svn_author = pool_intern("svn:author"); - keys.svn_date = pool_intern("svn:date"); - keys.svn_executable = pool_intern("svn:executable"); - keys.svn_special = pool_intern("svn:special"); - 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(uint32_t key, const char *val, uint32_t len, + static void handle_property(const struct strbuf *key_buf, + const char *val, uint32_t len, uint32_t *type_set) { - if (key == keys.svn_log) { + const char *key = key_buf->buf; + size_t keylen = key_buf->len; + + switch (keylen + 1) { + case sizeof("svn:log"): + if (constcmp(key, "svn:log")) + break; if (!val) die("invalid dump: unsets svn:log"); - /* Value length excludes terminating nul. */ - rev_ctx.log = log_copy(len + 1, val); + strbuf_reset(&rev_ctx.log); + strbuf_add(&rev_ctx.log, val, len); - } else if (key == keys.svn_author) { + break; + case sizeof("svn:author"): + if (constcmp(key, "svn:author")) + break; - rev_ctx.author = pool_intern(val); + strbuf_reset(&rev_ctx.author); + if (val) + strbuf_add(&rev_ctx.author, val, len); - } else if (key == keys.svn_date) { + break; + case sizeof("svn:date"): + if (constcmp(key, "svn:date")) + break; if (!val) die("invalid dump: unsets svn:date"); if (parse_date_basic(val, &rev_ctx.timestamp, NULL)) @@@ -290,26 -294,35 +288,36 @@@ void svndump_read(const char *url char *t; uint32_t active_ctx = DUMP_CTX; uint32_t len; - uint32_t key; - reset_dump_ctx(pool_intern(url)); + reset_dump_ctx(url); while ((t = buffer_read_line(&input))) { - val = strstr(t, ": "); + val = strchr(t, ':'); if (!val) continue; - *val++ = '\0'; - *val++ = '\0'; - key = pool_intern(t); + val++; + if (*val != ' ') + continue; + val++; - 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); if (dump_ctx.version > 3) die("expected svn dump format version <= 3, found %"PRIu32, dump_ctx.version); - } else if (key == keys.uuid) { + break; + case sizeof("UUID"): + if (constcmp(t, "UUID")) + continue; - dump_ctx.uuid = pool_intern(val); + strbuf_reset(&dump_ctx.uuid); + strbuf_addstr(&dump_ctx.uuid, val); - } else if (key == keys.revision_number) { + break; + case sizeof("Revision-number"): + if (constcmp(t, "Revision-number")) + continue; if (active_ctx == NODE_CTX) handle_node(); if (active_ctx != DUMP_CTX) @@@ -385,14 -427,9 +422,13 @@@ int svndump_init(const char *filename if (buffer_init(&input, filename)) return error("cannot open %s: %s", filename, strerror(errno)); repo_init(); - reset_dump_ctx(~0); + strbuf_init(&dump_ctx.uuid, 4096); + strbuf_init(&dump_ctx.url, 4096); + strbuf_init(&rev_ctx.log, 4096); + strbuf_init(&rev_ctx.author, 4096); + reset_dump_ctx(NULL); reset_rev_ctx(0); reset_node_ctx(NULL); - init_keys(); return 0; }