commit 0553a4e327ba2ad58f38556354f97c8029888f78 from: Stefan Sperling date: Mon Apr 30 13:00:05 2018 UTC split fetching and drawing of commits into separate steps commit - ad7de8d907a8f1a02d6449c9795f79a11d74d1b5 commit + 0553a4e327ba2ad58f38556354f97c8029888f78 blob - c31cd3fda721b5e2d4da9cc906d189a82ed3cce9 blob + 6db8041962c3853a56ab07eb07ae195c6a807b9d --- tog/tog.c +++ tog/tog.c @@ -85,8 +85,7 @@ usage_log(void) } static const struct got_error * -draw_commit(struct got_commit_object *commit, struct got_object_id *id, - struct got_repository *repo) +draw_commit(struct got_commit_object *commit, struct got_object_id *id) { const struct got_error *err = NULL; char *logmsg0 = NULL, *logmsg = NULL; @@ -150,19 +149,17 @@ struct commit_queue_entry { struct got_object_id *id; struct got_commit_object *commit; }; +TAILQ_HEAD(commit_queue, commit_queue_entry); static const struct got_error * -draw_commits(struct got_object *root_obj, struct got_object_id *root_id, - struct got_repository *repo, int selected) +fetch_commits(struct commit_queue *commits, struct got_object *root_obj, + struct got_object_id *root_id, struct got_repository *repo, int limit) { const struct got_error *err; struct got_commit_object *root_commit; - TAILQ_HEAD(, commit_queue_entry) commits; struct commit_queue_entry *entry; int ncommits = 0; - TAILQ_INIT(&commits); - err = got_object_commit_open(&root_commit, repo, root_obj); if (err) return err; @@ -177,30 +174,16 @@ draw_commits(struct got_object *root_obj, struct got_o return err; } entry->commit = root_commit; - TAILQ_INSERT_HEAD(&commits, entry, entry); + TAILQ_INSERT_HEAD(commits, entry, entry); - wclear(tog_log_view.window); - - while (!TAILQ_EMPTY(&commits) && ncommits < LINES) { + while (entry->commit->nparents > 0 && ncommits < limit) { struct got_parent_id *pid; struct got_object *obj; struct got_commit_object *pcommit; struct commit_queue_entry *pentry; - entry = TAILQ_FIRST(&commits); + entry = TAILQ_LAST(commits, commit_queue); - if (ncommits == selected) - wstandout(tog_log_view.window); - err = draw_commit(entry->commit, entry->id, repo); - if (ncommits == selected) - wstandend(tog_log_view.window); - if (err) - break; - ncommits++; - - if (entry->commit->nparents == 0) - break; - /* Follow the first parent (TODO: handle merge commits). */ pid = SIMPLEQ_FIRST(&entry->commit->parent_ids); err = got_object_open(&obj, repo, pid->id); @@ -229,35 +212,61 @@ draw_commits(struct got_object *root_obj, struct got_o break; } pentry->commit = pcommit; - TAILQ_INSERT_TAIL(&commits, pentry, entry); + TAILQ_INSERT_TAIL(commits, pentry, entry); + ncommits++; + } - TAILQ_REMOVE(&commits, entry, entry); + return err; +} + +static void +free_commits(struct commit_queue *commits) +{ + struct commit_queue_entry *entry; + + while (!TAILQ_EMPTY(commits)) { + entry = TAILQ_FIRST(commits); + TAILQ_REMOVE(commits, entry, entry); got_object_commit_close(entry->commit); free(entry->id); free(entry); } +} - while (!TAILQ_EMPTY(&commits)) { - entry = TAILQ_FIRST(&commits); - TAILQ_REMOVE(&commits, entry, entry); - got_object_commit_close(entry->commit); - free(entry->id); - free(entry); +static const struct got_error * +draw_commits(struct commit_queue *commits, int selected) +{ + const struct got_error *err = NULL; + struct commit_queue_entry *entry; + int ncommits = 0; + + wclear(tog_log_view.window); + + TAILQ_FOREACH(entry, commits, entry) { + if (ncommits == selected) + wstandout(tog_log_view.window); + err = draw_commit(entry->commit, entry->id); + if (ncommits == selected) + wstandend(tog_log_view.window); + if (err) + break; + ncommits++; } update_panels(); doupdate(); + return err; } - static const struct got_error * show_log_view(struct got_object_id *start_id, struct got_repository *repo) { const struct got_error *err = NULL; struct got_object *obj; - int ch, done = 0, selected = 0; + int ch, done = 0, selected = 0, refetch_commits = 1; struct got_object_id *id = start_id; + struct commit_queue commits; if (tog_log_view.window == NULL) { tog_log_view.window = newwin(0, 0, 0, 0); @@ -279,8 +288,17 @@ show_log_view(struct got_object_id *start_id, struct g goto done; } + TAILQ_INIT(&commits); do { - err = draw_commits(obj, id, repo, selected); + if (refetch_commits) { + free_commits(&commits); + err = fetch_commits(&commits, obj, id, repo, LINES); + if (err) + return err; + refetch_commits = 0; + } + + err = draw_commits(&commits, selected); if (err) return err; @@ -306,6 +324,7 @@ show_log_view(struct got_object_id *start_id, struct g nodelay(stdscr, TRUE); } while (!done); done: + free_commits(&commits); got_object_close(obj); return err; }