From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: AS31976 209.132.180.0/23 X-Spam-Status: No, score=-4.0 required=3.0 tests=AWL,BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, SPF_HELO_NONE,SPF_NONE shortcircuit=no autolearn=ham autolearn_force=no version=3.4.2 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by dcvr.yhbt.net (Postfix) with ESMTP id 2C0351F462 for ; Tue, 18 Jun 2019 18:14:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730269AbfFRSO3 (ORCPT ); Tue, 18 Jun 2019 14:14:29 -0400 Received: from mail-ed1-f67.google.com ([209.85.208.67]:37663 "EHLO mail-ed1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730169AbfFRSO2 (ORCPT ); Tue, 18 Jun 2019 14:14:28 -0400 Received: by mail-ed1-f67.google.com with SMTP id w13so23078048eds.4 for ; Tue, 18 Jun 2019 11:14:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=date:message-id:in-reply-to:references:from:subject:fcc :content-transfer-encoding:mime-version:to:cc; bh=yRw+J3NQRUlSO64KRTL0aH/aJyIViRbb47AFnnP7jvc=; b=YxFaYXmdreaqWUzkHd9UhXJUN9pWgAzrjCdVQzFjrE9NCGwDcS0GWk45D9zgSmSCG2 cKPp8DVC9KjX47aOjegbK50Ak9Tp4uIKOnlCixg9+70X/eEt1hSOX/zGKKtnqXtWebYH YxQs6RipUXAzHA/8+FcDUaVcoPkXnpYWplYUIAGqb3i/2jljVVHQ6tEoHKZn78W8Hkai m7wb6CvwEMazNUNKKVtI/P7f3UjzHhrTUcHcdIhzeJ35GC0ZfxhpqYNJYK3o8A0qgskt c0Vqqt18XPi9YJe+z8Opwfj3fxnVQnUWOhA6MVrOsXIvJhEDB6rNFtLx8xqanU919/ZH l0+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:message-id:in-reply-to:references:from :subject:fcc:content-transfer-encoding:mime-version:to:cc; bh=yRw+J3NQRUlSO64KRTL0aH/aJyIViRbb47AFnnP7jvc=; b=Ncag0KJ9kK1Y+zH2gSpNloYGkfXGmBGJTpe1ho6ZCQFOJlB9bPDUHpd2pUCOLhLl6G AftFXsOHpY0rPA50OmJ9TSgHSFlCu92y7PyrJPd5Wo48o7qFznqqfyjK8soO+KgxXlJZ n32yTzYcI00mczzbjoQrfD2OX0GxtZOXcrP9N4VEtYBWZuk7+q4hE7pWxHzRyXUm9qoU DIgZ12pPFR0CkNqTkaQqC9R+wc7yuJmylupozTKm8hp/bQnCB9Nj3liYjepxq+jYamzL srrH10oKSeiLmyYp3k8tJrdKkPktxkk+q8H1B2XAQ8AYH4b5dBaJS3+5+NUZq08Pb7Po h26A== X-Gm-Message-State: APjAAAUuhKsrnR/VBFycbPbSp6GgSxIWulh8aaLPlykAow/GtB+4kKDO XNZgcFlSVIl5QRJLDIX0KulQ0Ktx X-Google-Smtp-Source: APXvYqydEecx/EzJpg0K4kqkbICkbrAnwwFOwY1wtNtWpFW5Q6DXS/icIgVvVYjwAXYSmyTfwLebzQ== X-Received: by 2002:a50:b343:: with SMTP id r3mr40538648edd.16.1560881666022; Tue, 18 Jun 2019 11:14:26 -0700 (PDT) Received: from [127.0.0.1] ([13.74.141.28]) by smtp.gmail.com with ESMTPSA id c3sm320508ejo.43.2019.06.18.11.14.25 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 18 Jun 2019 11:14:25 -0700 (PDT) Date: Tue, 18 Jun 2019 11:14:25 -0700 (PDT) X-Google-Original-Date: Tue, 18 Jun 2019 18:14:06 GMT Message-Id: <0b236c27eba4e0109f499d75da9473ccfd193487.1560881661.git.gitgitgadget@gmail.com> In-Reply-To: References: From: "Derrick Stolee via GitGitGadget" Subject: [PATCH v6 04/18] commit-graph: load commit-graph chains Fcc: Sent Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit MIME-Version: 1.0 To: git@vger.kernel.org Cc: peff@peff.net, avarab@gmail.com, git@jeffhostetler.com, jrnieder@google.com, steadmon@google.com, johannes.schindelin@gmx.de, philipoakley@iee.org, Junio C Hamano , Derrick Stolee Sender: git-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org From: Derrick Stolee Prepare the logic for reading a chain of commit-graphs. First, look for a file at $OBJDIR/info/commit-graph. If it exists, then use that file and stop. Next, look for the chain file at $OBJDIR/info/commit-graphs/commit-graph-chain. If this file exists, then load the hash values as line-separated values in that file and load $OBJDIR/info/commit-graphs/graph-{hash[i]}.graph for each hash[i] in that file. The file is given in order, so the first hash corresponds to the "base" file and the final hash corresponds to the "tip" file. This implementation assumes that all of the graph-{hash}.graph files are in the same object directory as the commit-graph-chain file. This will be updated in a future change. This change is purposefully simple so we can isolate the different concerns. Signed-off-by: Derrick Stolee --- commit-graph.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 106 insertions(+), 6 deletions(-) diff --git a/commit-graph.c b/commit-graph.c index 96b07a674e..f7dfc6aecd 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -45,6 +45,19 @@ char *get_commit_graph_filename(const char *obj_dir) return xstrfmt("%s/info/commit-graph", obj_dir); } +static char *get_split_graph_filename(const char *obj_dir, + const char *oid_hex) +{ + return xstrfmt("%s/info/commit-graphs/graph-%s.graph", + obj_dir, + oid_hex); +} + +static char *get_chain_filename(const char *obj_dir) +{ + return xstrfmt("%s/info/commit-graphs/commit-graph-chain", obj_dir); +} + static uint8_t oid_version(void) { return 1; @@ -286,18 +299,105 @@ static struct commit_graph *load_commit_graph_one(const char *graph_file) return load_commit_graph_one_fd_st(fd, &st); } +static struct commit_graph *load_commit_graph_v1(struct repository *r, const char *obj_dir) +{ + char *graph_name = get_commit_graph_filename(obj_dir); + struct commit_graph *g = load_commit_graph_one(graph_name); + free(graph_name); + + return g; +} + +static int add_graph_to_chain(struct commit_graph *g, + struct commit_graph *chain, + struct object_id *oids, + int n) +{ + struct commit_graph *cur_g = chain; + + while (n) { + n--; + cur_g = cur_g->base_graph; + } + + g->base_graph = chain; + + if (chain) + g->num_commits_in_base = chain->num_commits + chain->num_commits_in_base; + + return 1; +} + +static struct commit_graph *load_commit_graph_chain(struct repository *r, const char *obj_dir) +{ + struct commit_graph *graph_chain = NULL; + struct strbuf line = STRBUF_INIT; + struct stat st; + struct object_id *oids; + int i = 0, valid = 1, count; + char *chain_name = get_chain_filename(obj_dir); + FILE *fp; + int stat_res; + + fp = fopen(chain_name, "r"); + stat_res = stat(chain_name, &st); + free(chain_name); + + if (!fp || + stat_res || + st.st_size <= the_hash_algo->hexsz) + return NULL; + + count = st.st_size / (the_hash_algo->hexsz + 1); + oids = xcalloc(count, sizeof(struct object_id)); + + for (i = 0; i < count && valid; i++) { + char *graph_name; + struct commit_graph *g; + + if (strbuf_getline_lf(&line, fp) == EOF) + break; + + if (get_oid_hex(line.buf, &oids[i])) { + warning(_("invalid commit-graph chain: line '%s' not a hash"), + line.buf); + valid = 0; + break; + } + + graph_name = get_split_graph_filename(obj_dir, line.buf); + g = load_commit_graph_one(graph_name); + free(graph_name); + + if (g && add_graph_to_chain(g, graph_chain, oids, i)) + graph_chain = g; + else + valid = 0; + } + + free(oids); + fclose(fp); + + return graph_chain; +} + +static struct commit_graph *read_commit_graph_one(struct repository *r, const char *obj_dir) +{ + struct commit_graph *g = load_commit_graph_v1(r, obj_dir); + + if (!g) + g = load_commit_graph_chain(r, obj_dir); + + return g; +} + static void prepare_commit_graph_one(struct repository *r, const char *obj_dir) { - char *graph_name; if (r->objects->commit_graph) return; - graph_name = get_commit_graph_filename(obj_dir); - r->objects->commit_graph = - load_commit_graph_one(graph_name); - - FREE_AND_NULL(graph_name); + r->objects->commit_graph = read_commit_graph_one(r, obj_dir); } /* -- gitgitgadget