#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 *source;
	struct packfile_list_entry *e;
	struct packed_git *lru_p = NULL;
	struct pack_window *lru_w = NULL, *lru_l = NULL;

	for (source = odb->sources; source; source = source->next) {
		struct odb_source_files *files = odb_source_files_downcast(source);
		for (e = files->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 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);
}

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 *source;
	struct packfile_list_entry *e;
	struct packed_git *lru_p = NULL;
	struct pack_window *mru_w = NULL;
	int accept_windows_inuse = 1;

	for (source = r->objects->sources; source; source = source->next) {
		struct odb_source_files *files = odb_source_files_downcast(source);
		for (e = files->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,
		unsigned long *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);
	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;
}

unsigned long unpack_object_header_buffer(const unsigned char *buf,
		unsigned long len, enum object_type *type, size_t *sizep)
{
	unsigned shift;
	size_t size, c;
	unsigned long 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;
	unsigned long left;
	unsigned long 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);
}

const struct packed_git *has_packed_and_bad(struct repository *r,
					    const struct object_id *oid)
{
	struct odb_source *source;

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

		for (e = files->packed->packs.head; e; e = e->next)
			if (oidset_contains(&e->pack->bad_objects, oid))
				return e->pack;
	}

	return NULL;
}

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 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)
{
	off_t offset;

	if (oidset_size(&p->bad_objects) &&
	    oidset_contains(&p->bad_objects, oid))
		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 *source;

	odb_prepare_alternates(r->objects);
	for (source = r->objects->sources; source; source = source->next) {
		struct odb_source_files *files = odb_source_files_downcast(source);
		if (!odb_source_read_object_info(&files->packed->base, oid, NULL, 0))
			return 1;
	}

	return 0;
}

int has_object_kept_pack(struct repository *r, const struct object_id *oid,
			 unsigned flags)
{
	struct odb_source *source;
	struct pack_entry e;

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

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

		for (; *cache; cache++) {
			struct packed_git *p = *cache;
			if (packfile_fill_entry(p, oid, &e))
				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_read_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_read_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_read_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_read_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;
}
