summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2014-05-09 09:36:09 +0200
committerCarlos Martín Nieto <cmn@dwim.me>2014-05-09 09:59:24 +0200
commit9dbd150f5f499bbf768d65c4ebb596651e77a1b8 (patch)
tree4d3e9f766a9f478b994430377405fcec1b02368d
parentb2559f477a3f8e2bc76140ca2c76d8cc30b5f5da (diff)
downloadlibgit2-9dbd150f5f499bbf768d65c4ebb596651e77a1b8.tar.gz
pack: simplify delta chain code
The switch makes the loop somewhat unwieldy. Let's assume it's fine and perform the check when we're accessing the data. This makes our code look a lot more like git's.
-rw-r--r--src/pack.c100
1 files changed, 51 insertions, 49 deletions
diff --git a/src/pack.c b/src/pack.c
index 664e8efb0..e1fd276b7 100644
--- a/src/pack.c
+++ b/src/pack.c
@@ -549,21 +549,38 @@ int git_packfile_unpack(
/* the first one is the base, so we expand that one */
elem = git_array_pop(chain);
+ base_type = elem->type;
if (elem->cached) {
cached = elem->cached_entry;
memcpy(obj, &cached->raw, sizeof(git_rawobj));
- base_type = obj->type;
- } else {
- curpos = elem->offset;
- error = packfile_unpack_compressed(obj, p, &w_curs, &curpos, elem->size, elem->type);
- git_mwindow_close(&w_curs);
- base_type = elem->type;
- free_base = 1;
}
if (error < 0)
goto cleanup;
+ switch (base_type) {
+ case GIT_OBJ_COMMIT:
+ case GIT_OBJ_TREE:
+ case GIT_OBJ_BLOB:
+ case GIT_OBJ_TAG:
+ if (!elem->cached) {
+ curpos = elem->offset;
+ error = packfile_unpack_compressed(obj, p, &w_curs, &curpos, elem->size, elem->type);
+ git_mwindow_close(&w_curs);
+ free_base = 1;
+ }
+ if (error < 0)
+ goto cleanup;
+ break;
+ case GIT_OBJ_OFS_DELTA:
+ case GIT_OBJ_REF_DELTA:
+ error = packfile_error("dependency chain ends in a delta");
+ goto cleanup;
+ default:
+ error = packfile_error("invalid packfile type in header");
+ goto cleanup;
+ }
+
/*
* Finding the object we want as the base element is
* problematic, as we need to make sure we don't accidentally
@@ -1229,7 +1246,7 @@ static int pack_dependency_chain(git_dependency_chain *chain_out, struct git_pac
git_dependency_chain chain = GIT_ARRAY_INIT;
git_mwindow *w_curs = NULL;
git_off_t curpos = obj_offset, base_offset;
- int error = 0, found_base = 0;
+ int error = 0;
size_t size;
git_otype type;
@@ -1237,7 +1254,7 @@ static int pack_dependency_chain(git_dependency_chain *chain_out, struct git_pac
return -1;
git_array_init_to_size(chain, 64);
- while (!found_base && error == 0) {
+ while (true) {
struct pack_chain_elem *elem;
git_pack_cache_entry *cached = NULL;
@@ -1248,6 +1265,16 @@ static int pack_dependency_chain(git_dependency_chain *chain_out, struct git_pac
goto on_error;
}
+ elem->base_key = obj_offset;
+
+ /* if we have a base cached, we can stop here instead */
+ if ((cached = cache_get(&p->bases, obj_offset)) != NULL) {
+ elem->cached_entry = cached;
+ elem->cached = 1;
+ elem->type = cached->raw.type;
+ break;
+ }
+
error = git_packfile_unpack_header(&size, &type, &p->mwf, &w_curs, &curpos);
git_mwindow_close(&w_curs);
@@ -1260,51 +1287,26 @@ static int pack_dependency_chain(git_dependency_chain *chain_out, struct git_pac
elem->type = type;
elem->base_key = obj_offset;
- switch (type) {
- case GIT_OBJ_OFS_DELTA:
- case GIT_OBJ_REF_DELTA:
- /* if we have a base cached, we can stop here instead */
- if ((cached = cache_get(&p->bases, obj_offset)) != NULL) {
- elem->cached_entry = cached;
- elem->cached = 1;
- found_base = 1;
- break;
- }
-
- base_offset = get_delta_base(p, &w_curs, &curpos, type, obj_offset);
- git_mwindow_close(&w_curs);
-
- if (base_offset == 0)
- return packfile_error("delta offset is zero");
- if (base_offset < 0) { /* must actually be an error code */
- error = (int)base_offset;
- goto on_error;
- }
-
- /* we need to pass the pos *after* the delta-base bit */
- elem->offset = curpos;
-
- /* go through the loop again, but with the new object */
- obj_offset = base_offset;
+ if (type != GIT_OBJ_OFS_DELTA && type != GIT_OBJ_REF_DELTA)
break;
- /* one of these means we've found the final object in the chain */
- case GIT_OBJ_COMMIT:
- case GIT_OBJ_TREE:
- case GIT_OBJ_BLOB:
- case GIT_OBJ_TAG:
- found_base = 1;
- break;
+ base_offset = get_delta_base(p, &w_curs, &curpos, type, obj_offset);
+ git_mwindow_close(&w_curs);
- default:
- error = packfile_error("invalid packfile type in header");
- break;
+ if (base_offset == 0) {
+ error = packfile_error("delta offset is zero");
+ goto on_error;
}
- }
+ if (base_offset < 0) { /* must actually be an error code */
+ error = (int)base_offset;
+ goto on_error;
+ }
+
+ /* we need to pass the pos *after* the delta-base bit */
+ elem->offset = curpos;
- if (!found_base) {
- git_array_clear(chain);
- return packfile_error("after dependency chain loop; cannot happen");
+ /* go through the loop again, but with the new object */
+ obj_offset = base_offset;
}
*chain_out = chain;