commit 0fd91dafe0b852573e3a6f82e986d8bebdaa25db from: Stefan Sperling date: Wed Mar 18 16:13:43 2020 UTC populate an in-progress pack index only if ref deltas are present commit - 950de2cd7ce881d3596a41afa88c20f21387c1e3 commit + 0fd91dafe0b852573e3a6f82e986d8bebdaa25db blob - 3d5f3fce1a9671ed367ea1dc222cda6d19e7c3c0 blob + 214ec0ace43c96d050e3c6e610171a914b8671a2 --- libexec/got-index-pack/got-index-pack.c +++ libexec/got-index-pack/got-index-pack.c @@ -419,7 +419,7 @@ indexed_obj_cmp(const void *pa, const void *pb) } static void -make_initial_packidx(struct got_packidx *packidx, int nobj, +make_packidx(struct got_packidx *packidx, int nobj, struct got_indexed_object **objects) { struct got_indexed_object *obj; @@ -429,11 +429,14 @@ make_initial_packidx(struct got_packidx *packidx, int mergesort(objects, nobj, sizeof(struct got_indexed_object *), indexed_obj_cmp); + memset(packidx->hdr.fanout_table, 0, + GOT_PACKIDX_V2_FANOUT_TABLE_ITEMS * sizeof(uint32_t)); + packidx->nlargeobj = 0; + for (i = 0; i < nobj; i++) { obj = objects[i]; - if (!obj->valid) - continue; - add_indexed_object(packidx, idx++, obj); + if (obj->valid) + add_indexed_object(packidx, idx++, obj); } } @@ -473,7 +476,7 @@ index_pack(struct got_pack *pack, int idxfd, uint8_t * SHA1_CTX ctx; uint8_t packidx_hash[SHA1_DIGEST_LENGTH]; ssize_t r, w; - int pass; + int pass, have_ref_deltas = 0; /* Check pack file header. */ r = read(pack->fd, &hdr, sizeof(hdr)); @@ -590,11 +593,14 @@ index_pack(struct got_pack *pack, int idxfd, uint8_t * obj->type == GOT_OBJ_TYPE_TAG) { objects[i]->valid = 1; nloose++; - } + } else if (obj->type == GOT_OBJ_TYPE_REF_DELTA) + have_ref_deltas = 1; } nvalid = nloose; - make_initial_packidx(&packidx, nobj, objects); + /* In order to resolve ref deltas we need an in-progress pack index. */ + if (have_ref_deltas) + make_packidx(&packidx, nobj, objects); /* * Second pass: We can now resolve deltas to compute the IDs of @@ -632,7 +638,8 @@ index_pack(struct got_pack *pack, int idxfd, uint8_t * objects[i]->valid = 1; n++; - update_packidx(&packidx, nobj, obj); + if (have_ref_deltas) + update_packidx(&packidx, nobj, obj); err = got_privsep_send_index_pack_progress(ibuf, nobj, nobj, nloose, nresolved + n); if (err) @@ -666,8 +673,7 @@ index_pack(struct got_pack *pack, int idxfd, uint8_t * goto done; } - /* We may have seen duplicates. Update our total object count. */ - nobj = betoh32(packidx.hdr.fanout_table[0xff]); + make_packidx(&packidx, nobj, objects); SHA1Init(&ctx); err = hwrite(idxfd, "\xfftOc\x00\x00\x00\x02", 8, &ctx); @@ -681,8 +687,6 @@ index_pack(struct got_pack *pack, int idxfd, uint8_t * nobj * SHA1_DIGEST_LENGTH, &ctx); if (err) goto done; - mergesort(objects, nobj, sizeof(struct got_indexed_object *), - indexed_obj_cmp); for(i = 0; i < nobj; i++){ PUTBE32(buf, objects[i]->crc); err = hwrite(idxfd, buf, 4, &ctx);