#define DISABLE_SIGN_COMPARE_WARNINGS

#include "git-compat-util.h"
#include "commit.h"
#include "gettext.h"
#include "hex.h"
#include "strbuf.h"
#include "tag.h"
#include "diff.h"
#include "revision.h"
#include "progress.h"
#include "list-objects.h"
#include "pack.h"
#include "pack-bitmap.h"
#include "pack-revindex.h"
#include "pack-objects.h"
#include "packfile.h"
#include "repository.h"
#include "trace2.h"
#include "odb.h"
#include "list-objects-filter-options.h"
#include "midx.h"
#include "config.h"
#include "pseudo-merge.h"

/*
 * An entry on the bitmap index, representing the bitmap for a given
 * commit.
 */
struct stored_bitmap {
	struct object_id oid;
	struct ewah_bitmap *root;
	struct stored_bitmap *xor;
	size_t map_pos;
	int flags;
};

/*
 * The active bitmap index for a repository. By design, repositories only have
 * a single bitmap index available (the index for the biggest packfile in
 * the repository), since bitmap indexes need full closure.
 *
 * If there is more than one bitmap index available (e.g. because of alternates),
 * the active bitmap index is the largest one.
 */
struct bitmap_index {
	/*
	 * The pack or multi-pack index (MIDX) that this bitmap index belongs
	 * to.
	 *
	 * Exactly one of these must be non-NULL; this specifies the object
	 * order used to interpret this bitmap.
	 */
	struct packed_git *pack;
	struct multi_pack_index *midx;

	/*
	 * If using a multi-pack index chain, 'base' points to the
	 * bitmap index corresponding to this bitmap's midx->base_midx.
	 *
	 * base_nr indicates how many layers precede this one, and is
	 * zero when base is NULL.
	 */
	struct bitmap_index *base;
	uint32_t base_nr;

	/* mmapped buffer of the whole bitmap index */
	unsigned char *map;
	size_t map_size; /* size of the mmaped buffer */
	size_t map_pos; /* current position when loading the index */

	/*
	 * Type indexes.
	 *
	 * Each bitmap marks which objects in the packfile  are of the given
	 * type. This provides type information when yielding the objects from
	 * the packfile during a walk, which allows for better delta bases.
	 */
	struct ewah_bitmap *commits;
	struct ewah_bitmap *trees;
	struct ewah_bitmap *blobs;
	struct ewah_bitmap *tags;

	/*
	 * Type index arrays when this bitmap is associated with an
	 * incremental multi-pack index chain.
	 *
	 * If n is the number of unique layers in the MIDX chain, then
	 * commits_all[n-1] is this structs 'commits' field,
	 * commits_all[n-2] is the commits field of this bitmap's
	 * 'base', and so on.
	 *
	 * When associated either with a non-incremental MIDX or a
	 * single packfile, these arrays each contain a single element.
	 */
	struct ewah_bitmap **commits_all;
	struct ewah_bitmap **trees_all;
	struct ewah_bitmap **blobs_all;
	struct ewah_bitmap **tags_all;

	/* Map from object ID -> `stored_bitmap` for all the bitmapped commits */
	kh_oid_map_t *bitmaps;

	/* Number of bitmapped commits */
	uint32_t entry_count;

	/* If not NULL, this is a name-hash cache pointing into map. */
	uint32_t *hashes;

	/* The checksum of the packfile or MIDX; points into map. */
	const unsigned char *checksum;

	/*
	 * If not NULL, this point into the commit table extension
	 * (within the memory mapped region `map`).
	 */
	unsigned char *table_lookup;

	/* This contains the pseudo-merge cache within 'map' (if found). */
	struct pseudo_merge_map pseudo_merges;

	/*
	 * Extended index.
	 *
	 * When trying to perform bitmap operations with objects that are not
	 * packed in `pack`, these objects are added to this "fake index" and
	 * are assumed to appear at the end of the packfile for all operations
	 */
	struct eindex {
		struct object **objects;
		uint32_t *hashes;
		uint32_t count, alloc;
		kh_oid_pos_t *positions;
	} ext_index;

	/* Bitmap result of the last performed walk */
	struct bitmap *result;

	/* "have" bitmap from the last performed walk */
	struct bitmap *haves;

	/* Version of the bitmap index */
	unsigned int version;
};

static int pseudo_merges_satisfied_nr;
static int pseudo_merges_cascades_nr;
static int existing_bitmaps_hits_nr;
static int existing_bitmaps_misses_nr;
static int roots_with_bitmaps_nr;
static int roots_without_bitmaps_nr;

static struct ewah_bitmap *lookup_stored_bitmap(struct stored_bitmap *st)
{
	struct ewah_bitmap *parent;
	struct ewah_bitmap *composed;

	if (!st->xor)
		return st->root;

	composed = ewah_pool_new();
	parent = lookup_stored_bitmap(st->xor);
	ewah_xor(st->root, parent, composed);

	ewah_pool_free(st->root);
	st->root = composed;
	st->xor = NULL;

	return composed;
}

struct ewah_bitmap *read_bitmap(const unsigned char *map,
				size_t map_size, size_t *map_pos)
{
	struct ewah_bitmap *b = ewah_pool_new();

	ssize_t bitmap_size = ewah_read_mmap(b, map + *map_pos,
					     map_size - *map_pos);

	if (bitmap_size < 0) {
		error(_("failed to load bitmap index (corrupted?)"));
		ewah_pool_free(b);
		return NULL;
	}

	*map_pos += bitmap_size;

	return b;
}

/*
 * Read a bitmap from the current read position on the mmaped
 * index, and increase the read position accordingly
 */
static struct ewah_bitmap *read_bitmap_1(struct bitmap_index *index)
{
	return read_bitmap(index->map, index->map_size, &index->map_pos);
}

static uint32_t bitmap_num_objects_total(struct bitmap_index *index)
{
	if (index->midx) {
		struct multi_pack_index *m = index->midx;
		return m->num_objects + m->num_objects_in_base;
	}
	return index->pack->num_objects;
}

static uint32_t bitmap_num_objects(struct bitmap_index *index)
{
	if (index->midx)
		return index->midx->num_objects;
	return index->pack->num_objects;
}

static uint32_t bitmap_name_hash(struct bitmap_index *index, uint32_t pos)
{
	if (bitmap_is_midx(index)) {
		while (index && pos < index->midx->num_objects_in_base) {
			ASSERT(bitmap_is_midx(index));
			index = index->base;
		}

		if (!index)
			BUG("NULL base bitmap for object position: %"PRIu32, pos);

		pos -= index->midx->num_objects_in_base;
		if (pos >= index->midx->num_objects)
			BUG("out-of-bounds midx bitmap object at %"PRIu32, pos);
	}

	if (!index->hashes)
		return 0;

	return get_be32(index->hashes + pos);
}

static struct repository *bitmap_repo(struct bitmap_index *bitmap_git)
{
	if (bitmap_is_midx(bitmap_git))
		return bitmap_git->midx->source->base.odb->repo;
	return bitmap_git->pack->repo;
}

static int load_bitmap_header(struct bitmap_index *index)
{
	struct bitmap_disk_header *header = (void *)index->map;
	const struct git_hash_algo *hash_algo = bitmap_repo(index)->hash_algo;

	size_t header_size = sizeof(*header) - GIT_MAX_RAWSZ + hash_algo->rawsz;

	if (index->map_size < header_size + hash_algo->rawsz)
		return error(_("corrupted bitmap index (too small)"));

	if (memcmp(header->magic, BITMAP_IDX_SIGNATURE, sizeof(BITMAP_IDX_SIGNATURE)) != 0)
		return error(_("corrupted bitmap index file (wrong header)"));

	index->version = ntohs(header->version);
	if (index->version != 1)
		return error(_("unsupported version '%d' for bitmap index file"), index->version);

	/* Parse known bitmap format options */
	{
		uint32_t flags = ntohs(header->options);
		size_t cache_size = st_mult(bitmap_num_objects(index), sizeof(uint32_t));
		unsigned char *index_end = index->map + index->map_size - hash_algo->rawsz;

		if ((flags & BITMAP_OPT_FULL_DAG) == 0)
			BUG("unsupported options for bitmap index file "
				"(Git requires BITMAP_OPT_FULL_DAG)");

		if (flags & BITMAP_OPT_HASH_CACHE) {
			if (cache_size > index_end - index->map - header_size)
				return error(_("corrupted bitmap index file (too short to fit hash cache)"));
			index->hashes = (void *)(index_end - cache_size);
			index_end -= cache_size;
		}

		if (flags & BITMAP_OPT_LOOKUP_TABLE) {
			size_t table_size = st_mult(ntohl(header->entry_count),
						    BITMAP_LOOKUP_TABLE_TRIPLET_WIDTH);
			if (table_size > index_end - index->map - header_size)
				return error(_("corrupted bitmap index file (too short to fit lookup table)"));
			if (git_env_bool("GIT_TEST_READ_COMMIT_TABLE", 1))
				index->table_lookup = (void *)(index_end - table_size);
			index_end -= table_size;
		}

		if (flags & BITMAP_OPT_PSEUDO_MERGES) {
			unsigned char *pseudo_merge_ofs;
			size_t table_size;
			uint32_t i;

			if (sizeof(table_size) > index_end - index->map - header_size)
				return error(_("corrupted bitmap index file (too short to fit pseudo-merge table header)"));

			table_size = get_be64(index_end - 8);
			if (table_size > index_end - index->map - header_size)
				return error(_("corrupted bitmap index file (too short to fit pseudo-merge table)"));

			if (git_env_bool("GIT_TEST_USE_PSEUDO_MERGES", 1)) {
				const unsigned char *ext = (index_end - table_size);

				index->pseudo_merges.map = index->map;
				index->pseudo_merges.map_size = index->map_size;
				index->pseudo_merges.commits = ext + get_be64(index_end - 16);
				index->pseudo_merges.commits_nr = get_be32(index_end - 20);
				index->pseudo_merges.nr = get_be32(index_end - 24);

				if (st_add(st_mult(index->pseudo_merges.nr,
						   sizeof(uint64_t)),
					   24) > table_size)
					return error(_("corrupted bitmap index file, pseudo-merge table too short"));

				CALLOC_ARRAY(index->pseudo_merges.v,
					     index->pseudo_merges.nr);

				pseudo_merge_ofs = index_end - 24 -
					(index->pseudo_merges.nr * sizeof(uint64_t));
				for (i = 0; i < index->pseudo_merges.nr; i++) {
					index->pseudo_merges.v[i].at = get_be64(pseudo_merge_ofs);
					pseudo_merge_ofs += sizeof(uint64_t);
				}
			}

			index_end -= table_size;
		}
	}

	index->entry_count = ntohl(header->entry_count);
	index->checksum = header->checksum;
	index->map_pos += header_size;
	return 0;
}

static struct stored_bitmap *store_bitmap(struct bitmap_index *index,
					  struct ewah_bitmap *root,
					  const struct object_id *oid,
					  struct stored_bitmap *xor_with,
					  int flags, size_t map_pos)
{
	struct stored_bitmap *stored;
	khiter_t hash_pos;
	int ret;

	stored = xmalloc(sizeof(struct stored_bitmap));
	stored->map_pos = map_pos;
	stored->root = root;
	stored->xor = xor_with;
	stored->flags = flags;
	oidcpy(&stored->oid, oid);

	hash_pos = kh_put_oid_map(index->bitmaps, stored->oid, &ret);

	/*
	 * A 0 return code means the insertion succeeded with no changes,
	 * because the SHA1 already existed on the map. This is bad, there
	 * shouldn't be duplicated commits in the index.
	 */
	if (ret == 0) {
		error(_("duplicate entry in bitmap index: '%s'"), oid_to_hex(oid));
		return NULL;
	}

	kh_value(index->bitmaps, hash_pos) = stored;
	return stored;
}

static inline uint32_t read_be32(const unsigned char *buffer, size_t *pos)
{
	uint32_t result = get_be32(buffer + *pos);
	(*pos) += sizeof(result);
	return result;
}

static inline uint8_t read_u8(const unsigned char *buffer, size_t *pos)
{
	return buffer[(*pos)++];
}

#define MAX_XOR_OFFSET 160

static int nth_bitmap_object_oid(struct bitmap_index *index,
				 struct object_id *oid,
				 uint32_t n)
{
	if (index->midx)
		return nth_midxed_object_oid(oid, index->midx, n) ? 0 : -1;
	return nth_packed_object_id(oid, index->pack, n);
}

static int load_bitmap_entries_v1(struct bitmap_index *index)
{
	uint32_t i;
	struct stored_bitmap *recent_bitmaps[MAX_XOR_OFFSET] = { NULL };

	for (i = 0; i < index->entry_count; ++i) {
		int xor_offset, flags;
		struct ewah_bitmap *bitmap = NULL;
		struct stored_bitmap *xor_bitmap = NULL;
		uint32_t commit_idx_pos;
		struct object_id oid;
		size_t entry_map_pos;

		if (index->map_size - index->map_pos < 6)
			return error(_("corrupt ewah bitmap: truncated header for entry %d"), i);

		entry_map_pos = index->map_pos;
		commit_idx_pos = read_be32(index->map, &index->map_pos);
		xor_offset = read_u8(index->map, &index->map_pos);
		flags = read_u8(index->map, &index->map_pos);

		if (nth_bitmap_object_oid(index, &oid, commit_idx_pos) < 0)
			return error(_("corrupt ewah bitmap: commit index %u out of range"),
				     (unsigned)commit_idx_pos);

		if (xor_offset > MAX_XOR_OFFSET || xor_offset > i)
			return error(_("corrupted bitmap pack index"));

		if (xor_offset > 0) {
			xor_bitmap = recent_bitmaps[(i - xor_offset) % MAX_XOR_OFFSET];

			if (!xor_bitmap)
				return error(_("invalid XOR offset in bitmap pack index"));
		}

		bitmap = read_bitmap_1(index);
		if (!bitmap)
			return -1;

		recent_bitmaps[i % MAX_XOR_OFFSET] =
			store_bitmap(index, bitmap, &oid, xor_bitmap, flags,
				     entry_map_pos);
	}

	return 0;
}

char *midx_bitmap_filename(struct multi_pack_index *midx)
{
	struct strbuf buf = STRBUF_INIT;
	if (midx->has_chain)
		get_split_midx_filename_ext(midx->source, &buf,
					    midx_get_checksum_hash(midx),
					    MIDX_EXT_BITMAP);
	else
		get_midx_filename_ext(midx->source, &buf,
				      midx_get_checksum_hash(midx),
				      MIDX_EXT_BITMAP);

	return strbuf_detach(&buf, NULL);
}

char *pack_bitmap_filename(struct packed_git *p)
{
	size_t len;

	if (!strip_suffix(p->pack_name, ".pack", &len))
		BUG("pack_name does not end in .pack");
	return xstrfmt("%.*s.bitmap", (int)len, p->pack_name);
}

static int open_midx_bitmap(struct bitmap_index *bitmap_git,
			    struct multi_pack_index *midx)
{
	struct stat st;
	char *bitmap_name = midx_bitmap_filename(midx);
	int fd = git_open(bitmap_name);
	uint32_t i;

	if (fd < 0) {
		if (errno != ENOENT)
			warning_errno("cannot open '%s'", bitmap_name);
		free(bitmap_name);
		return -1;
	}
	free(bitmap_name);

	if (fstat(fd, &st)) {
		error_errno(_("cannot fstat bitmap file"));
		close(fd);
		return -1;
	}

	if (bitmap_git->pack || bitmap_git->midx) {
		struct strbuf buf = STRBUF_INIT;
		get_midx_filename(midx->source, &buf);
		trace2_data_string("bitmap", bitmap_repo(bitmap_git),
				   "ignoring extra midx bitmap file", buf.buf);
		close(fd);
		strbuf_release(&buf);
		return -1;
	}

	bitmap_git->midx = midx;
	bitmap_git->map_size = xsize_t(st.st_size);
	bitmap_git->map_pos = 0;
	bitmap_git->map = xmmap(NULL, bitmap_git->map_size, PROT_READ,
				MAP_PRIVATE, fd, 0);
	close(fd);

	if (load_bitmap_header(bitmap_git) < 0)
		goto cleanup;

	if (!hasheq(midx_get_checksum_hash(bitmap_git->midx), bitmap_git->checksum,
		    bitmap_repo(bitmap_git)->hash_algo)) {
		error(_("checksum doesn't match in MIDX and bitmap"));
		goto cleanup;
	}

	if (load_midx_revindex(bitmap_git->midx)) {
		warning(_("multi-pack bitmap is missing required reverse index"));
		goto cleanup;
	}

	for (i = 0; i < bitmap_git->midx->num_packs + bitmap_git->midx->num_packs_in_base; i++) {
		if (prepare_midx_pack(bitmap_git->midx, i)) {
			warning(_("could not open pack %s"),
				bitmap_git->midx->pack_names[i]);
			goto cleanup;
		}
	}

	if (midx->base_midx) {
		bitmap_git->base = prepare_midx_bitmap_git(midx->base_midx);
		if (!bitmap_git->base) {
			warning(_("could not open bitmap for base MIDX"));
			goto cleanup;
		}
		bitmap_git->base_nr = bitmap_git->base->base_nr + 1;
	} else {
		bitmap_git->base_nr = 0;
	}

	return 0;

cleanup:
	munmap(bitmap_git->map, bitmap_git->map_size);
	bitmap_git->map_size = 0;
	bitmap_git->map_pos = 0;
	bitmap_git->map = NULL;
	bitmap_git->midx = NULL;
	return -1;
}

static int open_pack_bitmap(struct bitmap_index *bitmap_git, struct packed_git *packfile)
{
	int fd;
	struct stat st;
	char *bitmap_name;

	bitmap_name = pack_bitmap_filename(packfile);
	fd = git_open(bitmap_name);

	if (fd < 0) {
		if (errno != ENOENT)
			warning_errno("cannot open '%s'", bitmap_name);
		free(bitmap_name);
		return -1;
	}
	free(bitmap_name);

	if (fstat(fd, &st)) {
		error_errno(_("cannot fstat bitmap file"));
		close(fd);
		return -1;
	}

	if (bitmap_git->pack || bitmap_git->midx) {
		trace2_data_string("bitmap", bitmap_repo(bitmap_git),
				   "ignoring extra bitmap file",
				   packfile->pack_name);
		close(fd);
		return -1;
	}

	if (!is_pack_valid(packfile)) {
		close(fd);
		return -1;
	}

	bitmap_git->pack = packfile;
	bitmap_git->map_size = xsize_t(st.st_size);
	bitmap_git->map = xmmap(NULL, bitmap_git->map_size, PROT_READ, MAP_PRIVATE, fd, 0);
	bitmap_git->map_pos = 0;
	bitmap_git->base_nr = 0;
	close(fd);

	if (load_bitmap_header(bitmap_git) < 0) {
		munmap(bitmap_git->map, bitmap_git->map_size);
		bitmap_git->map = NULL;
		bitmap_git->map_size = 0;
		bitmap_git->map_pos = 0;
		bitmap_git->pack = NULL;
		return -1;
	}

	trace2_data_string("bitmap", bitmap_repo(bitmap_git),
			   "opened bitmap file", packfile->pack_name);
	return 0;
}

static int load_reverse_index(struct repository *r, struct bitmap_index *bitmap_git)
{
	if (bitmap_is_midx(bitmap_git)) {
		struct multi_pack_index *m;

		/*
		 * The multi-pack-index's .rev file is already loaded via
		 * open_pack_bitmap().
		 *
		 * But we still need to open the individual pack .rev files,
		 * since we will need to make use of them in pack-objects.
		 */
		for (m = bitmap_git->midx; m; m = m->base_midx) {
			uint32_t i;
			int ret;

			for (i = 0; i < m->num_packs; i++) {
				ret = load_pack_revindex(r, m->packs[i]);
				if (ret)
					return ret;
			}
		}
		return 0;
	}
	return load_pack_revindex(r, bitmap_git->pack);
}

static void load_all_type_bitmaps(struct bitmap_index *bitmap_git)
{
	struct bitmap_index *curr = bitmap_git;
	size_t i = bitmap_git->base_nr;

	ALLOC_ARRAY(bitmap_git->commits_all, bitmap_git->base_nr + 1);
	ALLOC_ARRAY(bitmap_git->trees_all, bitmap_git->base_nr + 1);
	ALLOC_ARRAY(bitmap_git->blobs_all, bitmap_git->base_nr + 1);
	ALLOC_ARRAY(bitmap_git->tags_all, bitmap_git->base_nr + 1);

	while (curr) {
		bitmap_git->commits_all[i] = curr->commits;
		bitmap_git->trees_all[i] = curr->trees;
		bitmap_git->blobs_all[i] = curr->blobs;
		bitmap_git->tags_all[i] = curr->tags;

		curr = curr->base;
		if (curr && !i)
			BUG("unexpected number of bitmap layers, expected %"PRIu32,
			    bitmap_git->base_nr + 1);
		i -= 1;
	}
}

static int load_bitmap(struct repository *r, struct bitmap_index *bitmap_git,
		       int recursing)
{
	assert(bitmap_git->map);

	bitmap_git->bitmaps = kh_init_oid_map();
	bitmap_git->ext_index.positions = kh_init_oid_pos();

	if (load_reverse_index(r, bitmap_git))
		return -1;

	if (!(bitmap_git->commits = read_bitmap_1(bitmap_git)) ||
		!(bitmap_git->trees = read_bitmap_1(bitmap_git)) ||
		!(bitmap_git->blobs = read_bitmap_1(bitmap_git)) ||
		!(bitmap_git->tags = read_bitmap_1(bitmap_git)))
		return -1;

	if (!bitmap_git->table_lookup && load_bitmap_entries_v1(bitmap_git) < 0)
		return -1;

	if (bitmap_git->base) {
		if (!bitmap_is_midx(bitmap_git))
			BUG("non-MIDX bitmap has non-NULL base bitmap index");
		if (load_bitmap(r, bitmap_git->base, 1) < 0)
			return -1;
	}

	if (!recursing)
		load_all_type_bitmaps(bitmap_git);

	return 0;
}

static int open_bitmap_for_source(struct odb_source_packed *source,
				  struct bitmap_index *bitmap_git)
{
	struct multi_pack_index *midx = get_multi_pack_index(source);
	struct packfile_list_entry *e;
	bool found = false;

	if (midx && !open_midx_bitmap(bitmap_git, midx))
		found = true;

	for (e = packfile_store_get_packs(source); e; e = e->next) {
		/*
		 * When tracing is enabled we want to keep looking to report
		 * duplicates even if we have already found a bitmap.
		 */
		if (found && !trace2_is_enabled())
			break;

		if (!open_pack_bitmap(bitmap_git, e->pack))
			found = true;
	}

	return found ? 0 : -1;
}

static int open_bitmap(struct repository *r,
		       struct bitmap_index *bitmap_git)
{
	struct odb_source *source;
	bool found = false;

	assert(!bitmap_git->map);

	odb_prepare_alternates(r->objects);
	for (source = r->objects->sources; source; source = source->next) {
		struct odb_source_files *files = odb_source_files_downcast(source);

		if (!open_bitmap_for_source(files->packed, bitmap_git))
			found = true;

		/*
		 * The only reason to keep looking after having found a bitmap
		 * is to report duplicates.
		 */
		if (found && !trace2_is_enabled())
			break;
	}

	return found ? 0 : -1;
}

struct bitmap_index *prepare_bitmap_git(struct repository *r)
{
	struct bitmap_index *bitmap_git = xcalloc(1, sizeof(*bitmap_git));

	if (!open_bitmap(r, bitmap_git) && !load_bitmap(r, bitmap_git, 0))
		return bitmap_git;

	free_bitmap_index(bitmap_git);
	return NULL;
}

struct bitmap_index *prepare_midx_bitmap_git(struct multi_pack_index *midx)
{
	struct bitmap_index *bitmap_git = xcalloc(1, sizeof(*bitmap_git));

	if (!open_midx_bitmap(bitmap_git, midx))
		return bitmap_git;

	free_bitmap_index(bitmap_git);
	return NULL;
}

struct bitmap_index *prepare_bitmap_git_for_source(struct odb_source_packed *source)
{
	struct bitmap_index *bitmap_git = xcalloc(1, sizeof(*bitmap_git));

	if (!open_bitmap_for_source(source, bitmap_git) &&
	    !load_bitmap(source->base.odb->repo, bitmap_git, 0))
		return bitmap_git;

	free_bitmap_index(bitmap_git);
	return NULL;
}

int bitmap_index_contains_pack(struct bitmap_index *bitmap, struct packed_git *pack)
{
	for (; bitmap; bitmap = bitmap->base) {
		if (bitmap_is_midx(bitmap)) {
			for (size_t i = 0; i < bitmap->midx->num_packs; i++)
				if (bitmap->midx->packs[i] == pack)
					return 1;
		} else if (bitmap->pack == pack) {
			return 1;
		}
	}

	return 0;
}

struct include_data {
	struct bitmap_index *bitmap_git;
	struct bitmap *base;
	struct bitmap *seen;
};

struct bitmap_lookup_table_triplet {
	uint32_t commit_pos;
	uint64_t offset;
	uint32_t xor_row;
};

struct bitmap_lookup_table_xor_item {
	struct object_id oid;
	uint64_t offset;
};

/*
 * Given a `triplet` struct pointer and pointer `p`, this
 * function reads the triplet beginning at `p` into the struct.
 * Note that this function assumes that there is enough memory
 * left for filling the `triplet` struct from `p`.
 */
static int bitmap_lookup_table_get_triplet_by_pointer(struct bitmap_lookup_table_triplet *triplet,
						      const unsigned char *p)
{
	if (!triplet)
		return -1;

	triplet->commit_pos = get_be32(p);
	p += sizeof(uint32_t);
	triplet->offset = get_be64(p);
	p += sizeof(uint64_t);
	triplet->xor_row = get_be32(p);
	return 0;
}

/*
 * This function gets the raw triplet from `row`'th row in the
 * lookup table and fills that data to the `triplet`.
 */
static int bitmap_lookup_table_get_triplet(struct bitmap_index *bitmap_git,
					   uint32_t pos,
					   struct bitmap_lookup_table_triplet *triplet)
{
	unsigned char *p = NULL;
	if (pos >= bitmap_git->entry_count)
		return error(_("corrupt bitmap lookup table: triplet position out of index"));

	p = bitmap_git->table_lookup + st_mult(pos, BITMAP_LOOKUP_TABLE_TRIPLET_WIDTH);

	return bitmap_lookup_table_get_triplet_by_pointer(triplet, p);
}

/*
 * Searches for a matching triplet. `commit_pos` is a pointer
 * to the wanted commit position value. `table_entry` points to
 * a triplet in lookup table. The first 4 bytes of each
 * triplet (pointed by `table_entry`) are compared with `*commit_pos`.
 */
static int triplet_cmp(const void *commit_pos, const void *table_entry)
{

	uint32_t a = *(uint32_t *)commit_pos;
	uint32_t b = get_be32(table_entry);
	if (a > b)
		return 1;
	else if (a < b)
		return -1;

	return 0;
}

static uint32_t bitmap_bsearch_pos(struct bitmap_index *bitmap_git,
			    struct object_id *oid,
			    uint32_t *result)
{
	int found;

	if (bitmap_is_midx(bitmap_git))
		found = bsearch_midx(oid, bitmap_git->midx, result);
	else
		found = bsearch_pack(oid, bitmap_git->pack, result);

	return found;
}

/*
 * `bsearch_triplet_by_pos` function searches for the raw triplet
 * having commit position same as `commit_pos` and fills `triplet`
 * object from the raw triplet. Returns 1 on success and 0 on
 * failure.
 */
static int bitmap_bsearch_triplet_by_pos(uint32_t commit_pos,
				  struct bitmap_index *bitmap_git,
				  struct bitmap_lookup_table_triplet *triplet)
{
	unsigned char *p = bsearch(&commit_pos, bitmap_git->table_lookup, bitmap_git->entry_count,
				   BITMAP_LOOKUP_TABLE_TRIPLET_WIDTH, triplet_cmp);

	if (!p)
		return -1;

	return bitmap_lookup_table_get_triplet_by_pointer(triplet, p);
}

static struct stored_bitmap *lazy_bitmap_for_commit(struct bitmap_index *bitmap_git,
						    struct commit *commit)
{
	uint32_t commit_pos, xor_row;
	uint64_t offset;
	int flags;
	struct bitmap_lookup_table_triplet triplet;
	struct object_id *oid = &commit->object.oid;
	struct ewah_bitmap *bitmap;
	struct stored_bitmap *xor_bitmap = NULL;
	const int bitmap_header_size = 6;
	static struct bitmap_lookup_table_xor_item *xor_items = NULL;
	static size_t xor_items_nr = 0, xor_items_alloc = 0;
	static int is_corrupt = 0;
	int xor_flags;
	khiter_t hash_pos;
	struct bitmap_lookup_table_xor_item *xor_item;
	size_t entry_map_pos;

	if (is_corrupt)
		return NULL;

	if (!bitmap_bsearch_pos(bitmap_git, oid, &commit_pos))
		return NULL;

	if (bitmap_bsearch_triplet_by_pos(commit_pos, bitmap_git, &triplet) < 0)
		return NULL;

	xor_items_nr = 0;
	offset = triplet.offset;
	xor_row = triplet.xor_row;

	while (xor_row != 0xffffffff) {
		ALLOC_GROW(xor_items, xor_items_nr + 1, xor_items_alloc);

		if (xor_items_nr + 1 >= bitmap_git->entry_count) {
			error(_("corrupt bitmap lookup table: xor chain exceeds entry count"));
			goto corrupt;
		}

		if (bitmap_lookup_table_get_triplet(bitmap_git, xor_row, &triplet) < 0)
			goto corrupt;

		xor_item = &xor_items[xor_items_nr];
		xor_item->offset = triplet.offset;

		if (nth_bitmap_object_oid(bitmap_git, &xor_item->oid, triplet.commit_pos) < 0) {
			error(_("corrupt bitmap lookup table: commit index %u out of range"),
				triplet.commit_pos);
			goto corrupt;
		}

		hash_pos = kh_get_oid_map(bitmap_git->bitmaps, xor_item->oid);

		/*
		 * If desired bitmap is already stored, we don't need
		 * to iterate further. Because we know that bitmaps
		 * that are needed to be parsed to parse this bitmap
		 * has already been stored. So, assign this stored bitmap
		 * to the xor_bitmap.
		 */
		if (hash_pos < kh_end(bitmap_git->bitmaps) &&
			(xor_bitmap = kh_value(bitmap_git->bitmaps, hash_pos)))
			break;
		xor_items_nr++;
		xor_row = triplet.xor_row;
	}

	while (xor_items_nr) {
		xor_item = &xor_items[xor_items_nr - 1];
		bitmap_git->map_pos = xor_item->offset;
		if (bitmap_git->map_size - bitmap_git->map_pos < bitmap_header_size) {
			error(_("corrupt ewah bitmap: truncated header for bitmap of commit \"%s\""),
				oid_to_hex(&xor_item->oid));
			goto corrupt;
		}

		entry_map_pos = bitmap_git->map_pos;
		bitmap_git->map_pos += sizeof(uint32_t) + sizeof(uint8_t);
		xor_flags = read_u8(bitmap_git->map, &bitmap_git->map_pos);
		bitmap = read_bitmap_1(bitmap_git);

		if (!bitmap)
			goto corrupt;

		xor_bitmap = store_bitmap(bitmap_git, bitmap, &xor_item->oid,
					  xor_bitmap, xor_flags, entry_map_pos);
		xor_items_nr--;
	}

	bitmap_git->map_pos = offset;
	if (bitmap_git->map_size - bitmap_git->map_pos < bitmap_header_size) {
		error(_("corrupt ewah bitmap: truncated header for bitmap of commit \"%s\""),
			oid_to_hex(oid));
		goto corrupt;
	}

	/*
	 * Don't bother reading the commit's index position or its xor
	 * offset:
	 *
	 *   - The commit's index position is irrelevant to us, since
	 *     load_bitmap_entries_v1 only uses it to learn the object
	 *     id which is used to compute the hashmap's key. We already
	 *     have an object id, so no need to look it up again.
	 *
	 *   - The xor_offset is unusable for us, since it specifies how
	 *     many entries previous to ours we should look at. This
	 *     makes sense when reading the bitmaps sequentially (as in
	 *     load_bitmap_entries_v1()), since we can keep track of
	 *     each bitmap as we read them.
	 *
	 *     But it can't work for us, since the bitmap's don't have a
	 *     fixed size. So we learn the position of the xor'd bitmap
	 *     from the commit table (and resolve it to a bitmap in the
	 *     above if-statement).
	 *
	 * Instead, we can skip ahead and immediately read the flags and
	 * ewah bitmap.
	 */
	entry_map_pos = bitmap_git->map_pos;
	bitmap_git->map_pos += sizeof(uint32_t) + sizeof(uint8_t);
	flags = read_u8(bitmap_git->map, &bitmap_git->map_pos);
	bitmap = read_bitmap_1(bitmap_git);

	if (!bitmap)
		goto corrupt;

	return store_bitmap(bitmap_git, bitmap, oid, xor_bitmap, flags,
			    entry_map_pos);

corrupt:
	free(xor_items);
	is_corrupt = 1;
	return NULL;
}

static struct ewah_bitmap *find_bitmap_for_commit(struct bitmap_index *bitmap_git,
						  struct commit *commit,
						  struct bitmap_index **found)
{
	khiter_t hash_pos;
	if (!bitmap_git)
		return NULL;

	hash_pos = kh_get_oid_map(bitmap_git->bitmaps, commit->object.oid);
	if (hash_pos >= kh_end(bitmap_git->bitmaps)) {
		struct stored_bitmap *bitmap = NULL;
		if (!bitmap_git->table_lookup)
			return find_bitmap_for_commit(bitmap_git->base, commit,
						      found);

		/* this is a fairly hot codepath - no trace2_region please */
		/* NEEDSWORK: cache misses aren't recorded */
		bitmap = lazy_bitmap_for_commit(bitmap_git, commit);
		if (!bitmap)
			return find_bitmap_for_commit(bitmap_git->base, commit,
						      found);
		if (found)
			*found = bitmap_git;
		return lookup_stored_bitmap(bitmap);
	}
	if (found)
		*found = bitmap_git;
	return lookup_stored_bitmap(kh_value(bitmap_git->bitmaps, hash_pos));
}

struct ewah_bitmap *bitmap_for_commit(struct bitmap_index *bitmap_git,
				      struct commit *commit)
{
	return find_bitmap_for_commit(bitmap_git, commit, NULL);
}

static inline int bitmap_position_extended(struct bitmap_index *bitmap_git,
					   const struct object_id *oid)
{
	kh_oid_pos_t *positions = bitmap_git->ext_index.positions;
	khiter_t pos = kh_get_oid_pos(positions, *oid);

	if (pos < kh_end(positions)) {
		int bitmap_pos = kh_value(positions, pos);
		return bitmap_pos + bitmap_num_objects_total(bitmap_git);
	}

	return -1;
}

static inline int bitmap_position_packfile(struct bitmap_index *bitmap_git,
					   const struct object_id *oid)
{
	uint32_t pos;
	off_t offset = find_pack_entry_one(oid, bitmap_git->pack);
	if (!offset)
		return -1;

	if (offset_to_pack_pos(bitmap_git->pack, offset, &pos) < 0)
		return -1;
	return pos;
}

static int bitmap_position_midx(struct bitmap_index *bitmap_git,
				const struct object_id *oid)
{
	uint32_t want, got;
	if (!bsearch_midx(oid, bitmap_git->midx, &want))
		return -1;

	if (midx_to_pack_pos(bitmap_git->midx, want, &got) < 0)
		return -1;
	return got;
}

static int bitmap_position(struct bitmap_index *bitmap_git,
			   const struct object_id *oid)
{
	int pos;
	if (bitmap_is_midx(bitmap_git))
		pos = bitmap_position_midx(bitmap_git, oid);
	else
		pos = bitmap_position_packfile(bitmap_git, oid);
	return (pos >= 0) ? pos : bitmap_position_extended(bitmap_git, oid);
}

static int ext_index_add_object(struct bitmap_index *bitmap_git,
				struct object *object, const char *name)
{
	struct eindex *eindex = &bitmap_git->ext_index;

	khiter_t hash_pos;
	int hash_ret;
	int bitmap_pos;

	hash_pos = kh_put_oid_pos(eindex->positions, object->oid, &hash_ret);
	if (hash_ret > 0) {
		if (eindex->count >= eindex->alloc) {
			eindex->alloc = (eindex->alloc + 16) * 3 / 2;
			REALLOC_ARRAY(eindex->objects, eindex->alloc);
			REALLOC_ARRAY(eindex->hashes, eindex->alloc);
		}

		bitmap_pos = eindex->count;
		eindex->objects[eindex->count] = object;
		eindex->hashes[eindex->count] = pack_name_hash(name);
		kh_value(eindex->positions, hash_pos) = bitmap_pos;
		eindex->count++;
	} else {
		bitmap_pos = kh_value(eindex->positions, hash_pos);
	}

	return bitmap_pos + bitmap_num_objects_total(bitmap_git);
}

struct bitmap_show_data {
	struct bitmap_index *bitmap_git;
	struct bitmap *base;
};

static void show_object(struct object *object, const char *name, void *data_)
{
	struct bitmap_show_data *data = data_;
	int bitmap_pos;

	bitmap_pos = bitmap_position(data->bitmap_git, &object->oid);

	if (bitmap_pos < 0)
		bitmap_pos = ext_index_add_object(data->bitmap_git, object,
						  name);

	bitmap_set(data->base, bitmap_pos);
}

static void show_commit(struct commit *commit UNUSED,
			void *data UNUSED)
{
}

static unsigned apply_pseudo_merges_for_commit_1(struct bitmap_index *bitmap_git,
						 struct bitmap *result,
						 struct commit *commit,
						 uint32_t commit_pos)
{
	struct bitmap_index *curr = bitmap_git;
	int ret = 0;

	while (curr) {
		ret += apply_pseudo_merges_for_commit(&curr->pseudo_merges,
						      result, commit,
						      commit_pos);
		curr = curr->base;
	}

	if (ret)
		pseudo_merges_satisfied_nr += ret;

	return ret;
}

static int add_to_include_set(struct bitmap_index *bitmap_git,
			      struct include_data *data,
			      struct commit *commit,
			      int bitmap_pos)
{
	struct ewah_bitmap *partial;

	if (data->seen && bitmap_get(data->seen, bitmap_pos))
		return 0;

	if (bitmap_get(data->base, bitmap_pos))
		return 0;

	partial = bitmap_for_commit(bitmap_git, commit);
	if (partial) {
		existing_bitmaps_hits_nr++;

		bitmap_or_ewah(data->base, partial);
		return 0;
	}

	existing_bitmaps_misses_nr++;

	bitmap_set(data->base, bitmap_pos);
	if (apply_pseudo_merges_for_commit_1(bitmap_git, data->base, commit,
					     bitmap_pos))
		return 0;

	return 1;
}

static int should_include(struct commit *commit, void *_data)
{
	struct include_data *data = _data;
	int bitmap_pos;

	bitmap_pos = bitmap_position(data->bitmap_git, &commit->object.oid);
	if (bitmap_pos < 0)
		bitmap_pos = ext_index_add_object(data->bitmap_git,
						  (struct object *)commit,
						  NULL);

	if (!add_to_include_set(data->bitmap_git, data, commit, bitmap_pos)) {
		struct commit_list *parent = commit->parents;

		while (parent) {
			parent->item->object.flags |= SEEN;
			parent = parent->next;
		}

		return 0;
	}

	return 1;
}

static int should_include_obj(struct object *obj, void *_data)
{
	struct include_data *data = _data;
	int bitmap_pos;

	bitmap_pos = bitmap_position(data->bitmap_git, &obj->oid);
	if (bitmap_pos < 0)
		return 1;
	if ((data->seen && bitmap_get(data->seen, bitmap_pos)) ||
	     bitmap_get(data->base, bitmap_pos)) {
		obj->flags |= SEEN;
		return 0;
	}
	return 1;
}

static int add_commit_to_bitmap(struct bitmap_index *bitmap_git,
				struct bitmap **base,
				struct commit *commit)
{
	struct ewah_bitmap *or_with = bitmap_for_commit(bitmap_git, commit);

	if (!or_with) {
		existing_bitmaps_misses_nr++;
		return 0;
	}

	existing_bitmaps_hits_nr++;

	if (!*base)
		*base = ewah_to_bitmap(or_with);
	else
		bitmap_or_ewah(*base, or_with);

	return 1;
}

static struct bitmap *fill_in_bitmap(struct bitmap_index *bitmap_git,
				     struct rev_info *revs,
				     struct bitmap *base,
				     struct bitmap *seen)
{
	struct include_data incdata;
	struct bitmap_show_data show_data;

	if (!base)
		base = bitmap_new();

	incdata.bitmap_git = bitmap_git;
	incdata.base = base;
	incdata.seen = seen;

	revs->include_check = should_include;
	revs->include_check_obj = should_include_obj;
	revs->include_check_data = &incdata;

	if (prepare_revision_walk(revs))
		die(_("revision walk setup failed"));

	show_data.bitmap_git = bitmap_git;
	show_data.base = base;

	traverse_commit_list(revs, show_commit, show_object, &show_data);

	revs->include_check = NULL;
	revs->include_check_obj = NULL;
	revs->include_check_data = NULL;

	return base;
}

struct bitmap_boundary_cb {
	struct bitmap_index *bitmap_git;
	struct bitmap *base;

	struct object_array boundary;
};

static void show_boundary_commit(struct commit *commit, void *_data)
{
	struct bitmap_boundary_cb *data = _data;

	if (commit->object.flags & BOUNDARY)
		add_object_array(&commit->object, "", &data->boundary);

	if (commit->object.flags & UNINTERESTING) {
		if (bitmap_walk_contains(data->bitmap_git, data->base,
					 &commit->object.oid))
			return;

		add_commit_to_bitmap(data->bitmap_git, &data->base, commit);
	}
}

static void show_boundary_object(struct object *object UNUSED,
				 const char *name UNUSED,
				 void *data UNUSED)
{
	BUG("should not be called");
}

static unsigned cascade_pseudo_merges_1(struct bitmap_index *bitmap_git,
					struct bitmap *result,
					struct bitmap *roots)
{
	int ret = cascade_pseudo_merges(&bitmap_git->pseudo_merges,
					result, roots);
	if (ret) {
		pseudo_merges_cascades_nr++;
		pseudo_merges_satisfied_nr += ret;
	}

	return ret;
}

static struct bitmap *find_boundary_objects(struct bitmap_index *bitmap_git,
					    struct rev_info *revs,
					    struct object_list *roots)
{
	struct bitmap_boundary_cb cb;
	struct object_list *root;
	struct repository *repo;
	unsigned int i;
	unsigned int tmp_blobs, tmp_trees, tmp_tags;
	int any_missing = 0;
	int existing_bitmaps = 0;

	cb.bitmap_git = bitmap_git;
	cb.base = bitmap_new();
	object_array_init(&cb.boundary);

	repo = bitmap_repo(bitmap_git);

	revs->ignore_missing_links = 1;

	if (bitmap_git->pseudo_merges.nr) {
		struct bitmap *roots_bitmap = bitmap_new();
		struct object_list *objects = NULL;

		for (objects = roots; objects; objects = objects->next) {
			struct object *object = objects->item;
			int pos;

			pos = bitmap_position(bitmap_git, &object->oid);
			if (pos < 0)
				continue;

			bitmap_set(roots_bitmap, pos);
		}

		cascade_pseudo_merges_1(bitmap_git, cb.base, roots_bitmap);
		bitmap_free(roots_bitmap);
	}

	/*
	 * OR in any existing reachability bitmaps among `roots` into
	 * `cb.base`.
	 */
	for (root = roots; root; root = root->next) {
		struct object *object = root->item;
		if (object->type != OBJ_COMMIT ||
		    bitmap_walk_contains(bitmap_git, cb.base, &object->oid))
			continue;

		if (add_commit_to_bitmap(bitmap_git, &cb.base,
					 (struct commit *)object)) {
			existing_bitmaps = 1;
			continue;
		}

		any_missing = 1;
	}

	if (!any_missing)
		goto cleanup;

	if (existing_bitmaps)
		cascade_pseudo_merges_1(bitmap_git, cb.base, NULL);

	tmp_blobs = revs->blob_objects;
	tmp_trees = revs->tree_objects;
	tmp_tags = revs->tag_objects;
	revs->blob_objects = 0;
	revs->tree_objects = 0;
	revs->tag_objects = 0;

	/*
	 * We didn't have complete coverage of the roots. First setup a
	 * revision walk to (a) OR in any bitmaps that are UNINTERESTING
	 * between the tips and boundary, and (b) record the boundary.
	 */
	trace2_region_enter("pack-bitmap", "boundary-prepare", repo);
	if (prepare_revision_walk(revs))
		die("revision walk setup failed");
	trace2_region_leave("pack-bitmap", "boundary-prepare", repo);

	trace2_region_enter("pack-bitmap", "boundary-traverse", repo);
	revs->boundary = 1;
	traverse_commit_list_filtered(revs,
				      show_boundary_commit,
				      show_boundary_object,
				      &cb, NULL);
	revs->boundary = 0;
	trace2_region_leave("pack-bitmap", "boundary-traverse", repo);

	revs->blob_objects = tmp_blobs;
	revs->tree_objects = tmp_trees;
	revs->tag_objects = tmp_tags;

	reset_revision_walk();
	clear_object_flags(repo, UNINTERESTING);

	/*
	 * Then add the boundary commit(s) as fill-in traversal tips.
	 */
	trace2_region_enter("pack-bitmap", "boundary-fill-in", repo);
	for (i = 0; i < cb.boundary.nr; i++) {
		struct object *obj = cb.boundary.objects[i].item;
		if (bitmap_walk_contains(bitmap_git, cb.base, &obj->oid))
			obj->flags |= SEEN;
		else
			add_pending_object(revs, obj, "");
	}
	if (revs->pending.nr)
		cb.base = fill_in_bitmap(bitmap_git, revs, cb.base, NULL);
	trace2_region_leave("pack-bitmap", "boundary-fill-in", repo);

cleanup:
	object_array_clear(&cb.boundary);
	revs->ignore_missing_links = 0;

	return cb.base;
}

struct ewah_bitmap *pseudo_merge_bitmap_for_commit(struct bitmap_index *bitmap_git,
						   struct commit *commit)
{
	struct commit_list *p;
	struct bitmap *parents;
	struct pseudo_merge *match = NULL;

	if (!bitmap_git->pseudo_merges.nr)
		return NULL;

	parents = bitmap_new();

	for (p = commit->parents; p; p = p->next) {
		int pos = bitmap_position(bitmap_git, &p->item->object.oid);
		if (pos < 0 || pos >= bitmap_num_objects(bitmap_git))
			goto done;

		/*
		 * Use bitmap-relative positions instead of offsetting
		 * by bitmap_git->num_objects_in_base because we use
		 * this to find a match in pseudo_merge_for_parents(),
		 * and pseudo-merge groups cannot span multiple bitmap
		 * layers.
		 */
		bitmap_set(parents, pos);
	}

	match = pseudo_merge_for_parents(&bitmap_git->pseudo_merges, parents);

done:
	bitmap_free(parents);
	if (match)
		return pseudo_merge_bitmap(&bitmap_git->pseudo_merges, match);

	return NULL;
}

static void unsatisfy_all_pseudo_merges(struct bitmap_index *bitmap_git)
{
	uint32_t i;
	for (i = 0; i < bitmap_git->pseudo_merges.nr; i++)
		bitmap_git->pseudo_merges.v[i].satisfied = 0;
}

static struct bitmap *find_objects(struct bitmap_index *bitmap_git,
				   struct rev_info *revs,
				   struct object_list *roots,
				   struct bitmap *seen)
{
	struct bitmap *base = NULL;
	int needs_walk = 0;
	unsigned existing_bitmaps = 0;

	struct object_list *not_mapped = NULL;

	unsatisfy_all_pseudo_merges(bitmap_git);

	if (bitmap_git->pseudo_merges.nr) {
		struct bitmap *roots_bitmap = bitmap_new();
		struct object_list *objects = NULL;

		for (objects = roots; objects; objects = objects->next) {
			struct object *object = objects->item;
			int pos;

			pos = bitmap_position(bitmap_git, &object->oid);
			if (pos < 0)
				continue;

			bitmap_set(roots_bitmap, pos);
		}

		base = bitmap_new();
		cascade_pseudo_merges_1(bitmap_git, base, roots_bitmap);
		bitmap_free(roots_bitmap);
	}

	/*
	 * Go through all the roots for the walk. The ones that have bitmaps
	 * on the bitmap index will be `or`ed together to form an initial
	 * global reachability analysis.
	 *
	 * The ones without bitmaps in the index will be stored in the
	 * `not_mapped_list` for further processing.
	 */
	while (roots) {
		struct object *object = roots->item;

		roots = roots->next;

		if (base) {
			int pos = bitmap_position(bitmap_git, &object->oid);
			if (pos > 0 && bitmap_get(base, pos)) {
				object->flags |= SEEN;
				continue;
			}
		}

		if (object->type == OBJ_COMMIT &&
		    add_commit_to_bitmap(bitmap_git, &base, (struct commit *)object)) {
			object->flags |= SEEN;
			existing_bitmaps = 1;
			continue;
		}

		object_list_insert(object, &not_mapped);
	}

	/*
	 * Best case scenario: We found bitmaps for all the roots,
	 * so the resulting `or` bitmap has the full reachability analysis
	 */
	if (!not_mapped)
		return base;

	roots = not_mapped;

	if (existing_bitmaps)
		cascade_pseudo_merges_1(bitmap_git, base, NULL);

	/*
	 * Let's iterate through all the roots that don't have bitmaps to
	 * check if we can determine them to be reachable from the existing
	 * global bitmap.
	 *
	 * If we cannot find them in the existing global bitmap, we'll need
	 * to push them to an actual walk and run it until we can confirm
	 * they are reachable
	 */
	while (roots) {
		struct object *object = roots->item;
		int pos;

		roots = roots->next;
		pos = bitmap_position(bitmap_git, &object->oid);

		if (pos < 0 || base == NULL || !bitmap_get(base, pos)) {
			object->flags &= ~UNINTERESTING;
			add_pending_object(revs, object, "");
			needs_walk = 1;

			roots_without_bitmaps_nr++;
		} else {
			object->flags |= SEEN;

			roots_with_bitmaps_nr++;
		}
	}

	if (needs_walk) {
		/*
		 * This fill-in traversal may walk over some objects
		 * again, since we have already traversed in order to
		 * find the boundary.
		 *
		 * But this extra walk should be extremely cheap, since
		 * all commit objects are loaded into memory, and
		 * because we skip walking to parents that are
		 * UNINTERESTING, since it will be marked in the haves
		 * bitmap already (or it has an on-disk bitmap, since
		 * OR-ing it in covers all of its ancestors).
		 */
		base = fill_in_bitmap(bitmap_git, revs, base, seen);
	}

	object_list_free(&not_mapped);

	return base;
}

static void show_extended_objects(struct bitmap_index *bitmap_git,
				  struct rev_info *revs,
				  show_reachable_fn show_reach)
{
	struct bitmap *objects = bitmap_git->result;
	struct eindex *eindex = &bitmap_git->ext_index;
	uint32_t i;

	for (i = 0; i < eindex->count; ++i) {
		struct object *obj;

		if (!bitmap_get(objects,
				st_add(bitmap_num_objects_total(bitmap_git),
				       i)))
			continue;

		obj = eindex->objects[i];
		if ((obj->type == OBJ_BLOB && !revs->blob_objects) ||
		    (obj->type == OBJ_TREE && !revs->tree_objects) ||
		    (obj->type == OBJ_TAG && !revs->tag_objects))
			continue;

		show_reach(&obj->oid, obj->type, 0, eindex->hashes[i], NULL, 0, NULL);
	}
}

static void init_type_iterator(struct ewah_or_iterator *it,
			       struct bitmap_index *bitmap_git,
			       enum object_type type)
{
	switch (type) {
	case OBJ_COMMIT:
		ewah_or_iterator_init(it, bitmap_git->commits_all,
				      bitmap_git->base_nr + 1);
		break;

	case OBJ_TREE:
		ewah_or_iterator_init(it, bitmap_git->trees_all,
				      bitmap_git->base_nr + 1);
		break;

	case OBJ_BLOB:
		ewah_or_iterator_init(it, bitmap_git->blobs_all,
				      bitmap_git->base_nr + 1);
		break;

	case OBJ_TAG:
		ewah_or_iterator_init(it, bitmap_git->tags_all,
				      bitmap_git->base_nr + 1);
		break;

	default:
		BUG("object type %d not stored by bitmap type index", type);
		break;
	}
}

static int show_objects_for_type(
	struct bitmap_index *bitmap_git,
	struct bitmap *objects,
	enum object_type object_type,
	show_reachable_fn show_reach,
	void *payload)
{
	size_t i = 0;
	uint32_t offset;
	int ret;

	struct ewah_or_iterator it;
	eword_t filter;

	init_type_iterator(&it, bitmap_git, object_type);

	for (i = 0; i < objects->word_alloc &&
			ewah_or_iterator_next(&filter, &it); i++) {
		eword_t word = objects->words[i] & filter;
		size_t pos = (i * BITS_IN_EWORD);

		if (!word)
			continue;

		for (offset = 0; offset < BITS_IN_EWORD; ++offset) {
			struct packed_git *pack;
			struct object_id oid;
			uint32_t hash = 0, index_pos;
			off_t ofs;

			if ((word >> offset) == 0)
				break;

			offset += ewah_bit_ctz64(word >> offset);

			if (bitmap_is_midx(bitmap_git)) {
				struct multi_pack_index *m = bitmap_git->midx;
				uint32_t pack_id;

				index_pos = pack_pos_to_midx(m, pos + offset);
				ofs = nth_midxed_offset(m, index_pos);
				nth_midxed_object_oid(&oid, m, index_pos);

				pack_id = nth_midxed_pack_int_id(m, index_pos);
				pack = nth_midxed_pack(bitmap_git->midx, pack_id);
			} else {
				index_pos = pack_pos_to_index(bitmap_git->pack, pos + offset);
				ofs = pack_pos_to_offset(bitmap_git->pack, pos + offset);
				nth_bitmap_object_oid(bitmap_git, &oid, index_pos);

				pack = bitmap_git->pack;
			}

			hash = bitmap_name_hash(bitmap_git, index_pos);

			ret = show_reach(&oid, object_type, 0, hash, pack, ofs, payload);
			if (ret)
				goto out;
		}
	}

	ret = 0;

out:
	ewah_or_iterator_release(&it);
	return ret;
}

static int in_bitmapped_pack(struct bitmap_index *bitmap_git,
			     struct object_list *roots)
{
	while (roots) {
		struct object *object = roots->item;
		roots = roots->next;

		if (bitmap_is_midx(bitmap_git)) {
			if (bsearch_midx(&object->oid, bitmap_git->midx, NULL))
				return 1;
		} else {
			if (find_pack_entry_one(&object->oid, bitmap_git->pack) > 0)
				return 1;
		}
	}

	return 0;
}

static struct bitmap *find_tip_objects(struct bitmap_index *bitmap_git,
				       struct object_list *tip_objects,
				       enum object_type type)
{
	struct bitmap *result = bitmap_new();
	struct object_list *p;

	for (p = tip_objects; p; p = p->next) {
		int pos;

		if (p->item->type != type)
			continue;

		pos = bitmap_position(bitmap_git, &p->item->oid);
		if (pos < 0)
			continue;

		bitmap_set(result, pos);
	}

	return result;
}

static void filter_bitmap_exclude_type(struct bitmap_index *bitmap_git,
				       struct object_list *tip_objects,
				       struct bitmap *to_filter,
				       enum object_type type)
{
	struct eindex *eindex = &bitmap_git->ext_index;
	struct bitmap *tips;
	struct ewah_or_iterator it;
	eword_t mask;
	uint32_t i;

	/*
	 * The non-bitmap version of this filter never removes
	 * objects which the other side specifically asked for,
	 * so we must match that behavior.
	 */
	tips = find_tip_objects(bitmap_git, tip_objects, type);

	/*
	 * We can use the type-level bitmap for 'type' to work in whole
	 * words for the objects that are actually in the bitmapped
	 * packfile.
	 */
	for (i = 0, init_type_iterator(&it, bitmap_git, type);
	     i < to_filter->word_alloc && ewah_or_iterator_next(&mask, &it);
	     i++) {
		if (i < tips->word_alloc)
			mask &= ~tips->words[i];
		to_filter->words[i] &= ~mask;
	}

	/*
	 * Clear any objects that weren't in the packfile (and so would
	 * not have been caught by the loop above. We'll have to check
	 * them individually.
	 */
	for (i = 0; i < eindex->count; i++) {
		size_t pos = st_add(i, bitmap_num_objects_total(bitmap_git));
		if (eindex->objects[i]->type == type &&
		    bitmap_get(to_filter, pos) &&
		    !bitmap_get(tips, pos))
			bitmap_unset(to_filter, pos);
	}

	ewah_or_iterator_release(&it);
	bitmap_free(tips);
}

static void filter_bitmap_blob_none(struct bitmap_index *bitmap_git,
				    struct object_list *tip_objects,
				    struct bitmap *to_filter)
{
	filter_bitmap_exclude_type(bitmap_git, tip_objects, to_filter,
				   OBJ_BLOB);
}

static unsigned long get_size_by_pos(struct bitmap_index *bitmap_git,
				     uint32_t pos)
{
	size_t size;
	struct object_info oi = OBJECT_INFO_INIT;

	oi.sizep = &size;

	if (pos < bitmap_num_objects_total(bitmap_git)) {
		struct packed_git *pack;
		off_t ofs;

		if (bitmap_is_midx(bitmap_git)) {
			uint32_t midx_pos = pack_pos_to_midx(bitmap_git->midx, pos);
			uint32_t pack_id = nth_midxed_pack_int_id(bitmap_git->midx, midx_pos);

			pack = nth_midxed_pack(bitmap_git->midx, pack_id);
			ofs = nth_midxed_offset(bitmap_git->midx, midx_pos);
		} else {
			pack = bitmap_git->pack;
			ofs = pack_pos_to_offset(pack, pos);
		}

		if (packed_object_info(NULL, pack, ofs, &oi) < 0) {
			struct object_id oid;
			nth_bitmap_object_oid(bitmap_git, &oid,
					      pack_pos_to_index(pack, pos));
			die(_("unable to get size of %s"), oid_to_hex(&oid));
		}
	} else {
		size_t eindex_pos = pos - bitmap_num_objects_total(bitmap_git);
		struct eindex *eindex = &bitmap_git->ext_index;
		struct object *obj = eindex->objects[eindex_pos];
		if (odb_read_object_info_extended(bitmap_repo(bitmap_git)->objects, &obj->oid,
						  &oi, 0) < 0)
			die(_("unable to get size of %s"), oid_to_hex(&obj->oid));
	}

	return cast_size_t_to_ulong(size);
}

static void filter_bitmap_blob_limit(struct bitmap_index *bitmap_git,
				     struct object_list *tip_objects,
				     struct bitmap *to_filter,
				     unsigned long limit)
{
	struct eindex *eindex = &bitmap_git->ext_index;
	struct bitmap *tips;
	struct ewah_or_iterator it;
	eword_t mask;
	uint32_t i;

	tips = find_tip_objects(bitmap_git, tip_objects, OBJ_BLOB);

	for (i = 0, init_type_iterator(&it, bitmap_git, OBJ_BLOB);
	     i < to_filter->word_alloc && ewah_or_iterator_next(&mask, &it);
	     i++) {
		eword_t word = to_filter->words[i] & mask;
		unsigned offset;

		for (offset = 0; offset < BITS_IN_EWORD; offset++) {
			uint32_t pos;

			if ((word >> offset) == 0)
				break;
			offset += ewah_bit_ctz64(word >> offset);
			pos = i * BITS_IN_EWORD + offset;

			if (!bitmap_get(tips, pos) &&
			    get_size_by_pos(bitmap_git, pos) >= limit)
				bitmap_unset(to_filter, pos);
		}
	}

	for (i = 0; i < eindex->count; i++) {
		size_t pos = st_add(i, bitmap_num_objects(bitmap_git));
		if (eindex->objects[i]->type == OBJ_BLOB &&
		    bitmap_get(to_filter, pos) &&
		    !bitmap_get(tips, pos) &&
		    get_size_by_pos(bitmap_git, pos) >= limit)
			bitmap_unset(to_filter, pos);
	}

	ewah_or_iterator_release(&it);
	bitmap_free(tips);
}

static void filter_bitmap_tree_depth(struct bitmap_index *bitmap_git,
				     struct object_list *tip_objects,
				     struct bitmap *to_filter,
				     unsigned long limit)
{
	if (limit)
		BUG("filter_bitmap_tree_depth given non-zero limit");

	filter_bitmap_exclude_type(bitmap_git, tip_objects, to_filter,
				   OBJ_TREE);
	filter_bitmap_exclude_type(bitmap_git, tip_objects, to_filter,
				   OBJ_BLOB);
}

static void filter_bitmap_object_type(struct bitmap_index *bitmap_git,
				      struct object_list *tip_objects,
				      struct bitmap *to_filter,
				      enum object_type object_type)
{
	if (object_type < OBJ_COMMIT || object_type > OBJ_TAG)
		BUG("filter_bitmap_object_type given invalid object");

	if (object_type != OBJ_TAG)
		filter_bitmap_exclude_type(bitmap_git, tip_objects, to_filter, OBJ_TAG);
	if (object_type != OBJ_COMMIT)
		filter_bitmap_exclude_type(bitmap_git, tip_objects, to_filter, OBJ_COMMIT);
	if (object_type != OBJ_TREE)
		filter_bitmap_exclude_type(bitmap_git, tip_objects, to_filter, OBJ_TREE);
	if (object_type != OBJ_BLOB)
		filter_bitmap_exclude_type(bitmap_git, tip_objects, to_filter, OBJ_BLOB);
}

static int filter_bitmap(struct bitmap_index *bitmap_git,
			 struct object_list *tip_objects,
			 struct bitmap *to_filter,
			 const struct list_objects_filter_options *filter)
{
	if (!filter || filter->choice == LOFC_DISABLED)
		return 0;

	if (filter->choice == LOFC_BLOB_NONE) {
		if (bitmap_git)
			filter_bitmap_blob_none(bitmap_git, tip_objects,
						to_filter);
		return 0;
	}

	if (filter->choice == LOFC_BLOB_LIMIT) {
		if (bitmap_git)
			filter_bitmap_blob_limit(bitmap_git, tip_objects,
						 to_filter,
						 filter->blob_limit_value);
		return 0;
	}

	if (filter->choice == LOFC_TREE_DEPTH &&
	    filter->tree_exclude_depth == 0) {
		if (bitmap_git)
			filter_bitmap_tree_depth(bitmap_git, tip_objects,
						 to_filter,
						 filter->tree_exclude_depth);
		return 0;
	}

	if (filter->choice == LOFC_OBJECT_TYPE) {
		if (bitmap_git)
			filter_bitmap_object_type(bitmap_git, tip_objects,
						  to_filter,
						  filter->object_type);
		return 0;
	}

	if (filter->choice == LOFC_COMBINE) {
		int i;
		for (i = 0; i < filter->sub_nr; i++) {
			if (filter_bitmap(bitmap_git, tip_objects, to_filter,
					  &filter->sub[i]) < 0)
				return -1;
		}
		return 0;
	}

	/* filter choice not handled */
	return -1;
}

bool can_filter_bitmap(const struct list_objects_filter_options *filter)
{
	return !filter_bitmap(NULL, NULL, NULL, filter);
}

static void filter_packed_objects_from_bitmap(struct bitmap_index *bitmap_git,
					      struct bitmap *result)
{
	struct eindex *eindex = &bitmap_git->ext_index;
	uint32_t objects_nr;
	size_t i, pos;

	objects_nr = bitmap_num_objects_total(bitmap_git);
	pos = objects_nr / BITS_IN_EWORD;

	if (pos > result->word_alloc)
		pos = result->word_alloc;

	memset(result->words, 0x00, sizeof(eword_t) * pos);
	for (i = pos * BITS_IN_EWORD; i < objects_nr; i++)
		bitmap_unset(result, i);

	for (i = 0; i < eindex->count; ++i) {
		if (has_object_pack(bitmap_repo(bitmap_git),
				    &eindex->objects[i]->oid))
			bitmap_unset(result, objects_nr + i);
	}
}

int for_each_bitmapped_object(struct bitmap_index *bitmap_git,
			      const struct list_objects_filter_options *filter,
			      show_reachable_fn show_reach,
			      void *payload)
{
	const enum object_type types[] = {
		OBJ_COMMIT,
		OBJ_TREE,
		OBJ_BLOB,
		OBJ_TAG,
	};
	struct bitmap *filtered_bitmap = NULL;
	uint32_t objects_nr;
	size_t full_word_count;
	int ret;

	if (!can_filter_bitmap(filter)) {
		ret = -1;
		goto out;
	}

	objects_nr = bitmap_num_objects(bitmap_git);
	full_word_count = objects_nr / BITS_IN_EWORD;

	/* We start from the all-1 bitmap and then filter down from there. */
	filtered_bitmap = bitmap_word_alloc(full_word_count + !!(objects_nr % BITS_IN_EWORD));
	memset(filtered_bitmap->words, 0xff, full_word_count * sizeof(*filtered_bitmap->words));
	for (size_t i = full_word_count * BITS_IN_EWORD; i < objects_nr; i++)
		bitmap_set(filtered_bitmap, i);

	if (filter_bitmap(bitmap_git, NULL, filtered_bitmap, filter) < 0) {
		ret = -1;
		goto out;
	}

	for (size_t i = 0; i < ARRAY_SIZE(types); i++) {
		ret = show_objects_for_type(bitmap_git, filtered_bitmap,
					    types[i], show_reach, payload);
		if (ret)
			goto out;
	}

	ret = 0;
out:
	bitmap_free(filtered_bitmap);
	return ret;
}

struct bitmap_index *prepare_bitmap_walk(struct rev_info *revs,
					 int filter_provided_objects)
{
	unsigned int i;
	int use_boundary_traversal;

	struct object_list *wants = NULL;
	struct object_list *haves = NULL;

	struct bitmap *wants_bitmap = NULL;
	struct bitmap *haves_bitmap = NULL;

	struct bitmap_index *bitmap_git;
	struct repository *repo;

	/*
	 * We can't do pathspec limiting with bitmaps, because we don't know
	 * which commits are associated with which object changes (let alone
	 * even which objects are associated with which paths).
	 */
	if (revs->prune)
		return NULL;

	if (!can_filter_bitmap(&revs->filter))
		return NULL;

	/* try to open a bitmapped pack, but don't parse it yet
	 * because we may not need to use it */
	CALLOC_ARRAY(bitmap_git, 1);
	if (open_bitmap(revs->repo, bitmap_git) < 0)
		goto cleanup;

	for (i = 0; i < revs->pending.nr; ++i) {
		struct object *object = revs->pending.objects[i].item;

		if (object->type == OBJ_NONE)
			parse_object_or_die(revs->repo, &object->oid, NULL);

		while (object->type == OBJ_TAG) {
			struct tag *tag = (struct tag *) object;

			if (object->flags & UNINTERESTING)
				object_list_insert(object, &haves);
			else
				object_list_insert(object, &wants);

			object = parse_object_or_die(revs->repo, get_tagged_oid(tag), NULL);
			object->flags |= (tag->object.flags & UNINTERESTING);
		}

		if (object->flags & UNINTERESTING)
			object_list_insert(object, &haves);
		else
			object_list_insert(object, &wants);
	}

	use_boundary_traversal = git_env_bool(GIT_TEST_PACK_USE_BITMAP_BOUNDARY_TRAVERSAL, -1);
	if (use_boundary_traversal < 0) {
		prepare_repo_settings(revs->repo);
		use_boundary_traversal = revs->repo->settings.pack_use_bitmap_boundary_traversal;
	}

	if (!use_boundary_traversal) {
		/*
		 * if we have a HAVES list, but none of those haves is contained
		 * in the packfile that has a bitmap, we don't have anything to
		 * optimize here
		 */
		if (haves && !in_bitmapped_pack(bitmap_git, haves))
			goto cleanup;
	}

	/* if we don't want anything, we're done here */
	if (!wants)
		goto cleanup;

	/*
	 * now we're going to use bitmaps, so load the actual bitmap entries
	 * from disk. this is the point of no return; after this the rev_list
	 * becomes invalidated and we must perform the revwalk through bitmaps
	 */
	if (load_bitmap(revs->repo, bitmap_git, 0) < 0)
		goto cleanup;

	if (!use_boundary_traversal)
		object_array_clear(&revs->pending);

	repo = bitmap_repo(bitmap_git);

	if (haves) {
		if (use_boundary_traversal) {
			trace2_region_enter("pack-bitmap", "haves/boundary", repo);
			haves_bitmap = find_boundary_objects(bitmap_git, revs, haves);
			trace2_region_leave("pack-bitmap", "haves/boundary", repo);
		} else {
			trace2_region_enter("pack-bitmap", "haves/classic", repo);
			revs->ignore_missing_links = 1;
			haves_bitmap = find_objects(bitmap_git, revs, haves, NULL);
			reset_revision_walk();
			revs->ignore_missing_links = 0;
			trace2_region_leave("pack-bitmap", "haves/classic", repo);
		}

		if (!haves_bitmap)
			BUG("failed to perform bitmap walk");
	}

	if (use_boundary_traversal) {
		object_array_clear(&revs->pending);
		reset_revision_walk();
	}

	wants_bitmap = find_objects(bitmap_git, revs, wants, haves_bitmap);

	if (!wants_bitmap)
		BUG("failed to perform bitmap walk");

	if (haves_bitmap)
		bitmap_and_not(wants_bitmap, haves_bitmap);

	filter_bitmap(bitmap_git,
		      (revs->filter.choice && filter_provided_objects) ? NULL : wants,
		      wants_bitmap,
		      &revs->filter);

	if (revs->unpacked)
		filter_packed_objects_from_bitmap(bitmap_git, wants_bitmap);

	bitmap_git->result = wants_bitmap;
	bitmap_git->haves = haves_bitmap;

	object_list_free(&wants);
	object_list_free(&haves);

	trace2_data_intmax("bitmap", repo, "pseudo_merges_satisfied",
			   pseudo_merges_satisfied_nr);
	trace2_data_intmax("bitmap", repo, "pseudo_merges_cascades",
			   pseudo_merges_cascades_nr);
	trace2_data_intmax("bitmap", repo, "bitmap/hits",
			   existing_bitmaps_hits_nr);
	trace2_data_intmax("bitmap", repo, "bitmap/misses",
			   existing_bitmaps_misses_nr);
	trace2_data_intmax("bitmap", repo, "bitmap/roots_with_bitmap",
			   roots_with_bitmaps_nr);
	trace2_data_intmax("bitmap", repo, "bitmap/roots_without_bitmap",
			   roots_without_bitmaps_nr);

	return bitmap_git;

cleanup:
	free_bitmap_index(bitmap_git);
	object_list_free(&wants);
	object_list_free(&haves);
	return NULL;
}

/*
 * -1 means "stop trying further objects"; 0 means we may or may not have
 * reused, but you can keep feeding bits.
 */
static int try_partial_reuse(struct bitmap_index *bitmap_git,
			     struct bitmapped_pack *pack,
			     size_t bitmap_pos,
			     uint32_t pack_pos,
			     off_t offset,
			     struct bitmap *reuse,
			     struct pack_window **w_curs)
{
	off_t delta_obj_offset;
	enum object_type type;
	size_t size;

	if (pack_pos >= pack->p->num_objects)
		return -1; /* not actually in the pack */

	delta_obj_offset = offset;
	type = unpack_object_header(pack->p, w_curs, &offset, &size);
	if (type < 0)
		return -1; /* broken packfile, punt */

	if (type == OBJ_REF_DELTA || type == OBJ_OFS_DELTA) {
		off_t base_offset;
		uint32_t base_pos;
		uint32_t base_bitmap_pos;

		/*
		 * Find the position of the base object so we can look it up
		 * in our bitmaps. If we can't come up with an offset, or if
		 * that offset is not in the revidx, the pack is corrupt.
		 * There's nothing we can do, so just punt on this object,
		 * and the normal slow path will complain about it in
		 * more detail.
		 */
		base_offset = get_delta_base(pack->p, w_curs, &offset, type,
					     delta_obj_offset);
		if (!base_offset)
			return 0;

		offset_to_pack_pos(pack->p, base_offset, &base_pos);

		if (bitmap_is_midx(bitmap_git)) {
			/*
			 * Cross-pack deltas are rejected for now, but could
			 * theoretically be supported in the future.
			 *
			 * We would need to ensure that we're sending both
			 * halves of the delta/base pair, regardless of whether
			 * or not the two cross a pack boundary. If they do,
			 * then we must convert the delta to an REF_DELTA to
			 * refer back to the base in the other pack.
			 * */
			if (midx_pair_to_pack_pos(bitmap_git->midx,
						  pack->pack_int_id,
						  base_offset,
						  &base_bitmap_pos) < 0) {
				return 0;
			}
		} else {
			if (offset_to_pack_pos(pack->p, base_offset,
					       &base_pos) < 0)
				return 0;
			/*
			 * We assume delta dependencies always point backwards.
			 * This lets us do a single pass, and is basically
			 * always true due to the way OFS_DELTAs work. You would
			 * not typically find REF_DELTA in a bitmapped pack,
			 * since we only bitmap packs we write fresh, and
			 * OFS_DELTA is the default). But let's double check to
			 * make sure the pack wasn't written with odd
			 * parameters.
			 */
			if (base_pos >= pack_pos)
				return 0;
			base_bitmap_pos = pack->bitmap_pos + base_pos;
		}

		/*
		 * And finally, if we're not sending the base as part of our
		 * reuse chunk, then don't send this object either. The base
		 * would come after us, along with other objects not
		 * necessarily in the pack, which means we'd need to convert
		 * to REF_DELTA on the fly. Better to just let the normal
		 * object_entry code path handle it.
		 */
		if (!bitmap_get(reuse, base_bitmap_pos))
			return 0;
	}

	/*
	 * If we got here, then the object is OK to reuse. Mark it.
	 */
	bitmap_set(reuse, bitmap_pos);
	return 0;
}

static void reuse_partial_packfile_from_bitmap_1(struct bitmap_index *bitmap_git,
						 struct bitmapped_pack *pack,
						 struct bitmap *reuse)
{
	struct bitmap *result = bitmap_git->result;
	struct pack_window *w_curs = NULL;
	size_t pos = pack->bitmap_pos / BITS_IN_EWORD;

	if (!pack->bitmap_pos) {
		/*
		 * If we're processing the first (in the case of a MIDX, the
		 * preferred pack) or the only (in the case of single-pack
		 * bitmaps) pack, then we can reuse whole words at a time.
		 *
		 * This is because we know that any deltas in this range *must*
		 * have their bases chosen from the same pack, since:
		 *
		 * - In the single pack case, there is no other pack to choose
		 *   them from.
		 *
		 * - In the MIDX case, the first pack is the preferred pack, so
		 *   all ties are broken in favor of that pack (i.e. the one
		 *   we're currently processing). So any duplicate bases will be
		 *   resolved in favor of the pack we're processing.
		 */
		while (pos < result->word_alloc &&
		       pos < pack->bitmap_nr / BITS_IN_EWORD &&
		       result->words[pos] == (eword_t)~0)
			pos++;
		memset(reuse->words, 0xFF, pos * sizeof(eword_t));
	}

	for (; pos < result->word_alloc; pos++) {
		eword_t word = result->words[pos];
		size_t offset;

		for (offset = 0; offset < BITS_IN_EWORD; offset++) {
			size_t bit_pos;
			uint32_t pack_pos;
			off_t ofs;

			if (word >> offset == 0)
				break;

			offset += ewah_bit_ctz64(word >> offset);

			bit_pos = pos * BITS_IN_EWORD + offset;
			if (bit_pos < pack->bitmap_pos)
				continue;
			if (bit_pos >= pack->bitmap_pos + pack->bitmap_nr)
				goto done;

			if (bitmap_is_midx(bitmap_git)) {
				uint32_t midx_pos;

				midx_pos = pack_pos_to_midx(bitmap_git->midx, bit_pos);
				ofs = nth_midxed_offset(bitmap_git->midx, midx_pos);

				if (offset_to_pack_pos(pack->p, ofs, &pack_pos) < 0)
					BUG("could not find object in pack %s "
					    "at offset %"PRIuMAX" in MIDX",
					    pack_basename(pack->p), (uintmax_t)ofs);
			} else {
				pack_pos = cast_size_t_to_uint32_t(st_sub(bit_pos, pack->bitmap_pos));
				if (pack_pos >= pack->p->num_objects)
					BUG("advanced beyond the end of pack %s (%"PRIuMAX" > %"PRIu32")",
					    pack_basename(pack->p), (uintmax_t)pack_pos,
					    pack->p->num_objects);

				ofs = pack_pos_to_offset(pack->p, pack_pos);
			}

			if (try_partial_reuse(bitmap_git, pack, bit_pos,
					      pack_pos, ofs, reuse, &w_curs) < 0) {
				/*
				 * try_partial_reuse indicated we couldn't reuse
				 * any bits, so there is no point in trying more
				 * bits in the current word, or any other words
				 * in result.
				 *
				 * Jump out of both loops to avoid future
				 * unnecessary calls to try_partial_reuse.
				 */
				goto done;
			}
		}
	}

done:
	unuse_pack(&w_curs);
}

static int bitmapped_pack_cmp(const void *va, const void *vb)
{
	const struct bitmapped_pack *a = va;
	const struct bitmapped_pack *b = vb;

	if (a->bitmap_pos < b->bitmap_pos)
		return -1;
	if (a->bitmap_pos > b->bitmap_pos)
		return 1;
	return 0;
}

void reuse_partial_packfile_from_bitmap(struct bitmap_index *bitmap_git,
					struct bitmapped_pack **packs_out,
					size_t *packs_nr_out,
					struct bitmap **reuse_out,
					int multi_pack_reuse)
{
	struct repository *r = bitmap_repo(bitmap_git);
	struct bitmapped_pack *packs = NULL;
	struct bitmap *result = bitmap_git->result;
	struct bitmap *reuse;
	size_t i;
	size_t packs_nr = 0, packs_alloc = 0;
	size_t word_alloc;
	uint32_t objects_nr = 0;

	assert(result);

	load_reverse_index(r, bitmap_git);

	if (!bitmap_is_midx(bitmap_git) || !bitmap_git->midx->chunk_bitmapped_packs)
		multi_pack_reuse = 0;

	if (multi_pack_reuse) {
		struct multi_pack_index *m = bitmap_git->midx;
		for (i = 0; i < m->num_packs + m->num_packs_in_base; i++) {
			struct bitmapped_pack pack;
			if (nth_bitmapped_pack(bitmap_git->midx, &pack, i) < 0) {
				warning(_("unable to load pack: '%s', disabling pack-reuse"),
					bitmap_git->midx->pack_names[i]);
				free(packs);
				return;
			}

			if (!pack.bitmap_nr)
				continue;

			if (is_pack_valid(pack.p)) {
				ALLOC_GROW(packs, packs_nr + 1, packs_alloc);
				memcpy(&packs[packs_nr++], &pack, sizeof(pack));
			}

			objects_nr += pack.p->num_objects;
		}

		QSORT(packs, packs_nr, bitmapped_pack_cmp);
	} else {
		struct packed_git *pack;
		uint32_t pack_int_id;

		if (bitmap_is_midx(bitmap_git)) {
			struct multi_pack_index *m = bitmap_git->midx;
			uint32_t preferred_pack_pos;

			while (m->base_midx)
				m = m->base_midx;

			if (midx_preferred_pack(m, &preferred_pack_pos) < 0) {
				warning(_("unable to compute preferred pack, disabling pack-reuse"));
				return;
			}

			pack = nth_midxed_pack(m, preferred_pack_pos);
			pack_int_id = preferred_pack_pos;
		} else {
			pack = bitmap_git->pack;
			/*
			 * Any value for 'pack_int_id' will do here. When we
			 * process the pack via try_partial_reuse(), we won't
			 * use the `pack_int_id` field since we have a non-MIDX
			 * bitmap.
			 *
			 * Use '-1' as a sentinel value to make it clear
			 * that we do not expect to read this field.
			 */
			pack_int_id = -1;
		}

		if (is_pack_valid(pack)) {
			ALLOC_GROW(packs, packs_nr + 1, packs_alloc);
			packs[packs_nr].p = pack;
			packs[packs_nr].pack_int_id = pack_int_id;
			packs[packs_nr].bitmap_nr = pack->num_objects;
			packs[packs_nr].bitmap_pos = 0;
			packs[packs_nr].from_midx = bitmap_git->midx;
			packs_nr++;
		}

		objects_nr = pack->num_objects;
	}

	if (!packs_nr)
		return;

	word_alloc = objects_nr / BITS_IN_EWORD;
	if (objects_nr % BITS_IN_EWORD)
		word_alloc++;
	reuse = bitmap_word_alloc(word_alloc);

	for (i = 0; i < packs_nr; i++)
		reuse_partial_packfile_from_bitmap_1(bitmap_git, &packs[i], reuse);

	if (bitmap_is_empty(reuse)) {
		free(packs);
		bitmap_free(reuse);
		return;
	}

	/*
	 * Drop any reused objects from the result, since they will not
	 * need to be handled separately.
	 */
	bitmap_and_not(result, reuse);
	*packs_out = packs;
	*packs_nr_out = packs_nr;
	*reuse_out = reuse;
}

int bitmap_walk_contains(struct bitmap_index *bitmap_git,
			 struct bitmap *bitmap, const struct object_id *oid)
{
	int idx;

	if (!bitmap)
		return 0;

	idx = bitmap_position(bitmap_git, oid);
	return idx >= 0 && bitmap_get(bitmap, idx);
}

void traverse_bitmap_commit_list(struct bitmap_index *bitmap_git,
				 struct rev_info *revs,
				 show_reachable_fn show_reachable)
{
	assert(bitmap_git->result);

	show_objects_for_type(bitmap_git, bitmap_git->result,
			      OBJ_COMMIT, show_reachable, NULL);
	if (revs->tree_objects)
		show_objects_for_type(bitmap_git, bitmap_git->result,
				      OBJ_TREE, show_reachable, NULL);
	if (revs->blob_objects)
		show_objects_for_type(bitmap_git, bitmap_git->result,
				      OBJ_BLOB, show_reachable, NULL);
	if (revs->tag_objects)
		show_objects_for_type(bitmap_git, bitmap_git->result,
				      OBJ_TAG, show_reachable, NULL);

	show_extended_objects(bitmap_git, revs, show_reachable);
}

static uint32_t count_object_type(struct bitmap_index *bitmap_git,
				  enum object_type type)
{
	struct bitmap *objects = bitmap_git->result;
	struct eindex *eindex = &bitmap_git->ext_index;

	uint32_t i = 0, count = 0;
	struct ewah_or_iterator it;
	eword_t filter;

	init_type_iterator(&it, bitmap_git, type);

	while (i < objects->word_alloc && ewah_or_iterator_next(&filter, &it)) {
		eword_t word = objects->words[i++] & filter;
		count += ewah_bit_popcount64(word);
	}

	for (i = 0; i < eindex->count; ++i) {
		if (eindex->objects[i]->type == type &&
		    bitmap_get(objects,
			       st_add(bitmap_num_objects_total(bitmap_git), i)))
			count++;
	}

	ewah_or_iterator_release(&it);

	return count;
}

void count_bitmap_commit_list(struct bitmap_index *bitmap_git,
			      uint32_t *commits, uint32_t *trees,
			      uint32_t *blobs, uint32_t *tags)
{
	assert(bitmap_git->result);

	if (commits)
		*commits = count_object_type(bitmap_git, OBJ_COMMIT);

	if (trees)
		*trees = count_object_type(bitmap_git, OBJ_TREE);

	if (blobs)
		*blobs = count_object_type(bitmap_git, OBJ_BLOB);

	if (tags)
		*tags = count_object_type(bitmap_git, OBJ_TAG);
}

struct bitmap_test_data {
	struct bitmap_index *bitmap_git;
	struct bitmap *base;
	struct bitmap *commits;
	struct bitmap *trees;
	struct bitmap *blobs;
	struct bitmap *tags;
	struct progress *prg;
	size_t seen;

	struct bitmap_test_data *base_tdata;
};

static void test_bitmap_type(struct bitmap_test_data *tdata,
			     struct object *obj, int pos)
{
	enum object_type bitmap_type = OBJ_NONE;
	int bitmaps_nr = 0;

	if (bitmap_is_midx(tdata->bitmap_git)) {
		while (pos < tdata->bitmap_git->midx->num_objects_in_base)
			tdata = tdata->base_tdata;
	}

	if (bitmap_get(tdata->commits, pos)) {
		bitmap_type = OBJ_COMMIT;
		bitmaps_nr++;
	}
	if (bitmap_get(tdata->trees, pos)) {
		bitmap_type = OBJ_TREE;
		bitmaps_nr++;
	}
	if (bitmap_get(tdata->blobs, pos)) {
		bitmap_type = OBJ_BLOB;
		bitmaps_nr++;
	}
	if (bitmap_get(tdata->tags, pos)) {
		bitmap_type = OBJ_TAG;
		bitmaps_nr++;
	}

	if (bitmap_type == OBJ_NONE)
		die(_("object '%s' not found in type bitmaps"),
		    oid_to_hex(&obj->oid));

	if (bitmaps_nr > 1)
		die(_("object '%s' does not have a unique type"),
		    oid_to_hex(&obj->oid));

	if (bitmap_type != obj->type)
		die(_("object '%s': real type '%s', expected: '%s'"),
		    oid_to_hex(&obj->oid),
		    type_name(obj->type),
		    type_name(bitmap_type));
}

static void test_show_object(struct object *object,
			     const char *name UNUSED,
			     void *data)
{
	struct bitmap_test_data *tdata = data;
	int bitmap_pos;

	bitmap_pos = bitmap_position(tdata->bitmap_git, &object->oid);
	if (bitmap_pos < 0)
		die(_("object not in bitmap: '%s'"), oid_to_hex(&object->oid));
	test_bitmap_type(tdata, object, bitmap_pos);

	bitmap_set(tdata->base, bitmap_pos);
	display_progress(tdata->prg, ++tdata->seen);
}

static void test_show_commit(struct commit *commit, void *data)
{
	struct bitmap_test_data *tdata = data;
	int bitmap_pos;

	bitmap_pos = bitmap_position(tdata->bitmap_git,
				     &commit->object.oid);
	if (bitmap_pos < 0)
		die(_("object not in bitmap: '%s'"), oid_to_hex(&commit->object.oid));
	test_bitmap_type(tdata, &commit->object, bitmap_pos);

	bitmap_set(tdata->base, bitmap_pos);
	display_progress(tdata->prg, ++tdata->seen);
}

static uint32_t bitmap_total_entry_count(struct bitmap_index *bitmap_git)
{
	uint32_t total = 0;
	do {
		total = st_add(total, bitmap_git->entry_count);
		bitmap_git = bitmap_git->base;
	} while (bitmap_git);

	return total;
}

static void bitmap_test_data_prepare(struct bitmap_test_data *tdata,
				     struct bitmap_index *bitmap_git)
{
	memset(tdata, 0, sizeof(struct bitmap_test_data));

	tdata->bitmap_git = bitmap_git;
	tdata->base = bitmap_new();
	tdata->commits = ewah_to_bitmap(bitmap_git->commits);
	tdata->trees = ewah_to_bitmap(bitmap_git->trees);
	tdata->blobs = ewah_to_bitmap(bitmap_git->blobs);
	tdata->tags = ewah_to_bitmap(bitmap_git->tags);

	if (bitmap_git->base) {
		tdata->base_tdata = xmalloc(sizeof(struct bitmap_test_data));
		bitmap_test_data_prepare(tdata->base_tdata, bitmap_git->base);
	}
}

static void bitmap_test_data_release(struct bitmap_test_data *tdata)
{
	if (!tdata)
		return;

	bitmap_test_data_release(tdata->base_tdata);
	free(tdata->base_tdata);

	bitmap_free(tdata->base);
	bitmap_free(tdata->commits);
	bitmap_free(tdata->trees);
	bitmap_free(tdata->blobs);
	bitmap_free(tdata->tags);
}

void test_bitmap_walk(struct rev_info *revs)
{
	struct object *root;
	struct bitmap *result = NULL;
	size_t result_popcnt;
	struct bitmap_test_data tdata;
	struct bitmap_index *bitmap_git, *found;
	struct ewah_bitmap *bm;

	if (!(bitmap_git = prepare_bitmap_git(revs->repo)))
		die(_("failed to load bitmap indexes"));

	if (revs->pending.nr != 1)
		die(_("you must specify exactly one commit to test"));

	fprintf_ln(stderr, "Bitmap v%d test (%d entries%s, %d total)",
		bitmap_git->version,
		bitmap_git->entry_count,
		bitmap_git->table_lookup ? "" : " loaded",
		bitmap_total_entry_count(bitmap_git));

	root = revs->pending.objects[0].item;
	bm = find_bitmap_for_commit(bitmap_git, (struct commit *)root, &found);

	if (bm) {
		fprintf_ln(stderr, "Found bitmap for '%s'. %d bits / %08x checksum",
			oid_to_hex(&root->oid),
			(int)bm->bit_size, ewah_checksum(bm));

		if (bitmap_is_midx(found))
			fprintf_ln(stderr, "Located via MIDX '%s'.",
				   midx_get_checksum_hex(found->midx));
		else
			fprintf_ln(stderr, "Located via pack '%s'.",
				   hash_to_hex_algop(found->pack->hash,
						     revs->repo->hash_algo));

		result = ewah_to_bitmap(bm);
	}

	if (!result)
		die(_("commit '%s' doesn't have an indexed bitmap"), oid_to_hex(&root->oid));

	revs->tag_objects = 1;
	revs->tree_objects = 1;
	revs->blob_objects = 1;

	result_popcnt = bitmap_popcount(result);

	if (prepare_revision_walk(revs))
		die(_("revision walk setup failed"));

	bitmap_test_data_prepare(&tdata, bitmap_git);
	tdata.prg = start_progress(revs->repo,
				   "Verifying bitmap entries",
				   result_popcnt);

	traverse_commit_list(revs, &test_show_commit, &test_show_object, &tdata);

	stop_progress(&tdata.prg);

	if (bitmap_equals(result, tdata.base))
		fprintf_ln(stderr, "OK!");
	else
		die(_("mismatch in bitmap results"));

	bitmap_free(result);
	bitmap_test_data_release(&tdata);
	free_bitmap_index(bitmap_git);
}

int test_bitmap_commits(struct repository *r)
{
	struct object_id oid;
	MAYBE_UNUSED void *value;
	struct bitmap_index *bitmap_git = prepare_bitmap_git(r);

	if (!bitmap_git)
		die(_("failed to load bitmap indexes"));

	/*
	 * Since this function needs to print the bitmapped
	 * commits, bypass the commit lookup table (if one exists)
	 * by forcing the bitmap to eagerly load its entries.
	 */
	if (bitmap_git->table_lookup) {
		if (load_bitmap_entries_v1(bitmap_git) < 0)
			die(_("failed to load bitmap indexes"));
	}

	kh_foreach(bitmap_git->bitmaps, oid, value, {
		printf_ln("%s", oid_to_hex(&oid));
	});

	free_bitmap_index(bitmap_git);

	return 0;
}

int test_bitmap_commits_with_offset(struct repository *r)
{
	struct object_id oid;
	struct stored_bitmap *stored;
	struct bitmap_index *bitmap_git;
	size_t commit_idx_pos_map_pos, xor_offset_map_pos, flag_map_pos,
		ewah_bitmap_map_pos;

	bitmap_git = prepare_bitmap_git(r);
	if (!bitmap_git)
		die(_("failed to load bitmap indexes"));

	/*
	 * Since this function needs to know the position of each individual
	 * bitmap, bypass the commit lookup table (if one exists) by forcing
	 * the bitmap to eagerly load its entries.
	 */
	if (bitmap_git->table_lookup) {
		if (load_bitmap_entries_v1(bitmap_git) < 0)
			die(_("failed to load bitmap indexes"));
	}

	kh_foreach (bitmap_git->bitmaps, oid, stored, {
		commit_idx_pos_map_pos = stored->map_pos;
		xor_offset_map_pos = stored->map_pos + sizeof(uint32_t);
		flag_map_pos = xor_offset_map_pos + sizeof(uint8_t);
		ewah_bitmap_map_pos = flag_map_pos + sizeof(uint8_t);

		printf_ln("%s %"PRIuMAX" %"PRIuMAX" %"PRIuMAX" %"PRIuMAX,
			  oid_to_hex(&oid),
			  (uintmax_t)commit_idx_pos_map_pos,
			  (uintmax_t)xor_offset_map_pos,
			  (uintmax_t)flag_map_pos,
			  (uintmax_t)ewah_bitmap_map_pos);
	})
		;

	free_bitmap_index(bitmap_git);

	return 0;
}

int test_bitmap_hashes(struct repository *r)
{
	struct bitmap_index *bitmap_git = prepare_bitmap_git(r);
	struct object_id oid;
	uint32_t i, index_pos;

	if (!bitmap_git || !bitmap_git->hashes)
		goto cleanup;

	for (i = 0; i < bitmap_num_objects(bitmap_git); i++) {
		if (bitmap_is_midx(bitmap_git))
			index_pos = pack_pos_to_midx(bitmap_git->midx, i);
		else
			index_pos = pack_pos_to_index(bitmap_git->pack, i);

		nth_bitmap_object_oid(bitmap_git, &oid, index_pos);

		printf_ln("%s %"PRIu32"",
		       oid_to_hex(&oid), get_be32(bitmap_git->hashes + index_pos));
	}

cleanup:
	free_bitmap_index(bitmap_git);

	return 0;
}

static void bit_pos_to_object_id(struct bitmap_index *bitmap_git,
				 uint32_t bit_pos,
				 struct object_id *oid)
{
	uint32_t index_pos;

	if (bitmap_is_midx(bitmap_git))
		index_pos = pack_pos_to_midx(bitmap_git->midx, bit_pos);
	else
		index_pos = pack_pos_to_index(bitmap_git->pack, bit_pos);

	nth_bitmap_object_oid(bitmap_git, oid, index_pos);
}

int test_bitmap_pseudo_merges(struct repository *r)
{
	struct bitmap_index *bitmap_git;
	uint32_t i;

	bitmap_git = prepare_bitmap_git(r);
	if (!bitmap_git || !bitmap_git->pseudo_merges.nr)
		goto cleanup;

	for (i = 0; i < bitmap_git->pseudo_merges.nr; i++) {
		struct pseudo_merge *merge;
		struct ewah_bitmap *commits_bitmap, *merge_bitmap;

		merge = use_pseudo_merge(&bitmap_git->pseudo_merges,
					 &bitmap_git->pseudo_merges.v[i]);
		commits_bitmap = merge->commits;
		merge_bitmap = pseudo_merge_bitmap(&bitmap_git->pseudo_merges,
						   merge);

		printf("at=%"PRIuMAX", commits=%"PRIuMAX", objects=%"PRIuMAX"\n",
		       (uintmax_t)merge->at,
		       (uintmax_t)ewah_bitmap_popcount(commits_bitmap),
		       (uintmax_t)ewah_bitmap_popcount(merge_bitmap));
	}

cleanup:
	free_bitmap_index(bitmap_git);
	return 0;
}

static void dump_ewah_object_ids(struct bitmap_index *bitmap_git,
				 struct ewah_bitmap *bitmap)

{
	struct ewah_iterator it;
	eword_t word;
	uint32_t pos = 0;

	ewah_iterator_init(&it, bitmap);

	while (ewah_iterator_next(&word, &it)) {
		struct object_id oid;
		uint32_t offset;

		for (offset = 0; offset < BITS_IN_EWORD; offset++) {
			if (!(word >> offset))
				break;

			offset += ewah_bit_ctz64(word >> offset);

			bit_pos_to_object_id(bitmap_git, pos + offset, &oid);
			printf("%s\n", oid_to_hex(&oid));
		}
		pos += BITS_IN_EWORD;
	}
}

int test_bitmap_pseudo_merge_commits(struct repository *r, uint32_t n)
{
	struct bitmap_index *bitmap_git;
	struct pseudo_merge *merge;
	int ret = 0;

	bitmap_git = prepare_bitmap_git(r);
	if (!bitmap_git || !bitmap_git->pseudo_merges.nr)
		goto cleanup;

	if (n >= bitmap_git->pseudo_merges.nr) {
		ret = error(_("pseudo-merge index out of range "
			      "(%"PRIu32" >= %"PRIuMAX")"),
			    n, (uintmax_t)bitmap_git->pseudo_merges.nr);
		goto cleanup;
	}

	merge = use_pseudo_merge(&bitmap_git->pseudo_merges,
				 &bitmap_git->pseudo_merges.v[n]);
	dump_ewah_object_ids(bitmap_git, merge->commits);

cleanup:
	free_bitmap_index(bitmap_git);
	return ret;
}

int test_bitmap_pseudo_merge_objects(struct repository *r, uint32_t n)
{
	struct bitmap_index *bitmap_git;
	struct pseudo_merge *merge;
	int ret = 0;

	bitmap_git = prepare_bitmap_git(r);
	if (!bitmap_git || !bitmap_git->pseudo_merges.nr)
		goto cleanup;

	if (n >= bitmap_git->pseudo_merges.nr) {
		ret = error(_("pseudo-merge index out of range "
			      "(%"PRIu32" >= %"PRIuMAX")"),
			    n, (uintmax_t)bitmap_git->pseudo_merges.nr);
		goto cleanup;
	}

	merge = use_pseudo_merge(&bitmap_git->pseudo_merges,
				 &bitmap_git->pseudo_merges.v[n]);

	dump_ewah_object_ids(bitmap_git,
			     pseudo_merge_bitmap(&bitmap_git->pseudo_merges,
						 merge));

cleanup:
	free_bitmap_index(bitmap_git);
	return ret;
}

int rebuild_bitmap(const uint32_t *reposition,
		   struct ewah_bitmap *source,
		   struct bitmap *dest)
{
	uint32_t pos = 0;
	struct ewah_iterator it;
	eword_t word;

	ewah_iterator_init(&it, source);

	while (ewah_iterator_next(&word, &it)) {
		uint32_t offset, bit_pos;

		for (offset = 0; offset < BITS_IN_EWORD; ++offset) {
			if ((word >> offset) == 0)
				break;

			offset += ewah_bit_ctz64(word >> offset);

			bit_pos = reposition[pos + offset];
			if (bit_pos > 0)
				bitmap_set(dest, bit_pos - 1);
			else /* can't reuse, we don't have the object */
				return -1;
		}

		pos += BITS_IN_EWORD;
	}
	return 0;
}

uint32_t *create_bitmap_mapping(struct bitmap_index *bitmap_git,
				struct packing_data *mapping)
{
	struct repository *r = bitmap_repo(bitmap_git);
	uint32_t i, num_objects;
	uint32_t *reposition;

	if (!bitmap_is_midx(bitmap_git))
		load_reverse_index(r, bitmap_git);
	else if (load_midx_revindex(bitmap_git->midx))
		BUG("rebuild_existing_bitmaps: missing required rev-cache "
		    "extension");

	num_objects = bitmap_num_objects_total(bitmap_git);
	CALLOC_ARRAY(reposition, num_objects);

	for (i = 0; i < num_objects; ++i) {
		struct object_id oid;
		struct object_entry *oe;
		uint32_t index_pos;

		if (bitmap_is_midx(bitmap_git))
			index_pos = pack_pos_to_midx(bitmap_git->midx, i);
		else
			index_pos = pack_pos_to_index(bitmap_git->pack, i);
		nth_bitmap_object_oid(bitmap_git, &oid, index_pos);
		oe = packlist_find(mapping, &oid);

		if (oe) {
			reposition[i] = oe_in_pack_pos(mapping, oe) + 1;
			if (!oe->hash)
				oe->hash = bitmap_name_hash(bitmap_git, index_pos);
		}
	}

	return reposition;
}

void free_bitmap_index(struct bitmap_index *b)
{
	if (!b)
		return;

	if (b->map)
		munmap(b->map, b->map_size);
	ewah_pool_free(b->commits);
	ewah_pool_free(b->trees);
	ewah_pool_free(b->blobs);
	ewah_pool_free(b->tags);
	free(b->commits_all);
	free(b->trees_all);
	free(b->blobs_all);
	free(b->tags_all);
	if (b->bitmaps) {
		struct stored_bitmap *sb;
		kh_foreach_value(b->bitmaps, sb, {
			ewah_pool_free(sb->root);
			free(sb);
		});
	}
	kh_destroy_oid_map(b->bitmaps);
	free(b->ext_index.objects);
	free(b->ext_index.hashes);
	kh_destroy_oid_pos(b->ext_index.positions);
	bitmap_free(b->result);
	bitmap_free(b->haves);
	if (bitmap_is_midx(b)) {
		/*
		 * Multi-pack bitmaps need to have resources associated with
		 * their on-disk reverse indexes unmapped so that stale .rev and
		 * .bitmap files can be removed.
		 *
		 * Unlike pack-based bitmaps, multi-pack bitmaps can be read and
		 * written in the same 'git multi-pack-index write --bitmap'
		 * process. Close resources so they can be removed safely on
		 * platforms like Windows.
		 */
		close_midx_revindex(b->midx);
	}
	free_pseudo_merge_map(&b->pseudo_merges);
	free_bitmap_index(b->base);
	free(b);
}

int bitmap_has_oid_in_uninteresting(struct bitmap_index *bitmap_git,
				    const struct object_id *oid)
{
	return bitmap_git &&
		bitmap_walk_contains(bitmap_git, bitmap_git->haves, oid);
}

static off_t get_disk_usage_for_type(struct bitmap_index *bitmap_git,
				     enum object_type object_type)
{
	struct bitmap *result = bitmap_git->result;
	off_t total = 0;
	struct ewah_or_iterator it;
	eword_t filter;
	size_t i;

	init_type_iterator(&it, bitmap_git, object_type);
	for (i = 0; i < result->word_alloc &&
			ewah_or_iterator_next(&filter, &it); i++) {
		eword_t word = result->words[i] & filter;
		size_t base = (i * BITS_IN_EWORD);
		unsigned offset;

		if (!word)
			continue;

		for (offset = 0; offset < BITS_IN_EWORD; offset++) {
			if ((word >> offset) == 0)
				break;

			offset += ewah_bit_ctz64(word >> offset);

			if (bitmap_is_midx(bitmap_git)) {
				uint32_t pack_pos;
				uint32_t midx_pos = pack_pos_to_midx(bitmap_git->midx, base + offset);
				off_t offset = nth_midxed_offset(bitmap_git->midx, midx_pos);

				uint32_t pack_id = nth_midxed_pack_int_id(bitmap_git->midx, midx_pos);
				struct packed_git *pack = nth_midxed_pack(bitmap_git->midx, pack_id);

				if (offset_to_pack_pos(pack, offset, &pack_pos) < 0) {
					struct object_id oid;
					nth_midxed_object_oid(&oid, bitmap_git->midx, midx_pos);

					die(_("could not find '%s' in pack '%s' at offset %"PRIuMAX),
					    oid_to_hex(&oid),
					    pack->pack_name,
					    (uintmax_t)offset);
				}

				total += pack_pos_to_offset(pack, pack_pos + 1) - offset;
			} else {
				size_t pos = base + offset;
				total += pack_pos_to_offset(bitmap_git->pack, pos + 1) -
					 pack_pos_to_offset(bitmap_git->pack, pos);
			}
		}
	}

	ewah_or_iterator_release(&it);

	return total;
}

static off_t get_disk_usage_for_extended(struct bitmap_index *bitmap_git)
{
	struct bitmap *result = bitmap_git->result;
	struct eindex *eindex = &bitmap_git->ext_index;
	off_t total = 0;
	struct object_info oi = OBJECT_INFO_INIT;
	off_t object_size;
	size_t i;

	oi.disk_sizep = &object_size;

	for (i = 0; i < eindex->count; i++) {
		struct object *obj = eindex->objects[i];

		if (!bitmap_get(result,
				st_add(bitmap_num_objects_total(bitmap_git),
				       i)))
			continue;

		if (odb_read_object_info_extended(bitmap_repo(bitmap_git)->objects,
						  &obj->oid, &oi, 0) < 0)
			die(_("unable to get disk usage of '%s'"),
			    oid_to_hex(&obj->oid));

		total += object_size;
	}
	return total;
}

off_t get_disk_usage_from_bitmap(struct bitmap_index *bitmap_git,
				 struct rev_info *revs)
{
	off_t total = 0;

	total += get_disk_usage_for_type(bitmap_git, OBJ_COMMIT);
	if (revs->tree_objects)
		total += get_disk_usage_for_type(bitmap_git, OBJ_TREE);
	if (revs->blob_objects)
		total += get_disk_usage_for_type(bitmap_git, OBJ_BLOB);
	if (revs->tag_objects)
		total += get_disk_usage_for_type(bitmap_git, OBJ_TAG);

	total += get_disk_usage_for_extended(bitmap_git);

	return total;
}

int bitmap_is_midx(struct bitmap_index *bitmap_git)
{
	return !!bitmap_git->midx;
}

static const struct string_list *bitmap_preferred_tips(struct repository *r)
{
	const struct string_list *dest;

	if (!repo_config_get_string_multi(r, "pack.preferbitmaptips", &dest))
		return dest;
	return NULL;
}

void for_each_preferred_bitmap_tip(struct repository *repo,
				   refs_for_each_cb cb, void *cb_data)
{
	struct refs_for_each_ref_options opts = { 0 };
	struct string_list_item *item;
	const struct string_list *preferred_tips;
	struct strbuf buf = STRBUF_INIT;

	preferred_tips = bitmap_preferred_tips(repo);
	if (!preferred_tips)
		return;

	for_each_string_list_item(item, preferred_tips) {
		opts.prefix = item->string;

		if (!ends_with(opts.prefix, "/")) {
			strbuf_reset(&buf);
			strbuf_addf(&buf, "%s/", opts.prefix);
			opts.prefix = buf.buf;
		}

		refs_for_each_ref_ext(get_main_ref_store(repo),
				      cb, cb_data, &opts);
	}

	strbuf_release(&buf);
}

int bitmap_is_preferred_refname(struct repository *r, const char *refname)
{
	const struct string_list *preferred_tips = bitmap_preferred_tips(r);
	struct string_list_item *item;

	if (!preferred_tips)
		return 0;

	for_each_string_list_item(item, preferred_tips) {
		if (starts_with(refname, item->string))
			return 1;
	}

	return 0;
}

static int verify_bitmap_file(const struct git_hash_algo *algop,
			      const char *name)
{
	struct stat st;
	unsigned char *data;
	int fd = git_open(name);
	int res = 0;

	/* It is OK to not have the file. */
	if (fd < 0 || fstat(fd, &st)) {
		if (fd >= 0)
			close(fd);
		return 0;
	}

	data = xmmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
	close(fd);
	if (!hashfile_checksum_valid(algop, data, st.st_size))
		res = error(_("bitmap file '%s' has invalid checksum"),
			    name);

	munmap(data, st.st_size);
	return res;
}

int verify_bitmap_files(struct repository *r)
{
	struct odb_source *source;
	struct packed_git *p;
	int res = 0;

	odb_prepare_alternates(r->objects);
	for (source = r->objects->sources; source; source = source->next) {
		struct odb_source_files *files = odb_source_files_downcast(source);
		struct multi_pack_index *m = get_multi_pack_index(files->packed);
		char *midx_bitmap_name;

		if (!m)
			continue;

		midx_bitmap_name = midx_bitmap_filename(m);
		res |= verify_bitmap_file(r->hash_algo, midx_bitmap_name);
		free(midx_bitmap_name);
	}

	repo_for_each_pack(r, p) {
		char *pack_bitmap_name = pack_bitmap_filename(p);
		res |= verify_bitmap_file(r->hash_algo, pack_bitmap_name);
		free(pack_bitmap_name);
	}

	return res;
}
