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 <dstolee@microsoft.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Derrick Stolee committed
Jul 12, 2018 at 15:39 UTC
4d80560c546179654c32499132a6bdaf3c45b16f
8 files changed
+143
-1
Makefile
+1
@@ -717,6 +717,7 @@ TEST_BUILTINS_OBJS += test-online-cpus.o
717
TEST_BUILTINS_OBJS += test-path-utils.o
718
TEST_BUILTINS_OBJS += test-prio-queue.o
719
TEST_BUILTINS_OBJS += test-read-cache.o
720
+TEST_BUILTINS_OBJS += test-read-midx.o
721
TEST_BUILTINS_OBJS += test-ref-store.o
722
TEST_BUILTINS_OBJS += test-regex.o
723
TEST_BUILTINS_OBJS += test-revision-walking.o
midx.c
+79
@@ -1,18 +1,97 @@
1
#include "cache.h"
2
#include "csum-file.h"
3
#include "lockfile.h"
4
+#include "object-store.h"
5
#include "midx.h"
6
7
#define MIDX_SIGNATURE 0x4d494458 /* "MIDX" */
8
#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
13
#define MIDX_HASH_VERSION 1
14
#define MIDX_HEADER_SIZE 12
15
+#define MIDX_HASH_LEN 20
16
+#define MIDX_MIN_SIZE (MIDX_HEADER_SIZE + MIDX_HASH_LEN)
17
18
static char *get_midx_filename(const char *object_dir)
19
{
20
return xstrfmt("%s/pack/multi-pack-index", object_dir);
21
}
22
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
+
95
static size_t write_midx_header(struct hashfile *f,
96
unsigned char num_chunks,
97
uint32_t num_packs)
midx.h
+18
@@ -1,6 +1,24 @@
1
#ifndef __MIDX_H__
2
#define __MIDX_H__
3
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
+
22
int write_midx_file(const char *object_dir);
23
24
#endif
object-store.h
+2
@@ -84,6 +84,8 @@ struct packed_git {
84
char pack_name[FLEX_ARRAY]; /* more */
85
};
86
87
+struct multi_pack_index;
88
+
89
struct raw_object_store {
90
/*
91
* Path to the repository's object store.
t/helper/test-read-midx.c
new
+31
@@ -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
+1
@@ -27,6 +27,7 @@ static struct test_cmd cmds[] = {
27
{ "path-utils", cmd__path_utils },
28
{ "prio-queue", cmd__prio_queue },
29
{ "read-cache", cmd__read_cache },
30
+ { "read-midx", cmd__read_midx },
31
{ "ref-store", cmd__ref_store },
32
{ "regex", cmd__regex },
33
{ "revision-walking", cmd__revision_walking },
t/helper/test-tool.h
+1
@@ -21,6 +21,7 @@ int cmd__online_cpus(int argc, const char **argv);
21
int cmd__path_utils(int argc, const char **argv);
22
int cmd__prio_queue(int argc, const char **argv);
23
int cmd__read_cache(int argc, const char **argv);
24
+int cmd__read_midx(int argc, const char **argv);
25
int cmd__ref_store(int argc, const char **argv);
26
int cmd__regex(int argc, const char **argv);
27
int cmd__revision_walking(int argc, const char **argv);
t/t5319-multi-pack-index.sh
+10
-1
@@ -3,10 +3,19 @@
3
test_description='multi-pack-indexes'
4
. ./test-lib.sh
5
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
+
15
test_expect_success 'write midx with no packs' '
16
test_when_finished rm -f pack/multi-pack-index &&
17
git multi-pack-index --object-dir=. write &&
9
- test_path_is_file pack/multi-pack-index
18
+ midx_read_expect
19
'
20
21
test_done