#define DISABLE_SIGN_COMPARE_WARNINGS

#include "git-compat-util.h"
#include "environment.h"
#include "gettext.h"
#include "hex.h"
#include "list.h"
#include "pack.h"
#include "repository.h"
#include "dir.h"
#include "packfile.h"
#include "delta.h"
#include "hash-lookup.h"
#include "commit.h"
#include "object.h"
#include "tag.h"
#include "trace.h"
#include "tree-walk.h"
#include "tree.h"
#include "object-file.h"
#include "odb.h"
#include "odb/streaming.h"
#include "midx.h"
#include "commit-graph.h"
#include "pack-revindex.h"
#include "promisor-remote.h"
#include "pack-mtimes.h"

char *odb_pack_name(struct repository *r, struct strbuf *buf,
		    const unsigned char *hash, const char *ext)
{
	strbuf_reset(buf);
	strbuf_addf(buf, "%s/pack/pack-%s.%s", repo_get_object_directory(r),
		    hash_to_hex_algop(hash, r->hash_algo), ext);
	return buf->buf;
}

static unsigned int pack_used_ctr;
static unsigned int pack_mmap_calls;
static unsigned int peak_pack_open_windows;
static unsigned int pack_open_windows;
static unsigned int pack_open_fds;
static unsigned int pack_max_fds;
static size_t peak_pack_mapped;
static size_t pack_mapped;

#define SZ_FMT PRIuMAX
static inline uintmax_t sz_fmt(size_t s) { return s; }

void pack_report(struct repository *repo)
{
	fprintf(stderr,
		"pack_report: getpagesize()            = %10" SZ_FMT "\n"
		"pack_report: core.packedGitWindowSize = %10" SZ_FMT "\n"
		"pack_report: core.packedGitLimit      = %10" SZ_FMT "\n",
		sz_fmt(getpagesize()),
		sz_fmt(repo->settings.packed_git_window_size),
		sz_fmt(repo->settings.packed_git_limit));
	fprintf(stderr,
		"pack_report: pack_used_ctr            = %10u\n"
		"pack_report: pack_mmap_calls          = %10u\n"
		"pack_report: pack_open_windows        = %10u / %10u\n"
		"pack_report: pack_mapped              = "
			"%10" SZ_FMT " / %10" SZ_FMT "\n",
		pack_used_ctr,
		pack_mmap_calls,
		pack_open_windows, peak_pack_open_windows,
		sz_fmt(pack_mapped), sz_fmt(peak_pack_mapped));
}

/*
 * Open and mmap the index file at path, perform a couple of
 * consistency checks, then record its information to p.  Return 0 on
 * success.
 */
static int check_packed_git_idx(const char *path, struct packed_git *p)
{
	void *idx_map;
	size_t idx_size;
	int fd = git_open(path), ret;
	struct stat st;
	const unsigned int hashsz = p->repo->hash_algo->rawsz;

	if (fd < 0)
		return -1;
	if (fstat(fd, &st)) {
		close(fd);
		return -1;
	}
	idx_size = xsize_t(st.st_size);
	if (idx_size < 4 * 256 + hashsz + hashsz) {
		close(fd);
		return error("index file %s is too small", path);
	}
	idx_map = xmmap(NULL, idx_size, PROT_READ, MAP_PRIVATE, fd, 0);
	close(fd);

	ret = load_idx(path, hashsz, idx_map, idx_size, p);

	if (ret)
		munmap(idx_map, idx_size);

	return ret;
}

int load_idx(const char *path, const unsigned int hashsz, void *idx_map,
	     size_t idx_size, struct packed_git *p)
{
	struct pack_idx_header *hdr = idx_map;
	uint32_t version, nr, i, *index;

	if (idx_size < 4 * 256 + hashsz + hashsz)
		return error("index file %s is too small", path);
	if (!idx_map)
		return error("empty data");

	if (hdr->idx_signature == htonl(PACK_IDX_SIGNATURE)) {
		version = ntohl(hdr->idx_version);
		if (version < 2 || version > 2)
			return error("index file %s is version %"PRIu32
				     " and is not supported by this binary"
				     " (try upgrading GIT to a newer version)",
				     path, version);
	} else
		version = 1;

	nr = 0;
	index = idx_map;
	if (version > 1)
		index += 2;  /* skip index header */
	for (i = 0; i < 256; i++) {
		uint32_t n = ntohl(index[i]);
		if (n < nr)
			return error("non-monotonic index %s", path);
		nr = n;
	}

	if (version == 1) {
		/*
		 * Total size:
		 *  - 256 index entries 4 bytes each
		 *  - 24-byte entries * nr (object ID + 4-byte offset)
		 *  - hash of the packfile
		 *  - file checksum
		 */
		if (idx_size != st_add(4 * 256 + hashsz + hashsz, st_mult(nr, hashsz + 4)))
			return error("wrong index v1 file size in %s", path);
	} else if (version == 2) {
		/*
		 * Minimum size:
		 *  - 8 bytes of header
		 *  - 256 index entries 4 bytes each
		 *  - object ID entry * nr
		 *  - 4-byte crc entry * nr
		 *  - 4-byte offset entry * nr
		 *  - hash of the packfile
		 *  - file checksum
		 * And after the 4-byte offset table might be a
		 * variable sized table containing 8-byte entries
		 * for offsets larger than 2^31.
		 */
		size_t min_size = st_add(8 + 4*256 + hashsz + hashsz, st_mult(nr, hashsz + 4 + 4));
		size_t max_size = min_size;
		if (nr)
			max_size = st_add(max_size, st_mult(nr - 1, 8));
		if (idx_size < min_size || idx_size > max_size)
			return error("wrong index v2 file size in %s", path);
		if (idx_size != min_size &&
		    /*
		     * make sure we can deal with large pack offsets.
		     * 31-bit signed offset won't be enough, neither
		     * 32-bit unsigned one will be.
		     */
		    (sizeof(off_t) <= 4))
			return error("pack too large for current definition of off_t in %s", path);
		p->crc_offset = st_add(8 + 4 * 256, st_mult(nr, hashsz));
	}

	p->index_version = version;
	p->index_data = idx_map;
	p->index_size = idx_size;
	p->num_objects = nr;
	return 0;
}

int open_pack_index(struct packed_git *p)
{
	char *idx_name;
	size_t len;
	int ret;

	if (p->index_data)
		return 0;

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

uint32_t get_pack_fanout(struct packed_git *p, uint32_t value)
{
	const uint32_t *level1_ofs = p->index_data;

	if (!level1_ofs) {
		if (open_pack_index(p))
			return 0;
		level1_ofs = p->index_data;
	}

	if (p->index_version > 1) {
		level1_ofs += 2;
	}

	return ntohl(level1_ofs[value]);
}

static struct packed_git *alloc_packed_git(struct repository *r, int extra)
{
	struct packed_git *p = xmalloc(st_add(sizeof(*p), extra));
	memset(p, 0, sizeof(*p));
	p->pack_fd = -1;
	p->repo = r;
	return p;
}

static char *pack_path_from_idx(const char *idx_path)
{
	size_t len;
	if (!strip_suffix(idx_path, ".idx", &len))
		BUG("idx path does not end in .idx: %s", idx_path);
	return xstrfmt("%.*s.pack", (int)len, idx_path);
}

struct packed_git *parse_pack_index(struct repository *r, unsigned char *sha1,
				    const char *idx_path)
{
	char *path = pack_path_from_idx(idx_path);
	size_t alloc = st_add(strlen(path), 1);
	struct packed_git *p = alloc_packed_git(r, alloc);

	memcpy(p->pack_name, path, alloc); /* includes NUL */
	free(path);
	hashcpy(p->hash, sha1, p->repo->hash_algo);
	if (check_packed_git_idx(idx_path, p)) {
		free(p);
		return NULL;
	}

	return p;
}

static void scan_windows(struct packed_git *p,
	struct packed_git **lru_p,
	struct pack_window **lru_w,
	struct pack_window **lru_l)
{
	struct pack_window *w, *w_l;

	for (w_l = NULL, w = p->windows; w; w = w->next) {
		if (!w->inuse_cnt) {
			if (!*lru_w || w->last_used < (*lru_w)->last_used) {
				*lru_p = p;
				*lru_w = w;
				*lru_l = w_l;
			}
		}
		w_l = w;
	}
}

static int unuse_one_window(struct object_database *odb)
{
	struct odb_source_files *files = odb_source_files_downcast(odb->source);
	struct packfile_list_entry *e;
	struct packed_git *lru_p = NULL;
	struct pack_window *lru_w = NULL, *lru_l = NULL;

	for (struct odb_files_dir *dir = files->dirs; dir; dir = dir->next) {
		for (e = dir->packed->packs.head; e; e = e->next)
			scan_windows(e->pack, &lru_p, &lru_w, &lru_l);
	}

	if (lru_p) {
		munmap(lru_w->base, lru_w->len);
		pack_mapped -= lru_w->len;
		if (lru_l)
			lru_l->next = lru_w->next;
		else
			lru_p->windows = lru_w->next;
		free(lru_w);
		pack_open_windows--;
		return 1;
	}
	return 0;
}

void close_pack_windows(struct packed_git *p)
{
	while (p->windows) {
		struct pack_window *w = p->windows;

		if (w->inuse_cnt)
			die("pack '%s' still has open windows to it",
			    p->pack_name);
		munmap(w->base, w->len);
		pack_mapped -= w->len;
		pack_open_windows--;
		p->windows = w->next;
		free(w);
	}
}

int close_pack_fd(struct packed_git *p)
{
	if (p->pack_fd < 0)
		return 0;

	close(p->pack_fd);
	pack_open_fds--;
	p->pack_fd = -1;

	return 1;
}

void close_pack_index(struct packed_git *p)
{
	if (p->index_data) {
		munmap((void *)p->index_data, p->index_size);
		p->index_data = NULL;
	}
}

static void close_pack_revindex(struct packed_git *p)
{
	FREE_AND_NULL(p->revindex);

	if (!p->revindex_map)
		return;

	munmap((void *)p->revindex_map, p->revindex_size);
	p->revindex_map = NULL;
	p->revindex_data = NULL;
}

static void close_pack_mtimes(struct packed_git *p)
{
	if (!p->mtimes_map)
		return;

	munmap((void *)p->mtimes_map, p->mtimes_size);
	p->mtimes_map = NULL;
}

void unlink_pack_path(const char *pack_name, int force_delete)
{
	static const char *exts[] = {".idx", ".pack", ".rev", ".keep", ".bitmap", ".promisor", ".mtimes"};
	int i;
	struct strbuf buf = STRBUF_INIT;
	size_t plen;

	strbuf_addstr(&buf, pack_name);
	strip_suffix_mem(buf.buf, &buf.len, ".pack");
	plen = buf.len;

	if (!force_delete) {
		strbuf_addstr(&buf, ".keep");
		if (!access(buf.buf, F_OK)) {
			strbuf_release(&buf);
			return;
		}
	}

	for (i = 0; i < ARRAY_SIZE(exts); i++) {
		strbuf_setlen(&buf, plen);
		strbuf_addstr(&buf, exts[i]);
		unlink(buf.buf);
	}

	strbuf_release(&buf);
}

/*
 * The LRU pack is the one with the oldest MRU window, preferring packs
 * with no used windows, or the oldest mtime if it has no windows allocated.
 */
static void find_lru_pack(struct packed_git *p, struct packed_git **lru_p, struct pack_window **mru_w, int *accept_windows_inuse)
{
	struct pack_window *w, *this_mru_w;
	int has_windows_inuse = 0;

	/*
	 * Reject this pack if it has windows and the previously selected
	 * one does not.  If this pack does not have windows, reject
	 * it if the pack file is newer than the previously selected one.
	 */
	if (*lru_p && !*mru_w && (p->windows || p->mtime > (*lru_p)->mtime))
		return;

	for (w = this_mru_w = p->windows; w; w = w->next) {
		/*
		 * Reject this pack if any of its windows are in use,
		 * but the previously selected pack did not have any
		 * inuse windows.  Otherwise, record that this pack
		 * has windows in use.
		 */
		if (w->inuse_cnt) {
			if (*accept_windows_inuse)
				has_windows_inuse = 1;
			else
				return;
		}

		if (w->last_used > this_mru_w->last_used)
			this_mru_w = w;

		/*
		 * Reject this pack if it has windows that have been
		 * used more recently than the previously selected pack.
		 * If the previously selected pack had windows inuse and
		 * we have not encountered a window in this pack that is
		 * inuse, skip this check since we prefer a pack with no
		 * inuse windows to one that has inuse windows.
		 */
		if (*mru_w && *accept_windows_inuse == has_windows_inuse &&
		    this_mru_w->last_used > (*mru_w)->last_used)
			return;
	}

	/*
	 * Select this pack.
	 */
	*mru_w = this_mru_w;
	*lru_p = p;
	*accept_windows_inuse = has_windows_inuse;
}

static int close_one_pack(struct repository *r)
{
	struct odb_source_files *files = odb_source_files_downcast(r->objects->source);
	struct packfile_list_entry *e;
	struct packed_git *lru_p = NULL;
	struct pack_window *mru_w = NULL;
	int accept_windows_inuse = 1;

	for (struct odb_files_dir *dir = files->dirs; dir; dir = dir->next) {
		for (e = dir->packed->packs.head; e; e = e->next) {
			if (e->pack->pack_fd == -1)
				continue;
			find_lru_pack(e->pack, &lru_p, &mru_w, &accept_windows_inuse);
		}
	}

	if (lru_p)
		return close_pack_fd(lru_p);

	return 0;
}

static unsigned int get_max_fd_limit(void)
{
#ifdef RLIMIT_NOFILE
	{
		struct rlimit lim;

		if (!getrlimit(RLIMIT_NOFILE, &lim))
			return lim.rlim_cur;
	}
#endif

#ifdef _SC_OPEN_MAX
	{
		long open_max = sysconf(_SC_OPEN_MAX);
		if (0 < open_max)
			return open_max;
		/*
		 * Otherwise, we got -1 for one of the two
		 * reasons:
		 *
		 * (1) sysconf() did not understand _SC_OPEN_MAX
		 *     and signaled an error with -1; or
		 * (2) sysconf() said there is no limit.
		 *
		 * We _could_ clear errno before calling sysconf() to
		 * tell these two cases apart and return a huge number
		 * in the latter case to let the caller cap it to a
		 * value that is not so selfish, but letting the
		 * fallback OPEN_MAX codepath take care of these cases
		 * is a lot simpler.
		 */
	}
#endif

#ifdef OPEN_MAX
	return OPEN_MAX;
#else
	return 1; /* see the caller ;-) */
#endif
}

const char *pack_basename(struct packed_git *p)
{
	const char *ret = strrchr(p->pack_name, '/');
	if (ret)
		ret = ret + 1; /* skip past slash */
	else
		ret = p->pack_name; /* we only have a base */
	return ret;
}

/*
 * Do not call this directly as this leaks p->pack_fd on error return;
 * call open_packed_git() instead.
 */
static int open_packed_git_1(struct packed_git *p)
{
	struct stat st;
	struct pack_header hdr;
	unsigned char hash[GIT_MAX_RAWSZ];
	unsigned char *idx_hash;
	ssize_t read_result;
	const unsigned hashsz = p->repo->hash_algo->rawsz;

	if (open_pack_index(p))
		return error("packfile %s index unavailable", p->pack_name);

	if (!pack_max_fds) {
		unsigned int max_fds = get_max_fd_limit();

		/* Save 3 for stdin/stdout/stderr, 22 for work */
		if (25 < max_fds)
			pack_max_fds = max_fds - 25;
		else
			pack_max_fds = 1;
	}

	while (pack_max_fds <= pack_open_fds && close_one_pack(p->repo))
		; /* nothing */

	p->pack_fd = git_open(p->pack_name);
	if (p->pack_fd < 0 || fstat(p->pack_fd, &st))
		return -1;
	pack_open_fds++;

	/* If we created the struct before we had the pack we lack size. */
	if (!p->pack_size) {
		if (!S_ISREG(st.st_mode))
			return error("packfile %s not a regular file", p->pack_name);
		p->pack_size = st.st_size;
	} else if (p->pack_size != st.st_size)
		return error("packfile %s size changed", p->pack_name);

	/* Verify we recognize this pack file format. */
	read_result = read_in_full(p->pack_fd, &hdr, sizeof(hdr));
	if (read_result < 0)
		return error_errno("error reading from %s", p->pack_name);
	if (read_result != sizeof(hdr))
		return error("file %s is far too short to be a packfile", p->pack_name);
	if (hdr.hdr_signature != htonl(PACK_SIGNATURE))
		return error("file %s is not a GIT packfile", p->pack_name);
	if (!pack_version_ok(hdr.hdr_version))
		return error("packfile %s is version %"PRIu32" and not"
			" supported (try upgrading GIT to a newer version)",
			p->pack_name, ntohl(hdr.hdr_version));

	/* Verify the pack matches its index. */
	if (p->num_objects != ntohl(hdr.hdr_entries))
		return error("packfile %s claims to have %"PRIu32" objects"
			     " while index indicates %"PRIu32" objects",
			     p->pack_name, ntohl(hdr.hdr_entries),
			     p->num_objects);
	read_result = pread_in_full(p->pack_fd, hash, hashsz,
					p->pack_size - hashsz);
	if (read_result < 0)
		return error_errno("error reading from %s", p->pack_name);
	if (read_result != hashsz)
		return error("packfile %s signature is unavailable", p->pack_name);
	idx_hash = ((unsigned char *)p->index_data) + p->index_size - hashsz * 2;
	if (!hasheq(hash, idx_hash, p->repo->hash_algo))
		return error("packfile %s does not match index", p->pack_name);
	return 0;
}

static int open_packed_git(struct packed_git *p)
{
	if (!open_packed_git_1(p))
		return 0;
	close_pack_fd(p);
	return -1;
}

static int in_window(struct repository *r, struct pack_window *win,
		     off_t offset)
{
	/* We must promise at least one full hash after the
	 * offset is available from this window, otherwise the offset
	 * is not actually in this window and a different window (which
	 * has that one hash excess) must be used.  This is to support
	 * the object header and delta base parsing routines below.
	 */
	off_t win_off = win->offset;
	return win_off <= offset
		&& (offset + r->hash_algo->rawsz) <= (win_off + win->len);
}

unsigned char *use_pack(struct packed_git *p,
		struct pack_window **w_cursor,
		off_t offset,
		size_t *left)
{
	struct pack_window *win = *w_cursor;

	/* Since packfiles end in a hash of their content and it's
	 * pointless to ask for an offset into the middle of that
	 * hash, and the in_window function above wouldn't match
	 * don't allow an offset too close to the end of the file.
	 */
	if (!p->pack_size && p->pack_fd == -1 && open_packed_git(p))
		die("packfile %s cannot be accessed", p->pack_name);
	if (offset > (p->pack_size - p->repo->hash_algo->rawsz))
		die("offset beyond end of packfile (truncated pack?)");
	if (offset < 0)
		die(_("offset before end of packfile (broken .idx?)"));

	if (!win || !in_window(p->repo, win, offset)) {
		if (win)
			win->inuse_cnt--;
		for (win = p->windows; win; win = win->next) {
			if (in_window(p->repo, win, offset))
				break;
		}
		if (!win) {
			size_t window_align;
			off_t len;
			struct repo_settings *settings;

			/* lazy load the settings in case it hasn't been setup */
			prepare_repo_settings(p->repo);
			settings = &p->repo->settings;

			window_align = settings->packed_git_window_size / 2;

			if (p->pack_fd == -1 && open_packed_git(p))
				die("packfile %s cannot be accessed", p->pack_name);

			CALLOC_ARRAY(win, 1);
			win->offset = (offset / window_align) * window_align;
			len = p->pack_size - win->offset;
			if (len > settings->packed_git_window_size)
				len = settings->packed_git_window_size;
			win->len = (size_t)len;
			pack_mapped += win->len;

			while (settings->packed_git_limit < pack_mapped &&
			       unuse_one_window(p->repo->objects))
				; /* nothing */
			win->base = xmmap_gently(NULL, win->len,
				PROT_READ, MAP_PRIVATE,
				p->pack_fd, win->offset);
			if (win->base == MAP_FAILED)
				die_errno(_("packfile %s cannot be mapped%s"),
					  p->pack_name, mmap_os_err());
			if (!win->offset && win->len == p->pack_size
				&& !p->do_not_close)
				close_pack_fd(p);
			pack_mmap_calls++;
			pack_open_windows++;
			if (pack_mapped > peak_pack_mapped)
				peak_pack_mapped = pack_mapped;
			if (pack_open_windows > peak_pack_open_windows)
				peak_pack_open_windows = pack_open_windows;
			win->next = p->windows;
			p->windows = win;
		}
	}
	if (win != *w_cursor) {
		win->last_used = pack_used_ctr++;
		win->inuse_cnt++;
		*w_cursor = win;
	}
	offset -= win->offset;
	if (left)
		*left = win->len - xsize_t(offset);
	return win->base + offset;
}

void unuse_pack(struct pack_window **w_cursor)
{
	struct pack_window *w = *w_cursor;
	if (w) {
		w->inuse_cnt--;
		*w_cursor = NULL;
	}
}

struct packed_git *add_packed_git(struct repository *r, const char *path,
				  size_t path_len, int local)
{
	struct stat st;
	size_t alloc;
	struct packed_git *p;
	struct object_id oid;

	/*
	 * Make sure a corresponding .pack file exists and that
	 * the index looks sane.
	 */
	if (!strip_suffix_mem(path, &path_len, ".idx"))
		return NULL;

	/*
	 * ".promisor" is long enough to hold any suffix we're adding (and
	 * the use xsnprintf double-checks that)
	 */
	alloc = st_add3(path_len, strlen(".promisor"), 1);
	p = alloc_packed_git(r, alloc);
	memcpy(p->pack_name, path, path_len);

	/*
	 * Note that we have to check auxiliary data structures before we check
	 * for the ".pack" file to exist to avoid races with a packfile that is
	 * in the process of being deleted. The ".pack" file is unlinked before
	 * its auxiliary data structures, so we know that we either get a
	 * consistent snapshot of all data structures or that we'll fail to
	 * stat(3p) the packfile itself and thus return `NULL`.
	 *
	 * As such, we cannot bail out before the access(3p) calls in case the
	 * packfile doesn't exist without doing two stat(3p) calls for it.
	 */
	xsnprintf(p->pack_name + path_len, alloc - path_len, ".keep");
	if (!access(p->pack_name, F_OK))
		p->pack_keep = 1;

	xsnprintf(p->pack_name + path_len, alloc - path_len, ".promisor");
	if (!access(p->pack_name, F_OK))
		p->pack_promisor = 1;

	xsnprintf(p->pack_name + path_len, alloc - path_len, ".mtimes");
	if (!access(p->pack_name, F_OK))
		p->is_cruft = 1;

	xsnprintf(p->pack_name + path_len, alloc - path_len, ".pack");
	if (stat(p->pack_name, &st) || !S_ISREG(st.st_mode)) {
		free(p);
		return NULL;
	}

	/* ok, it looks sane as far as we can check without
	 * actually mapping the pack file.
	 */
	p->pack_size = st.st_size;
	p->pack_local = local;
	p->mtime = st.st_mtime;
	if (path_len < r->hash_algo->hexsz ||
	    get_oid_hex_algop(path + path_len - r->hash_algo->hexsz, &oid,
			      r->hash_algo))
		hashclr(p->hash, r->hash_algo);
	else
		hashcpy(p->hash, oid.hash, r->hash_algo);

	return p;
}

void packfile_store_add_pack(struct odb_source_packed *store,
			     struct packed_git *pack)
{
	if (pack->pack_fd != -1)
		pack_open_fds++;

	packfile_list_append(&store->packs, pack, 1);
	strmap_put(&store->packs_by_path, pack->pack_name, pack);
}

struct packed_git *packfile_store_load_pack(struct odb_source_packed *store,
					    const char *idx_path, int local)
{
	struct strbuf key = STRBUF_INIT;
	struct packed_git *p;

	/*
	 * We're being called with the path to the index file, but `pack_map`
	 * holds the path to the packfile itself.
	 */
	strbuf_addstr(&key, idx_path);
	strbuf_strip_suffix(&key, ".idx");
	strbuf_addstr(&key, ".pack");

	p = strmap_get(&store->packs_by_path, key.buf);
	if (!p) {
		p = add_packed_git(store->base.odb->repo, idx_path,
				   strlen(idx_path), local);
		if (p)
			packfile_store_add_pack(store, p);
	}

	strbuf_release(&key);
	return p;
}

void for_each_file_in_pack_subdir(const char *objdir,
				  const char *subdir,
				  each_file_in_pack_dir_fn fn,
				  void *data)
{
	struct strbuf path = STRBUF_INIT;
	size_t dirnamelen;
	DIR *dir;
	struct dirent *de;

	strbuf_addstr(&path, objdir);
	strbuf_addstr(&path, "/pack");
	if (subdir)
		strbuf_addf(&path, "/%s", subdir);
	dir = opendir(path.buf);
	if (!dir) {
		if (errno != ENOENT)
			error_errno("unable to open object pack directory: %s",
				    path.buf);
		strbuf_release(&path);
		return;
	}
	strbuf_addch(&path, '/');
	dirnamelen = path.len;
	while ((de = readdir_skip_dot_and_dotdot(dir)) != NULL) {
		strbuf_setlen(&path, dirnamelen);
		strbuf_addstr(&path, de->d_name);

		fn(path.buf, path.len, de->d_name, data);
	}

	closedir(dir);
	strbuf_release(&path);
}

void for_each_file_in_pack_dir(const char *objdir,
			       each_file_in_pack_dir_fn fn,
			       void *data)
{
	for_each_file_in_pack_subdir(objdir, NULL, fn, data);
}

struct packfile_list_entry *packfile_store_get_packs(struct odb_source_packed *store)
{
	odb_source_prepare(&store->base, 0);

	if (store->midx) {
		struct multi_pack_index *m = store->midx;
		for (uint32_t i = 0; i < m->num_packs + m->num_packs_in_base; i++)
			prepare_midx_pack(m, i);
	}

	return store->packs.head;
}

size_t unpack_object_header_buffer(const unsigned char *buf, size_t len,
				   enum object_type *type, size_t *sizep)
{
	unsigned shift;
	size_t size, c, used = 0;

	c = buf[used++];
	*type = (c >> 4) & 7;
	size = c & 15;
	shift = 4;
	while (c & 0x80) {
		/*
		 * Each continuation byte adds 7 bits. Ensure shift won't
		 * overflow size_t (use size_t not long for 64-bit on Windows).
		 */
		if (len <= used || (bitsizeof(size_t) - 7) < shift) {
			error("bad object header");
			size = used = 0;
			break;
		}
		c = buf[used++];
		size = st_add(size, st_left_shift(c & 0x7f, shift));
		shift += 7;
	}
	*sizep = size;
	return used;
}

/*
 * Read a delta object's header at curpos in p (already inflated as needed)
 * and return the size of the result object (the post-application target).
 */
size_t get_size_from_delta(struct packed_git *p,
			   struct pack_window **w_curs,
			   off_t curpos)
{
	const unsigned char *data;
	unsigned char delta_head[20], *in;
	git_zstream stream;
	int st;

	memset(&stream, 0, sizeof(stream));
	stream.next_out = delta_head;
	stream.avail_out = sizeof(delta_head);

	git_inflate_init(&stream);
	do {
		in = use_pack(p, w_curs, curpos, &stream.avail_in);
		stream.next_in = in;
		/*
		 * Note: the window section returned by use_pack() must be
		 * available throughout git_inflate()'s unlocked execution. To
		 * ensure no other thread will modify the window in the
		 * meantime, we rely on the packed_window.inuse_cnt. This
		 * counter is incremented before window reading and checked
		 * before window disposal.
		 *
		 * Other worrying sections could be the call to close_pack_fd(),
		 * which can close packs even with in-use windows, and to
		 * odb_reprepare(). Regarding the former, mmap doc says:
		 * "closing the file descriptor does not unmap the region". And
		 * for the latter, it won't re-open already available packs.
		 */
		obj_read_unlock();
		st = git_inflate(&stream, Z_FINISH);
		obj_read_lock();
		curpos += stream.next_in - in;
	} while ((st == Z_OK || st == Z_BUF_ERROR) &&
		 stream.total_out < sizeof(delta_head));
	git_inflate_end(&stream);
	if ((st != Z_STREAM_END) && stream.total_out != sizeof(delta_head)) {
		error("delta data unpack-initial failed");
		return 0;
	}

	/* Examine the initial part of the delta to figure out
	 * the result size.
	 */
	data = delta_head;

	/* ignore base size */
	get_delta_hdr_size(&data, delta_head+sizeof(delta_head));

	/* Read the result size */
	return get_delta_hdr_size(&data, delta_head+sizeof(delta_head));
}

int unpack_object_header(struct packed_git *p,
			 struct pack_window **w_curs,
			 off_t *curpos,
			 size_t *sizep)
{
	unsigned char *base;
	size_t left, used;
	enum object_type type;

	/* use_pack() assures us we have [base, base + 20) available
	 * as a range that we can look at.  (Its actually the hash
	 * size that is assured.)  With our object header encoding
	 * the maximum deflated object size is 2^137, which is just
	 * insane, so we know won't exceed what we have been given.
	 */
	base = use_pack(p, w_curs, *curpos, &left);
	used = unpack_object_header_buffer(base, left, &type, sizep);
	if (!used) {
		type = OBJ_BAD;
	} else
		*curpos += used;

	return type;
}

void mark_bad_packed_object(struct packed_git *p, const struct object_id *oid)
{
	oidset_insert(&p->bad_objects, oid);
}

off_t get_delta_base(struct packed_git *p,
		     struct pack_window **w_curs,
		     off_t *curpos,
		     enum object_type type,
		     off_t delta_obj_offset)
{
	unsigned char *base_info = use_pack(p, w_curs, *curpos, NULL);
	off_t base_offset;

	/* use_pack() assured us we have [base_info, base_info + 20)
	 * as a range that we can look at without walking off the
	 * end of the mapped window.  Its actually the hash size
	 * that is assured.  An OFS_DELTA longer than the hash size
	 * is stupid, as then a REF_DELTA would be smaller to store.
	 */
	if (type == OBJ_OFS_DELTA) {
		unsigned used = 0;
		unsigned char c = base_info[used++];
		base_offset = c & 127;
		while (c & 128) {
			base_offset += 1;
			if (!base_offset || MSB(base_offset, 7))
				return 0;  /* overflow */
			c = base_info[used++];
			base_offset = (base_offset << 7) + (c & 127);
		}
		base_offset = delta_obj_offset - base_offset;
		if (base_offset <= 0 || base_offset >= delta_obj_offset)
			return 0;  /* out of bound */
		*curpos += used;
	} else if (type == OBJ_REF_DELTA) {
		/* The base entry _must_ be in the same pack */
		struct object_id oid;
		oidread(&oid, base_info, p->repo->hash_algo);
		base_offset = find_pack_entry_one(&oid, p);
		*curpos += p->repo->hash_algo->rawsz;
	} else
		die("I am totally screwed");
	return base_offset;
}

/*
 * Like get_delta_base above, but we return the sha1 instead of the pack
 * offset. This means it is cheaper for REF deltas (we do not have to do
 * the final object lookup), but more expensive for OFS deltas (we
 * have to load the revidx to convert the offset back into a sha1).
 */
static int get_delta_base_oid(struct packed_git *p,
			      struct pack_window **w_curs,
			      off_t curpos,
			      struct object_id *oid,
			      enum object_type type,
			      off_t delta_obj_offset)
{
	if (type == OBJ_REF_DELTA) {
		unsigned char *base = use_pack(p, w_curs, curpos, NULL);
		oidread(oid, base, p->repo->hash_algo);
		return 0;
	} else if (type == OBJ_OFS_DELTA) {
		uint32_t base_pos;
		off_t base_offset = get_delta_base(p, w_curs, &curpos,
						   type, delta_obj_offset);

		if (!base_offset)
			return -1;

		if (offset_to_pack_pos(p, base_offset, &base_pos) < 0)
			return -1;

		return nth_packed_object_id(oid, p,
					    pack_pos_to_index(p, base_pos));
	} else
		return -1;
}

static int retry_bad_packed_offset(struct repository *r,
				   struct packed_git *p,
				   off_t obj_offset)
{
	int type;
	uint32_t pos;
	struct object_id oid;
	if (offset_to_pack_pos(p, obj_offset, &pos) < 0)
		return OBJ_BAD;
	nth_packed_object_id(&oid, p, pack_pos_to_index(p, pos));
	mark_bad_packed_object(p, &oid);
	type = odb_read_object_info(r->objects, &oid, NULL);
	if (type <= OBJ_NONE)
		return OBJ_BAD;
	return type;
}

#define POI_STACK_PREALLOC 64

static enum object_type packed_to_object_type(struct repository *r,
					      struct packed_git *p,
					      off_t obj_offset,
					      enum object_type type,
					      struct pack_window **w_curs,
					      off_t curpos)
{
	off_t small_poi_stack[POI_STACK_PREALLOC];
	off_t *poi_stack = small_poi_stack;
	int poi_stack_nr = 0, poi_stack_alloc = POI_STACK_PREALLOC;

	while (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
		off_t base_offset;
		size_t size;
		/* Push the object we're going to leave behind */
		if (poi_stack_nr >= poi_stack_alloc && poi_stack == small_poi_stack) {
			poi_stack_alloc = alloc_nr(poi_stack_nr);
			ALLOC_ARRAY(poi_stack, poi_stack_alloc);
			COPY_ARRAY(poi_stack, small_poi_stack, poi_stack_nr);
		} else {
			ALLOC_GROW(poi_stack, poi_stack_nr+1, poi_stack_alloc);
		}
		poi_stack[poi_stack_nr++] = obj_offset;
		/* If parsing the base offset fails, just unwind */
		base_offset = get_delta_base(p, w_curs, &curpos, type, obj_offset);
		if (!base_offset)
			goto unwind;
		curpos = obj_offset = base_offset;
		type = unpack_object_header(p, w_curs, &curpos, &size);
		if (type <= OBJ_NONE) {
			/* If getting the base itself fails, we first
			 * retry the base, otherwise unwind */
			type = retry_bad_packed_offset(r, p, base_offset);
			if (type > OBJ_NONE)
				goto out;
			goto unwind;
		}
	}

	switch (type) {
	case OBJ_BAD:
	case OBJ_COMMIT:
	case OBJ_TREE:
	case OBJ_BLOB:
	case OBJ_TAG:
		break;
	default:
		error("unknown object type %i at offset %"PRIuMAX" in %s",
		      type, (uintmax_t)obj_offset, p->pack_name);
		type = OBJ_BAD;
	}

out:
	if (poi_stack != small_poi_stack)
		free(poi_stack);
	return type;

unwind:
	while (poi_stack_nr) {
		obj_offset = poi_stack[--poi_stack_nr];
		type = retry_bad_packed_offset(r, p, obj_offset);
		if (type > OBJ_NONE)
			goto out;
	}
	type = OBJ_BAD;
	goto out;
}

static struct hashmap delta_base_cache;
static size_t delta_base_cached;

static LIST_HEAD(delta_base_cache_lru);

struct delta_base_cache_key {
	struct packed_git *p;
	off_t base_offset;
};

struct delta_base_cache_entry {
	struct hashmap_entry ent;
	struct delta_base_cache_key key;
	struct list_head lru;
	void *data;
	size_t size;
	enum object_type type;
};

static unsigned int pack_entry_hash(struct packed_git *p, off_t base_offset)
{
	unsigned int hash;

	hash = (unsigned int)(intptr_t)p + (unsigned int)base_offset;
	hash += (hash >> 8) + (hash >> 16);
	return hash;
}

static struct delta_base_cache_entry *
get_delta_base_cache_entry(struct packed_git *p, off_t base_offset)
{
	struct hashmap_entry entry, *e;
	struct delta_base_cache_key key;

	if (!delta_base_cache.cmpfn)
		return NULL;

	hashmap_entry_init(&entry, pack_entry_hash(p, base_offset));
	key.p = p;
	key.base_offset = base_offset;
	e = hashmap_get(&delta_base_cache, &entry, &key);
	return e ? container_of(e, struct delta_base_cache_entry, ent) : NULL;
}

static int delta_base_cache_key_eq(const struct delta_base_cache_key *a,
				   const struct delta_base_cache_key *b)
{
	return a->p == b->p && a->base_offset == b->base_offset;
}

static int delta_base_cache_hash_cmp(const void *cmp_data UNUSED,
				     const struct hashmap_entry *va,
				     const struct hashmap_entry *vb,
				     const void *vkey)
{
	const struct delta_base_cache_entry *a, *b;
	const struct delta_base_cache_key *key = vkey;

	a = container_of(va, const struct delta_base_cache_entry, ent);
	b = container_of(vb, const struct delta_base_cache_entry, ent);

	if (key)
		return !delta_base_cache_key_eq(&a->key, key);
	else
		return !delta_base_cache_key_eq(&a->key, &b->key);
}

static int in_delta_base_cache(struct packed_git *p, off_t base_offset)
{
	return !!get_delta_base_cache_entry(p, base_offset);
}

/*
 * Remove the entry from the cache, but do _not_ free the associated
 * entry data. The caller takes ownership of the "data" buffer, and
 * should copy out any fields it wants before detaching.
 */
static void detach_delta_base_cache_entry(struct delta_base_cache_entry *ent)
{
	hashmap_remove(&delta_base_cache, &ent->ent, &ent->key);
	list_del(&ent->lru);
	delta_base_cached -= ent->size;
	free(ent);
}

static void *cache_or_unpack_entry(struct repository *r, struct packed_git *p,
				   off_t base_offset, size_t *base_size,
				   enum object_type *type)
{
	struct delta_base_cache_entry *ent;

	ent = get_delta_base_cache_entry(p, base_offset);
	if (!ent)
		return unpack_entry(r, p, base_offset, type, base_size);

	if (type)
		*type = ent->type;
	if (base_size)
		*base_size = ent->size;
	return xmemdupz(ent->data, ent->size);
}

static inline void release_delta_base_cache(struct delta_base_cache_entry *ent)
{
	free(ent->data);
	detach_delta_base_cache_entry(ent);
}

void clear_delta_base_cache(void)
{
	struct list_head *lru, *tmp;
	list_for_each_safe(lru, tmp, &delta_base_cache_lru) {
		struct delta_base_cache_entry *entry =
			list_entry(lru, struct delta_base_cache_entry, lru);
		release_delta_base_cache(entry);
	}
}

static void delta_base_cache_evict_entry(struct packed_git *p)
{
	struct list_head *lru, *tmp;

	list_for_each_safe(lru, tmp, &delta_base_cache_lru) {
		struct delta_base_cache_entry *entry =
			list_entry(lru, struct delta_base_cache_entry, lru);
		if (entry->key.p == p)
			release_delta_base_cache(entry);
	}
}

void close_pack(struct packed_git *p)
{
	close_pack_windows(p);
	close_pack_fd(p);
	close_pack_index(p);
	close_pack_revindex(p);
	close_pack_mtimes(p);
	oidset_clear(&p->bad_objects);
	delta_base_cache_evict_entry(p);
}

static void add_delta_base_cache(struct packed_git *p, off_t base_offset,
				 void *base, size_t base_size,
				 size_t delta_base_cache_limit,
				 enum object_type type)
{
	struct delta_base_cache_entry *ent;
	struct list_head *lru, *tmp;

	/*
	 * Check required to avoid redundant entries when more than one thread
	 * is unpacking the same object, in unpack_entry() (since its phases I
	 * and III might run concurrently across multiple threads).
	 */
	if (in_delta_base_cache(p, base_offset)) {
		free(base);
		return;
	}

	delta_base_cached += base_size;

	list_for_each_safe(lru, tmp, &delta_base_cache_lru) {
		struct delta_base_cache_entry *f =
			list_entry(lru, struct delta_base_cache_entry, lru);
		if (delta_base_cached <= delta_base_cache_limit)
			break;
		release_delta_base_cache(f);
	}

	ent = xmalloc(sizeof(*ent));
	ent->key.p = p;
	ent->key.base_offset = base_offset;
	ent->type = type;
	ent->data = base;
	ent->size = base_size;
	list_add_tail(&ent->lru, &delta_base_cache_lru);

	if (!delta_base_cache.cmpfn)
		hashmap_init(&delta_base_cache, delta_base_cache_hash_cmp, NULL, 0);
	hashmap_entry_init(&ent->ent, pack_entry_hash(p, base_offset));
	hashmap_add(&delta_base_cache, &ent->ent);
}

int packed_object_info_with_index_pos(struct odb_source_packed *source,
				      struct packed_git *p, off_t obj_offset,
				      uint32_t *maybe_index_pos, struct object_info *oi)
{
	struct pack_window *w_curs = NULL;
	size_t size;
	off_t curpos = obj_offset;
	enum object_type type = OBJ_NONE;
	uint32_t pack_pos;
	int ret;

	/*
	 * We always get the representation type, but only convert it to
	 * a "real" type later if the caller is interested.
	 */
	if (oi->contentp) {
		*oi->contentp = cache_or_unpack_entry(p->repo, p, obj_offset,
						      oi->sizep, &type);
		if (!*oi->contentp)
			type = OBJ_BAD;
	} else if (oi->sizep || oi->typep || oi->delta_base_oid) {
		type = unpack_object_header(p, &w_curs, &curpos, &size);
	}

	if (!oi->contentp && oi->sizep) {
		if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
			off_t tmp_pos = curpos;
			off_t base_offset = get_delta_base(p, &w_curs, &tmp_pos,
							   type, obj_offset);
			if (!base_offset) {
				ret = -1;
				goto out;
			}
			size = get_size_from_delta(p, &w_curs, tmp_pos);
			if (size == 0) {
				ret = -1;
				goto out;
			}
		}
		*oi->sizep = size;
	}

	if (oi->disk_sizep || (oi->mtimep && p->is_cruft)) {
		if (offset_to_pack_pos(p, obj_offset, &pack_pos) < 0) {
			error("could not find object at offset %"PRIuMAX" "
			      "in pack %s", (uintmax_t)obj_offset, p->pack_name);
			ret = -1;
			goto out;
		}
	}

	if (oi->disk_sizep)
		*oi->disk_sizep = pack_pos_to_offset(p, pack_pos + 1) - obj_offset;

	if (oi->mtimep) {
		if (p->is_cruft) {
			uint32_t index_pos;

			if (load_pack_mtimes(p) < 0)
				die(_("could not load .mtimes for cruft pack '%s'"),
				    pack_basename(p));

			if (maybe_index_pos)
				index_pos = *maybe_index_pos;
			else
				index_pos = pack_pos_to_index(p, pack_pos);

			*oi->mtimep = nth_packed_mtime(p, index_pos);
		} else {
			*oi->mtimep = p->mtime;
		}
	}

	if (oi->typep) {
		enum object_type ptot;
		ptot = packed_to_object_type(p->repo, p, obj_offset,
					     type, &w_curs, curpos);
		if (oi->typep)
			*oi->typep = ptot;
		if (ptot < 0) {
			ret = -1;
			goto out;
		}
	}

	if (oi->delta_base_oid) {
		if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) {
			if (get_delta_base_oid(p, &w_curs, curpos,
					       oi->delta_base_oid,
					       type, obj_offset) < 0) {
				ret = -1;
				goto out;
			}
		} else
			oidclr(oi->delta_base_oid, p->repo->hash_algo);
	}

	if (oi->source_infop) {
		if (!source)
			BUG("cannot request source without an owning source");
		oi->source_infop->source = &source->base;

		oi->source_infop->u.packed.offset = obj_offset;
		oi->source_infop->u.packed.pack = p;

		switch (type) {
		case OBJ_NONE:
			oi->source_infop->u.packed.type = PACKED_OBJECT_TYPE_UNKNOWN;
			break;
		case OBJ_REF_DELTA:
			oi->source_infop->u.packed.type = PACKED_OBJECT_TYPE_REF_DELTA;
			break;
		case OBJ_OFS_DELTA:
			oi->source_infop->u.packed.type = PACKED_OBJECT_TYPE_OFS_DELTA;
			break;
		default:
			oi->source_infop->u.packed.type = PACKED_OBJECT_TYPE_FULL;
			break;
		}
	}

	ret = 0;

out:
	unuse_pack(&w_curs);
	return ret;
}

int packed_object_info(struct odb_source_packed *source,
		       struct packed_git *p, off_t obj_offset,
		       struct object_info *oi)
{
	return packed_object_info_with_index_pos(source, p, obj_offset, NULL, oi);
}

static void *unpack_compressed_entry(struct packed_git *p,
				    struct pack_window **w_curs,
				    off_t curpos,
				    size_t size)
{
	int st;
	git_zstream stream;
	unsigned char *buffer, *in;

	buffer = xmallocz_gently(size);
	if (!buffer)
		return NULL;
	memset(&stream, 0, sizeof(stream));
	stream.next_out = buffer;
	stream.avail_out = size + 1;

	git_inflate_init(&stream);
	do {
		in = use_pack(p, w_curs, curpos, &stream.avail_in);
		stream.next_in = in;
		/*
		 * Note: we must ensure the window section returned by
		 * use_pack() will be available throughout git_inflate()'s
		 * unlocked execution. Please refer to the comment at
		 * get_size_from_delta() to see how this is done.
		 */
		obj_read_unlock();
		st = git_inflate(&stream, Z_FINISH);
		obj_read_lock();
		if (!stream.avail_out)
			break; /* the payload is larger than it should be */
		curpos += stream.next_in - in;
	} while (st == Z_OK || st == Z_BUF_ERROR);
	git_inflate_end(&stream);
	if ((st != Z_STREAM_END) || stream.total_out != size) {
		free(buffer);
		return NULL;
	}

	/* versions of zlib can clobber unconsumed portion of outbuf */
	buffer[size] = '\0';

	return buffer;
}

static void write_pack_access_log(struct packed_git *p, off_t obj_offset)
{
	static struct trace_key pack_access = TRACE_KEY_INIT(PACK_ACCESS);
	trace_printf_key(&pack_access, "%s %"PRIuMAX"\n",
			 p->pack_name, (uintmax_t)obj_offset);
}

int do_check_packed_object_crc;

#define UNPACK_ENTRY_STACK_PREALLOC 64
struct unpack_entry_stack_ent {
	off_t obj_offset;
	off_t curpos;
	size_t size;
};

void *unpack_entry(struct repository *r, struct packed_git *p, off_t obj_offset,
		   enum object_type *final_type, size_t *final_size)
{
	struct pack_window *w_curs = NULL;
	off_t curpos = obj_offset;
	void *data = NULL;
	size_t size;
	enum object_type type;
	struct unpack_entry_stack_ent small_delta_stack[UNPACK_ENTRY_STACK_PREALLOC];
	struct unpack_entry_stack_ent *delta_stack = small_delta_stack;
	int delta_stack_nr = 0, delta_stack_alloc = UNPACK_ENTRY_STACK_PREALLOC;
	int base_from_cache = 0;

	prepare_repo_settings(p->repo);

	write_pack_access_log(p, obj_offset);

	/* PHASE 1: drill down to the innermost base object */
	for (;;) {
		off_t base_offset;
		int i;
		struct delta_base_cache_entry *ent;

		ent = get_delta_base_cache_entry(p, curpos);
		if (ent) {
			type = ent->type;
			data = ent->data;
			size = ent->size;
			detach_delta_base_cache_entry(ent);
			base_from_cache = 1;
			break;
		}

		if (do_check_packed_object_crc && p->index_version > 1) {
			uint32_t pack_pos, index_pos;
			off_t len;

			if (offset_to_pack_pos(p, obj_offset, &pack_pos) < 0) {
				error("could not find object at offset %"PRIuMAX" in pack %s",
				      (uintmax_t)obj_offset, p->pack_name);
				data = NULL;
				goto out;
			}

			len = pack_pos_to_offset(p, pack_pos + 1) - obj_offset;
			index_pos = pack_pos_to_index(p, pack_pos);
			if (check_pack_crc(p, &w_curs, obj_offset, len, index_pos)) {
				struct object_id oid;
				nth_packed_object_id(&oid, p, index_pos);
				error("bad packed object CRC for %s",
				      oid_to_hex(&oid));
				mark_bad_packed_object(p, &oid);
				data = NULL;
				goto out;
			}
		}

		type = unpack_object_header(p, &w_curs, &curpos, &size);
		if (type != OBJ_OFS_DELTA && type != OBJ_REF_DELTA)
			break;

		base_offset = get_delta_base(p, &w_curs, &curpos, type, obj_offset);
		if (!base_offset) {
			error("failed to validate delta base reference "
			      "at offset %"PRIuMAX" from %s",
			      (uintmax_t)curpos, p->pack_name);
			/* bail to phase 2, in hopes of recovery */
			data = NULL;
			break;
		}

		/* push object, proceed to base */
		if (delta_stack_nr >= delta_stack_alloc
		    && delta_stack == small_delta_stack) {
			delta_stack_alloc = alloc_nr(delta_stack_nr);
			ALLOC_ARRAY(delta_stack, delta_stack_alloc);
			COPY_ARRAY(delta_stack, small_delta_stack,
				   delta_stack_nr);
		} else {
			ALLOC_GROW(delta_stack, delta_stack_nr+1, delta_stack_alloc);
		}
		i = delta_stack_nr++;
		delta_stack[i].obj_offset = obj_offset;
		delta_stack[i].curpos = curpos;
		delta_stack[i].size = size;

		curpos = obj_offset = base_offset;
	}

	/* PHASE 2: handle the base */
	switch (type) {
	case OBJ_OFS_DELTA:
	case OBJ_REF_DELTA:
		if (data)
			BUG("unpack_entry: left loop at a valid delta");
		break;
	case OBJ_COMMIT:
	case OBJ_TREE:
	case OBJ_BLOB:
	case OBJ_TAG:
		if (!base_from_cache)
			data = unpack_compressed_entry(p, &w_curs, curpos, size);
		break;
	default:
		data = NULL;
		error("unknown object type %i at offset %"PRIuMAX" in %s",
		      type, (uintmax_t)obj_offset, p->pack_name);
	}

	/* PHASE 3: apply deltas in order */

	/* invariants:
	 *   'data' holds the base data, or NULL if there was corruption
	 */
	while (delta_stack_nr) {
		void *delta_data;
		void *base = data;
		void *external_base = NULL;
		size_t delta_size, base_size = size;
		int i;
		off_t base_obj_offset = obj_offset;

		data = NULL;

		if (!base) {
			/*
			 * We're probably in deep shit, but let's try to fetch
			 * the required base anyway from another pack or loose.
			 * This is costly but should happen only in the presence
			 * of a corrupted pack, and is better than failing outright.
			 */
			uint32_t pos;
			struct object_id base_oid;
			if (!(offset_to_pack_pos(p, obj_offset, &pos))) {
				struct object_info oi = OBJECT_INFO_INIT;

				nth_packed_object_id(&base_oid, p,
						     pack_pos_to_index(p, pos));
				error("failed to read delta base object %s"
				      " at offset %"PRIuMAX" from %s",
				      oid_to_hex(&base_oid), (uintmax_t)obj_offset,
				      p->pack_name);
				mark_bad_packed_object(p, &base_oid);

				oi.typep = &type;
				oi.sizep = &base_size;
				oi.contentp = &base;
				if (odb_read_object_info_extended(r->objects, &base_oid,
								  &oi, 0) < 0)
					base = NULL;

				external_base = base;
			}
		}

		i = --delta_stack_nr;
		obj_offset = delta_stack[i].obj_offset;
		curpos = delta_stack[i].curpos;
		delta_size = delta_stack[i].size;

		if (!base)
			continue;

		delta_data = unpack_compressed_entry(p, &w_curs, curpos, delta_size);

		if (!delta_data) {
			error("failed to unpack compressed delta "
			      "at offset %"PRIuMAX" from %s",
			      (uintmax_t)curpos, p->pack_name);
			data = NULL;
		} else {
			data = patch_delta(base, base_size, delta_data,
					   delta_size, &size);

			/*
			 * We could not apply the delta; warn the user, but
			 * keep going. Our failure will be noticed either in
			 * the next iteration of the loop, or if this is the
			 * final delta, in the caller when we return NULL.
			 * Those code paths will take care of making a more
			 * explicit warning and retrying with another copy of
			 * the object.
			 */
			if (!data)
				error("failed to apply delta");
		}

		/*
		 * We delay adding `base` to the cache until the end of the loop
		 * because unpack_compressed_entry() momentarily releases the
		 * obj_read_mutex, giving another thread the chance to access
		 * the cache. Therefore, if `base` was already there, this other
		 * thread could free() it (e.g. to make space for another entry)
		 * before we are done using it.
		 */
		if (!external_base)
			add_delta_base_cache(p, base_obj_offset, base, base_size,
					     p->repo->settings.delta_base_cache_limit,
					     type);

		free(delta_data);
		free(external_base);
	}

	if (final_type)
		*final_type = type;
	if (final_size)
		*final_size = size;

out:
	unuse_pack(&w_curs);

	if (delta_stack != small_delta_stack)
		free(delta_stack);

	return data;
}

int bsearch_pack(const struct object_id *oid, const struct packed_git *p, uint32_t *result)
{
	const unsigned char *index_fanout = p->index_data;
	const unsigned char *index_lookup;
	const unsigned int hashsz = p->repo->hash_algo->rawsz;
	int index_lookup_width;

	if (!index_fanout)
		BUG("bsearch_pack called without a valid pack-index");

	index_lookup = index_fanout + 4 * 256;
	if (p->index_version == 1) {
		index_lookup_width = hashsz + 4;
		index_lookup += 4;
	} else {
		index_lookup_width = hashsz;
		index_fanout += 8;
		index_lookup += 8;
	}

	return bsearch_hash(oid->hash, (const uint32_t*)index_fanout,
			    index_lookup, index_lookup_width, result);
}

int nth_packed_object_id(struct object_id *oid,
			 struct packed_git *p,
			 uint32_t n)
{
	const unsigned char *index = p->index_data;
	const unsigned int hashsz = p->repo->hash_algo->rawsz;
	if (!index) {
		if (open_pack_index(p))
			return -1;
		index = p->index_data;
	}
	if (n >= p->num_objects)
		return -1;
	index += 4 * 256;
	if (p->index_version == 1) {
		oidread(oid, index + st_add(st_mult(hashsz + 4, n), 4),
			p->repo->hash_algo);
	} else {
		index += 8;
		oidread(oid, index + st_mult(hashsz, n), p->repo->hash_algo);
	}
	return 0;
}

void check_pack_index_ptr(const struct packed_git *p, const void *vptr)
{
	const unsigned char *ptr = vptr;
	const unsigned char *start = p->index_data;
	const unsigned char *end = start + p->index_size;
	if (ptr < start)
		die(_("offset before start of pack index for %s (corrupt index?)"),
		    p->pack_name);
	/* No need to check for underflow; .idx files must be at least 8 bytes */
	if (ptr >= end - 8)
		die(_("offset beyond end of pack index for %s (truncated index?)"),
		    p->pack_name);
}

off_t nth_packed_object_offset(const struct packed_git *p, uint32_t n)
{
	const unsigned char *index = p->index_data;
	const unsigned int hashsz = p->repo->hash_algo->rawsz;
	index += 4 * 256;
	if (p->index_version == 1) {
		return ntohl(*((uint32_t *)(index + st_mult(hashsz + 4, n))));
	} else {
		uint32_t off;
		index += st_add(8, st_mult(p->num_objects, hashsz + 4));
		off = ntohl(*((uint32_t *)(index + st_mult(4, n))));
		if (!(off & 0x80000000))
			return off;
		index += st_add(st_mult(p->num_objects, 4),
				st_mult(off & 0x7fffffff, 8));
		check_pack_index_ptr(p, index);
		return get_be64(index);
	}
}

off_t find_pack_entry_one(const struct object_id *oid,
			  struct packed_git *p)
{
	const unsigned char *index = p->index_data;
	uint32_t result;

	if (!index) {
		if (open_pack_index(p))
			return 0;
	}

	if (bsearch_pack(oid, p, &result))
		return nth_packed_object_offset(p, result);
	return 0;
}

int is_pack_valid(struct packed_git *p)
{
	/* An already open pack is known to be valid. */
	if (p->pack_fd != -1)
		return 1;

	/* If the pack has one window completely covering the
	 * file size, the pack is known to be valid even if
	 * the descriptor is not currently open.
	 */
	if (p->windows) {
		struct pack_window *w = p->windows;

		if (!w->offset && w->len == p->pack_size)
			return 1;
	}

	/* Force the pack to open to prove its valid. */
	return !open_packed_git(p);
}

int packfile_fill_entry(struct packed_git *p,
			const struct object_id *oid,
			struct pack_entry *e,
			struct packed_git **bad_pack)
{
	off_t offset;

	if (oidset_size(&p->bad_objects) &&
	    oidset_contains(&p->bad_objects, oid)) {
		if (bad_pack && !*bad_pack)
			*bad_pack = p;
		return 0;
	}

	offset = find_pack_entry_one(oid, p);
	if (!offset)
		return 0;

	/*
	 * We are about to tell the caller where they can locate the
	 * requested object.  We better make sure the packfile is
	 * still here and can be accessed before supplying that
	 * answer, as it may have been deleted since the index was
	 * loaded!
	 */
	if (!is_pack_valid(p))
		return 0;
	e->offset = offset;
	e->p = p;
	return 1;
}

static void maybe_invalidate_kept_pack_cache(struct odb_source_packed *store,
					     unsigned flags)
{
	if (!store->kept_cache.packs)
		return;
	if (store->kept_cache.flags == flags)
		return;
	FREE_AND_NULL(store->kept_cache.packs);
	store->kept_cache.flags = 0;
}

struct packed_git **packfile_store_get_kept_pack_cache(struct odb_source_packed *store,
						       unsigned flags)
{
	maybe_invalidate_kept_pack_cache(store, flags);

	if (!store->kept_cache.packs) {
		struct packed_git **packs = NULL;
		struct packfile_list_entry *e;
		size_t nr = 0, alloc = 0;

		/*
		 * We want "all" packs here, because we need to cover ones that
		 * are used by a midx, as well. We need to look in every one of
		 * them (instead of the midx itself) to cover duplicates. It's
		 * possible that an object is found in two packs that the midx
		 * covers, one kept and one not kept, but the midx returns only
		 * the non-kept version.
		 */
		for (e = packfile_store_get_packs(store); e; e = e->next) {
			struct packed_git *p = e->pack;

			if ((p->pack_keep && (flags & KEPT_PACK_ON_DISK)) ||
			    (p->pack_keep_in_core && (flags & KEPT_PACK_IN_CORE)) ||
			    (p->pack_keep_in_core_open && (flags & KEPT_PACK_IN_CORE_OPEN))) {
				ALLOC_GROW(packs, nr + 1, alloc);
				packs[nr++] = p;
			}
		}
		ALLOC_GROW(packs, nr + 1, alloc);
		packs[nr] = NULL;

		store->kept_cache.packs = packs;
		store->kept_cache.flags = flags;
	}

	return store->kept_cache.packs;
}

int has_object_pack(struct repository *r, const struct object_id *oid)
{
	struct odb_source_files *files = odb_source_files_downcast(r->objects->source);

	for (struct odb_files_dir *dir = files->dirs; dir; dir = dir->next) {
		if (!odb_source_read_object_info(&dir->packed->base, oid, NULL, 0, NULL))
			return 1;
	}

	return 0;
}

int has_object_kept_pack(struct repository *r, const struct object_id *oid,
			 unsigned flags)
{
	struct odb_source_files *files = odb_source_files_downcast(r->objects->source);
	struct pack_entry e;

	for (struct odb_files_dir *dir = files->dirs; dir; dir = dir->next) {
		struct packed_git **cache;

		cache = packfile_store_get_kept_pack_cache(dir->packed, flags);

		for (; *cache; cache++) {
			struct packed_git *p = *cache;
			if (packfile_fill_entry(p, oid, &e, NULL))
				return 1;
		}
	}

	return 0;
}

int for_each_object_in_pack(struct packed_git *p,
			    each_packed_object_fn cb, void *data,
			    enum odb_for_each_object_flags flags)
{
	uint32_t i;
	int r = 0;

	if (flags & ODB_FOR_EACH_OBJECT_PACK_ORDER) {
		if (load_pack_revindex(p->repo, p))
			return -1;
	}

	for (i = 0; i < p->num_objects; i++) {
		uint32_t index_pos;
		struct object_id oid;

		/*
		 * We are iterating "i" from 0 up to num_objects, but its
		 * meaning may be different, depending on the requested output
		 * order:
		 *
		 *   - in object-name order, it is the same as the index order
		 *     used by nth_packed_object_id(), so we can pass it
		 *     directly
		 *
		 *   - in pack-order, it is pack position, which we must
		 *     convert to an index position in order to get the oid.
		 */
		if (flags & ODB_FOR_EACH_OBJECT_PACK_ORDER)
			index_pos = pack_pos_to_index(p, i);
		else
			index_pos = i;

		if (nth_packed_object_id(&oid, p, index_pos) < 0)
			return error("unable to get sha1 of object %u in %s",
				     index_pos, p->pack_name);

		r = cb(&oid, p, index_pos, data);
		if (r)
			break;
	}
	return r;
}

struct add_promisor_object_data {
	struct repository *repo;
	struct oidset *set;
};

static int add_promisor_object(const struct object_id *oid,
			       struct object_info *oi UNUSED,
			       void *cb_data)
{
	struct add_promisor_object_data *data = cb_data;
	struct object *obj;
	int we_parsed_object;

	obj = lookup_object(data->repo, oid);
	if (obj && obj->parsed) {
		we_parsed_object = 0;
	} else {
		we_parsed_object = 1;
		obj = parse_object_with_flags(data->repo, oid,
					      PARSE_OBJECT_SKIP_HASH_CHECK);
	}

	if (!obj)
		return 1;

	oidset_insert(data->set, oid);

	/*
	 * If this is a tree, commit, or tag, the objects it refers
	 * to are also promisor objects. (Blobs refer to no objects->)
	 */
	if (obj->type == OBJ_TREE) {
		struct tree *tree = (struct tree *)obj;
		struct tree_desc desc;
		struct name_entry entry;
		if (init_tree_desc_gently(&desc, &tree->object.oid,
					  tree->buffer, tree->size, 0))
			/*
			 * Error messages are given when packs are
			 * verified, so do not print any here.
			 */
			return 0;
		while (tree_entry_gently(&desc, &entry))
			oidset_insert(data->set, &entry.oid);
		if (we_parsed_object)
			free_tree_buffer(tree);
	} else if (obj->type == OBJ_COMMIT) {
		struct commit *commit = (struct commit *) obj;
		struct commit_list *parents = commit->parents;

		oidset_insert(data->set, get_commit_tree_oid(commit));
		for (; parents; parents = parents->next)
			oidset_insert(data->set, &parents->item->object.oid);
	} else if (obj->type == OBJ_TAG) {
		struct tag *tag = (struct tag *) obj;
		oidset_insert(data->set, get_tagged_oid(tag));
	}
	return 0;
}

int is_promisor_object(struct repository *r, const struct object_id *oid)
{
	static struct oidset promisor_objects;
	static int promisor_objects_prepared;

	if (!promisor_objects_prepared) {
		if (repo_has_promisor_remote(r)) {
			struct add_promisor_object_data data = {
				.repo = r,
				.set = &promisor_objects,
			};

			odb_for_each_object(r->objects, NULL, add_promisor_object, &data,
					    ODB_FOR_EACH_OBJECT_PROMISOR_ONLY | ODB_FOR_EACH_OBJECT_PACK_ORDER);
		}
		promisor_objects_prepared = 1;
	}
	return oidset_contains(&promisor_objects, oid);
}

int parse_pack_header_option(const char *in, unsigned char *out, unsigned int *len)
{
	unsigned char *hdr;
	char *c;

	hdr = out;
	put_be32(hdr, PACK_SIGNATURE);
	hdr += 4;
	put_be32(hdr, strtoul(in, &c, 10));
	hdr += 4;
	if (*c != ',')
		return -1;
	put_be32(hdr, strtoul(c + 1, &c, 10));
	hdr += 4;
	if (*c)
		return -1;
	*len = hdr - out;
	return 0;
}

struct odb_packed_read_stream {
	struct odb_stream base;
	struct packed_git *pack;
	git_zstream z;
	enum {
		ODB_PACKED_READ_STREAM_UNINITIALIZED,
		ODB_PACKED_READ_STREAM_INUSE,
		ODB_PACKED_READ_STREAM_DONE,
		ODB_PACKED_READ_STREAM_ERROR,
	} z_state;
	off_t pos;
};

static ssize_t read_istream_pack_non_delta(struct odb_stream *_st, char *buf,
					   size_t sz)
{
	struct odb_packed_read_stream *st = (struct odb_packed_read_stream *)_st;
	size_t total_read = 0;

	switch (st->z_state) {
	case ODB_PACKED_READ_STREAM_UNINITIALIZED:
		memset(&st->z, 0, sizeof(st->z));
		git_inflate_init(&st->z);
		st->z_state = ODB_PACKED_READ_STREAM_INUSE;
		break;
	case ODB_PACKED_READ_STREAM_DONE:
		return 0;
	case ODB_PACKED_READ_STREAM_ERROR:
		return -1;
	case ODB_PACKED_READ_STREAM_INUSE:
		break;
	}

	while (total_read < sz) {
		int status;
		struct pack_window *window = NULL;
		unsigned char *mapped;

		mapped = use_pack(st->pack, &window,
				  st->pos, &st->z.avail_in);

		st->z.next_out = (unsigned char *)buf + total_read;
		st->z.avail_out = sz - total_read;
		st->z.next_in = mapped;
		status = git_inflate(&st->z, Z_FINISH);

		st->pos += st->z.next_in - mapped;
		total_read = st->z.next_out - (unsigned char *)buf;
		unuse_pack(&window);

		if (status == Z_STREAM_END) {
			git_inflate_end(&st->z);
			st->z_state = ODB_PACKED_READ_STREAM_DONE;
			break;
		}

		/*
		 * Unlike the loose object case, we do not have to worry here
		 * about running out of input bytes and spinning infinitely. If
		 * we get Z_BUF_ERROR due to too few input bytes, then we'll
		 * replenish them in the next use_pack() call when we loop. If
		 * we truly hit the end of the pack (i.e., because it's corrupt
		 * or truncated), then use_pack() catches that and will die().
		 */
		if (status != Z_OK && status != Z_BUF_ERROR) {
			git_inflate_end(&st->z);
			st->z_state = ODB_PACKED_READ_STREAM_ERROR;
			return -1;
		}
	}
	return total_read;
}

static int close_istream_pack_non_delta(struct odb_stream *_st)
{
	struct odb_packed_read_stream *st = (struct odb_packed_read_stream *)_st;
	if (st->z_state == ODB_PACKED_READ_STREAM_INUSE)
		git_inflate_end(&st->z);
	return 0;
}

int packfile_read_object_stream(struct odb_stream **out,
				const struct object_id *oid,
				struct packed_git *pack,
				off_t offset)
{
	struct odb_packed_read_stream *stream;
	struct pack_window *window = NULL;
	enum object_type in_pack_type;
	size_t size;

	in_pack_type = unpack_object_header(pack, &window, &offset, &size);
	unuse_pack(&window);

	if (repo_settings_get_big_file_threshold(pack->repo) >= size)
		return -1;

	switch (in_pack_type) {
	default:
		return -1; /* we do not do deltas for now */
	case OBJ_BAD:
		mark_bad_packed_object(pack, oid);
		return -1;
	case OBJ_COMMIT:
	case OBJ_TREE:
	case OBJ_BLOB:
	case OBJ_TAG:
		break;
	}

	CALLOC_ARRAY(stream, 1);
	stream->base.close = close_istream_pack_non_delta;
	stream->base.read = read_istream_pack_non_delta;
	stream->base.type = in_pack_type;
	stream->base.size = size;
	stream->z_state = ODB_PACKED_READ_STREAM_UNINITIALIZED;
	stream->pack = pack;
	stream->pos = offset;

	*out = &stream->base;

	return 0;
}
