packfile: define and use bsearch_pack()
The method bsearch_hash() generalizes binary searches using a fanout table. The only consumer is currently find_pack_entry_one(). It requires a bit of pointer arithmetic to align the fanout table and the lookup table depending on the pack-index version. Extract the pack-index pointer arithmetic to a new method, bsearch_pack(), so this can be re-used in other code paths. Signed-off-by: Derrick Stolee <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Derrick Stolee committed
Mar 22, 2018 at 13:40 UTC
3d475f46a8225a9cc549ac5cb2c51d6ecd9e0f7c
2 files changed
+34
-16
packfile.c
+26
-16
@@ -1654,6 +1654,29 @@ out:
1654
return data;
1655
}
1656
1657
+int bsearch_pack(const struct object_id *oid, const struct packed_git *p, uint32_t *result)
1658
+{
1659
+ const unsigned char *index_fanout = p->index_data;
1660
+ const unsigned char *index_lookup;
1661
+ int index_lookup_width;
1662
+
1663
+ if (!index_fanout)
1664
+ BUG("bsearch_pack called without a valid pack-index");
1665
+
1666
+ index_lookup = index_fanout + 4 * 256;
1667
+ if (p->index_version == 1) {
1668
+ index_lookup_width = 24;
1669
+ index_lookup += 4;
1670
+ } else {
1671
+ index_lookup_width = 20;
1672
+ index_fanout += 8;
1673
+ index_lookup += 8;
1674
+ }
1675
+
1676
+ return bsearch_hash(oid->hash, (const uint32_t*)index_fanout,
1677
+ index_lookup, index_lookup_width, result);
1678
+}
1679
+
1680
const unsigned char *nth_packed_object_sha1(struct packed_git *p,
1681
uint32_t n)
1682
{
@@ -1720,30 +1743,17 @@ off_t nth_packed_object_offset(const struct packed_git *p, uint32_t n)
1743
off_t find_pack_entry_one(const unsigned char *sha1,
1744
struct packed_git *p)
1745
{
1723
- const uint32_t *level1_ofs = p->index_data;
1746
const unsigned char *index = p->index_data;
1725
- unsigned stride;
1747
+ struct object_id oid;
1748
uint32_t result;
1749
1750
if (!index) {
1751
if (open_pack_index(p))
1752
return 0;
1731
- level1_ofs = p->index_data;
1732
- index = p->index_data;
1733
- }
1734
- if (p->index_version > 1) {
1735
- level1_ofs += 2;
1736
- index += 8;
1737
- }
1738
- index += 4 * 256;
1739
- if (p->index_version > 1) {
1740
- stride = 20;
1741
- } else {
1742
- stride = 24;
1743
- index += 4;
1753
}
1754
1746
- if (bsearch_hash(sha1, level1_ofs, index, stride, &result))
1755
+ hashcpy(oid.hash, sha1);
1756
+ if (bsearch_pack(&oid, p, &result))
1757
return nth_packed_object_offset(p, result);
1758
return 0;
1759
}
packfile.h
+8
@@ -78,6 +78,14 @@ extern struct packed_git *add_packed_git(const char *path, size_t path_len, int
78
*/
79
extern void check_pack_index_ptr(const struct packed_git *p, const void *ptr);
80
81
+/*
82
+ * Perform binary search on a pack-index for a given oid. Packfile is expected to
83
+ * have a valid pack-index.
84
+ *
85
+ * See 'bsearch_hash' for more information.
86
+ */
87
+int bsearch_pack(const struct object_id *oid, const struct packed_git *p, uint32_t *result);
88
+
89
/*
90
* Return the SHA-1 of the nth object within the specified packfile.
91
* Open the index if it is not already open. The return value points