Skip to content

Commit 4d80560

Browse files
derrickstoleegitster
authored andcommitted
multi-pack-index: load into memory
Create a new multi_pack_index struct for loading multi-pack-indexes into memory. Create a test-tool builtin for reading basic information about that multi-pack-index to verify the correct data is written. Signed-off-by: Derrick Stolee <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent fc59e74 commit 4d80560

File tree

8 files changed

+143
-1
lines changed

8 files changed

+143
-1
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,7 @@ TEST_BUILTINS_OBJS += test-online-cpus.o
717717
TEST_BUILTINS_OBJS += test-path-utils.o
718718
TEST_BUILTINS_OBJS += test-prio-queue.o
719719
TEST_BUILTINS_OBJS += test-read-cache.o
720+
TEST_BUILTINS_OBJS += test-read-midx.o
720721
TEST_BUILTINS_OBJS += test-ref-store.o
721722
TEST_BUILTINS_OBJS += test-regex.o
722723
TEST_BUILTINS_OBJS += test-revision-walking.o

midx.c

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,97 @@
11
#include "cache.h"
22
#include "csum-file.h"
33
#include "lockfile.h"
4+
#include "object-store.h"
45
#include "midx.h"
56

67
#define MIDX_SIGNATURE 0x4d494458 /* "MIDX" */
78
#define MIDX_VERSION 1
9+
#define MIDX_BYTE_FILE_VERSION 4
10+
#define MIDX_BYTE_HASH_VERSION 5
11+
#define MIDX_BYTE_NUM_CHUNKS 6
12+
#define MIDX_BYTE_NUM_PACKS 8
813
#define MIDX_HASH_VERSION 1
914
#define MIDX_HEADER_SIZE 12
15+
#define MIDX_HASH_LEN 20
16+
#define MIDX_MIN_SIZE (MIDX_HEADER_SIZE + MIDX_HASH_LEN)
1017

1118
static char *get_midx_filename(const char *object_dir)
1219
{
1320
return xstrfmt("%s/pack/multi-pack-index", object_dir);
1421
}
1522

23+
struct multi_pack_index *load_multi_pack_index(const char *object_dir)
24+
{
25+
struct multi_pack_index *m = NULL;
26+
int fd;
27+
struct stat st;
28+
size_t midx_size;
29+
void *midx_map = NULL;
30+
uint32_t hash_version;
31+
char *midx_name = get_midx_filename(object_dir);
32+
33+
fd = git_open(midx_name);
34+
35+
if (fd < 0)
36+
goto cleanup_fail;
37+
if (fstat(fd, &st)) {
38+
error_errno(_("failed to read %s"), midx_name);
39+
goto cleanup_fail;
40+
}
41+
42+
midx_size = xsize_t(st.st_size);
43+
44+
if (midx_size < MIDX_MIN_SIZE) {
45+
error(_("multi-pack-index file %s is too small"), midx_name);
46+
goto cleanup_fail;
47+
}
48+
49+
FREE_AND_NULL(midx_name);
50+
51+
midx_map = xmmap(NULL, midx_size, PROT_READ, MAP_PRIVATE, fd, 0);
52+
53+
FLEX_ALLOC_MEM(m, object_dir, object_dir, strlen(object_dir));
54+
m->fd = fd;
55+
m->data = midx_map;
56+
m->data_len = midx_size;
57+
58+
m->signature = get_be32(m->data);
59+
if (m->signature != MIDX_SIGNATURE) {
60+
error(_("multi-pack-index signature 0x%08x does not match signature 0x%08x"),
61+
m->signature, MIDX_SIGNATURE);
62+
goto cleanup_fail;
63+
}
64+
65+
m->version = m->data[MIDX_BYTE_FILE_VERSION];
66+
if (m->version != MIDX_VERSION) {
67+
error(_("multi-pack-index version %d not recognized"),
68+
m->version);
69+
goto cleanup_fail;
70+
}
71+
72+
hash_version = m->data[MIDX_BYTE_HASH_VERSION];
73+
if (hash_version != MIDX_HASH_VERSION) {
74+
error(_("hash version %u does not match"), hash_version);
75+
goto cleanup_fail;
76+
}
77+
m->hash_len = MIDX_HASH_LEN;
78+
79+
m->num_chunks = m->data[MIDX_BYTE_NUM_CHUNKS];
80+
81+
m->num_packs = get_be32(m->data + MIDX_BYTE_NUM_PACKS);
82+
83+
return m;
84+
85+
cleanup_fail:
86+
free(m);
87+
free(midx_name);
88+
if (midx_map)
89+
munmap(midx_map, midx_size);
90+
if (0 <= fd)
91+
close(fd);
92+
return NULL;
93+
}
94+
1695
static size_t write_midx_header(struct hashfile *f,
1796
unsigned char num_chunks,
1897
uint32_t num_packs)

midx.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,24 @@
11
#ifndef __MIDX_H__
22
#define __MIDX_H__
33

4+
struct multi_pack_index {
5+
int fd;
6+
7+
const unsigned char *data;
8+
size_t data_len;
9+
10+
uint32_t signature;
11+
unsigned char version;
12+
unsigned char hash_len;
13+
unsigned char num_chunks;
14+
uint32_t num_packs;
15+
uint32_t num_objects;
16+
17+
char object_dir[FLEX_ARRAY];
18+
};
19+
20+
struct multi_pack_index *load_multi_pack_index(const char *object_dir);
21+
422
int write_midx_file(const char *object_dir);
523

624
#endif

object-store.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,8 @@ struct packed_git {
8484
char pack_name[FLEX_ARRAY]; /* more */
8585
};
8686

87+
struct multi_pack_index;
88+
8789
struct raw_object_store {
8890
/*
8991
* Path to the repository's object store.

t/helper/test-read-midx.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#include "test-tool.h"
2+
#include "cache.h"
3+
#include "midx.h"
4+
#include "repository.h"
5+
#include "object-store.h"
6+
7+
static int read_midx_file(const char *object_dir)
8+
{
9+
struct multi_pack_index *m = load_multi_pack_index(object_dir);
10+
11+
if (!m)
12+
return 1;
13+
14+
printf("header: %08x %d %d %d\n",
15+
m->signature,
16+
m->version,
17+
m->num_chunks,
18+
m->num_packs);
19+
20+
printf("object-dir: %s\n", m->object_dir);
21+
22+
return 0;
23+
}
24+
25+
int cmd__read_midx(int argc, const char **argv)
26+
{
27+
if (argc != 2)
28+
usage("read-midx <object-dir>");
29+
30+
return read_midx_file(argv[1]);
31+
}

t/helper/test-tool.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ static struct test_cmd cmds[] = {
2727
{ "path-utils", cmd__path_utils },
2828
{ "prio-queue", cmd__prio_queue },
2929
{ "read-cache", cmd__read_cache },
30+
{ "read-midx", cmd__read_midx },
3031
{ "ref-store", cmd__ref_store },
3132
{ "regex", cmd__regex },
3233
{ "revision-walking", cmd__revision_walking },

t/helper/test-tool.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ int cmd__online_cpus(int argc, const char **argv);
2121
int cmd__path_utils(int argc, const char **argv);
2222
int cmd__prio_queue(int argc, const char **argv);
2323
int cmd__read_cache(int argc, const char **argv);
24+
int cmd__read_midx(int argc, const char **argv);
2425
int cmd__ref_store(int argc, const char **argv);
2526
int cmd__regex(int argc, const char **argv);
2627
int cmd__revision_walking(int argc, const char **argv);

t/t5319-multi-pack-index.sh

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,19 @@
33
test_description='multi-pack-indexes'
44
. ./test-lib.sh
55

6+
midx_read_expect () {
7+
cat >expect <<-EOF
8+
header: 4d494458 1 0 0
9+
object-dir: .
10+
EOF
11+
test-tool read-midx . >actual &&
12+
test_cmp expect actual
13+
}
14+
615
test_expect_success 'write midx with no packs' '
716
test_when_finished rm -f pack/multi-pack-index &&
817
git multi-pack-index --object-dir=. write &&
9-
test_path_is_file pack/multi-pack-index
18+
midx_read_expect
1019
'
1120

1221
test_done

0 commit comments

Comments
 (0)