File Coverage

deps/libgit2/src/libgit2/odb_mempack.c
Criterion Covered Total %
statement 77 82 93.9
branch 27 42 64.2
condition n/a
subroutine n/a
pod n/a
total 104 124 83.8


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