diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2012-11-05 11:33:10 -0600 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2012-11-05 16:00:29 -0600 |
commit | 09cc0b92dc60c726180cda36643e263c32d9a812 (patch) | |
tree | 8b07bb41b327e75c6c92616ec891809b11552ed7 /src | |
parent | a5e85d86b7e13352c553b0a43bc36fee5880b5c7 (diff) | |
download | libgit2-09cc0b92dc60c726180cda36643e263c32d9a812.tar.gz |
create callback to handle packs from fetch, move the indexer to odb_pack
Diffstat (limited to 'src')
-rw-r--r-- | src/fetch.c | 1 | ||||
-rw-r--r-- | src/odb.c | 25 | ||||
-rw-r--r-- | src/odb_pack.c | 67 | ||||
-rw-r--r-- | src/transports/smart_protocol.c | 28 |
4 files changed, 105 insertions, 16 deletions
diff --git a/src/fetch.c b/src/fetch.c index 4f9f0c6f9..81136fc5f 100644 --- a/src/fetch.c +++ b/src/fetch.c @@ -8,7 +8,6 @@ #include "git2/oid.h" #include "git2/refs.h" #include "git2/revwalk.h" -#include "git2/indexer.h" #include "git2/transport.h" #include "common.h" @@ -766,6 +766,31 @@ int git_odb_open_rstream(git_odb_stream **stream, git_odb *db, const git_oid *oi return error; } +int git_odb_write_pack(struct git_odb_writepack **out, git_odb *db, git_transfer_progress_callback progress_cb, void *progress_payload) +{ + unsigned int i; + int error = GIT_ERROR; + + assert(out && db); + + for (i = 0; i < db->backends.length && error < 0; ++i) { + backend_internal *internal = git_vector_get(&db->backends, i); + git_odb_backend *b = internal->backend; + + /* we don't write in alternates! */ + if (internal->is_alternate) + continue; + + if (b->writepack != NULL) + error = b->writepack(out, b, progress_cb, progress_payload); + } + + if (error == GIT_PASSTHROUGH) + error = 0; + + return error; +} + void * git_odb_backend_malloc(git_odb_backend *backend, size_t len) { GIT_UNUSED(backend); diff --git a/src/odb_pack.c b/src/odb_pack.c index 964e82afb..9f7a6ee1f 100644 --- a/src/odb_pack.c +++ b/src/odb_pack.c @@ -26,6 +26,11 @@ struct pack_backend { char *pack_folder; }; +struct pack_writepack { + struct git_odb_writepack parent; + git_indexer_stream *indexer_stream; +}; + /** * The wonderful tale of a Packed Object lookup query * =================================================== @@ -475,6 +480,67 @@ static int pack_backend__foreach(git_odb_backend *_backend, int (*cb)(git_oid *o return 0; } +static int pack_backend__writepack_add(struct git_odb_writepack *_writepack, const void *data, size_t size, git_transfer_progress *stats) +{ + struct pack_writepack *writepack = (struct pack_writepack *)_writepack; + + assert(writepack); + + return git_indexer_stream_add(writepack->indexer_stream, data, size, stats); +} + +static int pack_backend__writepack_commit(struct git_odb_writepack *_writepack, git_transfer_progress *stats) +{ + struct pack_writepack *writepack = (struct pack_writepack *)_writepack; + + assert(writepack); + + return git_indexer_stream_finalize(writepack->indexer_stream, stats); +} + +static void pack_backend__writepack_free(struct git_odb_writepack *_writepack) +{ + struct pack_writepack *writepack = (struct pack_writepack *)_writepack; + + assert(writepack); + + git_indexer_stream_free(writepack->indexer_stream); + git__free(writepack); +} + +static int pack_backend__writepack(struct git_odb_writepack **out, + git_odb_backend *_backend, + git_transfer_progress_callback progress_cb, + void *progress_payload) +{ + struct pack_backend *backend; + struct pack_writepack *writepack; + + assert(out && _backend); + + *out = NULL; + + backend = (struct pack_backend *)_backend; + + writepack = git__calloc(1, sizeof(struct pack_writepack)); + GITERR_CHECK_ALLOC(writepack); + + if (git_indexer_stream_new(&writepack->indexer_stream, + backend->pack_folder, progress_cb, progress_payload) < 0) { + git__free(writepack); + return -1; + } + + writepack->parent.backend = _backend; + writepack->parent.add = pack_backend__writepack_add; + writepack->parent.commit = pack_backend__writepack_commit; + writepack->parent.free = pack_backend__writepack_free; + + *out = (git_odb_writepack *)writepack; + + return 0; +} + static void pack_backend__free(git_odb_backend *_backend) { struct pack_backend *backend; @@ -553,6 +619,7 @@ int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir) backend->parent.read_header = NULL; backend->parent.exists = &pack_backend__exists; backend->parent.foreach = &pack_backend__foreach; + backend->parent.writepack = &pack_backend__writepack; backend->parent.free = &pack_backend__free; *backend_out = (git_odb_backend *)backend; diff --git a/src/transports/smart_protocol.c b/src/transports/smart_protocol.c index 4fdd72d69..e24eb2783 100644 --- a/src/transports/smart_protocol.c +++ b/src/transports/smart_protocol.c @@ -6,6 +6,7 @@ */ #include "smart.h" #include "refs.h" +#include "repository.h" #define NETWORK_XFER_THRESHOLD (100*1024) @@ -341,7 +342,7 @@ on_error: return error; } -static int no_sideband(transport_smart *t, git_indexer_stream *idx, gitno_buffer *buf, git_transfer_progress *stats) +static int no_sideband(transport_smart *t, struct git_odb_writepack *writepack, gitno_buffer *buf, git_transfer_progress *stats) { int recvd; @@ -351,7 +352,7 @@ static int no_sideband(transport_smart *t, git_indexer_stream *idx, gitno_buffer return GIT_EUSER; } - if (git_indexer_stream_add(idx, buf->data, buf->offset, stats) < 0) + if (writepack->add(writepack, buf->data, buf->offset, stats) < 0) return -1; gitno_consume_n(buf, buf->offset); @@ -360,7 +361,7 @@ static int no_sideband(transport_smart *t, git_indexer_stream *idx, gitno_buffer return -1; } while(recvd > 0); - if (git_indexer_stream_finalize(idx, stats)) + if (writepack->commit(writepack, stats)) return -1; return 0; @@ -396,9 +397,9 @@ int git_smart__download_pack( void *progress_payload) { transport_smart *t = (transport_smart *)transport; - git_buf path = GIT_BUF_INIT; gitno_buffer *buf = &t->buffer; - git_indexer_stream *idx = NULL; + git_odb *odb; + struct git_odb_writepack *writepack = NULL; int error = -1; struct network_packetsize_payload npp = {0}; @@ -416,19 +417,17 @@ int git_smart__download_pack( t->packetsize_cb(t->buffer.offset, t->packetsize_payload); } - if (git_buf_joinpath(&path, git_repository_path(repo), "objects/pack") < 0) - return -1; - - if (git_indexer_stream_new(&idx, git_buf_cstr(&path), progress_cb, progress_payload) < 0) + if ((error = git_repository_odb__weakptr(&odb, repo)) < 0 || + ((error = git_odb_write_pack(&writepack, odb, progress_cb, progress_payload)) < 0)) goto on_error; /* * If the remote doesn't support the side-band, we can feed - * the data directly to the indexer. Otherwise, we need to + * the data directly to the pack writer. Otherwise, we need to * check which one belongs there. */ if (!t->caps.side_band && !t->caps.side_band_64k) { - if (no_sideband(t, idx, buf, stats) < 0) + if (no_sideband(t, writepack, buf, stats) < 0) goto on_error; goto on_success; @@ -454,7 +453,7 @@ int git_smart__download_pack( git__free(pkt); } else if (pkt->type == GIT_PKT_DATA) { git_pkt_data *p = (git_pkt_data *) pkt; - if (git_indexer_stream_add(idx, p->data, p->len, stats) < 0) + if (writepack->add(writepack, p->data, p->len, stats) < 0) goto on_error; git__free(pkt); @@ -465,15 +464,14 @@ int git_smart__download_pack( } } while (1); - if (git_indexer_stream_finalize(idx, stats) < 0) + if (writepack->commit(writepack, stats) < 0) goto on_error; on_success: error = 0; on_error: - git_buf_free(&path); - git_indexer_stream_free(idx); + writepack->free(writepack); /* Trailing execution of progress_cb, if necessary */ if (npp.callback && npp.stats->received_bytes > npp.last_fired_bytes) |