]> git.proxmox.com Git - libgit2.git/blob - src/odb_mempack.c
Add BD on ca-certificates
[libgit2.git] / src / odb_mempack.c
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"
9
10 #include "git2/object.h"
11 #include "git2/sys/odb_backend.h"
12 #include "git2/sys/mempack.h"
13 #include "fileops.h"
14 #include "hash.h"
15 #include "odb.h"
16 #include "array.h"
17 #include "oidmap.h"
18
19 #include "git2/odb_backend.h"
20 #include "git2/types.h"
21 #include "git2/pack.h"
22
23 struct memobject {
24 git_oid oid;
25 size_t len;
26 git_object_t type;
27 char data[GIT_FLEX_ARRAY];
28 };
29
30 struct memory_packer_db {
31 git_odb_backend parent;
32 git_oidmap *objects;
33 git_array_t(struct memobject *) commits;
34 };
35
36 static int impl__write(git_odb_backend *_backend, const git_oid *oid, const void *data, size_t len, git_object_t type)
37 {
38 struct memory_packer_db *db = (struct memory_packer_db *)_backend;
39 struct memobject *obj = NULL;
40 size_t pos;
41 size_t alloc_len;
42 int rval;
43
44 pos = git_oidmap_put(db->objects, oid, &rval);
45 if (rval < 0)
46 return -1;
47
48 if (rval == 0)
49 return 0;
50
51 GIT_ERROR_CHECK_ALLOC_ADD(&alloc_len, sizeof(struct memobject), len);
52 obj = git__malloc(alloc_len);
53 GIT_ERROR_CHECK_ALLOC(obj);
54
55 memcpy(obj->data, data, len);
56 git_oid_cpy(&obj->oid, oid);
57 obj->len = len;
58 obj->type = type;
59
60 git_oidmap_set_key_at(db->objects, pos, &obj->oid);
61 git_oidmap_set_value_at(db->objects, pos, obj);
62
63 if (type == GIT_OBJECT_COMMIT) {
64 struct memobject **store = git_array_alloc(db->commits);
65 GIT_ERROR_CHECK_ALLOC(store);
66 *store = obj;
67 }
68
69 return 0;
70 }
71
72 static int impl__exists(git_odb_backend *backend, const git_oid *oid)
73 {
74 struct memory_packer_db *db = (struct memory_packer_db *)backend;
75
76 return git_oidmap_exists(db->objects, oid);
77 }
78
79 static int impl__read(void **buffer_p, size_t *len_p, git_object_t *type_p, git_odb_backend *backend, const git_oid *oid)
80 {
81 struct memory_packer_db *db = (struct memory_packer_db *)backend;
82 struct memobject *obj = NULL;
83 size_t pos;
84
85 pos = git_oidmap_lookup_index(db->objects, oid);
86 if (!git_oidmap_valid_index(db->objects, pos))
87 return GIT_ENOTFOUND;
88
89 obj = git_oidmap_value_at(db->objects, pos);
90
91 *len_p = obj->len;
92 *type_p = obj->type;
93 *buffer_p = git__malloc(obj->len);
94 GIT_ERROR_CHECK_ALLOC(*buffer_p);
95
96 memcpy(*buffer_p, obj->data, obj->len);
97 return 0;
98 }
99
100 static int impl__read_header(size_t *len_p, git_object_t *type_p, git_odb_backend *backend, const git_oid *oid)
101 {
102 struct memory_packer_db *db = (struct memory_packer_db *)backend;
103 struct memobject *obj = NULL;
104 size_t pos;
105
106 pos = git_oidmap_lookup_index(db->objects, oid);
107 if (!git_oidmap_valid_index(db->objects, pos))
108 return GIT_ENOTFOUND;
109
110 obj = git_oidmap_value_at(db->objects, pos);
111
112 *len_p = obj->len;
113 *type_p = obj->type;
114 return 0;
115 }
116
117 int git_mempack_dump(git_buf *pack, git_repository *repo, git_odb_backend *_backend)
118 {
119 struct memory_packer_db *db = (struct memory_packer_db *)_backend;
120 git_packbuilder *packbuilder;
121 uint32_t i;
122 int err = -1;
123
124 if (git_packbuilder_new(&packbuilder, repo) < 0)
125 return -1;
126
127 for (i = 0; i < db->commits.size; ++i) {
128 struct memobject *commit = db->commits.ptr[i];
129
130 err = git_packbuilder_insert_commit(packbuilder, &commit->oid);
131 if (err < 0)
132 goto cleanup;
133 }
134
135 err = git_packbuilder_write_buf(pack, packbuilder);
136
137 cleanup:
138 git_packbuilder_free(packbuilder);
139 return err;
140 }
141
142 void git_mempack_reset(git_odb_backend *_backend)
143 {
144 struct memory_packer_db *db = (struct memory_packer_db *)_backend;
145 struct memobject *object = NULL;
146
147 git_oidmap_foreach_value(db->objects, object, {
148 git__free(object);
149 });
150
151 git_array_clear(db->commits);
152
153 git_oidmap_clear(db->objects);
154 }
155
156 static void impl__free(git_odb_backend *_backend)
157 {
158 struct memory_packer_db *db = (struct memory_packer_db *)_backend;
159
160 git_mempack_reset(_backend);
161 git_oidmap_free(db->objects);
162 git__free(db);
163 }
164
165 int git_mempack_new(git_odb_backend **out)
166 {
167 struct memory_packer_db *db;
168
169 assert(out);
170
171 db = git__calloc(1, sizeof(struct memory_packer_db));
172 GIT_ERROR_CHECK_ALLOC(db);
173
174 db->objects = git_oidmap_alloc();
175
176 db->parent.version = GIT_ODB_BACKEND_VERSION;
177 db->parent.read = &impl__read;
178 db->parent.write = &impl__write;
179 db->parent.read_header = &impl__read_header;
180 db->parent.exists = &impl__exists;
181 db->parent.free = &impl__free;
182
183 *out = (git_odb_backend *)db;
184 return 0;
185 }