5 char *odb_pack_name(struct strbuf
*buf
,
6 const unsigned char *sha1
,
10 strbuf_addf(buf
, "%s/pack/pack-%s.%s", get_object_directory(),
11 sha1_to_hex(sha1
), ext
);
15 char *sha1_pack_name(const unsigned char *sha1
)
17 static struct strbuf buf
= STRBUF_INIT
;
18 return odb_pack_name(&buf
, sha1
, "pack");
21 char *sha1_pack_index_name(const unsigned char *sha1
)
23 static struct strbuf buf
= STRBUF_INIT
;
24 return odb_pack_name(&buf
, sha1
, "idx");
27 unsigned int pack_used_ctr
;
28 unsigned int pack_mmap_calls
;
29 unsigned int peak_pack_open_windows
;
30 unsigned int pack_open_windows
;
31 unsigned int pack_open_fds
;
32 unsigned int pack_max_fds
;
33 size_t peak_pack_mapped
;
35 struct packed_git
*packed_git
;
37 static struct mru packed_git_mru_storage
;
38 struct mru
*packed_git_mru
= &packed_git_mru_storage
;
40 #define SZ_FMT PRIuMAX
41 static inline uintmax_t sz_fmt(size_t s
) { return s
; }
43 void pack_report(void)
46 "pack_report: getpagesize() = %10" SZ_FMT
"\n"
47 "pack_report: core.packedGitWindowSize = %10" SZ_FMT
"\n"
48 "pack_report: core.packedGitLimit = %10" SZ_FMT
"\n",
49 sz_fmt(getpagesize()),
50 sz_fmt(packed_git_window_size
),
51 sz_fmt(packed_git_limit
));
53 "pack_report: pack_used_ctr = %10u\n"
54 "pack_report: pack_mmap_calls = %10u\n"
55 "pack_report: pack_open_windows = %10u / %10u\n"
56 "pack_report: pack_mapped = "
57 "%10" SZ_FMT
" / %10" SZ_FMT
"\n",
60 pack_open_windows
, peak_pack_open_windows
,
61 sz_fmt(pack_mapped
), sz_fmt(peak_pack_mapped
));
65 * Open and mmap the index file at path, perform a couple of
66 * consistency checks, then record its information to p. Return 0 on
69 static int check_packed_git_idx(const char *path
, struct packed_git
*p
)
72 struct pack_idx_header
*hdr
;
74 uint32_t version
, nr
, i
, *index
;
75 int fd
= git_open(path
);
84 idx_size
= xsize_t(st
.st_size
);
85 if (idx_size
< 4 * 256 + 20 + 20) {
87 return error("index file %s is too small", path
);
89 idx_map
= xmmap(NULL
, idx_size
, PROT_READ
, MAP_PRIVATE
, fd
, 0);
93 if (hdr
->idx_signature
== htonl(PACK_IDX_SIGNATURE
)) {
94 version
= ntohl(hdr
->idx_version
);
95 if (version
< 2 || version
> 2) {
96 munmap(idx_map
, idx_size
);
97 return error("index file %s is version %"PRIu32
98 " and is not supported by this binary"
99 " (try upgrading GIT to a newer version)",
108 index
+= 2; /* skip index header */
109 for (i
= 0; i
< 256; i
++) {
110 uint32_t n
= ntohl(index
[i
]);
112 munmap(idx_map
, idx_size
);
113 return error("non-monotonic index %s", path
);
121 * - 256 index entries 4 bytes each
122 * - 24-byte entries * nr (20-byte sha1 + 4-byte offset)
123 * - 20-byte SHA1 of the packfile
124 * - 20-byte SHA1 file checksum
126 if (idx_size
!= 4*256 + nr
* 24 + 20 + 20) {
127 munmap(idx_map
, idx_size
);
128 return error("wrong index v1 file size in %s", path
);
130 } else if (version
== 2) {
133 * - 8 bytes of header
134 * - 256 index entries 4 bytes each
135 * - 20-byte sha1 entry * nr
136 * - 4-byte crc entry * nr
137 * - 4-byte offset entry * nr
138 * - 20-byte SHA1 of the packfile
139 * - 20-byte SHA1 file checksum
140 * And after the 4-byte offset table might be a
141 * variable sized table containing 8-byte entries
142 * for offsets larger than 2^31.
144 unsigned long min_size
= 8 + 4*256 + nr
*(20 + 4 + 4) + 20 + 20;
145 unsigned long max_size
= min_size
;
147 max_size
+= (nr
- 1)*8;
148 if (idx_size
< min_size
|| idx_size
> max_size
) {
149 munmap(idx_map
, idx_size
);
150 return error("wrong index v2 file size in %s", path
);
152 if (idx_size
!= min_size
&&
154 * make sure we can deal with large pack offsets.
155 * 31-bit signed offset won't be enough, neither
156 * 32-bit unsigned one will be.
158 (sizeof(off_t
) <= 4)) {
159 munmap(idx_map
, idx_size
);
160 return error("pack too large for current definition of off_t in %s", path
);
164 p
->index_version
= version
;
165 p
->index_data
= idx_map
;
166 p
->index_size
= idx_size
;
171 int open_pack_index(struct packed_git
*p
)
180 if (!strip_suffix(p
->pack_name
, ".pack", &len
))
181 die("BUG: pack_name does not end in .pack");
182 idx_name
= xstrfmt("%.*s.idx", (int)len
, p
->pack_name
);
183 ret
= check_packed_git_idx(idx_name
, p
);
188 static struct packed_git
*alloc_packed_git(int extra
)
190 struct packed_git
*p
= xmalloc(st_add(sizeof(*p
), extra
));
191 memset(p
, 0, sizeof(*p
));
196 struct packed_git
*parse_pack_index(unsigned char *sha1
, const char *idx_path
)
198 const char *path
= sha1_pack_name(sha1
);
199 size_t alloc
= st_add(strlen(path
), 1);
200 struct packed_git
*p
= alloc_packed_git(alloc
);
202 memcpy(p
->pack_name
, path
, alloc
); /* includes NUL */
203 hashcpy(p
->sha1
, sha1
);
204 if (check_packed_git_idx(idx_path
, p
)) {
212 static void scan_windows(struct packed_git
*p
,
213 struct packed_git
**lru_p
,
214 struct pack_window
**lru_w
,
215 struct pack_window
**lru_l
)
217 struct pack_window
*w
, *w_l
;
219 for (w_l
= NULL
, w
= p
->windows
; w
; w
= w
->next
) {
221 if (!*lru_w
|| w
->last_used
< (*lru_w
)->last_used
) {
231 int unuse_one_window(struct packed_git
*current
)
233 struct packed_git
*p
, *lru_p
= NULL
;
234 struct pack_window
*lru_w
= NULL
, *lru_l
= NULL
;
237 scan_windows(current
, &lru_p
, &lru_w
, &lru_l
);
238 for (p
= packed_git
; p
; p
= p
->next
)
239 scan_windows(p
, &lru_p
, &lru_w
, &lru_l
);
241 munmap(lru_w
->base
, lru_w
->len
);
242 pack_mapped
-= lru_w
->len
;
244 lru_l
->next
= lru_w
->next
;
246 lru_p
->windows
= lru_w
->next
;
254 void release_pack_memory(size_t need
)
256 size_t cur
= pack_mapped
;
257 while (need
>= (cur
- pack_mapped
) && unuse_one_window(NULL
))