Skip to content

Commit

Permalink
pack-objects: Allow use of pre-generated pack.
Browse files Browse the repository at this point in the history
git-pack-objects can reuse pack files stored in $GIT_DIR/pack-cache
directory, when a necessary pack is found.  This is hopefully useful
when upload-pack (called from git-daemon) is expected to receive
requests for the same set of objects many times (e.g full cloning
request of any project, or updates from the set of heads previous day
to the latest for a slow moving project).

Currently git-pack-objects does *not* keep pack files it creates for
reusing.  It might be useful to add --update-cache option to it,
which would allow it store pack files it created in the pack-cache
directory, and prune rarely used ones from it.

Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
Junio C Hamano committed Oct 26, 2005
1 parent 7ebb6fc commit f3123c4
Show file tree
Hide file tree
Showing 4 changed files with 112 additions and 12 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ LIB_OBJS = \
object.o pack-check.o patch-delta.o path.o pkt-line.o \
quote.o read-cache.o refs.o run-command.o \
server-info.o setup.o sha1_file.o sha1_name.o strbuf.o \
tag.o tree.o usage.o config.o environment.o ctype.o \
tag.o tree.o usage.o config.o environment.o ctype.o copy.o \
$(DIFF_OBJS)

LIBS = $(LIB_FILE)
Expand Down
1 change: 1 addition & 0 deletions cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -413,4 +413,5 @@ static inline int sane_case(int x, int high)
return x;
}

extern int copy_fd(int ifd, int ofd);
#endif /* CACHE_H */
37 changes: 37 additions & 0 deletions copy.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "cache.h"

int copy_fd(int ifd, int ofd)
{
while (1) {
int len;
char buffer[8192];
char *buf = buffer;
len = read(ifd, buffer, sizeof(buffer));
if (!len)
break;
if (len < 0) {
if (errno == EAGAIN)
continue;
return error("copy-fd: read returned %s",
strerror(errno));
}
while (1) {
int written = write(ofd, buf, len);
if (written > 0) {
buf += written;
len -= written;
if (!len)
break;
}
if (!written)
return error("copy-fd: write returned 0");
if (errno == EAGAIN || errno == EINTR)
continue;
return error("copy-fd: write returned %s",
strerror(errno));
}
}
close(ifd);
return 0;
}

84 changes: 73 additions & 11 deletions pack-objects.c
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,71 @@ static void find_deltas(struct object_entry **list, int window, int depth)
free(array);
}

static void prepare_pack(int window, int depth)
{
get_object_details();

fprintf(stderr, "Packing %d objects\n", nr_objects);

sorted_by_type = create_sorted_list(type_size_sort);
if (window && depth)
find_deltas(sorted_by_type, window+1, depth);
write_pack_file();
}

static int reuse_cached_pack(unsigned char *sha1, int pack_to_stdout)
{
static const char cache[] = "pack-cache/pack-%s.%s";
char *cached_pack, *cached_idx;
int ifd, ofd, ifd_ix = -1;

cached_pack = git_path(cache, sha1_to_hex(sha1), "pack");
ifd = open(cached_pack, O_RDONLY);
if (ifd < 0)
return 0;

if (!pack_to_stdout) {
cached_idx = git_path(cache, sha1_to_hex(sha1), "idx");
ifd_ix = open(cached_idx, O_RDONLY);
if (ifd_ix < 0) {
close(ifd);
return 0;
}
}

fprintf(stderr, "Reusing %d objects pack %s\n", nr_objects,
sha1_to_hex(sha1));

if (pack_to_stdout) {
if (copy_fd(ifd, 1))
exit(1);
close(ifd);
}
else {
char name[PATH_MAX];
snprintf(name, sizeof(name),
"%s-%s.%s", base_name, sha1_to_hex(sha1), "pack");
ofd = open(name, O_CREAT | O_EXCL | O_WRONLY, 0666);
if (ofd < 0)
die("unable to open %s (%s)", name, strerror(errno));
if (copy_fd(ifd, ofd))
exit(1);
close(ifd);

snprintf(name, sizeof(name),
"%s-%s.%s", base_name, sha1_to_hex(sha1), "idx");
ofd = open(name, O_CREAT | O_EXCL | O_WRONLY, 0666);
if (ofd < 0)
die("unable to open %s (%s)", name, strerror(errno));
if (copy_fd(ifd_ix, ofd))
exit(1);
close(ifd_ix);
puts(sha1_to_hex(sha1));
}

return 1;
}

int main(int argc, char **argv)
{
SHA_CTX ctx;
Expand Down Expand Up @@ -472,9 +537,6 @@ int main(int argc, char **argv)
}
if (non_empty && !nr_objects)
return 0;
get_object_details();

fprintf(stderr, "Packing %d objects\n", nr_objects);

sorted_by_sha = create_sorted_list(sha1_sort);
SHA1_Init(&ctx);
Expand All @@ -485,14 +547,14 @@ int main(int argc, char **argv)
}
SHA1_Final(object_list_sha1, &ctx);

sorted_by_type = create_sorted_list(type_size_sort);
if (window && depth)
find_deltas(sorted_by_type, window+1, depth);

write_pack_file();
if (!pack_to_stdout) {
write_index_file();
puts(sha1_to_hex(object_list_sha1));
if (reuse_cached_pack(object_list_sha1, pack_to_stdout))
;
else {
prepare_pack(window, depth);
if (!pack_to_stdout) {
write_index_file();
puts(sha1_to_hex(object_list_sha1));
}
}
return 0;
}

0 comments on commit f3123c4

Please sign in to comment.