Andrew's git
/
gitweb.git
/ diff
summary
|
log
|
commit
| diff |
tree
commit
grep
author
committer
pickaxe
?
re
vcs-svn: implement perfect hash for node-prop keys
author
David Barr
<david.barr@cordelta.com>
Mon, 13 Dec 2010 08:13:24 +0000
(19:13 +1100)
committer
Jonathan Nieder
<jrnieder@gmail.com>
Tue, 22 Mar 2011 23:09:02 +0000
(18:09 -0500)
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.
This is a small step towards removing dependence on string_pool.
Signed-off-by: David Barr <david.barr@cordelta.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
vcs-svn/svndump.c
patch
|
blob
|
history
raw
|
patch
|
inline
| side by side (parent:
c9d1c8b
)
diff --git
a/vcs-svn/svndump.c
b/vcs-svn/svndump.c
index 15f822ea844ba64a12d19e02e12f244b2f99d4cb..322d1cd305868c5d4eef910b729aeaeeab899b01 100644
(file)
--- a/
vcs-svn/svndump.c
+++ b/
vcs-svn/svndump.c
@@
-14,6
+14,12
@@
#include "obj_pool.h"
#include "string_pool.h"
#include "obj_pool.h"
#include "string_pool.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
#define NODEACT_REPLACE 4
#define NODEACT_DELETE 3
#define NODEACT_ADD 2
@@
-58,8
+64,7
@@
static struct {
} dump_ctx;
static struct {
} 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,
+ 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 */
node_copyfrom_path, node_copyfrom_rev, text_content_length,
prop_content_length, content_length, svn_fs_dump_format_version,
/* version 3 format */
@@
-96,11
+101,6
@@
static void reset_dump_ctx(uint32_t url)
static void init_keys(void)
{
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.uuid = pool_intern("UUID");
keys.revision_number = pool_intern("Revision-number");
keys.node_path = pool_intern("Node-path");
@@
-117,22
+117,43
@@
static void init_keys(void)
keys.prop_delta = pool_intern("Prop-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)
{
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);
if (!val)
die("invalid dump: unsets svn:log");
/* Value length excludes terminating nul. */
rev_ctx.log = log_copy(len + 1, val);
- } else if (key == keys.svn_author) {
+ break;
+ case sizeof("svn:author"):
+ if (constcmp(key, "svn:author"))
+ break;
rev_ctx.author = pool_intern(val);
rev_ctx.author = pool_intern(val);
- } 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))
warning("invalid timestamp: %s", val);
if (!val)
die("invalid dump: unsets svn:date");
if (parse_date_basic(val, &rev_ctx.timestamp, NULL))
warning("invalid timestamp: %s", val);
- } else if (key == keys.svn_executable || key == keys.svn_special) {
+ break;
+ case sizeof("svn:executable"):
+ case sizeof("svn:special"):
+ if (keylen == strlen("svn:executable") &&
+ constcmp(key, "svn:executable"))
+ break;
+ if (keylen == strlen("svn:special") &&
+ constcmp(key, "svn:special"))
+ break;
if (*type_set) {
if (!val)
return;
if (*type_set) {
if (!val)
return;
@@
-143,7
+164,7
@@
static void handle_property(uint32_t key, const char *val, uint32_t len,
return;
}
*type_set = 1;
return;
}
*type_set = 1;
- node_ctx.type = key
== keys.svn_executable
?
+ node_ctx.type = key
len == strlen("svn:executable")
?
REPO_MODE_EXE :
REPO_MODE_LNK;
}
REPO_MODE_EXE :
REPO_MODE_LNK;
}
@@
-158,7
+179,7
@@
static void die_short_read(void)
static void read_props(void)
{
static void read_props(void)
{
-
uint32_t key = ~0
;
+
static struct strbuf key = STRBUF_INIT
;
const char *t;
/*
* NEEDSWORK: to support simple mode changes like
const char *t;
/*
* NEEDSWORK: to support simple mode changes like
@@
-195,16
+216,19
@@
static void read_props(void)
switch (type) {
case 'K':
switch (type) {
case 'K':
- key = pool_intern(val);
- continue;
case 'D':
case 'D':
- key = pool_intern(val);
+ strbuf_reset(&key);
+ if (val)
+ strbuf_add(&key, val, len);
+ if (type == 'K')
+ continue;
+ assert(type == 'D');
val = NULL;
len = 0;
/* fall through */
case 'V':
val = NULL;
len = 0;
/* fall through */
case 'V':
- handle_property(key, val, len, &type_set);
-
key = ~0
;
+ handle_property(
&
key, val, len, &type_set);
+
strbuf_reset(&key)
;
continue;
default:
die("invalid property line: %s\n", t);
continue;
default:
die("invalid property line: %s\n", t);