]> git.ipfire.org Git - thirdparty/git.git/commitdiff
parallel-checkout: support progress displaying
authorMatheus Tavares <matheus.bernardino@usp.br>
Mon, 19 Apr 2021 00:14:56 +0000 (21:14 -0300)
committerJunio C Hamano <gitster@pobox.com>
Mon, 19 Apr 2021 18:57:05 +0000 (11:57 -0700)
Original-patch-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Matheus Tavares <matheus.bernardino@usp.br>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
parallel-checkout.c
parallel-checkout.h
unpack-trees.c

index 3cc2028861a7ad87922c809a3f33d3a186b4c9e5..09e8b10a3593b5d124ccd4cfec5acc40e46e4de4 100644 (file)
@@ -3,6 +3,7 @@
 #include "entry.h"
 #include "parallel-checkout.h"
 #include "pkt-line.h"
+#include "progress.h"
 #include "run-command.h"
 #include "sigchain.h"
 #include "streaming.h"
@@ -17,6 +18,8 @@ struct parallel_checkout {
        enum pc_status status;
        struct parallel_checkout_item *items; /* The parallel checkout queue. */
        size_t nr, alloc;
+       struct progress *progress;
+       unsigned int *progress_cnt;
 };
 
 static struct parallel_checkout parallel_checkout;
@@ -146,6 +149,20 @@ int enqueue_checkout(struct cache_entry *ce, struct conv_attrs *ca)
        return 0;
 }
 
+size_t pc_queue_size(void)
+{
+       return parallel_checkout.nr;
+}
+
+static void advance_progress_meter(void)
+{
+       if (parallel_checkout.progress) {
+               (*parallel_checkout.progress_cnt)++;
+               display_progress(parallel_checkout.progress,
+                                *parallel_checkout.progress_cnt);
+       }
+}
+
 static int handle_results(struct checkout *state)
 {
        int ret = 0;
@@ -194,6 +211,7 @@ static int handle_results(struct checkout *state)
                         */
                        ret |= checkout_entry_ca(pc_item->ce, &pc_item->ca,
                                                 state, NULL, NULL);
+                       advance_progress_meter();
                        break;
                case PC_ITEM_PENDING:
                        have_pending = 1;
@@ -534,6 +552,9 @@ static void parse_and_save_result(const char *buffer, int len,
        pc_item->status = res->status;
        if (st)
                pc_item->st = *st;
+
+       if (res->status != PC_ITEM_COLLIDED)
+               advance_progress_meter();
 }
 
 static void gather_results_from_workers(struct pc_worker *workers,
@@ -596,11 +617,16 @@ static void write_items_sequentially(struct checkout *state)
 {
        size_t i;
 
-       for (i = 0; i < parallel_checkout.nr; i++)
-               write_pc_item(&parallel_checkout.items[i], state);
+       for (i = 0; i < parallel_checkout.nr; i++) {
+               struct parallel_checkout_item *pc_item = &parallel_checkout.items[i];
+               write_pc_item(pc_item, state);
+               if (pc_item->status != PC_ITEM_COLLIDED)
+                       advance_progress_meter();
+       }
 }
 
-int run_parallel_checkout(struct checkout *state, int num_workers, int threshold)
+int run_parallel_checkout(struct checkout *state, int num_workers, int threshold,
+                         struct progress *progress, unsigned int *progress_cnt)
 {
        int ret;
 
@@ -608,6 +634,8 @@ int run_parallel_checkout(struct checkout *state, int num_workers, int threshold
                BUG("cannot run parallel checkout: uninitialized or already running");
 
        parallel_checkout.status = PC_RUNNING;
+       parallel_checkout.progress = progress;
+       parallel_checkout.progress_cnt = progress_cnt;
 
        if (parallel_checkout.nr < num_workers)
                num_workers = parallel_checkout.nr;
index 2a68ab954dd11ff690ad478fb9162a97c411a6ef..80f539bcb77fc5e4f81656464c9a11d705d83c5f 100644 (file)
@@ -5,6 +5,7 @@
 
 struct cache_entry;
 struct checkout;
+struct progress;
 
 /****************************************************************
  * Users of parallel checkout
@@ -31,13 +32,15 @@ void init_parallel_checkout(void);
  * for later write and return 0.
  */
 int enqueue_checkout(struct cache_entry *ce, struct conv_attrs *ca);
+size_t pc_queue_size(void);
 
 /*
  * Write all the queued entries, returning 0 on success. If the number of
  * entries is smaller than the specified threshold, the operation is performed
  * sequentially.
  */
-int run_parallel_checkout(struct checkout *state, int num_workers, int threshold);
+int run_parallel_checkout(struct checkout *state, int num_workers, int threshold,
+                         struct progress *progress, unsigned int *progress_cnt);
 
 /****************************************************************
  * Interface with checkout--worker
index 0669748f215e40ab7b461ac425d4c71026e46c33..4b77e52c6b9e3e6cf1436daa4d3b9f912d1a2f3e 100644 (file)
@@ -474,17 +474,22 @@ static int check_updates(struct unpack_trees_options *o,
                struct cache_entry *ce = index->cache[i];
 
                if (ce->ce_flags & CE_UPDATE) {
+                       size_t last_pc_queue_size = pc_queue_size();
+
                        if (ce->ce_flags & CE_WT_REMOVE)
                                BUG("both update and delete flags are set on %s",
                                    ce->name);
-                       display_progress(progress, ++cnt);
                        ce->ce_flags &= ~CE_UPDATE;
                        errs |= checkout_entry(ce, &state, NULL, NULL);
+
+                       if (last_pc_queue_size == pc_queue_size())
+                               display_progress(progress, ++cnt);
                }
        }
-       stop_progress(&progress);
        if (pc_workers > 1)
-               errs |= run_parallel_checkout(&state, pc_workers, pc_threshold);
+               errs |= run_parallel_checkout(&state, pc_workers, pc_threshold,
+                                             progress, &cnt);
+       stop_progress(&progress);
        errs |= finish_delayed_checkout(&state, NULL);
        git_attr_set_direction(GIT_ATTR_CHECKIN);