Merge branch 'db/length-as-hash' into svn-fe
authorJonathan Nieder <jrnieder@gmail.com>
Tue, 22 Mar 2011 23:44:49 +0000 (18:44 -0500)
committerJonathan Nieder <jrnieder@gmail.com>
Tue, 22 Mar 2011 23:44:49 +0000 (18:44 -0500)
* 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

1  2 
vcs-svn/svndump.c

  #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;
  }