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 #ifndef INCLUDE_sys_git_odb_backend_h__
8 #define INCLUDE_sys_git_odb_backend_h__
9 
10 #include "git2/common.h"
11 #include "git2/types.h"
12 #include "git2/oid.h"
13 #include "git2/odb.h"
14 
15 /**
16  * @file git2/sys/backend.h
17  * @brief Git custom backend implementors functions
18  * @defgroup git_backend Git custom backend APIs
19  * @ingroup Git
20  * @{
21  */
22 GIT_BEGIN_DECL
23 
24 /**
25  * An instance for a custom backend
26  */
27 struct git_odb_backend {
28 	unsigned int version;
29 	git_odb *odb;
30 
31 	/* read and read_prefix each return to libgit2 a buffer which
32 	 * will be freed later. The buffer should be allocated using
33 	 * the function git_odb_backend_data_alloc to ensure that libgit2
34 	 * can safely free it later. */
35 	int GIT_CALLBACK(read)(
36 		void **, size_t *, git_object_t *, git_odb_backend *, const git_oid *);
37 
38 	/* To find a unique object given a prefix of its oid.  The oid given
39 	 * must be so that the remaining (GIT_OID_HEXSZ - len)*4 bits are 0s.
40 	 */
41 	int GIT_CALLBACK(read_prefix)(
42 		git_oid *, void **, size_t *, git_object_t *,
43 		git_odb_backend *, const git_oid *, size_t);
44 
45 	int GIT_CALLBACK(read_header)(
46 		size_t *, git_object_t *, git_odb_backend *, const git_oid *);
47 
48 	/**
49 	 * Write an object into the backend. The id of the object has
50 	 * already been calculated and is passed in.
51 	 */
52 	int GIT_CALLBACK(write)(
53 		git_odb_backend *, const git_oid *, const void *, size_t, git_object_t);
54 
55 	int GIT_CALLBACK(writestream)(
56 		git_odb_stream **, git_odb_backend *, git_object_size_t, git_object_t);
57 
58 	int GIT_CALLBACK(readstream)(
59 		git_odb_stream **, size_t *, git_object_t *,
60 		git_odb_backend *, const git_oid *);
61 
62 	int GIT_CALLBACK(exists)(
63 		git_odb_backend *, const git_oid *);
64 
65 	int GIT_CALLBACK(exists_prefix)(
66 		git_oid *, git_odb_backend *, const git_oid *, size_t);
67 
68 	/**
69 	 * If the backend implements a refreshing mechanism, it should be exposed
70 	 * through this endpoint. Each call to `git_odb_refresh()` will invoke it.
71 	 *
72 	 * However, the backend implementation should try to stay up-to-date as much
73 	 * as possible by itself as libgit2 will not automatically invoke
74 	 * `git_odb_refresh()`. For instance, a potential strategy for the backend
75 	 * implementation to achieve this could be to internally invoke this
76 	 * endpoint on failed lookups (ie. `exists()`, `read()`, `read_header()`).
77 	 */
78 	int GIT_CALLBACK(refresh)(git_odb_backend *);
79 
80 	int GIT_CALLBACK(foreach)(
81 		git_odb_backend *, git_odb_foreach_cb cb, void *payload);
82 
83 	int GIT_CALLBACK(writepack)(
84 		git_odb_writepack **, git_odb_backend *, git_odb *odb,
85 		git_indexer_progress_cb progress_cb, void *progress_payload);
86 
87 	/**
88 	 * "Freshens" an already existing object, updating its last-used
89 	 * time.  This occurs when `git_odb_write` was called, but the
90 	 * object already existed (and will not be re-written).  The
91 	 * underlying implementation may want to update last-used timestamps.
92 	 *
93 	 * If callers implement this, they should return `0` if the object
94 	 * exists and was freshened, and non-zero otherwise.
95 	 */
96 	int GIT_CALLBACK(freshen)(git_odb_backend *, const git_oid *);
97 
98 	/**
99 	 * Frees any resources held by the odb (including the `git_odb_backend`
100 	 * itself). An odb backend implementation must provide this function.
101 	 */
102 	void GIT_CALLBACK(free)(git_odb_backend *);
103 };
104 
105 #define GIT_ODB_BACKEND_VERSION 1
106 #define GIT_ODB_BACKEND_INIT {GIT_ODB_BACKEND_VERSION}
107 
108 /**
109  * Initializes a `git_odb_backend` with default values. Equivalent to
110  * creating an instance with GIT_ODB_BACKEND_INIT.
111  *
112  * @param backend the `git_odb_backend` struct to initialize.
113  * @param version Version the struct; pass `GIT_ODB_BACKEND_VERSION`
114  * @return Zero on success; -1 on failure.
115  */
116 GIT_EXTERN(int) git_odb_init_backend(
117 	git_odb_backend *backend,
118 	unsigned int version);
119 
120 /**
121  * Allocate data for an ODB object.  Custom ODB backends may use this
122  * to provide data back to the ODB from their read function.  This
123  * memory should not be freed once it is returned to libgit2.  If a
124  * custom ODB uses this function but encounters an error and does not
125  * return this data to libgit2, then they should use the corresponding
126  * git_odb_backend_data_free function.
127  *
128  * @param backend the ODB backend that is allocating this memory
129  * @param len the number of bytes to allocate
130  * @return the allocated buffer on success or NULL if out of memory
131  */
132 GIT_EXTERN(void *) git_odb_backend_data_alloc(git_odb_backend *backend, size_t len);
133 
134 /**
135  * Frees custom allocated ODB data.  This should only be called when
136  * memory allocated using git_odb_backend_data_alloc is not returned
137  * to libgit2 because the backend encountered an error in the read
138  * function after allocation and did not return this data to libgit2.
139  *
140  * @param backend the ODB backend that is freeing this memory
141  * @param data the buffer to free
142  */
143 GIT_EXTERN(void) git_odb_backend_data_free(git_odb_backend *backend, void *data);
144 
145 
146 /*
147  * Users can avoid deprecated functions by defining `GIT_DEPRECATE_HARD`.
148  */
149 #ifndef GIT_DEPRECATE_HARD
150 
151 /**
152  * Allocate memory for an ODB object from a custom backend.  This is
153  * an alias of `git_odb_backend_data_alloc` and is preserved for
154  * backward compatibility.
155  *
156  * This function is deprecated, but there is no plan to remove this
157  * function at this time.
158  *
159  * @deprecated git_odb_backend_data_alloc
160  * @see git_odb_backend_data_alloc
161  */
162 GIT_EXTERN(void *) git_odb_backend_malloc(git_odb_backend *backend, size_t len);
163 
164 #endif
165 
166 GIT_END_DECL
167 
168 #endif
169