mmapped_ref_iterator: inline into `packed_ref_iterator`

Since `packed_ref_iterator` is now delegating to `mmapped_ref_iterator` rather than `cache_ref_iterator` to do the heavy lifting, there is no need to keep the two iterators separate. So "inline" `mmapped_ref_iterator` into `packed_ref_iterator`. This removes a bunch of boilerplate. Signed-off-by: Michael Haggerty <mhagger@alum.mit.edu> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Michael Haggerty committed Sep 25, 2017 at 10:00 UTC 523ee2d7858a6b1c09ba550fd1710ebfeff27335
1 file changed +114 -170
refs/packed-backend.c
+114 -170
@@ -225,157 +225,6 @@ static NORETURN void die_invalid_line(const char *path,
225
226 }
227
228 -/*
229 - * This value is set in `base.flags` if the peeled value of the
230 - * current reference is known. In that case, `peeled` contains the
231 - * correct peeled value for the reference, which might be `null_sha1`
232 - * if the reference is not a tag or if it is broken.
233 - */
234 -#define REF_KNOWS_PEELED 0x40
235 -
236 -/*
237 - * An iterator over a packed-refs file that is currently mmapped.
238 - */
239 -struct mmapped_ref_iterator {
240 - struct ref_iterator base;
241 -
242 - struct packed_ref_cache *packed_refs;
243 -
244 - /* The current position in the mmapped file: */
245 - const char *pos;
246 -
247 - /* The end of the mmapped file: */
248 - const char *eof;
249 -
250 - struct object_id oid, peeled;
251 -
252 - struct strbuf refname_buf;
253 -};
254 -
255 -static int mmapped_ref_iterator_advance(struct ref_iterator *ref_iterator)
256 -{
257 - struct mmapped_ref_iterator *iter =
258 - (struct mmapped_ref_iterator *)ref_iterator;
259 - const char *p = iter->pos, *eol;
260 -
261 - strbuf_reset(&iter->refname_buf);
262 -
263 - if (iter->pos == iter->eof)
264 - return ref_iterator_abort(ref_iterator);
265 -
266 - iter->base.flags = REF_ISPACKED;
267 -
268 - if (iter->eof - p < GIT_SHA1_HEXSZ + 2 ||
269 - parse_oid_hex(p, &iter->oid, &p) ||
270 - !isspace(*p++))
271 - die_invalid_line(iter->packed_refs->refs->path,
272 - iter->pos, iter->eof - iter->pos);
273 -
274 - eol = memchr(p, '\n', iter->eof - p);
275 - if (!eol)
276 - die_unterminated_line(iter->packed_refs->refs->path,
277 - iter->pos, iter->eof - iter->pos);
278 -
279 - strbuf_add(&iter->refname_buf, p, eol - p);
280 - iter->base.refname = iter->refname_buf.buf;
281 -
282 - if (check_refname_format(iter->base.refname, REFNAME_ALLOW_ONELEVEL)) {
283 - if (!refname_is_safe(iter->base.refname))
284 - die("packed refname is dangerous: %s",
285 - iter->base.refname);
286 - oidclr(&iter->oid);
287 - iter->base.flags |= REF_BAD_NAME | REF_ISBROKEN;
288 - }
289 - if (iter->packed_refs->peeled == PEELED_FULLY ||
290 - (iter->packed_refs->peeled == PEELED_TAGS &&
291 - starts_with(iter->base.refname, "refs/tags/")))
292 - iter->base.flags |= REF_KNOWS_PEELED;
293 -
294 - iter->pos = eol + 1;
295 -
296 - if (iter->pos < iter->eof && *iter->pos == '^') {
297 - p = iter->pos + 1;
298 - if (iter->eof - p < GIT_SHA1_HEXSZ + 1 ||
299 - parse_oid_hex(p, &iter->peeled, &p) ||
300 - *p++ != '\n')
301 - die_invalid_line(iter->packed_refs->refs->path,
302 - iter->pos, iter->eof - iter->pos);
303 - iter->pos = p;
304 -
305 - /*
306 - * Regardless of what the file header said, we
307 - * definitely know the value of *this* reference. But
308 - * we suppress it if the reference is broken:
309 - */
310 - if ((iter->base.flags & REF_ISBROKEN)) {
311 - oidclr(&iter->peeled);
312 - iter->base.flags &= ~REF_KNOWS_PEELED;
313 - } else {
314 - iter->base.flags |= REF_KNOWS_PEELED;
315 - }
316 - } else {
317 - oidclr(&iter->peeled);
318 - }
319 -
320 - return ITER_OK;
321 -}
322 -
323 -static int mmapped_ref_iterator_peel(struct ref_iterator *ref_iterator,
324 - struct object_id *peeled)
325 -{
326 - struct mmapped_ref_iterator *iter =
327 - (struct mmapped_ref_iterator *)ref_iterator;
328 -
329 - if ((iter->base.flags & REF_KNOWS_PEELED)) {
330 - oidcpy(peeled, &iter->peeled);
331 - return is_null_oid(&iter->peeled) ? -1 : 0;
332 - } else if ((iter->base.flags & (REF_ISBROKEN | REF_ISSYMREF))) {
333 - return -1;
334 - } else {
335 - return !!peel_object(iter->oid.hash, peeled->hash);
336 - }
337 -}
338 -
339 -static int mmapped_ref_iterator_abort(struct ref_iterator *ref_iterator)
340 -{
341 - struct mmapped_ref_iterator *iter =
342 - (struct mmapped_ref_iterator *)ref_iterator;
343 -
344 - release_packed_ref_cache(iter->packed_refs);
345 - strbuf_release(&iter->refname_buf);
346 - base_ref_iterator_free(ref_iterator);
347 - return ITER_DONE;
348 -}
349 -
350 -static struct ref_iterator_vtable mmapped_ref_iterator_vtable = {
351 - mmapped_ref_iterator_advance,
352 - mmapped_ref_iterator_peel,
353 - mmapped_ref_iterator_abort
354 -};
355 -
356 -struct ref_iterator *mmapped_ref_iterator_begin(
357 - struct packed_ref_cache *packed_refs,
358 - const char *pos, const char *eof)
359 -{
360 - struct mmapped_ref_iterator *iter = xcalloc(1, sizeof(*iter));
361 - struct ref_iterator *ref_iterator = &iter->base;
362 -
363 - if (!packed_refs->buf)
364 - return empty_ref_iterator_begin();
365 -
366 - base_ref_iterator_init(ref_iterator, &mmapped_ref_iterator_vtable, 1);
367 -
368 - iter->packed_refs = packed_refs;
369 - acquire_packed_ref_cache(iter->packed_refs);
370 - iter->pos = pos;
371 - iter->eof = eof;
372 - strbuf_init(&iter->refname_buf, 0);
373 -
374 - iter->base.oid = &iter->oid;
375 -
376 - return ref_iterator;
377 -}
378 -
228 struct packed_ref_entry {
229 const char *start;
230 size_t len;
@@ -858,38 +707,120 @@ static int packed_read_raw_ref(struct ref_store *ref_store,
707 return 0;
708 }
709
710 +/*
711 + * This value is set in `base.flags` if the peeled value of the
712 + * current reference is known. In that case, `peeled` contains the
713 + * correct peeled value for the reference, which might be `null_sha1`
714 + * if the reference is not a tag or if it is broken.
715 + */
716 +#define REF_KNOWS_PEELED 0x40
717 +
718 +/*
719 + * An iterator over a packed-refs file that is currently mmapped.
720 + */
721 struct packed_ref_iterator {
722 struct ref_iterator base;
723
864 - struct packed_ref_cache *cache;
865 - struct ref_iterator *iter0;
724 + struct packed_ref_cache *packed_refs;
725 +
726 + /* The current position in the mmapped file: */
727 + const char *pos;
728 +
729 + /* The end of the mmapped file: */
730 + const char *eof;
731 +
732 + struct object_id oid, peeled;
733 +
734 + struct strbuf refname_buf;
735 +
736 unsigned int flags;
737 };
738
739 +static int next_record(struct packed_ref_iterator *iter)
740 +{
741 + const char *p = iter->pos, *eol;
742 +
743 + strbuf_reset(&iter->refname_buf);
744 +
745 + if (iter->pos == iter->eof)
746 + return ITER_DONE;
747 +
748 + iter->base.flags = REF_ISPACKED;
749 +
750 + if (iter->eof - p < GIT_SHA1_HEXSZ + 2 ||
751 + parse_oid_hex(p, &iter->oid, &p) ||
752 + !isspace(*p++))
753 + die_invalid_line(iter->packed_refs->refs->path,
754 + iter->pos, iter->eof - iter->pos);
755 +
756 + eol = memchr(p, '\n', iter->eof - p);
757 + if (!eol)
758 + die_unterminated_line(iter->packed_refs->refs->path,
759 + iter->pos, iter->eof - iter->pos);
760 +
761 + strbuf_add(&iter->refname_buf, p, eol - p);
762 + iter->base.refname = iter->refname_buf.buf;
763 +
764 + if (check_refname_format(iter->base.refname, REFNAME_ALLOW_ONELEVEL)) {
765 + if (!refname_is_safe(iter->base.refname))
766 + die("packed refname is dangerous: %s",
767 + iter->base.refname);
768 + oidclr(&iter->oid);
769 + iter->base.flags |= REF_BAD_NAME | REF_ISBROKEN;
770 + }
771 + if (iter->packed_refs->peeled == PEELED_FULLY ||
772 + (iter->packed_refs->peeled == PEELED_TAGS &&
773 + starts_with(iter->base.refname, "refs/tags/")))
774 + iter->base.flags |= REF_KNOWS_PEELED;
775 +
776 + iter->pos = eol + 1;
777 +
778 + if (iter->pos < iter->eof && *iter->pos == '^') {
779 + p = iter->pos + 1;
780 + if (iter->eof - p < GIT_SHA1_HEXSZ + 1 ||
781 + parse_oid_hex(p, &iter->peeled, &p) ||
782 + *p++ != '\n')
783 + die_invalid_line(iter->packed_refs->refs->path,
784 + iter->pos, iter->eof - iter->pos);
785 + iter->pos = p;
786 +
787 + /*
788 + * Regardless of what the file header said, we
789 + * definitely know the value of *this* reference. But
790 + * we suppress it if the reference is broken:
791 + */
792 + if ((iter->base.flags & REF_ISBROKEN)) {
793 + oidclr(&iter->peeled);
794 + iter->base.flags &= ~REF_KNOWS_PEELED;
795 + } else {
796 + iter->base.flags |= REF_KNOWS_PEELED;
797 + }
798 + } else {
799 + oidclr(&iter->peeled);
800 + }
801 +
802 + return ITER_OK;
803 +}
804 +
805 static int packed_ref_iterator_advance(struct ref_iterator *ref_iterator)
806 {
807 struct packed_ref_iterator *iter =
808 (struct packed_ref_iterator *)ref_iterator;
809 int ok;
810
875 - while ((ok = ref_iterator_advance(iter->iter0)) == ITER_OK) {
811 + while ((ok = next_record(iter)) == ITER_OK) {
812 if (iter->flags & DO_FOR_EACH_PER_WORKTREE_ONLY &&
877 - ref_type(iter->iter0->refname) != REF_TYPE_PER_WORKTREE)
813 + ref_type(iter->base.refname) != REF_TYPE_PER_WORKTREE)
814 continue;
815
816 if (!(iter->flags & DO_FOR_EACH_INCLUDE_BROKEN) &&
881 - !ref_resolves_to_object(iter->iter0->refname,
882 - iter->iter0->oid,
883 - iter->iter0->flags))
817 + !ref_resolves_to_object(iter->base.refname, &iter->oid,
818 + iter->flags))
819 continue;
820
886 - iter->base.refname = iter->iter0->refname;
887 - iter->base.oid = iter->iter0->oid;
888 - iter->base.flags = iter->iter0->flags;
821 return ITER_OK;
822 }
823
892 - iter->iter0 = NULL;
824 if (ref_iterator_abort(ref_iterator) != ITER_DONE)
825 ok = ITER_ERROR;
826
@@ -902,7 +833,14 @@ static int packed_ref_iterator_peel(struct ref_iterator *ref_iterator,
833 struct packed_ref_iterator *iter =
834 (struct packed_ref_iterator *)ref_iterator;
835
905 - return ref_iterator_peel(iter->iter0, peeled);
836 + if ((iter->base.flags & REF_KNOWS_PEELED)) {
837 + oidcpy(peeled, &iter->peeled);
838 + return is_null_oid(&iter->peeled) ? -1 : 0;
839 + } else if ((iter->base.flags & (REF_ISBROKEN | REF_ISSYMREF))) {
840 + return -1;
841 + } else {
842 + return !!peel_object(iter->oid.hash, peeled->hash);
843 + }
844 }
845
846 static int packed_ref_iterator_abort(struct ref_iterator *ref_iterator)
@@ -911,10 +849,8 @@ static int packed_ref_iterator_abort(struct ref_iterator *ref_iterator)
849 (struct packed_ref_iterator *)ref_iterator;
850 int ok = ITER_DONE;
851
914 - if (iter->iter0)
915 - ok = ref_iterator_abort(iter->iter0);
916 -
917 - release_packed_ref_cache(iter->cache);
852 + strbuf_release(&iter->refname_buf);
853 + release_packed_ref_cache(iter->packed_refs);
854 base_ref_iterator_free(ref_iterator);
855 return ok;
856 }
@@ -940,6 +876,11 @@ static struct ref_iterator *packed_ref_iterator_begin(
876 required_flags |= REF_STORE_ODB;
877 refs = packed_downcast(ref_store, required_flags, "ref_iterator_begin");
878
879 + packed_refs = get_packed_ref_cache(refs);
880 +
881 + if (!packed_refs->buf)
882 + return empty_ref_iterator_begin();
883 +
884 iter = xcalloc(1, sizeof(*iter));
885 ref_iterator = &iter->base;
886 base_ref_iterator_init(ref_iterator, &packed_ref_iterator_vtable, 1);
@@ -949,7 +890,7 @@ static struct ref_iterator *packed_ref_iterator_begin(
890 * the packed-ref cache is up to date with what is on disk,
891 * and re-reads it if not.
892 */
952 - iter->cache = packed_refs = get_packed_ref_cache(refs);
893 + iter->packed_refs = packed_refs;
894 acquire_packed_ref_cache(packed_refs);
895
896 if (prefix && *prefix)
@@ -957,8 +898,11 @@ static struct ref_iterator *packed_ref_iterator_begin(
898 else
899 start = packed_refs->buf + packed_refs->header_len;
900
960 - iter->iter0 = mmapped_ref_iterator_begin(packed_refs,
961 - start, packed_refs->eof);
901 + iter->pos = start;
902 + iter->eof = packed_refs->eof;
903 + strbuf_init(&iter->refname_buf, 0);
904 +
905 + iter->base.oid = &iter->oid;
906
907 iter->flags = flags;
908