#define DISABLE_SIGN_COMPARE_WARNINGS

#include "git-compat-util.h"
#include "environment.h"
#include "gettext.h"
#include "hex.h"
#include "odb.h"
#include "commit.h"
#include "diff.h"
#include "revision.h"
#include "progress.h"
#include "pack.h"
#include "pack-bitmap.h"
#include "hash-lookup.h"
#include "pack-objects.h"
#include "path.h"
#include "commit-reach.h"
#include "prio-queue.h"
#include "trace2.h"
#include "tree.h"
#include "tree-walk.h"
#include "pseudo-merge.h"
#include "oid-array.h"
#include "config.h"
#include "alloc.h"
#include "refs.h"
#include "strmap.h"
#include "midx.h"
#include "pack-revindex.h"

struct bitmapped_commit {
	struct commit *commit;
	struct ewah_bitmap *bitmap;
	struct ewah_bitmap *write_as;
	struct ewah_bitmap *pseudo_merge_parents;
	int flags;
	int xor_offset;
	uint32_t commit_pos;
	unsigned pseudo_merge : 1;
};

static inline int bitmap_writer_nr_selected_commits(struct bitmap_writer *writer)
{
	return writer->selected_nr - writer->pseudo_merges_nr;
}

void bitmap_writer_init(struct bitmap_writer *writer, struct repository *r,
			struct packing_data *pdata,
			struct multi_pack_index *midx)
{
	memset(writer, 0, sizeof(struct bitmap_writer));
	if (writer->bitmaps)
		BUG("bitmap writer already initialized");
	writer->repo = r;
	writer->bitmaps = kh_init_oid_map();
	writer->pseudo_merge_commits = kh_init_oid_map();
	writer->to_pack = pdata;
	writer->midx = midx;

	string_list_init_dup(&writer->pseudo_merge_groups);

	load_pseudo_merges_from_config(r, &writer->pseudo_merge_groups);
}

static void free_pseudo_merge_commit_idx(struct pseudo_merge_commit_idx *idx)
{
	if (!idx)
		return;
	free(idx->pseudo_merge);
	free(idx);
}

static void pseudo_merge_group_release_cb(void *payload, const char *name UNUSED)
{
	pseudo_merge_group_release(payload);
	free(payload);
}

void bitmap_writer_free(struct bitmap_writer *writer)
{
	uint32_t i;
	struct pseudo_merge_commit_idx *idx;

	if (!writer)
		return;

	ewah_free(writer->commits);
	ewah_free(writer->trees);
	ewah_free(writer->blobs);
	ewah_free(writer->tags);

	kh_destroy_oid_map(writer->bitmaps);
	free(writer->pos_cache);

	kh_foreach_value(writer->pseudo_merge_commits, idx,
			 free_pseudo_merge_commit_idx(idx));
	kh_destroy_oid_map(writer->pseudo_merge_commits);
	string_list_clear_func(&writer->pseudo_merge_groups,
			       pseudo_merge_group_release_cb);

	for (i = 0; i < writer->selected_nr; i++) {
		struct bitmapped_commit *bc = &writer->selected[i];
		if (bc->write_as != bc->bitmap)
			ewah_free(bc->write_as);
		ewah_free(bc->bitmap);
		ewah_free(bc->pseudo_merge_parents);
	}
	free(writer->selected);
}

void bitmap_writer_show_progress(struct bitmap_writer *writer, int show)
{
	writer->show_progress = show;
}

/**
 * Build the initial type index for the packfile or multi-pack-index
 */
void bitmap_writer_build_type_index(struct bitmap_writer *writer,
				    struct pack_idx_entry **index)
{
	uint32_t i;
	uint32_t base_objects = 0;

	if (writer->midx)
		base_objects = writer->midx->num_objects +
			writer->midx->num_objects_in_base;

	writer->commits = ewah_new();
	writer->trees = ewah_new();
	writer->blobs = ewah_new();
	writer->tags = ewah_new();
	ALLOC_ARRAY(writer->to_pack->in_pack_pos, writer->to_pack->nr_objects);

	for (i = 0; i < writer->to_pack->nr_objects; ++i) {
		struct object_entry *entry = (struct object_entry *)index[i];
		enum object_type real_type;

		oe_set_in_pack_pos(writer->to_pack, entry, i);

		switch (oe_type(entry)) {
		case OBJ_COMMIT:
		case OBJ_TREE:
		case OBJ_BLOB:
		case OBJ_TAG:
			real_type = oe_type(entry);
			break;

		default:
			real_type = odb_read_object_info(writer->to_pack->repo->objects,
							 &entry->idx.oid, NULL);
			break;
		}

		switch (real_type) {
		case OBJ_COMMIT:
			ewah_set(writer->commits, i + base_objects);
			break;

		case OBJ_TREE:
			ewah_set(writer->trees, i + base_objects);
			break;

		case OBJ_BLOB:
			ewah_set(writer->blobs, i + base_objects);
			break;

		case OBJ_TAG:
			ewah_set(writer->tags, i + base_objects);
			break;

		default:
			die("Missing type information for %s (%d/%d)",
			    oid_to_hex(&entry->idx.oid), real_type,
			    oe_type(entry));
		}
	}
}

int bitmap_writer_has_bitmapped_object_id(struct bitmap_writer *writer,
					  const struct object_id *oid)
{
	return kh_get_oid_map(writer->bitmaps, *oid) != kh_end(writer->bitmaps);
}

/**
 * Compute the actual bitmaps
 */

void bitmap_writer_push_commit(struct bitmap_writer *writer,
			       struct commit *commit, unsigned pseudo_merge)
{
	if (writer->selected_nr >= writer->selected_alloc) {
		writer->selected_alloc = (writer->selected_alloc + 32) * 2;
		REALLOC_ARRAY(writer->selected, writer->selected_alloc);
	}

	if (!pseudo_merge) {
		int hash_ret;
		khiter_t hash_pos = kh_put_oid_map(writer->bitmaps,
						   commit->object.oid,
						   &hash_ret);

		if (!hash_ret)
			die(_("duplicate entry when writing bitmap index: %s"),
			    oid_to_hex(&commit->object.oid));
		kh_value(writer->bitmaps, hash_pos) = NULL;
	}

	writer->selected[writer->selected_nr].commit = commit;
	writer->selected[writer->selected_nr].bitmap = NULL;
	writer->selected[writer->selected_nr].write_as = NULL;
	writer->selected[writer->selected_nr].flags = 0;
	writer->selected[writer->selected_nr].pseudo_merge = pseudo_merge;
	writer->selected[writer->selected_nr].pseudo_merge_parents = NULL;

	writer->selected_nr++;
}

struct bitmap_pos_cache_entry {
	struct object_id oid;
	uint32_t pos;
};

#define BITMAP_POS_MIN_CACHE_SIZE (1U << 10)
#define BITMAP_POS_MAX_CACHE_SIZE (1U << 21)
#define BITMAP_POS_CACHE_VALID    (1U << 31)

static void bitmap_writer_init_pos_cache(struct bitmap_writer *writer)
{
	if (writer->pos_cache)
		return;

	writer->pos_cache_nr = BITMAP_POS_MIN_CACHE_SIZE;

	while (writer->pos_cache_nr < writer->to_pack->nr_objects &&
	       writer->pos_cache_nr < BITMAP_POS_MAX_CACHE_SIZE)
		writer->pos_cache_nr <<= 1;

	CALLOC_ARRAY(writer->pos_cache, writer->pos_cache_nr);
}

static size_t bitmap_writer_pos_cache_slot(struct bitmap_writer *writer,
					   const struct object_id *oid)
{
	return oidhash(oid) & (writer->pos_cache_nr - 1);
}

static bool bitmap_writer_pos_cache_valid(struct bitmap_writer *writer,
					  size_t slot)
{
	return !!(writer->pos_cache[slot].pos & BITMAP_POS_CACHE_VALID);
}

static int find_cached_object_pos(struct bitmap_writer *writer,
				  const struct object_id *oid, uint32_t *pos)
{
	size_t slot = bitmap_writer_pos_cache_slot(writer, oid);

	if (bitmap_writer_pos_cache_valid(writer, slot) &&
	    oideq(&writer->pos_cache[slot].oid, oid)) {
		writer->pos_cache_hits++;
		*pos = writer->pos_cache[slot].pos & ~BITMAP_POS_CACHE_VALID;
		return 1;
	}

	writer->pos_cache_misses++;
	return 0;
}

static uint32_t store_cached_object_pos(struct bitmap_writer *writer,
					const struct object_id *oid,
					uint32_t pos)
{
	size_t slot;

	if (pos & BITMAP_POS_CACHE_VALID)
		return pos; /* too large to cache */

	slot = bitmap_writer_pos_cache_slot(writer, oid);

	oidcpy(&writer->pos_cache[slot].oid, oid);
	writer->pos_cache[slot].pos = pos | BITMAP_POS_CACHE_VALID;

	return pos;
}

static uint32_t find_object_pos(struct bitmap_writer *writer,
				const struct object_id *oid, int *found)
{
	struct object_entry *entry;
	uint32_t pos;

	bitmap_writer_init_pos_cache(writer);

	if (find_cached_object_pos(writer, oid, &pos)) {
		if (found)
			*found = 1;
		return pos;
	}

	entry = packlist_find(writer->to_pack, oid);
	if (entry) {
		uint32_t base_objects = 0;

		if (writer->midx)
			base_objects = writer->midx->num_objects +
				writer->midx->num_objects_in_base;
		pos = oe_in_pack_pos(writer->to_pack, entry) + base_objects;
	} else if (writer->midx) {
		uint32_t at;

		if (!bsearch_midx(oid, writer->midx, &at))
			goto missing;
		if (midx_to_pack_pos(writer->midx, at, &pos) < 0)
			goto missing;
	} else {
		goto missing;
	}

	if (found)
		*found = 1;
	return store_cached_object_pos(writer, oid, pos);

missing:
	if (found)
		*found = 0;
	warning("Failed to write bitmap index. Packfile doesn't have full closure "
		"(object %s is missing)", oid_to_hex(oid));
	return 0;
}

static int bitmapped_commit_date_cmp(const void *_a, const void *_b)
{
	const struct bitmapped_commit *a = _a;
	const struct bitmapped_commit *b = _b;

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

static void compute_xor_offsets(struct bitmap_writer *writer)
{
	static const int MAX_XOR_OFFSET_SEARCH = 10;

	int i, next = 0;
	int nr = bitmap_writer_nr_selected_commits(writer);

	if (nr > 1) {
		QSORT(writer->selected, nr, bitmapped_commit_date_cmp);

		for (i = 0; i < nr; i++) {
			struct bitmapped_commit *stored = &writer->selected[i];
			khiter_t hash_pos = kh_get_oid_map(writer->bitmaps,
							   stored->commit->object.oid);

			if (hash_pos == kh_end(writer->bitmaps))
				BUG("selected commit missing from bitmap map: %s",
				    oid_to_hex(&stored->commit->object.oid));

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

	while (next < writer->selected_nr) {
		struct bitmapped_commit *stored = &writer->selected[next];
		int best_offset = 0;
		struct ewah_bitmap *best_bitmap = stored->bitmap;
		struct ewah_bitmap *test_xor;

		if (stored->pseudo_merge)
			goto next;

		for (i = 1; i <= MAX_XOR_OFFSET_SEARCH; ++i) {
			int curr = next - i;

			if (curr < 0)
				break;
			if (writer->selected[curr].pseudo_merge)
				continue;

			test_xor = ewah_pool_new();
			ewah_xor(writer->selected[curr].bitmap, stored->bitmap, test_xor);

			if (test_xor->buffer_size < best_bitmap->buffer_size) {
				if (best_bitmap != stored->bitmap)
					ewah_pool_free(best_bitmap);

				best_bitmap = test_xor;
				best_offset = i;
			} else {
				ewah_pool_free(test_xor);
			}
		}

next:
		stored->xor_offset = best_offset;
		stored->write_as = best_bitmap;

		next++;
	}
}

struct bb_commit {
	struct commit_list *reverse_edges;
	struct bitmap *commit_mask;
	struct bitmap *bitmap;
	unsigned selected:1,
		 maximal:1,
		 pseudo_merge:1;
	unsigned idx; /* within selected array */
};

static void clear_bb_commit(struct bb_commit *commit)
{
	commit_list_free(commit->reverse_edges);
	bitmap_free(commit->commit_mask);
	bitmap_free(commit->bitmap);
}

define_commit_slab(bb_data, struct bb_commit);

struct bitmap_builder {
	struct bb_data data;
	struct commit_stack commits;
};

static void bitmap_builder_init(struct bitmap_builder *bb,
				struct bitmap_writer *writer,
				struct bitmap_index *old_bitmap)
{
	struct rev_info revs;
	struct commit *commit;
	struct commit_list *reusable = NULL;
	struct commit_list *r;
	unsigned int i, num_maximal = 0;

	init_bb_data(&bb->data);
	commit_stack_init(&bb->commits);

	reset_revision_walk();
	repo_init_revisions(writer->to_pack->repo, &revs, NULL);
	revs.topo_order = 1;
	revs.first_parent_only = 1;

	for (i = 0; i < bitmap_writer_nr_selected_commits(writer); i++) {
		struct bitmapped_commit *bc = &writer->selected[i];
		struct bb_commit *ent = bb_data_at(&bb->data, bc->commit);

		if (bc->pseudo_merge)
			BUG("unexpected pseudo-merge at %"PRIuMAX,
			    (uintmax_t)i);

		ent->selected = 1;
		ent->maximal = 1;
		ent->pseudo_merge = 0;
		ent->idx = i;

		ent->commit_mask = bitmap_new();
		bitmap_set(ent->commit_mask, i);

		add_pending_object(&revs, &bc->commit->object, "");
	}

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

	while ((commit = get_revision(&revs))) {
		struct commit_list *p = commit->parents;
		struct bb_commit *c_ent;

		parse_commit_or_die(commit);

		c_ent = bb_data_at(&bb->data, commit);

		/*
		 * If there is no commit_mask, there is no reason to iterate
		 * over this commit; it is not selected (if it were, it would
		 * not have a blank commit mask) and all its children have
		 * existing bitmaps (see the comment starting with "This commit
		 * has an existing bitmap" below), so it does not contribute
		 * anything to the final bitmap file or its descendants.
		 */
		if (!c_ent->commit_mask)
			continue;

		if (old_bitmap && bitmap_for_commit(old_bitmap, commit)) {
			/*
			 * This commit has an existing bitmap, so we can
			 * get its bits immediately without an object
			 * walk. That is, it is reusable as-is and there is no
			 * need to continue walking beyond it.
			 *
			 * Mark it as such and add it to bb->commits separately
			 * to avoid allocating a position in the commit mask.
			 */
			commit_list_insert(commit, &reusable);
			goto next;
		}

		if (c_ent->maximal) {
			num_maximal++;
			commit_stack_push(&bb->commits, commit);
		}

		if (p) {
			struct bb_commit *p_ent = bb_data_at(&bb->data, p->item);
			int c_not_p, p_not_c;

			if (!p_ent->commit_mask) {
				p_ent->commit_mask = bitmap_new();
				c_not_p = 1;
				p_not_c = 0;
			} else {
				c_not_p = bitmap_is_subset(c_ent->commit_mask, p_ent->commit_mask);
				p_not_c = bitmap_is_subset(p_ent->commit_mask, c_ent->commit_mask);
			}

			if (!c_not_p)
				continue;

			bitmap_or(p_ent->commit_mask, c_ent->commit_mask);

			if (p_not_c)
				p_ent->maximal = 1;
			else {
				p_ent->maximal = 0;
				commit_list_free(p_ent->reverse_edges);
				p_ent->reverse_edges = NULL;
			}

			if (c_ent->maximal) {
				commit_list_insert(commit, &p_ent->reverse_edges);
			} else {
				struct commit_list *cc = c_ent->reverse_edges;

				for (; cc; cc = cc->next) {
					if (!commit_list_contains(cc->item, p_ent->reverse_edges))
						commit_list_insert(cc->item, &p_ent->reverse_edges);
				}
			}
		}

next:
		bitmap_free(c_ent->commit_mask);
		c_ent->commit_mask = NULL;
	}

	for (r = reusable; r; r = r->next) {
		commit_stack_push(&bb->commits, r->item);
	}

	trace2_data_intmax("pack-bitmap-write", writer->repo,
			   "num_selected_commits", writer->selected_nr);
	trace2_data_intmax("pack-bitmap-write", writer->repo,
			   "num_maximal_commits", num_maximal);

	release_revisions(&revs);
	commit_list_free(reusable);
}

static void bitmap_builder_clear(struct bitmap_builder *bb)
{
	deep_clear_bb_data(&bb->data, clear_bb_commit);
	commit_stack_clear(&bb->commits);
}

static int fill_bitmap_tree(struct bitmap_writer *writer,
			    struct bitmap *bitmap,
			    struct tree *tree,
			    uint32_t pos)
{
	int found;
	struct tree_desc desc;
	struct name_entry entry;

	bitmap_set(bitmap, pos);

	if (repo_parse_tree(writer->repo, tree) < 0)
		die("unable to load tree object %s",
		    oid_to_hex(&tree->object.oid));
	init_tree_desc(&desc, &tree->object.oid, tree->buffer, tree->size);

	while (tree_entry(&desc, &entry)) {
		switch (object_type(entry.mode)) {
		case OBJ_TREE:
			pos = find_object_pos(writer, &entry.oid, &found);
			if (!found)
				return -1;
			if (bitmap_get(bitmap, pos)) {
				/*
				 * If our bit is already set, then there
				 * is nothing to do. Both this tree and
				 * all of its children will be set.
				 */
				break;
			}

			if (fill_bitmap_tree(writer, bitmap,
					     lookup_tree(writer->repo,
							 &entry.oid), pos) < 0)
				return -1;
			break;
		case OBJ_BLOB:
			pos = find_object_pos(writer, &entry.oid, &found);
			if (!found)
				return -1;
			bitmap_set(bitmap, pos);
			break;
		default:
			/* Gitlink, etc; not reachable */
			break;
		}
	}

	free_tree_buffer(tree);
	return 0;
}

static int reused_bitmaps_nr;
static int reused_pseudo_merge_bitmaps_nr;
static int pseudo_merge_bitmap_nr;
static int pseudo_merge_bitmap_parents;

static int fill_bitmap_commit_calls_nr;
static int fill_bitmap_commit_found_ancestor_nr;

static int fill_bitmap_commit(struct bitmap_writer *writer,
			      struct bb_commit *ent,
			      struct commit *commit,
			      struct prio_queue *queue,
			      struct prio_queue *tree_queue,
			      struct bitmap_index *old_bitmap,
			      const uint32_t *mapping)
{
	struct commit *c;
	struct tree *t;
	int found;
	int from_pseudo_merge = commit->object.flags & BITMAP_PSEUDO_MERGE;
	uint32_t pos;

	if (ent->pseudo_merge)
		BUG("unexpected pseudo-merge commit in fill_bitmap_commit()");

	fill_bitmap_commit_calls_nr++;

	if (!ent->bitmap)
		ent->bitmap = bitmap_new();

	prio_queue_put(queue, commit);

	while ((c = prio_queue_get(queue))) {
		struct commit_list *p;

		if (old_bitmap && mapping) {
			struct ewah_bitmap *old;
			struct bitmap *remapped = bitmap_new();

			old = bitmap_for_commit(old_bitmap, c);
			/*
			 * If this commit has an old bitmap, then translate that
			 * bitmap and add its bits to this one. No need to walk
			 * parents or the tree for this commit.
			 */
			if (old && !rebuild_bitmap(mapping, old, remapped)) {
				bitmap_or(ent->bitmap, remapped);
				bitmap_free(remapped);
				reused_bitmaps_nr++;
				continue;
			}
			bitmap_free(remapped);
		}

		/*
		 * If we encounter an ancestor for which we have already
		 * computed a bitmap during this build (i.e. a regular
		 * selected commit processed earlier in topo order), we can
		 * short-circuit the walk: its stored bitmap already covers
		 * the commit itself, its tree, and all of its ancestors.
		 */
		if (c != commit) {
			khiter_t hash_pos = kh_get_oid_map(writer->bitmaps,
							   c->object.oid);
			if (hash_pos != kh_end(writer->bitmaps)) {
				struct bitmapped_commit *stored =
					kh_value(writer->bitmaps, hash_pos);
				if (stored && stored->bitmap) {
					fill_bitmap_commit_found_ancestor_nr++;
					bitmap_or_ewah(ent->bitmap,
						       stored->bitmap);
					continue;
				}
			}
		}

		/*
		 * Mark ourselves and queue our tree. The commit
		 * walk ensures we cover all parents.
		 */
		if (!(c->object.flags & BITMAP_PSEUDO_MERGE)) {
			struct tree *tree;

			if (from_pseudo_merge && !c->object.parsed) {
				/*
				 * Commits reachable from selected
				 * non-pseudo-merges are already parsed
				 * by the regular bitmap build.
				 *
				 * However, pseudo-merge fills can also
				 * reach commits that were not covered
				 * there, so parse any such leftovers
				 * before reading their tree or parents.
				 */
				if (repo_parse_commit(writer->repo, c))
					return -1;
			}

			pos = find_object_pos(writer, &c->object.oid, &found);
			if (!found)
				return -1;
			bitmap_set(ent->bitmap, pos);

			tree = repo_get_commit_tree(writer->repo, c);
			if (!tree)
				return -1;
			prio_queue_put(tree_queue, tree);
		}

		for (p = c->parents; p; p = p->next) {
			pos = find_object_pos(writer, &p->item->object.oid,
					      &found);
			if (!found)
				return -1;
			if (!bitmap_get(ent->bitmap, pos)) {
				bitmap_set(ent->bitmap, pos);
				prio_queue_put(queue, p->item);
			}
		}
	}

	while ((t = prio_queue_get(tree_queue))) {
		int found;

		pos = find_object_pos(writer, &t->object.oid, &found);
		if (!found)
			return -1;
		if (bitmap_get(ent->bitmap, pos)) {
			/*
			 * If our bit is already set, then there is
			 * nothing to do. Both this tree and all of its
			 * children will be set.
			 */
			continue;
		}

		if (fill_bitmap_tree(writer, ent->bitmap, t, pos) < 0)
			return -1;
	}
	return 0;
}

static int reuse_pseudo_merge_bitmap(struct bitmap_index *old_bitmap,
				     const uint32_t *mapping,
				     struct commit *merge,
				     struct ewah_bitmap **out)
{
	struct ewah_bitmap *old;
	struct bitmap *remapped;

	if (!old_bitmap || !mapping)
		return 0;

	old = pseudo_merge_bitmap_for_commit(old_bitmap, merge);
	if (!old)
		return 0;

	remapped = bitmap_new();
	if (rebuild_bitmap(mapping, old, remapped) < 0) {
		bitmap_free(remapped);
		return 0;
	}

	*out = bitmap_to_ewah(remapped);
	bitmap_free(remapped);
	reused_pseudo_merge_bitmaps_nr++;
	return 1;
}

static int build_pseudo_merge_bitmap(struct bitmap_writer *writer,
				     struct bitmap_index *old_bitmap,
				     const uint32_t *mapping,
				     struct commit *merge,
				     struct ewah_bitmap **out)
{
	struct bb_commit ent = { 0 };
	struct prio_queue queue = { NULL };
	struct prio_queue tree_queue = { NULL };
	unsigned parents = commit_list_count(merge->parents);
	int ret;

	ent.bitmap = bitmap_new();

	pseudo_merge_bitmap_nr++;
	pseudo_merge_bitmap_parents += parents;

	if (reuse_pseudo_merge_bitmap(old_bitmap, mapping, merge, out)) {
		ret = 0;
		goto done;
	}

	ret = fill_bitmap_commit(writer, &ent, merge, &queue, &tree_queue,
				 old_bitmap, mapping);

	if (!ret)
		*out = bitmap_to_ewah(ent.bitmap);

done:
	bitmap_free(ent.bitmap);
	clear_prio_queue(&queue);
	clear_prio_queue(&tree_queue);

	return ret;
}

static int build_pseudo_merge_bitmaps(struct bitmap_writer *writer,
				      struct bitmap_index *old_bitmap,
				      const uint32_t *mapping,
				      int *nr_stored)
{
	size_t i = bitmap_writer_nr_selected_commits(writer);
	int ret = 0;

	if (!writer->pseudo_merges_nr)
		return 0;

	trace2_region_enter("pack-bitmap-write", "building_pseudo_merge_bitmaps",
			    writer->repo);

	for (; i < writer->selected_nr; i++) {
		struct bitmapped_commit *merge = &writer->selected[i];
		struct commit_list *p;
		struct bitmap *parents = bitmap_new();
		struct ewah_bitmap *objects = NULL;

		if (!merge->pseudo_merge)
			BUG("found non-pseudo merge commit at %"PRIuMAX,
			    (uintmax_t)i);

		for (p = merge->commit->parents; p; p = p->next) {
			int found;
			uint32_t pos = find_object_pos(writer,
						       &p->item->object.oid,
						       &found);
			if (!found) {
				bitmap_free(parents);
				ret = -1;
				goto done;
			}
			bitmap_set(parents, pos);
		}

		merge->pseudo_merge_parents = bitmap_to_ewah(parents);
		bitmap_free(parents);

		if (build_pseudo_merge_bitmap(writer, old_bitmap, mapping,
					      merge->commit, &objects) < 0) {
			ret = -1;
			goto done;
		}
		merge->bitmap = objects;

		(*nr_stored)++;
		display_progress(writer->progress, *nr_stored);
	}

done:
	trace2_region_leave("pack-bitmap-write", "building_pseudo_merge_bitmaps",
			    writer->repo);

	trace2_data_intmax("pack-bitmap-write", writer->repo,
			   "pseudo_merge_bitmap_nr",
			   pseudo_merge_bitmap_nr);
	trace2_data_intmax("pack-bitmap-write", writer->repo,
			   "building_bitmaps_pseudo_merge_reused",
			   reused_pseudo_merge_bitmaps_nr);
	trace2_data_intmax("pack-bitmap-write", writer->repo,
			   "pseudo_merge_bitmap_parents",
			   pseudo_merge_bitmap_parents);

	return ret;
}

static void store_selected(struct bitmap_writer *writer,
			   struct bb_commit *ent, struct commit *commit)
{
	struct bitmapped_commit *stored = &writer->selected[ent->idx];
	khiter_t hash_pos;

	stored->bitmap = bitmap_to_ewah(ent->bitmap);

	if (ent->pseudo_merge)
		return;

	hash_pos = kh_get_oid_map(writer->bitmaps, commit->object.oid);
	if (hash_pos == kh_end(writer->bitmaps))
		die(_("attempted to store non-selected commit: '%s'"),
		    oid_to_hex(&commit->object.oid));

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

int bitmap_writer_build(struct bitmap_writer *writer)
{
	struct bitmap_builder bb;
	size_t i;
	int nr_stored = 0; /* for progress */
	struct prio_queue queue = { compare_commits_by_gen_then_commit_date };
	struct prio_queue tree_queue = { NULL };
	struct bitmap_index *old_bitmap;
	uint32_t *mapping = NULL;
	int closed = 1; /* until proven otherwise */

	if (writer->show_progress)
		writer->progress = start_progress(writer->repo,
						  "Building bitmaps",
						  writer->selected_nr);

	writer->pos_cache_hits = 0;
	writer->pos_cache_misses = 0;

	trace2_region_enter("pack-bitmap-write", "building_bitmaps_total",
			    writer->repo);

	old_bitmap = prepare_bitmap_git(writer->to_pack->repo);
	if (old_bitmap)
		mapping = create_bitmap_mapping(old_bitmap, writer->to_pack);
	else
		mapping = NULL;

	bitmap_builder_init(&bb, writer, old_bitmap);
	for (i = bb.commits.nr; i > 0; i--) {
		struct commit *commit = bb.commits.items[i-1];
		struct bb_commit *ent = bb_data_at(&bb.data, commit);
		struct commit *child;
		int reused = 0;

		if (fill_bitmap_commit(writer, ent, commit, &queue, &tree_queue,
				       old_bitmap, mapping) < 0) {
			closed = 0;
			break;
		}

		if (ent->selected) {
			store_selected(writer, ent, commit);
			nr_stored++;
			display_progress(writer->progress, nr_stored);
		}

		while ((child = pop_commit(&ent->reverse_edges))) {
			struct bb_commit *child_ent =
				bb_data_at(&bb.data, child);

			if (child_ent->bitmap)
				bitmap_or(child_ent->bitmap, ent->bitmap);
			else if (reused)
				child_ent->bitmap = bitmap_dup(ent->bitmap);
			else {
				child_ent->bitmap = ent->bitmap;
				reused = 1;
			}
		}
		if (!reused)
			bitmap_free(ent->bitmap);
		ent->bitmap = NULL;
	}
	if (closed &&
	    build_pseudo_merge_bitmaps(writer, old_bitmap, mapping,
				       &nr_stored) < 0)
		closed = 0;
	clear_prio_queue(&queue);
	clear_prio_queue(&tree_queue);
	bitmap_builder_clear(&bb);
	free_bitmap_index(old_bitmap);
	free(mapping);

	trace2_region_leave("pack-bitmap-write", "building_bitmaps_total",
			    writer->repo);
	trace2_data_intmax("pack-bitmap-write", writer->repo,
			   "building_bitmaps_reused", reused_bitmaps_nr);
	trace2_data_intmax("pack-bitmap-write", writer->repo,
			   "fill_bitmap_commit_calls_nr",
			   fill_bitmap_commit_calls_nr);
	trace2_data_intmax("pack-bitmap-write", writer->repo,
			   "fill_bitmap_commit_found_ancestor_nr",
			   fill_bitmap_commit_found_ancestor_nr);
	trace2_data_intmax("pack-bitmap-write", writer->repo,
			   "bitmap_pos_cache_hits", writer->pos_cache_hits);
	trace2_data_intmax("pack-bitmap-write", writer->repo,
			   "bitmap_pos_cache_misses", writer->pos_cache_misses);

	stop_progress(&writer->progress);

	if (closed)
		compute_xor_offsets(writer);
	return closed ? 0 : -1;
}

/**
 * Select the commits that will be bitmapped
 */
static inline unsigned int next_commit_index(unsigned int idx)
{
	static const unsigned int MIN_COMMITS = 100;
	static const unsigned int MAX_COMMITS = 5000;

	static const unsigned int MUST_REGION = 100;
	static const unsigned int MIN_REGION = 20000;

	unsigned int offset, next;

	if (idx <= MUST_REGION)
		return 0;

	if (idx <= MIN_REGION) {
		offset = idx - MUST_REGION;
		return (offset < MIN_COMMITS) ? offset : MIN_COMMITS;
	}

	offset = idx - MIN_REGION;
	next = (offset < MAX_COMMITS) ? offset : MAX_COMMITS;

	return (next > MIN_COMMITS) ? next : MIN_COMMITS;
}

static int date_compare(const void *_a, const void *_b)
{
	struct commit *a = *(struct commit **)_a;
	struct commit *b = *(struct commit **)_b;
	return (long)b->date - (long)a->date;
}

void bitmap_writer_select_commits(struct bitmap_writer *writer,
				  struct commit **indexed_commits,
				  unsigned int indexed_commits_nr)
{
	unsigned int i = 0, j, next;

	QSORT(indexed_commits, indexed_commits_nr, date_compare);

	if (indexed_commits_nr < 100) {
		for (i = 0; i < indexed_commits_nr; ++i)
			bitmap_writer_push_commit(writer, indexed_commits[i], 0);

		select_pseudo_merges(writer);

		return;
	}

	if (writer->show_progress)
		writer->progress = start_progress(writer->repo,
						  "Selecting bitmap commits", 0);

	for (;;) {
		struct commit *chosen = NULL;

		next = next_commit_index(i);

		if (i + next >= indexed_commits_nr)
			break;

		if (next == 0) {
			chosen = indexed_commits[i];
		} else {
			chosen = indexed_commits[i + next];

			for (j = 0; j <= next; ++j) {
				struct commit *cm = indexed_commits[i + j];

				if ((cm->object.flags & NEEDS_BITMAP) != 0) {
					chosen = cm;
					break;
				}

				if (cm->parents && cm->parents->next)
					chosen = cm;
			}
		}

		bitmap_writer_push_commit(writer, chosen, 0);

		i += next + 1;
		display_progress(writer->progress, i);
	}

	stop_progress(&writer->progress);

	select_pseudo_merges(writer);
}


static int hashwrite_ewah_helper(void *f, const void *buf, size_t len)
{
	/* hashwrite will die on error */
	hashwrite(f, buf, len);
	return len;
}

/**
 * Write the bitmap index to disk
 */
static inline void dump_bitmap(struct hashfile *f, struct ewah_bitmap *bitmap)
{
	if (ewah_serialize_to(bitmap, hashwrite_ewah_helper, f) < 0)
		die("Failed to write bitmap index");
}

static const struct object_id *oid_access(size_t pos, const void *table)
{
	const struct pack_idx_entry * const *index = table;
	return &index[pos]->oid;
}

static void write_selected_commits_v1(struct bitmap_writer *writer,
				      struct hashfile *f, off_t *offsets)
{
	int i;

	for (i = 0; i < bitmap_writer_nr_selected_commits(writer); ++i) {
		struct bitmapped_commit *stored = &writer->selected[i];
		if (stored->pseudo_merge)
			BUG("unexpected pseudo-merge among selected: %s",
			    oid_to_hex(&stored->commit->object.oid));

		if (offsets)
			offsets[i] = hashfile_total(f);

		hashwrite_be32(f, stored->commit_pos);
		hashwrite_u8(f, stored->xor_offset);
		hashwrite_u8(f, stored->flags);

		dump_bitmap(f, stored->write_as);
	}
}

static int pseudo_merge_commit_pos_cmp(const void *_va, const void *_vb,
				       void *_data)
{
	struct bitmap_writer *writer = _data;
	uint32_t pos_a = find_object_pos(writer, _va, NULL);
	uint32_t pos_b = find_object_pos(writer, _vb, NULL);

	if (pos_a < pos_b)
		return -1;
	if (pos_a > pos_b)
		return 1;
	return 0;
}

static void write_pseudo_merges(struct bitmap_writer *writer,
				struct hashfile *f)
{
	struct oid_array commits = OID_ARRAY_INIT;
	off_t *pseudo_merge_ofs = NULL;
	off_t start, table_start, next_ext;

	uint32_t base = bitmap_writer_nr_selected_commits(writer);
	size_t i, j = 0;

	CALLOC_ARRAY(pseudo_merge_ofs, writer->pseudo_merges_nr);

	start = hashfile_total(f);

	for (i = 0; i < writer->pseudo_merges_nr; i++) {
		struct bitmapped_commit *merge = &writer->selected[base + i];

		if (!merge->pseudo_merge)
			BUG("found non-pseudo merge commit at %"PRIuMAX, (uintmax_t)i);

		if (!merge->pseudo_merge_parents || !merge->bitmap)
			BUG("missing pseudo-merge bitmap for commit %s",
			    oid_to_hex(&merge->commit->object.oid));

		pseudo_merge_ofs[i] = hashfile_total(f);
		dump_bitmap(f, merge->pseudo_merge_parents);
		dump_bitmap(f, merge->bitmap);
	}

	next_ext = st_add(hashfile_total(f),
			  st_mult(kh_size(writer->pseudo_merge_commits),
				  sizeof(uint32_t) + sizeof(uint64_t)));

	table_start = hashfile_total(f);

	commits.alloc = kh_size(writer->pseudo_merge_commits);
	CALLOC_ARRAY(commits.oid, commits.alloc);

	for (i = kh_begin(writer->pseudo_merge_commits); i != kh_end(writer->pseudo_merge_commits); i++) {
		if (!kh_exist(writer->pseudo_merge_commits, i))
			continue;
		oid_array_append(&commits, &kh_key(writer->pseudo_merge_commits, i));
	}

	/*
	 * Sort the commits by their bit position so that the lookup
	 * table can be binary searched by the reader (see
	 * find_pseudo_merge()).
	 */
	QSORT_S(commits.oid, commits.nr, pseudo_merge_commit_pos_cmp, writer);

	/* write lookup table (non-extended) */
	for (i = 0; i < commits.nr; i++) {
		int hash_pos;
		struct pseudo_merge_commit_idx *c;

		hash_pos = kh_get_oid_map(writer->pseudo_merge_commits,
					  commits.oid[i]);
		if (hash_pos == kh_end(writer->pseudo_merge_commits))
			BUG("could not find pseudo-merge commit %s",
			    oid_to_hex(&commits.oid[i]));

		c = kh_value(writer->pseudo_merge_commits, hash_pos);

		hashwrite_be32(f, find_object_pos(writer, &commits.oid[i],
						  NULL));
		if (c->nr == 1)
			hashwrite_be64(f, pseudo_merge_ofs[c->pseudo_merge[0]]);
		else if (c->nr > 1) {
			if (next_ext & ((uint64_t)1<<63))
				die(_("too many pseudo-merges"));
			hashwrite_be64(f, next_ext | ((uint64_t)1<<63));
			next_ext = st_add3(next_ext,
					   sizeof(uint32_t),
					   st_mult(c->nr, sizeof(uint64_t)));
		} else
			BUG("expected commit '%s' to have at least one "
			    "pseudo-merge", oid_to_hex(&commits.oid[i]));
	}

	/* write lookup table (extended) */
	for (i = 0; i < commits.nr; i++) {
		int hash_pos;
		struct pseudo_merge_commit_idx *c;

		hash_pos = kh_get_oid_map(writer->pseudo_merge_commits,
					  commits.oid[i]);
		if (hash_pos == kh_end(writer->pseudo_merge_commits))
			BUG("could not find pseudo-merge commit %s",
			    oid_to_hex(&commits.oid[i]));

		c = kh_value(writer->pseudo_merge_commits, hash_pos);
		if (c->nr == 1)
			continue;

		hashwrite_be32(f, c->nr);
		for (j = 0; j < c->nr; j++)
			hashwrite_be64(f, pseudo_merge_ofs[c->pseudo_merge[j]]);
	}

	/* write positions for all pseudo merges */
	for (i = 0; i < writer->pseudo_merges_nr; i++)
		hashwrite_be64(f, pseudo_merge_ofs[i]);

	hashwrite_be32(f, writer->pseudo_merges_nr);
	hashwrite_be32(f, kh_size(writer->pseudo_merge_commits));
	hashwrite_be64(f, table_start - start);
	hashwrite_be64(f, hashfile_total(f) - start + sizeof(uint64_t));

	oid_array_clear(&commits);
	free(pseudo_merge_ofs);
}

static int table_cmp(const void *_va, const void *_vb, void *_data)
{
	struct bitmap_writer *writer = _data;
	struct bitmapped_commit *a = &writer->selected[*(uint32_t *)_va];
	struct bitmapped_commit *b = &writer->selected[*(uint32_t *)_vb];

	if (a->commit_pos < b->commit_pos)
		return -1;
	else if (a->commit_pos > b->commit_pos)
		return 1;

	return 0;
}

static void write_lookup_table(struct bitmap_writer *writer, struct hashfile *f,
			       off_t *offsets)
{
	uint32_t i;
	uint32_t *table, *table_inv;

	ALLOC_ARRAY(table, bitmap_writer_nr_selected_commits(writer));
	ALLOC_ARRAY(table_inv, bitmap_writer_nr_selected_commits(writer));

	for (i = 0; i < bitmap_writer_nr_selected_commits(writer); i++)
		table[i] = i;

	/*
	 * At the end of this sort table[j] = i means that the i'th
	 * bitmap corresponds to j'th bitmapped commit (among the selected
	 * commits) in lex order of OIDs.
	 */
	QSORT_S(table, bitmap_writer_nr_selected_commits(writer), table_cmp, writer);

	/* table_inv helps us discover that relationship (i'th bitmap
	 * to j'th commit by j = table_inv[i])
	 */
	for (i = 0; i < bitmap_writer_nr_selected_commits(writer); i++)
		table_inv[table[i]] = i;

	trace2_region_enter("pack-bitmap-write", "writing_lookup_table", writer->repo);
	for (i = 0; i < bitmap_writer_nr_selected_commits(writer); i++) {
		struct bitmapped_commit *selected = &writer->selected[table[i]];
		uint32_t xor_offset = selected->xor_offset;
		uint32_t xor_row;

		if (xor_offset) {
			/*
			 * xor_index stores the index (in the bitmap entries)
			 * of the corresponding xor bitmap. But we need to convert
			 * this index into lookup table's index. So, table_inv[xor_index]
			 * gives us the index position w.r.t. the lookup table.
			 *
			 * If "k = table[i] - xor_offset" then the xor base is the k'th
			 * bitmap. `table_inv[k]` gives us the position of that bitmap
			 * in the lookup table.
			 */
			uint32_t xor_index = table[i] - xor_offset;
			xor_row = table_inv[xor_index];
		} else {
			xor_row = 0xffffffff;
		}

		hashwrite_be32(f, writer->selected[table[i]].commit_pos);
		hashwrite_be64(f, (uint64_t)offsets[table[i]]);
		hashwrite_be32(f, xor_row);
	}
	trace2_region_leave("pack-bitmap-write", "writing_lookup_table", writer->repo);

	free(table);
	free(table_inv);
}

static void write_hash_cache(struct hashfile *f,
			     struct pack_idx_entry **index,
			     uint32_t index_nr)
{
	uint32_t i;

	for (i = 0; i < index_nr; ++i) {
		struct object_entry *entry = (struct object_entry *)index[i];
		hashwrite_be32(f, entry->hash);
	}
}

void bitmap_writer_set_checksum(struct bitmap_writer *writer,
				const unsigned char *sha1)
{
	hashcpy(writer->pack_checksum, sha1, writer->repo->hash_algo);
}

void bitmap_writer_finish(struct bitmap_writer *writer,
			  struct pack_idx_entry **index,
			  const char *filename,
			  uint16_t options)
{
	static uint16_t default_version = 1;
	static uint16_t flags = BITMAP_OPT_FULL_DAG;
	struct strbuf tmp_file = STRBUF_INIT;
	struct hashfile *f;
	off_t *offsets = NULL;
	uint32_t i, base_objects;

	struct bitmap_disk_header header;

	int fd = odb_mkstemp(writer->repo->objects, &tmp_file,
			     "pack/tmp_bitmap_XXXXXX");

	if (writer->pseudo_merges_nr)
		options |= BITMAP_OPT_PSEUDO_MERGES;

	f = hashfd(writer->repo->hash_algo, fd, tmp_file.buf);

	memcpy(header.magic, BITMAP_IDX_SIGNATURE, sizeof(BITMAP_IDX_SIGNATURE));
	header.version = htons(default_version);
	header.options = htons(flags | options);
	header.entry_count = htonl(bitmap_writer_nr_selected_commits(writer));
	hashcpy(header.checksum, writer->pack_checksum, writer->repo->hash_algo);

	hashwrite(f, &header, sizeof(header) - GIT_MAX_RAWSZ + writer->repo->hash_algo->rawsz);
	dump_bitmap(f, writer->commits);
	dump_bitmap(f, writer->trees);
	dump_bitmap(f, writer->blobs);
	dump_bitmap(f, writer->tags);

	if (options & BITMAP_OPT_LOOKUP_TABLE)
		CALLOC_ARRAY(offsets, writer->to_pack->nr_objects);

	if (writer->midx)
		base_objects = writer->midx->num_objects +
			writer->midx->num_objects_in_base;
	else
		base_objects = 0;

	for (i = 0; i < bitmap_writer_nr_selected_commits(writer); i++) {
		struct bitmapped_commit *stored = &writer->selected[i];
		int commit_pos = oid_pos(&stored->commit->object.oid, index,
					 writer->to_pack->nr_objects,
					 oid_access);

		if (commit_pos < 0)
			BUG("trying to write commit not in index");
		stored->commit_pos = commit_pos + base_objects;
	}

	write_selected_commits_v1(writer, f, offsets);

	if (options & BITMAP_OPT_PSEUDO_MERGES)
		write_pseudo_merges(writer, f);

	if (options & BITMAP_OPT_LOOKUP_TABLE)
		write_lookup_table(writer, f, offsets);

	if (options & BITMAP_OPT_HASH_CACHE)
		write_hash_cache(f, index, writer->to_pack->nr_objects);

	finalize_hashfile(f, NULL, FSYNC_COMPONENT_PACK_METADATA,
			  CSUM_HASH_IN_STREAM | CSUM_FSYNC | CSUM_CLOSE);

	if (adjust_shared_perm(writer->repo, tmp_file.buf))
		die_errno("unable to make temporary bitmap file readable");

	if (rename(tmp_file.buf, filename))
		die_errno("unable to rename temporary bitmap file to '%s'", filename);

	strbuf_release(&tmp_file);
	free(offsets);
}
