-
Notifications
You must be signed in to change notification settings - Fork 25.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
pack-mtimes: support reading .mtimes files
To store the individual mtimes of objects in a cruft pack, introduce a new `.mtimes` format that can optionally accompany a single pack in the repository. The format is defined in Documentation/technical/pack-format.txt, and stores a 4-byte network order timestamp for each object in name (index) order. This patch prepares for cruft packs by defining the `.mtimes` format, and introducing a basic API that callers can use to read out individual mtimes. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
- Loading branch information
Showing
7 changed files
with
202 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
#include "git-compat-util.h" | ||
#include "pack-mtimes.h" | ||
#include "object-store.h" | ||
#include "packfile.h" | ||
|
||
static char *pack_mtimes_filename(struct packed_git *p) | ||
{ | ||
size_t len; | ||
if (!strip_suffix(p->pack_name, ".pack", &len)) | ||
BUG("pack_name does not end in .pack"); | ||
return xstrfmt("%.*s.mtimes", (int)len, p->pack_name); | ||
} | ||
|
||
#define MTIMES_HEADER_SIZE (12) | ||
|
||
struct mtimes_header { | ||
uint32_t signature; | ||
uint32_t version; | ||
uint32_t hash_id; | ||
}; | ||
|
||
static int load_pack_mtimes_file(char *mtimes_file, | ||
uint32_t num_objects, | ||
const uint32_t **data_p, size_t *len_p) | ||
{ | ||
int fd, ret = 0; | ||
struct stat st; | ||
uint32_t *data = NULL; | ||
size_t mtimes_size, expected_size; | ||
struct mtimes_header header; | ||
|
||
fd = git_open(mtimes_file); | ||
|
||
if (fd < 0) { | ||
ret = -1; | ||
goto cleanup; | ||
} | ||
if (fstat(fd, &st)) { | ||
ret = error_errno(_("failed to read %s"), mtimes_file); | ||
goto cleanup; | ||
} | ||
|
||
mtimes_size = xsize_t(st.st_size); | ||
|
||
if (mtimes_size < MTIMES_HEADER_SIZE) { | ||
ret = error(_("mtimes file %s is too small"), mtimes_file); | ||
goto cleanup; | ||
} | ||
|
||
data = xmmap(NULL, mtimes_size, PROT_READ, MAP_PRIVATE, fd, 0); | ||
|
||
header.signature = ntohl(data[0]); | ||
header.version = ntohl(data[1]); | ||
header.hash_id = ntohl(data[2]); | ||
|
||
if (header.signature != MTIMES_SIGNATURE) { | ||
ret = error(_("mtimes file %s has unknown signature"), mtimes_file); | ||
goto cleanup; | ||
} | ||
|
||
if (header.version != 1) { | ||
ret = error(_("mtimes file %s has unsupported version %"PRIu32), | ||
mtimes_file, header.version); | ||
goto cleanup; | ||
} | ||
|
||
if (!(header.hash_id == 1 || header.hash_id == 2)) { | ||
ret = error(_("mtimes file %s has unsupported hash id %"PRIu32), | ||
mtimes_file, header.hash_id); | ||
goto cleanup; | ||
} | ||
|
||
|
||
expected_size = MTIMES_HEADER_SIZE; | ||
expected_size = st_add(expected_size, st_mult(sizeof(uint32_t), num_objects)); | ||
expected_size = st_add(expected_size, 2 * (header.hash_id == 1 ? GIT_SHA1_RAWSZ : GIT_SHA256_RAWSZ)); | ||
|
||
if (mtimes_size != expected_size) { | ||
ret = error(_("mtimes file %s is corrupt"), mtimes_file); | ||
goto cleanup; | ||
} | ||
|
||
cleanup: | ||
if (ret) { | ||
if (data) | ||
munmap(data, mtimes_size); | ||
} else { | ||
*len_p = mtimes_size; | ||
*data_p = data; | ||
} | ||
|
||
close(fd); | ||
return ret; | ||
} | ||
|
||
int load_pack_mtimes(struct packed_git *p) | ||
{ | ||
char *mtimes_name = NULL; | ||
int ret = 0; | ||
|
||
if (!p->is_cruft) | ||
return ret; /* not a cruft pack */ | ||
if (p->mtimes_map) | ||
return ret; /* already loaded */ | ||
|
||
ret = open_pack_index(p); | ||
if (ret < 0) | ||
goto cleanup; | ||
|
||
mtimes_name = pack_mtimes_filename(p); | ||
ret = load_pack_mtimes_file(mtimes_name, | ||
p->num_objects, | ||
&p->mtimes_map, | ||
&p->mtimes_size); | ||
cleanup: | ||
free(mtimes_name); | ||
return ret; | ||
} | ||
|
||
uint32_t nth_packed_mtime(struct packed_git *p, uint32_t pos) | ||
{ | ||
if (!p->mtimes_map) | ||
BUG("pack .mtimes file not loaded for %s", p->pack_name); | ||
if (p->num_objects <= pos) | ||
BUG("pack .mtimes out-of-bounds (%"PRIu32" vs %"PRIu32")", | ||
pos, p->num_objects); | ||
|
||
return get_be32(p->mtimes_map + pos + 3); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#ifndef PACK_MTIMES_H | ||
#define PACK_MTIMES_H | ||
|
||
#include "git-compat-util.h" | ||
|
||
#define MTIMES_SIGNATURE 0x4d544d45 /* "MTME" */ | ||
#define MTIMES_VERSION 1 | ||
|
||
struct packed_git; | ||
|
||
/* | ||
* Loads the .mtimes file corresponding to "p", if any, returning zero | ||
* on success. | ||
*/ | ||
int load_pack_mtimes(struct packed_git *p); | ||
|
||
/* Returns the mtime associated with the object at position "pos" (in | ||
* lexicographic/index order) in pack "p". | ||
* | ||
* Note that it is a BUG() to call this function if either (a) "p" does | ||
* not have a corresponding .mtimes file, or (b) it does, but it hasn't | ||
* been loaded | ||
*/ | ||
uint32_t nth_packed_mtime(struct packed_git *p, uint32_t pos); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters