Factor out the mmap window code

This code is useful for more things than just the packfile handling
code. Factor it out so it can be reused.

Signed-off-by: Carlos Martín Nieto <carlos@cmartin.tk>
This commit is contained in:
Carlos Martín Nieto 2011-06-28 20:39:30 +02:00
parent 03d88ed415
commit 7bfdb3d22b
3 changed files with 372 additions and 227 deletions

271
src/mwindow.c Normal file
View File

@ -0,0 +1,271 @@
/*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2,
* as published by the Free Software Foundation.
*
* In addition to the permissions in the GNU General Public License,
* the authors give you unlimited permission to link the compiled
* version of this file into combinations with other programs,
* and to distribute those combinations without any restriction
* coming from the use of this file. (The General Public License
* restrictions do apply in other respects; for example, they cover
* modification of the file, and distribution when not linked into
* a combined executable.)
*
* This file is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "common.h"
#include "mwindow.h"
#include "vector.h"
#include "fileops.h"
#include "map.h"
#define DEFAULT_WINDOW_SIZE \
(sizeof(void*) >= 8 \
? 1 * 1024 * 1024 * 1024 \
: 32 * 1024 * 1024)
#define DEFAULT_MAPPED_LIMIT \
((1024L * 1024L) * (sizeof(void*) >= 8 ? 8192 : 256))
/*
* We need this because each process is only allowed a specific amount
* of memory. Making it writable should generate one instance per
* process, but we still need to set a couple of variables.
*/
static git_mwindow_ctl ctl = {
.window_size = DEFAULT_WINDOW_SIZE,
.mapped_limit = DEFAULT_MAPPED_LIMIT
};
/*
* Free all the windows in a sequence, typically because we're done
* with the file
*/
void git_mwindow_free_all(git_mwindow_file *mwf)
{
unsigned int i;
/*
* Remove these windows from the global list
*/
for (i = 0; i < ctl.windowfiles.length; ++i){
if (git_vector_get(&ctl.windowfiles, i) == mwf) {
git_vector_remove(&ctl.windowfiles, i);
break;
}
}
if (ctl.windowfiles.length == 0) {
git_vector_free(&ctl.windowfiles);
ctl.windowfiles.contents = NULL;
}
while (mwf->windows) {
git_mwindow *w = mwf->windows;
assert(w->inuse_cnt == 0);
ctl.mapped -= w->window_map.len;
ctl.open_windows--;
git_futils_mmap_free(&w->window_map);
mwf->windows = w->next;
free(w);
}
}
/*
* Check if a window 'win' contains the address 'offset'
*/
int git_mwindow_contains(git_mwindow *win, off_t offset)
{
off_t win_off = win->offset;
return win_off <= offset
&& offset <= (off_t)(win_off + win->window_map.len);
}
/*
* Find the least-recently-used window in a file
*/
void git_mwindow_scan_lru(
git_mwindow_file *mwf,
git_mwindow **lru_w,
git_mwindow **lru_l)
{
git_mwindow *w, *w_l;
for (w_l = NULL, w = mwf->windows; w; w = w->next) {
if (!w->inuse_cnt) {
/*
* If the current one is more recent than the last one,
* store it in the output parameter. If lru_w is NULL,
* it's the first loop, so store it as well.
*/
if (!*lru_w || w->last_used < (*lru_w)->last_used) {
*lru_w = w;
*lru_l = w_l;
}
}
w_l = w;
}
}
/*
* Close the least recently used window. You should check to see if
* the file descriptors need closing from time to time.
*/
int git_mwindow_close_lru(git_mwindow_file *mwf)
{
unsigned int i;
git_mwindow *lru_w = NULL, *lru_l = NULL;
/* FIMXE: Does this give us any advantage? */
if(mwf->windows)
git_mwindow_scan_lru(mwf, &lru_w, &lru_l);
for (i = 0; i < ctl.windowfiles.length; ++i) {
git_mwindow_scan_lru(git_vector_get(&ctl.windowfiles, i), &lru_w, &lru_l);
}
if (lru_w) {
git_mwindow_close(&lru_w);
ctl.mapped -= lru_w->window_map.len;
git_futils_mmap_free(&lru_w->window_map);
if (lru_l)
lru_l->next = lru_w->next;
else
mwf->windows = lru_w->next;
free(lru_w);
ctl.open_windows--;
return GIT_SUCCESS;
}
return git__throw(GIT_ERROR, "Failed to close memory window. Couln't find LRU");
}
static git_mwindow *new_window(git_mwindow_file *mwf, git_file fd, size_t size, off_t offset)
{
size_t walign = ctl.window_size / 2;
size_t len;
git_mwindow *w;
w = git__malloc(sizeof(*w));
if (w == NULL)
return w;
memset(w, 0x0, sizeof(*w));
w->offset = (offset / walign) * walign;
len = size - w->offset;
if (len > ctl.window_size)
len = ctl.window_size;
ctl.mapped += len;
while(ctl.mapped_limit < ctl.mapped &&
git_mwindow_close_lru(mwf) == GIT_SUCCESS) {}
/* FIXME: Shouldn't we error out if there's an error in closing lru? */
if (git_futils_mmap_ro(&w->window_map, fd, w->offset, len) < GIT_SUCCESS)
goto cleanup;
ctl.mmap_calls++;
ctl.open_windows++;
if (ctl.mapped > ctl.peak_mapped)
ctl.peak_mapped = ctl.mapped;
if (ctl.open_windows > ctl.peak_open_windows)
ctl.peak_open_windows = ctl.open_windows;
return w;
cleanup:
free(w);
return NULL;
}
/*
* Open a new window, closing the least recenty used until we have
* enough space. Don't forget to add it to your list
*/
unsigned char *git_mwindow_open(git_mwindow_file *mwf, git_mwindow **cursor, git_file fd,
size_t size, off_t offset, int extra, unsigned int *left)
{
git_mwindow *w = *cursor;
if (!w || !git_mwindow_contains(w, offset + extra)) {
if (w) {
w->inuse_cnt--;
}
for (w = mwf->windows; w; w = w->next) {
if (git_mwindow_contains(w, offset + extra))
break;
}
/*
* If there isn't a suitable window, we need to create a new
* one.
*/
if (!w) {
w = new_window(mwf, fd, size, offset);
if (w == NULL)
return NULL;
w->next = mwf->windows;
mwf->windows = w;
}
}
/* If we changed w, store it in the cursor */
if (w != *cursor) {
w->last_used = ctl.used_ctr++;
w->inuse_cnt++;
*cursor = w;
}
offset -= w->offset;
assert(git__is_sizet(offset));
if (left)
*left = w->window_map.len - offset;
return (unsigned char *) w->window_map.data + offset;
free(w);
return NULL;
}
int git_mwindow_file_register(git_mwindow_file *mwf)
{
int error;
if (ctl.windowfiles.length == 0 &&
(error = git_vector_init(&ctl.windowfiles, 8, NULL)) < GIT_SUCCESS)
return error;
return git_vector_insert(&ctl.windowfiles, mwf);
}
void git_mwindow_close(git_mwindow **window)
{
git_mwindow *w = *window;
if (w) {
w->inuse_cnt--;
*window = NULL;
}
}

64
src/mwindow.h Normal file
View File

@ -0,0 +1,64 @@
/*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License, version 2,
* as published by the Free Software Foundation.
*
* In addition to the permissions in the GNU General Public License,
* the authors give you unlimited permission to link the compiled
* version of this file into combinations with other programs,
* and to distribute those combinations without any restriction
* coming from the use of this file. (The General Public License
* restrictions do apply in other respects; for example, they cover
* modification of the file, and distribution when not linked into
* a combined executable.)
*
* This file is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#ifndef INCLUDE_mwindow__
#define INCLUDE_mwindow__
#include "map.h"
#include "vector.h"
#include "fileops.h"
typedef struct git_mwindow {
struct git_mwindow *next;
git_map window_map;
off_t offset;
unsigned int last_used;
unsigned int inuse_cnt;
} git_mwindow;
typedef struct git_mwindow_file {
git_mwindow *windows;
} git_mwindow_file;
typedef struct git_mwindow_ctl {
size_t mapped;
unsigned int open_windows;
size_t window_size; /* needs default value */
size_t mapped_limit; /* needs default value */
unsigned int mmap_calls;
unsigned int peak_open_windows;
size_t peak_mapped;
size_t used_ctr;
git_vector windowfiles;
} git_mwindow_ctl;
int git_mwindow_contains(git_mwindow *win, off_t offset);
void git_mwindow_free_all(git_mwindow_file *mwf);
unsigned char *git_mwindow_open(git_mwindow_file *mwf, git_mwindow **cursor, git_file fd, size_t size, off_t offset, int extra, unsigned int *left);
void git_mwindow_scan_lru(git_mwindow_file *mwf, git_mwindow **lru_w, git_mwindow **lru_l);
int git_mwindow_file_register(git_mwindow_file *mwf);
void git_mwindow_close(git_mwindow **w_cursor);
#endif

View File

@ -32,17 +32,10 @@
#include "odb.h" #include "odb.h"
#include "delta-apply.h" #include "delta-apply.h"
#include "sha1_lookup.h" #include "sha1_lookup.h"
#include "mwindow.h"
#include "git2/odb_backend.h" #include "git2/odb_backend.h"
#define DEFAULT_WINDOW_SIZE \
(sizeof(void*) >= 8 \
? 1 * 1024 * 1024 * 1024 \
: 32 * 1024 * 1024)
#define DEFAULT_MAPPED_LIMIT \
((1024L * 1024L) * (sizeof(void*) >= 8 ? 8192 : 256))
#define PACK_SIGNATURE 0x5041434b /* "PACK" */ #define PACK_SIGNATURE 0x5041434b /* "PACK" */
#define PACK_VERSION 2 #define PACK_VERSION 2
#define pack_version_ok(v) ((v) == htonl(2) || (v) == htonl(3)) #define pack_version_ok(v) ((v) == htonl(2) || (v) == htonl(3))
@ -76,18 +69,11 @@ struct pack_idx_header {
uint32_t idx_version; uint32_t idx_version;
}; };
struct pack_window {
struct pack_window *next;
git_map window_map;
off_t offset;
unsigned int last_used;
unsigned int inuse_cnt;
};
struct pack_file { struct pack_file {
struct pack_window *windows; int pack_fd;
git_mwindow_file mwf;
//git_mwindow *windows;
off_t pack_size; off_t pack_size;
git_map index_map; git_map index_map;
uint32_t num_objects; uint32_t num_objects;
@ -96,7 +82,6 @@ struct pack_file {
int index_version; int index_version;
git_time_t mtime; git_time_t mtime;
int pack_fd;
unsigned pack_local:1, pack_keep:1; unsigned pack_local:1, pack_keep:1;
git_oid sha1; git_oid sha1;
@ -116,19 +101,6 @@ struct pack_backend {
struct pack_file *last_found; struct pack_file *last_found;
char *pack_folder; char *pack_folder;
time_t pack_folder_mtime; time_t pack_folder_mtime;
size_t window_size; /* needs default value */
size_t mapped_limit; /* needs default value */
size_t peak_mapped;
size_t mapped;
size_t used_ctr;
unsigned int peak_open_windows;
unsigned int open_windows;
unsigned int mmap_calls;
}; };
/** /**
@ -226,8 +198,6 @@ struct pack_backend {
*/ */
/*********************************************************** /***********************************************************
* *
* FORWARD DECLARATIONS * FORWARD DECLARATIONS
@ -235,19 +205,10 @@ struct pack_backend {
***********************************************************/ ***********************************************************/
static void pack_window_free_all(struct pack_backend *backend, struct pack_file *p); static void pack_window_free_all(struct pack_backend *backend, struct pack_file *p);
static int pack_window_contains(struct pack_window *win, off_t offset); static int pack_window_contains(git_mwindow *win, off_t offset);
static void pack_window_scan_lru(struct pack_file *p, struct pack_file **lru_p, static unsigned char *pack_window_open(struct pack_file *p,
struct pack_window **lru_w, struct pack_window **lru_l); git_mwindow **w_cursor, off_t offset, unsigned int *left);
static int pack_window_close_lru( struct pack_backend *backend,
struct pack_file *current, git_file keep_fd);
static void pack_window_close(struct pack_window **w_cursor);
static unsigned char *pack_window_open( struct pack_backend *backend,
struct pack_file *p, struct pack_window **w_cursor, off_t offset,
unsigned int *left);
static int packfile_sort__cb(const void *a_, const void *b_); static int packfile_sort__cb(const void *a_, const void *b_);
@ -299,8 +260,7 @@ static int pack_entry_find_prefix(struct pack_entry *e,
const git_oid *short_oid, const git_oid *short_oid,
unsigned int len); unsigned int len);
static off_t get_delta_base(struct pack_backend *backend, static off_t get_delta_base(struct pack_file *p, git_mwindow **w_curs,
struct pack_file *p, struct pack_window **w_curs,
off_t *curpos, git_otype type, off_t *curpos, git_otype type,
off_t delta_obj_offset); off_t delta_obj_offset);
@ -313,16 +273,14 @@ static unsigned long packfile_unpack_header1(
static int packfile_unpack_header( static int packfile_unpack_header(
size_t *size_p, size_t *size_p,
git_otype *type_p, git_otype *type_p,
struct pack_backend *backend,
struct pack_file *p, struct pack_file *p,
struct pack_window **w_curs, git_mwindow **w_curs,
off_t *curpos); off_t *curpos);
static int packfile_unpack_compressed( static int packfile_unpack_compressed(
git_rawobj *obj, git_rawobj *obj,
struct pack_backend *backend,
struct pack_file *p, struct pack_file *p,
struct pack_window **w_curs, git_mwindow **w_curs,
off_t curpos, off_t curpos,
size_t size, size_t size,
git_otype type); git_otype type);
@ -331,7 +289,7 @@ static int packfile_unpack_delta(
git_rawobj *obj, git_rawobj *obj,
struct pack_backend *backend, struct pack_backend *backend,
struct pack_file *p, struct pack_file *p,
struct pack_window **w_curs, git_mwindow **w_curs,
off_t curpos, off_t curpos,
size_t delta_size, size_t delta_size,
git_otype delta_type, git_otype delta_type,
@ -350,23 +308,12 @@ static int packfile_unpack(git_rawobj *obj, struct pack_backend *backend,
* *
***********************************************************/ ***********************************************************/
void pack_window_free_all(struct pack_backend *backend, struct pack_file *p) GIT_INLINE(void) pack_window_free_all(struct pack_backend *GIT_UNUSED(backend), struct pack_file *p)
{ {
while (p->windows) { git_mwindow_free_all(&p->mwf);
struct pack_window *w = p->windows;
assert(w->inuse_cnt == 0);
backend->mapped -= w->window_map.len;
backend->open_windows--;
git_futils_mmap_free(&w->window_map);
p->windows = w->next;
free(w);
}
} }
GIT_INLINE(int) pack_window_contains(struct pack_window *win, off_t offset) GIT_INLINE(int) pack_window_contains(git_mwindow *win, off_t offset)
{ {
/* We must promise at least 20 bytes (one hash) after the /* We must promise at least 20 bytes (one hash) after the
* offset is available from this window, otherwise the offset * offset is available from this window, otherwise the offset
@ -374,86 +321,15 @@ GIT_INLINE(int) pack_window_contains(struct pack_window *win, off_t offset)
* has that one hash excess) must be used. This is to support * has that one hash excess) must be used. This is to support
* the object header and delta base parsing routines below. * the object header and delta base parsing routines below.
*/ */
off_t win_off = win->offset; return git_mwindow_contains(win, offset + 20);
return win_off <= offset
&& (offset + 20) <= (off_t)(win_off + win->window_map.len);
}
static void pack_window_scan_lru(
struct pack_file *p,
struct pack_file **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 pack_window_close_lru(
struct pack_backend *backend,
struct pack_file *current,
git_file keep_fd)
{
struct pack_file *lru_p = NULL;
struct pack_window *lru_w = NULL, *lru_l = NULL;
size_t i;
if (current)
pack_window_scan_lru(current, &lru_p, &lru_w, &lru_l);
for (i = 0; i < backend->packs.length; ++i)
pack_window_scan_lru(git_vector_get(&backend->packs, i), &lru_p, &lru_w, &lru_l);
if (lru_p) {
backend->mapped -= lru_w->window_map.len;
git_futils_mmap_free(&lru_w->window_map);
if (lru_l)
lru_l->next = lru_w->next;
else {
lru_p->windows = lru_w->next;
if (!lru_p->windows && lru_p->pack_fd != keep_fd) {
p_close(lru_p->pack_fd);
lru_p->pack_fd = -1;
}
}
free(lru_w);
backend->open_windows--;
return GIT_SUCCESS;
}
return git__throw(GIT_ERROR, "Failed to close pack window");
}
static void pack_window_close(struct pack_window **w_cursor)
{
struct pack_window *w = *w_cursor;
if (w) {
w->inuse_cnt--;
*w_cursor = NULL;
}
} }
static unsigned char *pack_window_open( static unsigned char *pack_window_open(
struct pack_backend *backend,
struct pack_file *p, struct pack_file *p,
struct pack_window **w_cursor, git_mwindow **w_cursor,
off_t offset, off_t offset,
unsigned int *left) unsigned int *left)
{ {
struct pack_window *win = *w_cursor;
if (p->pack_fd == -1 && packfile_open(p) < GIT_SUCCESS) if (p->pack_fd == -1 && packfile_open(p) < GIT_SUCCESS)
return NULL; return NULL;
@ -465,73 +341,8 @@ static unsigned char *pack_window_open(
if (offset > (p->pack_size - 20)) if (offset > (p->pack_size - 20))
return NULL; return NULL;
if (!win || !pack_window_contains(win, offset)) { return git_mwindow_open(&p->mwf, w_cursor, p->pack_fd, p->pack_size, offset, 20, left);
}
if (win)
win->inuse_cnt--;
for (win = p->windows; win; win = win->next) {
if (pack_window_contains(win, offset))
break;
}
if (!win) {
size_t window_align = backend->window_size / 2;
size_t len;
win = git__calloc(1, sizeof(*win));
if (win == NULL)
return NULL;
win->offset = (offset / window_align) * window_align;
len = (size_t)(p->pack_size - win->offset);
if (len > backend->window_size)
len = backend->window_size;
backend->mapped += len;
while (backend->mapped_limit < backend->mapped &&
pack_window_close_lru(backend, p, p->pack_fd) == GIT_SUCCESS) {}
if (git_futils_mmap_ro(&win->window_map, p->pack_fd,
win->offset, len) < GIT_SUCCESS) {
free(win);
return NULL;
}
backend->mmap_calls++;
backend->open_windows++;
if (backend->mapped > backend->peak_mapped)
backend->peak_mapped = backend->mapped;
if (backend->open_windows > backend->peak_open_windows)
backend->peak_open_windows = backend->open_windows;
win->next = p->windows;
p->windows = win;
}
}
if (win != *w_cursor) {
win->last_used = backend->used_ctr++;
win->inuse_cnt++;
*w_cursor = win;
}
offset -= win->offset;
assert(git__is_sizet(offset));
if (left)
*left = win->window_map.len - (size_t)offset;
return (unsigned char *)win->window_map.data + offset;
}
@ -766,6 +577,11 @@ static int packfile_open(struct pack_file *p)
if (p->pack_fd < 0 || p_fstat(p->pack_fd, &st) < GIT_SUCCESS) if (p->pack_fd < 0 || p_fstat(p->pack_fd, &st) < GIT_SUCCESS)
return git__throw(GIT_EOSERR, "Failed to open packfile. File appears to be corrupted"); return git__throw(GIT_EOSERR, "Failed to open packfile. File appears to be corrupted");
if (git_mwindow_file_register(&p->mwf) < GIT_SUCCESS) {
p_close(p->pack_fd);
return git__throw(GIT_ERROR, "Failed to register packfile windows");
}
/* If we created the struct before we had the pack we lack size. */ /* If we created the struct before we had the pack we lack size. */
if (!p->pack_size) { if (!p->pack_size) {
if (!S_ISREG(st.st_mode)) if (!S_ISREG(st.st_mode))
@ -1210,9 +1026,8 @@ static unsigned long packfile_unpack_header1(
static int packfile_unpack_header( static int packfile_unpack_header(
size_t *size_p, size_t *size_p,
git_otype *type_p, git_otype *type_p,
struct pack_backend *backend,
struct pack_file *p, struct pack_file *p,
struct pack_window **w_curs, git_mwindow **w_curs,
off_t *curpos) off_t *curpos)
{ {
unsigned char *base; unsigned char *base;
@ -1225,7 +1040,7 @@ static int packfile_unpack_header(
* the maximum deflated object size is 2^137, which is just * the maximum deflated object size is 2^137, which is just
* insane, so we know won't exceed what we have been given. * insane, so we know won't exceed what we have been given.
*/ */
base = pack_window_open(backend, p, w_curs, *curpos, &left); base = pack_window_open(p, w_curs, *curpos, &left);
if (base == NULL) if (base == NULL)
return GIT_ENOMEM; return GIT_ENOMEM;
@ -1240,9 +1055,8 @@ static int packfile_unpack_header(
static int packfile_unpack_compressed( static int packfile_unpack_compressed(
git_rawobj *obj, git_rawobj *obj,
struct pack_backend *backend,
struct pack_file *p, struct pack_file *p,
struct pack_window **w_curs, git_mwindow **w_curs,
off_t curpos, off_t curpos,
size_t size, size_t size,
git_otype type) git_otype type)
@ -1265,7 +1079,7 @@ static int packfile_unpack_compressed(
} }
do { do {
in = pack_window_open(backend, p, w_curs, curpos, &stream.avail_in); in = pack_window_open(p, w_curs, curpos, &stream.avail_in);
stream.next_in = in; stream.next_in = in;
st = inflate(&stream, Z_FINISH); st = inflate(&stream, Z_FINISH);
@ -1289,14 +1103,13 @@ static int packfile_unpack_compressed(
} }
static off_t get_delta_base( static off_t get_delta_base(
struct pack_backend *backend,
struct pack_file *p, struct pack_file *p,
struct pack_window **w_curs, git_mwindow **w_curs,
off_t *curpos, off_t *curpos,
git_otype type, git_otype type,
off_t delta_obj_offset) off_t delta_obj_offset)
{ {
unsigned char *base_info = pack_window_open(backend, p, w_curs, *curpos, NULL); unsigned char *base_info = pack_window_open(p, w_curs, *curpos, NULL);
off_t base_offset; off_t base_offset;
git_oid unused; git_oid unused;
@ -1336,7 +1149,7 @@ static int packfile_unpack_delta(
git_rawobj *obj, git_rawobj *obj,
struct pack_backend *backend, struct pack_backend *backend,
struct pack_file *p, struct pack_file *p,
struct pack_window **w_curs, git_mwindow **w_curs,
off_t curpos, off_t curpos,
size_t delta_size, size_t delta_size,
git_otype delta_type, git_otype delta_type,
@ -1346,11 +1159,11 @@ static int packfile_unpack_delta(
git_rawobj base, delta; git_rawobj base, delta;
int error; int error;
base_offset = get_delta_base(backend, p, w_curs, &curpos, delta_type, obj_offset); base_offset = get_delta_base(p, w_curs, &curpos, delta_type, obj_offset);
if (base_offset == 0) if (base_offset == 0)
return git__throw(GIT_EOBJCORRUPTED, "Delta offset is zero"); return git__throw(GIT_EOBJCORRUPTED, "Delta offset is zero");
pack_window_close(w_curs); git_mwindow_close(w_curs);
error = packfile_unpack(&base, backend, p, base_offset); error = packfile_unpack(&base, backend, p, base_offset);
/* TODO: git.git tries to load the base from other packfiles /* TODO: git.git tries to load the base from other packfiles
@ -1358,7 +1171,7 @@ static int packfile_unpack_delta(
if (error < GIT_SUCCESS) if (error < GIT_SUCCESS)
return git__rethrow(error, "Corrupted delta"); return git__rethrow(error, "Corrupted delta");
error = packfile_unpack_compressed(&delta, backend, p, w_curs, curpos, delta_size, delta_type); error = packfile_unpack_compressed(&delta, p, w_curs, curpos, delta_size, delta_type);
if (error < GIT_SUCCESS) { if (error < GIT_SUCCESS) {
free(base.data); free(base.data);
return git__rethrow(error, "Corrupted delta"); return git__rethrow(error, "Corrupted delta");
@ -1383,7 +1196,7 @@ static int packfile_unpack(
struct pack_file *p, struct pack_file *p,
off_t obj_offset) off_t obj_offset)
{ {
struct pack_window *w_curs = NULL; git_mwindow *w_curs = NULL;
off_t curpos = obj_offset; off_t curpos = obj_offset;
int error; int error;
@ -1398,7 +1211,7 @@ static int packfile_unpack(
obj->len = 0; obj->len = 0;
obj->type = GIT_OBJ_BAD; obj->type = GIT_OBJ_BAD;
error = packfile_unpack_header(&size, &type, backend, p, &w_curs, &curpos); error = packfile_unpack_header(&size, &type, p, &w_curs, &curpos);
if (error < GIT_SUCCESS) if (error < GIT_SUCCESS)
return git__rethrow(error, "Failed to unpack packfile"); return git__rethrow(error, "Failed to unpack packfile");
@ -1415,7 +1228,7 @@ static int packfile_unpack(
case GIT_OBJ_BLOB: case GIT_OBJ_BLOB:
case GIT_OBJ_TAG: case GIT_OBJ_TAG:
error = packfile_unpack_compressed( error = packfile_unpack_compressed(
obj, backend, p, &w_curs, curpos, obj, p, &w_curs, curpos,
size, type); size, type);
break; break;
@ -1424,7 +1237,7 @@ static int packfile_unpack(
break; break;
} }
pack_window_close(&w_curs); git_mwindow_close(&w_curs);
return error == GIT_SUCCESS ? GIT_SUCCESS : git__rethrow(error, "Failed to unpack packfile"); return error == GIT_SUCCESS ? GIT_SUCCESS : git__rethrow(error, "Failed to unpack packfile");
} }
@ -1551,9 +1364,6 @@ int git_odb_backend_pack(git_odb_backend **backend_out, const char *objects_dir)
return GIT_ENOMEM; return GIT_ENOMEM;
} }
backend->window_size = DEFAULT_WINDOW_SIZE;
backend->mapped_limit = DEFAULT_MAPPED_LIMIT;
git_path_join(path, objects_dir, "pack"); git_path_join(path, objects_dir, "pack");
if (git_futils_isdir(path) == GIT_SUCCESS) { if (git_futils_isdir(path) == GIT_SUCCESS) {
backend->pack_folder = git__strdup(path); backend->pack_folder = git__strdup(path);