Commit 216863c4 by Ben Straub

Fetch/indexer: progress callbacks

parent 0ae81fc4
...@@ -23,6 +23,11 @@ typedef struct git_indexer_stats { ...@@ -23,6 +23,11 @@ typedef struct git_indexer_stats {
} git_indexer_stats; } git_indexer_stats;
/**
* Type for progress callbacks during indexing
*/
typedef void (*git_indexer_progress_callback)(const git_indexer_stats *stats, void *payload);
typedef struct git_indexer git_indexer; typedef struct git_indexer git_indexer;
typedef struct git_indexer_stream git_indexer_stream; typedef struct git_indexer_stream git_indexer_stream;
...@@ -31,8 +36,14 @@ typedef struct git_indexer_stream git_indexer_stream; ...@@ -31,8 +36,14 @@ typedef struct git_indexer_stream git_indexer_stream;
* *
* @param out where to store the indexer instance * @param out where to store the indexer instance
* @param path to the directory where the packfile should be stored * @param path to the directory where the packfile should be stored
* @param progress_cb function to call with progress information
* @param progress_payload payload for the progress callback
*/ */
GIT_EXTERN(int) git_indexer_stream_new(git_indexer_stream **out, const char *path); GIT_EXTERN(int) git_indexer_stream_new(
git_indexer_stream **out,
const char *path,
git_indexer_progress_callback progress_cb,
void *progress_callback_payload);
/** /**
* Add data to the indexer * Add data to the indexer
......
...@@ -184,9 +184,15 @@ GIT_EXTERN(int) git_remote_ls(git_remote *remote, git_headlist_cb list_cb, void ...@@ -184,9 +184,15 @@ GIT_EXTERN(int) git_remote_ls(git_remote *remote, git_headlist_cb list_cb, void
* *
* @param remote the remote to download from * @param remote the remote to download from
* @param filename where to store the temporary filename * @param filename where to store the temporary filename
* @param progress_cb function to call with progress information
* @param progress_payload payload for the progress callback
* @return 0 or an error code * @return 0 or an error code
*/ */
GIT_EXTERN(int) git_remote_download(git_remote *remote, git_off_t *bytes); GIT_EXTERN(int) git_remote_download(
git_remote *remote,
git_off_t *bytes,
git_indexer_progress_callback progress_cb,
void *progress_payload);
/** /**
* Check whether the remote is connected * Check whether the remote is connected
......
...@@ -258,7 +258,7 @@ static int setup_remotes_and_fetch(git_repository *repo, const char *origin_url) ...@@ -258,7 +258,7 @@ static int setup_remotes_and_fetch(git_repository *repo, const char *origin_url)
if (!git_remote_add(&origin, repo, GIT_REMOTE_ORIGIN, origin_url)) { if (!git_remote_add(&origin, repo, GIT_REMOTE_ORIGIN, origin_url)) {
/* Connect and download everything */ /* Connect and download everything */
if (!git_remote_connect(origin, GIT_DIR_FETCH)) { if (!git_remote_connect(origin, GIT_DIR_FETCH)) {
if (!git_remote_download(origin, &bytes)) { if (!git_remote_download(origin, &bytes, NULL, NULL)) {
/* Create "origin/foo" branches for all remote branches */ /* Create "origin/foo" branches for all remote branches */
if (!git_remote_update_tips(origin)) { if (!git_remote_update_tips(origin)) {
/* Point HEAD to the same ref as the remote's head */ /* Point HEAD to the same ref as the remote's head */
......
...@@ -302,7 +302,11 @@ on_error: ...@@ -302,7 +302,11 @@ on_error:
return error; return error;
} }
int git_fetch_download_pack(git_remote *remote, git_off_t *bytes) int git_fetch_download_pack(
git_remote *remote,
git_off_t *bytes,
git_indexer_progress_callback progress_cb,
void *progress_payload)
{ {
git_transport *t = remote->transport; git_transport *t = remote->transport;
...@@ -312,7 +316,8 @@ int git_fetch_download_pack(git_remote *remote, git_off_t *bytes) ...@@ -312,7 +316,8 @@ int git_fetch_download_pack(git_remote *remote, git_off_t *bytes)
if (t->own_logic) if (t->own_logic)
return t->download_pack(t, remote->repo, bytes, &remote->stats); return t->download_pack(t, remote->repo, bytes, &remote->stats);
return git_fetch__download_pack(t, remote->repo, bytes, &remote->stats); return git_fetch__download_pack(t, remote->repo, bytes, &remote->stats,
progress_cb, progress_payload);
} }
...@@ -348,7 +353,9 @@ int git_fetch__download_pack( ...@@ -348,7 +353,9 @@ int git_fetch__download_pack(
git_transport *t, git_transport *t,
git_repository *repo, git_repository *repo,
git_off_t *bytes, git_off_t *bytes,
git_indexer_stats *stats) git_indexer_stats *stats,
git_indexer_progress_callback progress_cb,
void *progress_payload)
{ {
git_buf path = GIT_BUF_INIT; git_buf path = GIT_BUF_INIT;
gitno_buffer *buf = &t->buffer; gitno_buffer *buf = &t->buffer;
...@@ -358,7 +365,7 @@ int git_fetch__download_pack( ...@@ -358,7 +365,7 @@ int git_fetch__download_pack(
if (git_buf_joinpath(&path, git_repository_path(repo), "objects/pack") < 0) if (git_buf_joinpath(&path, git_repository_path(repo), "objects/pack") < 0)
return -1; return -1;
if (git_indexer_stream_new(&idx, git_buf_cstr(&path)) < 0) if (git_indexer_stream_new(&idx, git_buf_cstr(&path), progress_cb, progress_payload) < 0)
goto on_error; goto on_error;
git_buf_free(&path); git_buf_free(&path);
......
...@@ -10,9 +10,21 @@ ...@@ -10,9 +10,21 @@
#include "netops.h" #include "netops.h"
int git_fetch_negotiate(git_remote *remote); int git_fetch_negotiate(git_remote *remote);
int git_fetch_download_pack(git_remote *remote, git_off_t *bytes);
int git_fetch__download_pack(git_transport *t, git_repository *repo, git_off_t *bytes, git_indexer_stats *stats); int git_fetch_download_pack(
git_remote *remote,
git_off_t *bytes,
git_indexer_progress_callback progress_cb,
void *progress_payload);
int git_fetch__download_pack(
git_transport *t,
git_repository *repo,
git_off_t *bytes,
git_indexer_stats *stats,
git_indexer_progress_callback progress_cb,
void *progress_payload);
int git_fetch_setup_walk(git_revwalk **out, git_repository *repo); int git_fetch_setup_walk(git_revwalk **out, git_repository *repo);
#endif #endif
...@@ -49,6 +49,8 @@ struct git_indexer_stream { ...@@ -49,6 +49,8 @@ struct git_indexer_stream {
git_vector deltas; git_vector deltas;
unsigned int fanout[256]; unsigned int fanout[256];
git_oid hash; git_oid hash;
git_indexer_progress_callback progress_cb;
void *progress_payload;
}; };
struct delta_info { struct delta_info {
...@@ -138,7 +140,11 @@ static int cache_cmp(const void *a, const void *b) ...@@ -138,7 +140,11 @@ static int cache_cmp(const void *a, const void *b)
return git_oid_cmp(&ea->sha1, &eb->sha1); return git_oid_cmp(&ea->sha1, &eb->sha1);
} }
int git_indexer_stream_new(git_indexer_stream **out, const char *prefix) int git_indexer_stream_new(
git_indexer_stream **out,
const char *prefix,
git_indexer_progress_callback progress_cb,
void *progress_payload)
{ {
git_indexer_stream *idx; git_indexer_stream *idx;
git_buf path = GIT_BUF_INIT; git_buf path = GIT_BUF_INIT;
...@@ -147,6 +153,8 @@ int git_indexer_stream_new(git_indexer_stream **out, const char *prefix) ...@@ -147,6 +153,8 @@ int git_indexer_stream_new(git_indexer_stream **out, const char *prefix)
idx = git__calloc(1, sizeof(git_indexer_stream)); idx = git__calloc(1, sizeof(git_indexer_stream));
GITERR_CHECK_ALLOC(idx); GITERR_CHECK_ALLOC(idx);
idx->progress_cb = progress_cb;
idx->progress_payload = progress_payload;
error = git_buf_joinpath(&path, prefix, suff); error = git_buf_joinpath(&path, prefix, suff);
if (error < 0) if (error < 0)
...@@ -273,6 +281,12 @@ on_error: ...@@ -273,6 +281,12 @@ on_error:
return -1; return -1;
} }
static void do_progress_callback(git_indexer_stream *idx, git_indexer_stats *stats)
{
if (!idx->progress_cb) return;
idx->progress_cb(stats, idx->progress_payload);
}
int git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t size, git_indexer_stats *stats) int git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t size, git_indexer_stats *stats)
{ {
int error; int error;
...@@ -326,6 +340,7 @@ int git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t siz ...@@ -326,6 +340,7 @@ int git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t siz
memset(stats, 0, sizeof(git_indexer_stats)); memset(stats, 0, sizeof(git_indexer_stats));
stats->total = (unsigned int)idx->nr_objects; stats->total = (unsigned int)idx->nr_objects;
do_progress_callback(idx, stats);
} }
/* Now that we have data in the pack, let's try to parse it */ /* Now that we have data in the pack, let's try to parse it */
...@@ -362,6 +377,7 @@ int git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t siz ...@@ -362,6 +377,7 @@ int git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t siz
return error; return error;
stats->received++; stats->received++;
do_progress_callback(idx, stats);
continue; continue;
} }
...@@ -381,6 +397,7 @@ int git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t siz ...@@ -381,6 +397,7 @@ int git_indexer_stream_add(git_indexer_stream *idx, const void *data, size_t siz
stats->processed = (unsigned int)++processed; stats->processed = (unsigned int)++processed;
stats->received++; stats->received++;
do_progress_callback(idx, stats);
} }
return 0; return 0;
......
...@@ -433,7 +433,11 @@ int git_remote_ls(git_remote *remote, git_headlist_cb list_cb, void *payload) ...@@ -433,7 +433,11 @@ int git_remote_ls(git_remote *remote, git_headlist_cb list_cb, void *payload)
return 0; return 0;
} }
int git_remote_download(git_remote *remote, git_off_t *bytes) int git_remote_download(
git_remote *remote,
git_off_t *bytes,
git_indexer_progress_callback progress_cb,
void *progress_payload)
{ {
int error; int error;
...@@ -442,7 +446,7 @@ int git_remote_download(git_remote *remote, git_off_t *bytes) ...@@ -442,7 +446,7 @@ int git_remote_download(git_remote *remote, git_off_t *bytes)
if ((error = git_fetch_negotiate(remote)) < 0) if ((error = git_fetch_negotiate(remote)) < 0)
return error; return error;
return git_fetch_download_pack(remote, bytes); return git_fetch_download_pack(remote, bytes, progress_cb, progress_payload);
} }
int git_remote_update_tips(git_remote *remote) int git_remote_update_tips(git_remote *remote)
......
...@@ -28,11 +28,19 @@ static int update_tips(const char *refname, const git_oid *a, const git_oid *b, ...@@ -28,11 +28,19 @@ static int update_tips(const char *refname, const git_oid *a, const git_oid *b,
return 0; return 0;
} }
static void progress(const git_indexer_stats *stats, void *payload)
{
GIT_UNUSED(stats);
bool *was_called = (bool*)payload;
*was_called = true;
}
static void do_fetch(const char *url, int flag, int n) static void do_fetch(const char *url, int flag, int n)
{ {
git_remote *remote; git_remote *remote;
git_off_t bytes; git_off_t bytes;
git_remote_callbacks callbacks; git_remote_callbacks callbacks;
bool progress_was_called = false;
memset(&callbacks, 0, sizeof(git_remote_callbacks)); memset(&callbacks, 0, sizeof(git_remote_callbacks));
callbacks.update_tips = update_tips; callbacks.update_tips = update_tips;
...@@ -42,10 +50,11 @@ static void do_fetch(const char *url, int flag, int n) ...@@ -42,10 +50,11 @@ static void do_fetch(const char *url, int flag, int n)
git_remote_set_callbacks(remote, &callbacks); git_remote_set_callbacks(remote, &callbacks);
git_remote_set_autotag(remote, flag); git_remote_set_autotag(remote, flag);
cl_git_pass(git_remote_connect(remote, GIT_DIR_FETCH)); cl_git_pass(git_remote_connect(remote, GIT_DIR_FETCH));
cl_git_pass(git_remote_download(remote, &bytes)); cl_git_pass(git_remote_download(remote, &bytes, progress, &progress_was_called));
git_remote_disconnect(remote); git_remote_disconnect(remote);
cl_git_pass(git_remote_update_tips(remote)); cl_git_pass(git_remote_update_tips(remote));
cl_assert_equal_i(counter, n); cl_assert_equal_i(counter, n);
cl_assert_equal_i(progress_was_called, true);
git_remote_free(remote); git_remote_free(remote);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment