pack-revindex: store entries directly in packed_git

A pack_revindex struct has two elements: the revindex entries themselves, and a pointer to the packed_git. We need both to do lookups, because only the latter knows things like the number of objects in the pack. Now that packed_git contains the pack_revindex struct it's just as easy to pass around the packed_git itself, and we do not need the extra back-pointer. We can instead just store the entries directly in the pack. All functions which took a pack_revindex now just take a packed_git. We still lazy-load in find_pack_revindex, so most callers are unaffected. The exception is the bitmap code, which computes the revindex and caches the pointer when we load the bitmaps. We can continue to load, drop the extra cache pointer, and just access bitmap_git.pack.revindex directly. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Dec 21, 2015 at 01:20 UTC 9d98bbf5785708da4effc9b8f34ba6e18d726625
4 files changed +32 -41
cache.h
+1 -1
@@ -1118,7 +1118,7 @@ extern struct packed_git {
1118 pack_keep:1,
1119 do_not_close:1;
1120 unsigned char sha1[20];
1121 - struct pack_revindex reverse_index;
1121 + struct revindex_entry *revindex;
1122 /* something like ".git/objects/pack/xxxxx.pack" */
1123 char pack_name[FLEX_ARRAY]; /* more */
1124 } *packed_git;
pack-bitmap.c
+5 -8
@@ -33,9 +33,6 @@ static struct bitmap_index {
33 /* Packfile to which this bitmap index belongs to */
34 struct packed_git *pack;
35
36 - /* reverse index for the packfile */
37 - struct pack_revindex *reverse_index;
38 -
36 /*
37 * Mark the first `reuse_objects` in the packfile as reused:
38 * they will be sent as-is without using them for repacking
@@ -293,7 +290,7 @@ static int load_pack_bitmap(void)
290
291 bitmap_git.bitmaps = kh_init_sha1();
292 bitmap_git.ext_index.positions = kh_init_sha1_pos();
296 - bitmap_git.reverse_index = revindex_for_pack(bitmap_git.pack);
293 + load_pack_revindex(bitmap_git.pack);
294
295 if (!(bitmap_git.commits = read_bitmap_1(&bitmap_git)) ||
296 !(bitmap_git.trees = read_bitmap_1(&bitmap_git)) ||
@@ -379,7 +376,7 @@ static inline int bitmap_position_packfile(const unsigned char *sha1)
376 if (!offset)
377 return -1;
378
382 - return find_revindex_position(bitmap_git.reverse_index, offset);
379 + return find_revindex_position(bitmap_git.pack, offset);
380 }
381
382 static int bitmap_position(const unsigned char *sha1)
@@ -631,7 +628,7 @@ static void show_objects_for_type(
628 if (pos + offset < bitmap_git.reuse_objects)
629 continue;
630
634 - entry = &bitmap_git.reverse_index->revindex[pos + offset];
631 + entry = &bitmap_git.pack->revindex[pos + offset];
632 sha1 = nth_packed_object_sha1(bitmap_git.pack, entry->nr);
633
634 if (bitmap_git.hashes)
@@ -805,7 +802,7 @@ int reuse_partial_packfile_from_bitmap(struct packed_git **packfile,
802 return -1;
803
804 bitmap_git.reuse_objects = *entries = reuse_objects;
808 - *up_to = bitmap_git.reverse_index->revindex[reuse_objects].offset;
805 + *up_to = bitmap_git.pack->revindex[reuse_objects].offset;
806 *packfile = bitmap_git.pack;
807
808 return 0;
@@ -1037,7 +1034,7 @@ int rebuild_existing_bitmaps(struct packing_data *mapping,
1034 struct revindex_entry *entry;
1035 struct object_entry *oe;
1036
1040 - entry = &bitmap_git.reverse_index->revindex[i];
1037 + entry = &bitmap_git.pack->revindex[i];
1038 sha1 = nth_packed_object_sha1(bitmap_git.pack, entry->nr);
1039 oe = packlist_find(mapping, sha1, NULL);
1040
pack-revindex.c
+22 -25
@@ -115,14 +115,13 @@ static void sort_revindex(struct revindex_entry *entries, unsigned n, off_t max)
115 /*
116 * Ordered list of offsets of objects in the pack.
117 */
118 -static void create_pack_revindex(struct pack_revindex *rix)
118 +static void create_pack_revindex(struct packed_git *p)
119 {
120 - struct packed_git *p = rix->p;
120 unsigned num_ent = p->num_objects;
121 unsigned i;
122 const char *index = p->index_data;
123
125 - rix->revindex = xmalloc(sizeof(*rix->revindex) * (num_ent + 1));
124 + p->revindex = xmalloc(sizeof(*p->revindex) * (num_ent + 1));
125 index += 4 * 256;
126
127 if (p->index_version > 1) {
@@ -132,46 +131,42 @@ static void create_pack_revindex(struct pack_revindex *rix)
131 for (i = 0; i < num_ent; i++) {
132 uint32_t off = ntohl(*off_32++);
133 if (!(off & 0x80000000)) {
135 - rix->revindex[i].offset = off;
134 + p->revindex[i].offset = off;
135 } else {
137 - rix->revindex[i].offset =
136 + p->revindex[i].offset =
137 ((uint64_t)ntohl(*off_64++)) << 32;
139 - rix->revindex[i].offset |=
138 + p->revindex[i].offset |=
139 ntohl(*off_64++);
140 }
142 - rix->revindex[i].nr = i;
141 + p->revindex[i].nr = i;
142 }
143 } else {
144 for (i = 0; i < num_ent; i++) {
145 uint32_t hl = *((uint32_t *)(index + 24 * i));
147 - rix->revindex[i].offset = ntohl(hl);
148 - rix->revindex[i].nr = i;
146 + p->revindex[i].offset = ntohl(hl);
147 + p->revindex[i].nr = i;
148 }
149 }
150
151 /* This knows the pack format -- the 20-byte trailer
152 * follows immediately after the last object data.
153 */
155 - rix->revindex[num_ent].offset = p->pack_size - 20;
156 - rix->revindex[num_ent].nr = -1;
157 - sort_revindex(rix->revindex, num_ent, p->pack_size);
154 + p->revindex[num_ent].offset = p->pack_size - 20;
155 + p->revindex[num_ent].nr = -1;
156 + sort_revindex(p->revindex, num_ent, p->pack_size);
157 }
158
160 -struct pack_revindex *revindex_for_pack(struct packed_git *p)
159 +void load_pack_revindex(struct packed_git *p)
160 {
162 - struct pack_revindex *rix = &p->reverse_index;
163 - if (!rix->revindex) {
164 - rix->p = p;
165 - create_pack_revindex(rix);
166 - }
167 - return rix;
161 + if (!p->revindex)
162 + create_pack_revindex(p);
163 }
164
170 -int find_revindex_position(struct pack_revindex *pridx, off_t ofs)
165 +int find_revindex_position(struct packed_git *p, off_t ofs)
166 {
167 int lo = 0;
173 - int hi = pridx->p->num_objects + 1;
174 - struct revindex_entry *revindex = pridx->revindex;
168 + int hi = p->num_objects + 1;
169 + struct revindex_entry *revindex = p->revindex;
170
171 do {
172 unsigned mi = lo + (hi - lo) / 2;
@@ -189,11 +184,13 @@ int find_revindex_position(struct pack_revindex *pridx, off_t ofs)
184
185 struct revindex_entry *find_pack_revindex(struct packed_git *p, off_t ofs)
186 {
192 - struct pack_revindex *pridx = revindex_for_pack(p);
193 - int pos = find_revindex_position(pridx, ofs);
187 + int pos;
188 +
189 + load_pack_revindex(p);
190 + pos = find_revindex_position(p, ofs);
191
192 if (pos < 0)
193 return NULL;
194
198 - return pridx->revindex + pos;
195 + return p->revindex + pos;
196 }
pack-revindex.h
+4 -7
@@ -1,18 +1,15 @@
1 #ifndef PACK_REVINDEX_H
2 #define PACK_REVINDEX_H
3
4 +struct packed_git;
5 +
6 struct revindex_entry {
7 off_t offset;
8 unsigned int nr;
9 };
10
9 -struct pack_revindex {
10 - struct packed_git *p;
11 - struct revindex_entry *revindex;
12 -};
13 -
14 -struct pack_revindex *revindex_for_pack(struct packed_git *p);
15 -int find_revindex_position(struct pack_revindex *pridx, off_t ofs);
11 +void load_pack_revindex(struct packed_git *p);
12 +int find_revindex_position(struct packed_git *p, off_t ofs);
13
14 struct revindex_entry *find_pack_revindex(struct packed_git *p, off_t ofs);
15