Re: [PATCH v3 2/4] read-cache: add index.skipHash config option
- From
Ævar Arnfjörð Bjarmason <avarab@gmail.com>
- Date
- Dec 15, 2022, 16:12 UTC
- Message-ID
- <221215.861qp03agm.gmgdl@evledraar.gmail.com>
- In-Reply-To
- <00738c81a1212970910da6f29fe3ecef87c2ec3a.1671116820.git.gitgitgadget@gmail.com>
On Thu, Dec 15 2022, Derrick Stolee via GitGitGadget wrote:
> From: Derrick Stolee <derrickstolee@github.com>
> + end = (unsigned char *)hdr + size;
Commentary: The "unsigned char *" cast has moved up here from the below, that's needed (we're casting from the struct), and we should get rid of it from below, good.
> + start = end - the_hash_algo->rawsz;
Okey, so here we mark the start, which is the end minus the rawsz, but...
Show 9 quoted lines
> + oidread(&oid, start); > + if (oideq(&oid, null_oid())) > + return 0; > + > the_hash_algo->init_fn(&c); > the_hash_algo->update_fn(&c, hdr, size - the_hash_algo->rawsz); > the_hash_algo->final_fn(hash, &c); > - if (!hasheq(hash, (unsigned char *)hdr + size - the_hash_algo->rawsz)) > + if (!hasheq(hash, end - the_hash_algo->rawsz))
...here we got rid of the cast, which is good, but let's not use "end - the_hash_algo->rawsz" here, let's use "start", which you already computed as "end - the_hash_algo->rawsz". This is just repeating it.
I wondered if I just missed it being modified in the interim before carefully re-reading this, but we pass your tests with:
- if (!hasheq(hash, end - the_hash_algo->rawsz)) + assert((end - the_hash_algo->rawsz) == start); + if (!hasheq(hash, start))
So, we can indeed juse the simpler "start" here, and it makes it easier to read, as we're assured that it didn't move in the interim.
> + git_config_get_maybe_bool("index.skiphash", (int *)&f->skip_hash);Aside from the question of whether we use the repo_*() variant here, which I noted in my reply to the CL. The cast is suspicious.
So, in the 1/4 we added this as *unsigned*: + * If set to 1, skip_hash indicates that we should + * not actually compute the hash for this hashfile and + * instead only use it as a buffered write. + */ + unsigned int skip_hash;
But you need the cast here since the config API can and will set the "dest" to -1. See the "*dest == -1" test in git_configset_get_value().
So, here we're relying on a "unsigned int" cast'd to "int" correctly doing the right thing on a "-1" assignment.
I'm not sure if that's portable or leads to undefined behavior, but in any case, won't such a -1 value be read back as ~0 from that "unsigned int" variable on most modern platforms?
Just bypassing that entirely and making it "int" seems better here, or having an intermediate variable.
I also wondered if this was all my fault, in your original version you were doing:
int skip_hash;
[...]
if (!git_config_get_maybe_bool("index.skiphash", &skip_hash))
f->skip_hash = skip_hash;And I suggested that this was redundant, and that you could just write to "f->skip_hash" directly.
But I didn't notice it was "unsigned", and in any case your original version had the same issue of assigning a -1 to the unsigned variable...