progress: add sparse mode to force 100% complete message
Add new start_sparse_progress() and start_delayed_sparse_progress() constructors and "sparse" flag to struct progress. Teach stop_progress() to force a 100% complete progress message before printing the final "done" message when "sparse" is set. Calling display_progress() for every item in a large set can be expensive. If callers try to filter this for performance reasons, such as emitting every k-th item, progress would not reach 100% unless they made a final call to display_progress() with the item count before calling stop_progress(). Now this is automatic when "sparse" is set. Signed-off-by: Jeff Hostetler <jeffhost@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>maint
							parent
							
								
									041f5ea1cf
								
							
						
					
					
						commit
						9d81ecb52b
					
				
							
								
								
									
										38
									
								
								progress.c
								
								
								
								
							
							
						
						
									
										38
									
								
								progress.c
								
								
								
								
							|  | @ -34,6 +34,7 @@ struct progress { | |||
| 	uint64_t total; | ||||
| 	unsigned last_percent; | ||||
| 	unsigned delay; | ||||
| 	unsigned sparse; | ||||
| 	struct throughput *throughput; | ||||
| 	uint64_t start_ns; | ||||
| }; | ||||
|  | @ -194,7 +195,7 @@ int display_progress(struct progress *progress, uint64_t n) | |||
| } | ||||
|  | ||||
| static struct progress *start_progress_delay(const char *title, uint64_t total, | ||||
| 					     unsigned delay) | ||||
| 					     unsigned delay, unsigned sparse) | ||||
| { | ||||
| 	struct progress *progress = malloc(sizeof(*progress)); | ||||
| 	if (!progress) { | ||||
|  | @ -208,6 +209,7 @@ static struct progress *start_progress_delay(const char *title, uint64_t total, | |||
| 	progress->last_value = -1; | ||||
| 	progress->last_percent = -1; | ||||
| 	progress->delay = delay; | ||||
| 	progress->sparse = sparse; | ||||
| 	progress->throughput = NULL; | ||||
| 	progress->start_ns = getnanotime(); | ||||
| 	set_progress_signal(); | ||||
|  | @ -216,16 +218,46 @@ static struct progress *start_progress_delay(const char *title, uint64_t total, | |||
|  | ||||
| struct progress *start_delayed_progress(const char *title, uint64_t total) | ||||
| { | ||||
| 	return start_progress_delay(title, total, 2); | ||||
| 	return start_progress_delay(title, total, 2, 0); | ||||
| } | ||||
|  | ||||
| struct progress *start_progress(const char *title, uint64_t total) | ||||
| { | ||||
| 	return start_progress_delay(title, total, 0); | ||||
| 	return start_progress_delay(title, total, 0, 0); | ||||
| } | ||||
|  | ||||
| /* | ||||
|  * Here "sparse" means that the caller might use some sampling criteria to | ||||
|  * decide when to call display_progress() rather than calling it for every | ||||
|  * integer value in[0 .. total).  In particular, the caller might not call | ||||
|  * display_progress() for the last value in the range. | ||||
|  * | ||||
|  * When "sparse" is set, stop_progress() will automatically force the done | ||||
|  * message to show 100%. | ||||
|  */ | ||||
| struct progress *start_sparse_progress(const char *title, uint64_t total) | ||||
| { | ||||
| 	return start_progress_delay(title, total, 0, 1); | ||||
| } | ||||
|  | ||||
| struct progress *start_delayed_sparse_progress(const char *title, | ||||
| 					       uint64_t total) | ||||
| { | ||||
| 	return start_progress_delay(title, total, 2, 1); | ||||
| } | ||||
|  | ||||
| static void finish_if_sparse(struct progress *progress) | ||||
| { | ||||
| 	if (progress && | ||||
| 	    progress->sparse && | ||||
| 	    progress->last_value != progress->total) | ||||
| 		display_progress(progress, progress->total); | ||||
| } | ||||
|  | ||||
| void stop_progress(struct progress **p_progress) | ||||
| { | ||||
| 	finish_if_sparse(*p_progress); | ||||
|  | ||||
| 	stop_progress_msg(p_progress, _("done")); | ||||
| } | ||||
|  | ||||
|  |  | |||
|  | @ -6,7 +6,10 @@ struct progress; | |||
| void display_throughput(struct progress *progress, uint64_t total); | ||||
| int display_progress(struct progress *progress, uint64_t n); | ||||
| struct progress *start_progress(const char *title, uint64_t total); | ||||
| struct progress *start_sparse_progress(const char *title, uint64_t total); | ||||
| struct progress *start_delayed_progress(const char *title, uint64_t total); | ||||
| struct progress *start_delayed_sparse_progress(const char *title, | ||||
| 					       uint64_t total); | ||||
| void stop_progress(struct progress **progress); | ||||
| void stop_progress_msg(struct progress **progress, const char *msg); | ||||
|  | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Jeff Hostetler
						Jeff Hostetler