]>
Commit | Line | Data |
---|---|---|
6105d597 VM |
1 | /* |
2 | * Copyright (C) the libgit2 contributors. All rights reserved. | |
3 | * | |
4 | * This file is part of libgit2, distributed under the GNU GPL v2 with | |
5 | * a Linking Exception. For full terms see the included COPYING file. | |
6 | */ | |
7 | ||
8 | #include "common.h" | |
eae0bfdc | 9 | |
e579e0f7 | 10 | #include "buf.h" |
22a2d3d5 | 11 | #include "futils.h" |
6105d597 VM |
12 | #include "hash.h" |
13 | #include "odb.h" | |
14 | #include "array.h" | |
15 | #include "oidmap.h" | |
e579e0f7 | 16 | #include "pack-objects.h" |
6105d597 VM |
17 | |
18 | #include "git2/odb_backend.h" | |
e579e0f7 | 19 | #include "git2/object.h" |
6105d597 VM |
20 | #include "git2/types.h" |
21 | #include "git2/pack.h" | |
e579e0f7 MB |
22 | #include "git2/sys/odb_backend.h" |
23 | #include "git2/sys/mempack.h" | |
6105d597 | 24 | |
6105d597 VM |
25 | struct memobject { |
26 | git_oid oid; | |
27 | size_t len; | |
ac3d33df | 28 | git_object_t type; |
8468a440 | 29 | char data[GIT_FLEX_ARRAY]; |
6105d597 VM |
30 | }; |
31 | ||
32 | struct memory_packer_db { | |
33 | git_odb_backend parent; | |
34 | git_oidmap *objects; | |
35 | git_array_t(struct memobject *) commits; | |
36 | }; | |
37 | ||
ac3d33df | 38 | static int impl__write(git_odb_backend *_backend, const git_oid *oid, const void *data, size_t len, git_object_t type) |
6105d597 VM |
39 | { |
40 | struct memory_packer_db *db = (struct memory_packer_db *)_backend; | |
ac3d33df | 41 | struct memobject *obj = NULL; |
f1453c59 | 42 | size_t alloc_len; |
6105d597 | 43 | |
22a2d3d5 | 44 | if (git_oidmap_exists(db->objects, oid)) |
6105d597 VM |
45 | return 0; |
46 | ||
ac3d33df | 47 | GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, sizeof(struct memobject), len); |
f1453c59 | 48 | obj = git__malloc(alloc_len); |
ac3d33df | 49 | GIT_ERROR_CHECK_ALLOC(obj); |
6105d597 VM |
50 | |
51 | memcpy(obj->data, data, len); | |
52 | git_oid_cpy(&obj->oid, oid); | |
53 | obj->len = len; | |
54 | obj->type = type; | |
55 | ||
22a2d3d5 UG |
56 | if (git_oidmap_set(db->objects, &obj->oid, obj) < 0) |
57 | return -1; | |
6105d597 | 58 | |
ac3d33df | 59 | if (type == GIT_OBJECT_COMMIT) { |
6105d597 | 60 | struct memobject **store = git_array_alloc(db->commits); |
ac3d33df | 61 | GIT_ERROR_CHECK_ALLOC(store); |
6105d597 VM |
62 | *store = obj; |
63 | } | |
64 | ||
65 | return 0; | |
66 | } | |
67 | ||
68 | static int impl__exists(git_odb_backend *backend, const git_oid *oid) | |
69 | { | |
70 | struct memory_packer_db *db = (struct memory_packer_db *)backend; | |
6105d597 | 71 | |
036daa59 | 72 | return git_oidmap_exists(db->objects, oid); |
6105d597 VM |
73 | } |
74 | ||
ac3d33df | 75 | static int impl__read(void **buffer_p, size_t *len_p, git_object_t *type_p, git_odb_backend *backend, const git_oid *oid) |
6105d597 VM |
76 | { |
77 | struct memory_packer_db *db = (struct memory_packer_db *)backend; | |
22a2d3d5 | 78 | struct memobject *obj; |
6105d597 | 79 | |
22a2d3d5 | 80 | if ((obj = git_oidmap_get(db->objects, oid)) == NULL) |
6105d597 VM |
81 | return GIT_ENOTFOUND; |
82 | ||
6105d597 VM |
83 | *len_p = obj->len; |
84 | *type_p = obj->type; | |
85 | *buffer_p = git__malloc(obj->len); | |
ac3d33df | 86 | GIT_ERROR_CHECK_ALLOC(*buffer_p); |
6105d597 VM |
87 | |
88 | memcpy(*buffer_p, obj->data, obj->len); | |
89 | return 0; | |
90 | } | |
91 | ||
ac3d33df | 92 | static int impl__read_header(size_t *len_p, git_object_t *type_p, git_odb_backend *backend, const git_oid *oid) |
6105d597 VM |
93 | { |
94 | struct memory_packer_db *db = (struct memory_packer_db *)backend; | |
22a2d3d5 | 95 | struct memobject *obj; |
6105d597 | 96 | |
22a2d3d5 | 97 | if ((obj = git_oidmap_get(db->objects, oid)) == NULL) |
6105d597 VM |
98 | return GIT_ENOTFOUND; |
99 | ||
6105d597 VM |
100 | *len_p = obj->len; |
101 | *type_p = obj->type; | |
102 | return 0; | |
103 | } | |
104 | ||
e579e0f7 MB |
105 | static int git_mempack__dump( |
106 | git_str *pack, | |
107 | git_repository *repo, | |
108 | git_odb_backend *_backend) | |
6105d597 VM |
109 | { |
110 | struct memory_packer_db *db = (struct memory_packer_db *)_backend; | |
111 | git_packbuilder *packbuilder; | |
112 | uint32_t i; | |
113 | int err = -1; | |
114 | ||
115 | if (git_packbuilder_new(&packbuilder, repo) < 0) | |
116 | return -1; | |
117 | ||
22a2d3d5 UG |
118 | git_packbuilder_set_threads(packbuilder, 0); |
119 | ||
6105d597 VM |
120 | for (i = 0; i < db->commits.size; ++i) { |
121 | struct memobject *commit = db->commits.ptr[i]; | |
122 | ||
123 | err = git_packbuilder_insert_commit(packbuilder, &commit->oid); | |
124 | if (err < 0) | |
125 | goto cleanup; | |
126 | } | |
127 | ||
e579e0f7 | 128 | err = git_packbuilder__write_buf(pack, packbuilder); |
6105d597 VM |
129 | |
130 | cleanup: | |
131 | git_packbuilder_free(packbuilder); | |
132 | return err; | |
133 | } | |
134 | ||
e579e0f7 MB |
135 | int git_mempack_dump( |
136 | git_buf *pack, | |
137 | git_repository *repo, | |
138 | git_odb_backend *_backend) | |
139 | { | |
140 | GIT_BUF_WRAP_PRIVATE(pack, git_mempack__dump, repo, _backend); | |
141 | } | |
142 | ||
22a2d3d5 | 143 | int git_mempack_reset(git_odb_backend *_backend) |
6105d597 VM |
144 | { |
145 | struct memory_packer_db *db = (struct memory_packer_db *)_backend; | |
146 | struct memobject *object = NULL; | |
147 | ||
9694d9ba | 148 | git_oidmap_foreach_value(db->objects, object, { |
6105d597 VM |
149 | git__free(object); |
150 | }); | |
151 | ||
152 | git_array_clear(db->commits); | |
8e177b2b | 153 | |
220d6f8a | 154 | git_oidmap_clear(db->objects); |
22a2d3d5 UG |
155 | |
156 | return 0; | |
6105d597 VM |
157 | } |
158 | ||
159 | static void impl__free(git_odb_backend *_backend) | |
160 | { | |
707f6537 BW |
161 | struct memory_packer_db *db = (struct memory_packer_db *)_backend; |
162 | ||
4b3ec53c | 163 | git_mempack_reset(_backend); |
707f6537 | 164 | git_oidmap_free(db->objects); |
707f6537 | 165 | git__free(db); |
6105d597 VM |
166 | } |
167 | ||
168 | int git_mempack_new(git_odb_backend **out) | |
169 | { | |
170 | struct memory_packer_db *db; | |
171 | ||
c25aa7cd | 172 | GIT_ASSERT_ARG(out); |
6105d597 VM |
173 | |
174 | db = git__calloc(1, sizeof(struct memory_packer_db)); | |
ac3d33df | 175 | GIT_ERROR_CHECK_ALLOC(db); |
6105d597 | 176 | |
22a2d3d5 UG |
177 | if (git_oidmap_new(&db->objects) < 0) |
178 | return -1; | |
6105d597 | 179 | |
6a8127d7 | 180 | db->parent.version = GIT_ODB_BACKEND_VERSION; |
6105d597 VM |
181 | db->parent.read = &impl__read; |
182 | db->parent.write = &impl__write; | |
183 | db->parent.read_header = &impl__read_header; | |
184 | db->parent.exists = &impl__exists; | |
185 | db->parent.free = &impl__free; | |
186 | ||
187 | *out = (git_odb_backend *)db; | |
188 | return 0; | |
189 | } |