]> git.proxmox.com Git - libgit2.git/blame - src/odb_mempack.c
Upload to experimental
[libgit2.git] / src / odb_mempack.c
CommitLineData
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
25struct 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
32struct memory_packer_db {
33 git_odb_backend parent;
34 git_oidmap *objects;
35 git_array_t(struct memobject *) commits;
36};
37
ac3d33df 38static 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
68static 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 75static 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 92static 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
105static 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
130cleanup:
131 git_packbuilder_free(packbuilder);
132 return err;
133}
134
e579e0f7
MB
135int 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 143int 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
159static 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
168int 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}