aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sha1_file.c44
1 files changed, 28 insertions, 16 deletions
diff --git a/sha1_file.c b/sha1_file.c
index 63123cc47..01a2f8779 100644
--- a/sha1_file.c
+++ b/sha1_file.c
@@ -451,23 +451,34 @@ static int check_packed_git_idx(const char *path, unsigned long *idx_size_,
return 0;
}
-static int unuse_one_window(void)
-{
- struct packed_git *p, *lru_p = NULL;
- struct pack_window *w, *w_l, *lru_w = NULL, *lru_l = NULL;
-
- for (p = packed_git; p; p = p->next) {
- 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;
- }
+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;
}
+ w_l = w;
}
+}
+
+static int unuse_one_window(struct packed_git *current)
+{
+ struct packed_git *p, *lru_p = NULL;
+ struct pack_window *lru_w = NULL, *lru_l = NULL;
+
+ if (current)
+ scan_windows(current, &lru_p, &lru_w, &lru_l);
+ for (p = packed_git; p; p = p->next)
+ scan_windows(p, &lru_p, &lru_w, &lru_l);
if (lru_p) {
munmap(lru_w->base, lru_w->len);
pack_mapped -= lru_w->len;
@@ -475,7 +486,7 @@ static int unuse_one_window(void)
lru_l->next = lru_w->next;
else {
lru_p->windows = lru_w->next;
- if (!lru_p->windows) {
+ if (!lru_p->windows && lru_p != current) {
close(lru_p->pack_fd);
lru_p->pack_fd = -1;
}
@@ -584,7 +595,8 @@ unsigned char* use_pack(struct packed_git *p,
if (win->len > packed_git_window_size)
win->len = packed_git_window_size;
pack_mapped += win->len;
- while (packed_git_limit < pack_mapped && unuse_one_window())
+ while (packed_git_limit < pack_mapped
+ && unuse_one_window(p))
; /* nothing */
win->base = mmap(NULL, win->len,
PROT_READ, MAP_PRIVATE,