From: Florian Achleitner <florian.achleitner.2.6.31@gmail.com>
To: git@vger.kernel.org
Cc: David Michael Barr <b@rr-dav.id.au>,
Jonathan Nieder <jrnieder@gmail.com>,
Florian Achleitner <florian.achleitner.2.6.31@gmail.com>
Subject: [RFC 3/5] vcs-svn/svndump: restructure node_ctx, rev_ctx handling
Date: Fri, 17 Aug 2012 22:40:08 +0200 [thread overview]
Message-ID: <1345236010-1648-4-git-send-email-florian.achleitner.2.6.31@gmail.com> (raw)
In-Reply-To: <1345236010-1648-3-git-send-email-florian.achleitner.2.6.31@gmail.com>
As a preparation for handling branches in svndumps, make rev_ctx
and node_ctx more flexible.
Add the object to work on to the arguments of reset_*_ctx() and to
handle_node() to allow for multiple *_ctx objects.
Convert the static global node_ctx to a linked list ofsuch objects
to be able to accumulate all Node data of a revision in memory
before processing it.
Signed-off-by: Florian Achleitner <florian.achleitner.2.6.31@gmail.com>
---
vcs-svn/svndump.c | 207 +++++++++++++++++++++++++++++++----------------------
vcs-svn/svndump.h | 2 +
2 files changed, 124 insertions(+), 85 deletions(-)
diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c
index 296be8c..2fca9f8 100644
--- a/vcs-svn/svndump.c
+++ b/vcs-svn/svndump.c
@@ -38,42 +38,81 @@
static struct line_buffer input = LINE_BUFFER_INIT;
-static struct node_ctx_t node_ctx;
+static struct node_ctx_t *node_ctx;
static struct rev_ctx_t rev_ctx;
static struct dump_ctx_t dump_ctx;
+static const char *current_ref;
+static struct node_ctx_t *node_list, *node_list_tail;
-static void reset_node_ctx(char *fname)
+static struct node_ctx_t *new_node_ctx(char *fname)
{
- node_ctx.type = 0;
- node_ctx.action = NODEACT_UNKNOWN;
- node_ctx.prop_length = -1;
- node_ctx.text_length = -1;
- strbuf_reset(&node_ctx.src);
- node_ctx.srcRev = 0;
- strbuf_reset(&node_ctx.dst);
+ struct node_ctx_t *node = xmalloc(sizeof(struct node_ctx_t));
+ trace_printf("new_node_ctx %p\n", node);
+ node->type = 0;
+ node->action = NODEACT_UNKNOWN;
+ node->prop_length = -1;
+ node->text_length = -1;
+ strbuf_init(&node->src, 4096);
+ node->srcRev = 0;
+ strbuf_init(&node->dst, 4096);
if (fname)
- strbuf_addstr(&node_ctx.dst, fname);
- node_ctx.text_delta = 0;
- node_ctx.prop_delta = 0;
+ strbuf_addstr(&node->dst, fname);
+ node->text_delta = 0;
+ node->prop_delta = 0;
+ node->dataref = NULL;
+ node->next = NULL;
+ return node;
}
-static void reset_rev_ctx(uint32_t revision)
+static void free_node_ctx(struct node_ctx_t *node)
{
- rev_ctx.revision = revision;
- rev_ctx.timestamp = 0;
- strbuf_reset(&rev_ctx.log);
- strbuf_reset(&rev_ctx.author);
- strbuf_reset(&rev_ctx.note);
+ trace_printf("free_node_ctx %p\n", node);
+ strbuf_release(&node->src);
+ strbuf_release(&node->dst);
+ free((char*)node->dataref);
+ free(node);
}
-static void reset_dump_ctx(const char *url)
+static void free_node_list()
{
- strbuf_reset(&dump_ctx.url);
+ struct node_ctx_t *p = node_list, *n;
+ trace_printf("free_node_list head %p tail %p\n", node_list, node_list_tail);
+ while (p) {
+ n = p->next;
+ free_node_ctx(p);
+ p = n;
+ }
+ node_list = node_list_tail = NULL;
+}
+
+static void append_node_list(struct node_ctx_t *n)
+{
+ trace_printf("append_node_list %p head %p tail %p\n", n, node_list, node_list_tail);
+ if (!node_list)
+ node_list = node_list_tail = n;
+ else {
+ node_list_tail->next = n;
+ node_list_tail = n;
+ }
+}
+
+static void reset_rev_ctx(struct rev_ctx_t *rev, uint32_t revision)
+{
+ rev->revision = revision;
+ rev->timestamp = 0;
+ strbuf_reset(&rev->log);
+ strbuf_reset(&rev->author);
+ strbuf_reset(&rev->note);
+}
+
+static void reset_dump_ctx(struct dump_ctx_t *dump, const char *url)
+{
+ strbuf_reset(&dump->url);
if (url)
- strbuf_addstr(&dump_ctx.url, url);
- dump_ctx.version = 1;
- strbuf_reset(&dump_ctx.uuid);
+ strbuf_addstr(&dump->url, url);
+ dump->version = 1;
+ strbuf_reset(&dump->uuid);
}
static void handle_property(const struct strbuf *key_buf,
@@ -121,11 +160,11 @@ static void handle_property(const struct strbuf *key_buf,
die("invalid dump: sets type twice");
}
if (!val) {
- node_ctx.type = REPO_MODE_BLB;
+ node_ctx->type = REPO_MODE_BLB;
return;
}
*type_set = 1;
- node_ctx.type = keylen == strlen("svn:executable") ?
+ node_ctx->type = keylen == strlen("svn:executable") ?
REPO_MODE_EXE :
REPO_MODE_LNK;
}
@@ -193,11 +232,11 @@ static void read_props(void)
}
}
-static void handle_node(void)
+static void handle_node(struct node_ctx_t *node)
{
- const uint32_t type = node_ctx.type;
- const int have_props = node_ctx.prop_length != -1;
- const int have_text = node_ctx.text_length != -1;
+ const uint32_t type = node->type;
+ const int have_props = node->prop_length != -1;
+ const int have_text = node->text_length != -1;
/*
* Old text for this node:
* NULL - directory or bug
@@ -208,21 +247,21 @@ static void handle_node(void)
const char *old_data = NULL;
uint32_t old_mode = REPO_MODE_BLB;
- if (node_ctx.action == NODEACT_DELETE) {
- if (have_text || have_props || node_ctx.srcRev)
+ if (node->action == NODEACT_DELETE) {
+ if (have_text || have_props || node->srcRev)
die("invalid dump: deletion node has "
"copyfrom info, text, or properties");
- repo_delete(node_ctx.dst.buf);
+ repo_delete(node->dst.buf);
return;
}
- if (node_ctx.action == NODEACT_REPLACE) {
- repo_delete(node_ctx.dst.buf);
- node_ctx.action = NODEACT_ADD;
+ if (node->action == NODEACT_REPLACE) {
+ repo_delete(node->dst.buf);
+ node->action = NODEACT_ADD;
}
- if (node_ctx.srcRev) {
- repo_copy(node_ctx.srcRev, node_ctx.src.buf, node_ctx.dst.buf);
- if (node_ctx.action == NODEACT_ADD)
- node_ctx.action = NODEACT_CHANGE;
+ if (node->srcRev) {
+ repo_copy(node->srcRev, node->src.buf, node->dst.buf);
+ if (node->action == NODEACT_ADD)
+ node->action = NODEACT_CHANGE;
}
if (have_text && type == REPO_MODE_DIR)
die("invalid dump: directories cannot have text attached");
@@ -230,20 +269,20 @@ static void handle_node(void)
/*
* Find old content (old_data) and decide on the new mode.
*/
- if (node_ctx.action == NODEACT_CHANGE && !*node_ctx.dst.buf) {
+ if (node->action == NODEACT_CHANGE && !*node->dst.buf) {
if (type != REPO_MODE_DIR)
die("invalid dump: root of tree is not a regular file");
old_data = NULL;
- } else if (node_ctx.action == NODEACT_CHANGE) {
+ } else if (node->action == NODEACT_CHANGE) {
uint32_t mode;
- old_data = repo_read_path(node_ctx.dst.buf, &mode);
+ old_data = repo_read_path(node->dst.buf, &mode); /* malloced buffer */
if (mode == REPO_MODE_DIR && type != REPO_MODE_DIR)
die("invalid dump: cannot modify a directory into a file");
if (mode != REPO_MODE_DIR && type == REPO_MODE_DIR)
die("invalid dump: cannot modify a file into a directory");
- node_ctx.type = mode;
+ node->type = mode;
old_mode = mode;
- } else if (node_ctx.action == NODEACT_ADD) {
+ } else if (node->action == NODEACT_ADD) {
if (type == REPO_MODE_DIR)
old_data = NULL;
else if (have_text)
@@ -258,9 +297,9 @@ static void handle_node(void)
* Adjust mode to reflect properties.
*/
if (have_props) {
- if (!node_ctx.prop_delta)
- node_ctx.type = type;
- if (node_ctx.prop_length)
+ if (!node->prop_delta)
+ node->type = type;
+ if (node->prop_length)
read_props();
}
@@ -274,17 +313,17 @@ static void handle_node(void)
/* For the fast_export_* functions, NULL means empty. */
old_data = NULL;
if (!have_text) {
- fast_export_modify(node_ctx.dst.buf, node_ctx.type, old_data);
+ fast_export_modify(node->dst.buf, node->type, old_data);
return;
}
- if (!node_ctx.text_delta) {
- fast_export_modify(node_ctx.dst.buf, node_ctx.type, "inline");
- fast_export_data(node_ctx.type, node_ctx.text_length, &input, NULL);
+ if (!node->text_delta) {
+ fast_export_modify(node->dst.buf, node->type, "inline");
+ fast_export_data(node->type, node->text_length, &input, NULL);
return;
}
- fast_export_modify(node_ctx.dst.buf, node_ctx.type, "inline");
- fast_export_blob_delta(node_ctx.type, old_mode, old_data,
- node_ctx.text_length, &input, NULL);
+ fast_export_modify(node->dst.buf, node->type, "inline");
+ fast_export_blob_delta(node->type, old_mode, old_data,
+ node->text_length, &input, NULL);
}
static void begin_revision(const char *remote_ref)
@@ -316,7 +355,7 @@ void svndump_read(const char *url, const char *local_ref, const char *notes_ref)
uint32_t active_ctx = DUMP_CTX;
uint32_t len;
- reset_dump_ctx(url);
+ reset_dump_ctx(&dump_ctx, url);
while ((t = buffer_read_line(&input))) {
val = strchr(t, ':');
if (!val)
@@ -346,13 +385,13 @@ void svndump_read(const char *url, const char *local_ref, const char *notes_ref)
if (constcmp(t, "Revision-number"))
continue;
if (active_ctx == NODE_CTX)
- handle_node();
+ handle_node(node_ctx);
if (active_ctx == REV_CTX)
begin_revision(local_ref);
if (active_ctx != DUMP_CTX)
end_revision(notes_ref);
active_ctx = REV_CTX;
- reset_rev_ctx(atoi(val));
+ reset_rev_ctx(&rev_ctx, atoi(val));
strbuf_addf(&rev_ctx.note, "%s\n", t);
break;
case sizeof("Node-path"):
@@ -360,11 +399,11 @@ void svndump_read(const char *url, const char *local_ref, const char *notes_ref)
continue;
if (!constcmp(t + strlen("Node-"), "path")) {
if (active_ctx == NODE_CTX)
- handle_node();
+ handle_node(node_ctx);
if (active_ctx == REV_CTX)
begin_revision(local_ref);
active_ctx = NODE_CTX;
- reset_node_ctx(val);
+ node_ctx = new_node_ctx(val);
strbuf_addf(&rev_ctx.note, "%s\n", t);
break;
}
@@ -372,9 +411,9 @@ void svndump_read(const char *url, const char *local_ref, const char *notes_ref)
continue;
strbuf_addf(&rev_ctx.note, "%s\n", t);
if (!strcmp(val, "dir"))
- node_ctx.type = REPO_MODE_DIR;
+ node_ctx->type = REPO_MODE_DIR;
else if (!strcmp(val, "file"))
- node_ctx.type = REPO_MODE_BLB;
+ node_ctx->type = REPO_MODE_BLB;
else
fprintf(stderr, "Unknown node-kind: %s\n", val);
break;
@@ -383,29 +422,29 @@ void svndump_read(const char *url, const char *local_ref, const char *notes_ref)
continue;
strbuf_addf(&rev_ctx.note, "%s\n", t);
if (!strcmp(val, "delete")) {
- node_ctx.action = NODEACT_DELETE;
+ node_ctx->action = NODEACT_DELETE;
} else if (!strcmp(val, "add")) {
- node_ctx.action = NODEACT_ADD;
+ node_ctx->action = NODEACT_ADD;
} else if (!strcmp(val, "change")) {
- node_ctx.action = NODEACT_CHANGE;
+ node_ctx->action = NODEACT_CHANGE;
} else if (!strcmp(val, "replace")) {
- node_ctx.action = NODEACT_REPLACE;
+ node_ctx->action = NODEACT_REPLACE;
} else {
fprintf(stderr, "Unknown node-action: %s\n", val);
- node_ctx.action = NODEACT_UNKNOWN;
+ node_ctx->action = NODEACT_UNKNOWN;
}
break;
case sizeof("Node-copyfrom-path"):
if (constcmp(t, "Node-copyfrom-path"))
continue;
- strbuf_reset(&node_ctx.src);
- strbuf_addstr(&node_ctx.src, val);
+ strbuf_reset(&node_ctx->src);
+ strbuf_addstr(&node_ctx->src, val);
strbuf_addf(&rev_ctx.note, "%s\n", t);
break;
case sizeof("Node-copyfrom-rev"):
if (constcmp(t, "Node-copyfrom-rev"))
continue;
- node_ctx.srcRev = atoi(val);
+ node_ctx->srcRev = atoi(val);
strbuf_addf(&rev_ctx.note, "%s\n", t);
break;
case sizeof("Text-content-length"):
@@ -424,19 +463,19 @@ void svndump_read(const char *url, const char *local_ref, const char *notes_ref)
die("unrepresentable length in dump: %s", val);
if (*t == 'T')
- node_ctx.text_length = (off_t) len;
+ node_ctx->text_length = (off_t) len;
else
- node_ctx.prop_length = (off_t) len;
+ node_ctx->prop_length = (off_t) len;
break;
}
case sizeof("Text-delta"):
if (!constcmp(t, "Text-delta")) {
- node_ctx.text_delta = !strcmp(val, "true");
+ 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");
break;
case sizeof("Content-length"):
if (constcmp(t, "Content-length"))
@@ -450,7 +489,7 @@ void svndump_read(const char *url, const char *local_ref, const char *notes_ref)
if (active_ctx == REV_CTX) {
read_props();
} else if (active_ctx == NODE_CTX) {
- handle_node();
+ handle_node(node_ctx);
active_ctx = INTERNODE_CTX;
} else {
fprintf(stderr, "Unexpected content length header: %"PRIu32"\n", len);
@@ -462,7 +501,7 @@ void svndump_read(const char *url, const char *local_ref, const char *notes_ref)
if (buffer_ferror(&input))
die_short_read();
if (active_ctx == NODE_CTX)
- handle_node();
+ handle_node(node_ctx);
if (active_ctx == REV_CTX)
begin_revision(local_ref);
if (active_ctx != DUMP_CTX)
@@ -477,11 +516,10 @@ static void init(int report_fd)
strbuf_init(&rev_ctx.log, 4096);
strbuf_init(&rev_ctx.author, 4096);
strbuf_init(&rev_ctx.note, 4096);
- strbuf_init(&node_ctx.src, 4096);
- strbuf_init(&node_ctx.dst, 4096);
- reset_dump_ctx(NULL);
- reset_rev_ctx(0);
- reset_node_ctx(NULL);
+ reset_dump_ctx(&dump_ctx, NULL);
+ reset_rev_ctx(&rev_ctx, 0);
+ node_ctx = new_node_ctx(NULL);
+ node_list = node_list_tail = NULL;
return;
}
@@ -504,14 +542,12 @@ int svndump_init_fd(int in_fd, int back_fd)
void svndump_deinit(void)
{
fast_export_deinit();
- reset_dump_ctx(NULL);
- reset_rev_ctx(0);
- reset_node_ctx(NULL);
+ reset_dump_ctx(&dump_ctx, NULL);
+ reset_rev_ctx(&rev_ctx, 0);
strbuf_release(&rev_ctx.log);
strbuf_release(&rev_ctx.author);
strbuf_release(&rev_ctx.note);
- strbuf_release(&node_ctx.src);
- strbuf_release(&node_ctx.dst);
+ free_node_list();
if (buffer_deinit(&input))
fprintf(stderr, "Input error\n");
if (ferror(stdout))
@@ -524,4 +560,5 @@ void svndump_reset(void)
strbuf_release(&dump_ctx.url);
strbuf_release(&rev_ctx.log);
strbuf_release(&rev_ctx.author);
+ free_node_list();
}
diff --git a/vcs-svn/svndump.h b/vcs-svn/svndump.h
index d545453..29794df 100644
--- a/vcs-svn/svndump.h
+++ b/vcs-svn/svndump.h
@@ -13,6 +13,8 @@ struct node_ctx_t {
off_t prop_length, text_length;
struct strbuf src, dst;
uint32_t text_delta, prop_delta;
+ const char *dataref;
+ struct node_ctx_t *next;
};
struct rev_ctx_t {
--
1.7.9.5
next prev parent reply other threads:[~2012-08-17 20:41 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-08-17 20:40 [RFC 1/5] GSOC: prepare svndump for branch detection Florian Achleitner
2012-08-17 20:40 ` [RFC 1/5] vcs-svn: Add sha1 calculaton to fast_export and line_buffer Florian Achleitner
2012-08-17 20:40 ` [RFC 2/5] svndump: move struct definitions to .h Florian Achleitner
2012-08-17 20:40 ` Florian Achleitner [this message]
2012-08-17 20:40 ` [RFC 4/5] vcs-svn/svndump: rewrite handle_node(), begin|end_revision() Florian Achleitner
2012-08-17 20:40 ` [RFC 5/5] vcs-svn: remove repo_tree Florian Achleitner
2012-08-18 18:37 ` [RFC 1/5] GSOC: prepare svndump for branch detection David Michael Barr
2012-08-20 6:26 ` Florian Achleitner
2012-08-20 6:57 ` Junio C Hamano
2012-08-20 13:35 ` Florian Achleitner
2012-08-20 16:45 ` Jonathan Nieder
2012-08-20 17:43 ` Florian Achleitner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1345236010-1648-4-git-send-email-florian.achleitner.2.6.31@gmail.com \
--to=florian.achleitner.2.6.31@gmail.com \
--cc=b@rr-dav.id.au \
--cc=git@vger.kernel.org \
--cc=jrnieder@gmail.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).