File Coverage

deps/libgit2/src/odb_mempack.c
Criterion Covered Total %
statement 74 79 93.6
branch 25 38 65.7
condition n/a
subroutine n/a
pod n/a
total 99 117 84.6


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