Skip to content

Commit 77b1e71

Browse files
committed
Updated odb backend to current libgit2
1 parent cef2099 commit 77b1e71

File tree

1 file changed

+153
-125
lines changed

1 file changed

+153
-125
lines changed

redis/hiredis.c

Lines changed: 153 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -26,180 +26,208 @@
2626
#include <assert.h>
2727
#include <string.h>
2828
#include <git2.h>
29-
#include <git2/odb_backend.h>
29+
#include <git2/sys/odb_backend.h>
3030
#include <hiredis/hiredis.h>
3131

3232
typedef struct {
33-
git_odb_backend parent;
33+
git_odb_backend parent;
3434

35-
redisContext *db;
36-
} hiredis_backend;
35+
const char *prefix;
36+
const char *repo_path;
37+
redisContext *db;
38+
} hiredis_odb_backend;
3739

38-
int hiredis_backend__read_header(size_t *len_p, git_otype *type_p, git_odb_backend *_backend, const git_oid *oid)
40+
int hiredis_odb_backend__read_header(size_t *len_p, git_otype *type_p, git_odb_backend *_backend, const git_oid *oid)
3941
{
40-
hiredis_backend *backend;
41-
int error;
42-
redisReply *reply;
43-
44-
assert(len_p && type_p && _backend && oid);
45-
46-
backend = (hiredis_backend *) _backend;
47-
error = GIT_ERROR;
48-
49-
reply = redisCommand(backend->db, "HMGET %b %s %s", oid->id, GIT_OID_RAWSZ,
50-
"type", "size");
51-
52-
if (reply && reply->type == REDIS_REPLY_ARRAY) {
53-
if (reply->element[0]->type != REDIS_REPLY_NIL &&
54-
reply->element[0]->type != REDIS_REPLY_NIL) {
55-
*type_p = (git_otype) atoi(reply->element[0]->str);
56-
*len_p = (size_t) atoi(reply->element[1]->str);
57-
error = GIT_SUCCESS;
58-
} else {
59-
error = GIT_ENOTFOUND;
60-
}
61-
} else {
62-
error = GIT_ERROR;
63-
}
64-
65-
freeReplyObject(reply);
66-
return error;
42+
hiredis_odb_backend *backend;
43+
int error;
44+
redisReply *reply;
45+
char *str_id = calloc(GIT_OID_HEXSZ + 1, sizeof(char));
46+
47+
assert(len_p && type_p && _backend && oid);
48+
49+
backend = (hiredis_odb_backend *) _backend;
50+
error = GIT_ERROR;
51+
52+
git_oid_tostr(str_id, GIT_OID_HEXSZ, oid);
53+
54+
reply = redisCommand(backend->db, "HMGET %s:%s:odb:%s %s %s", backend->prefix, backend->repo_path, str_id, "type", "size");
55+
56+
if (reply && reply->type == REDIS_REPLY_ARRAY) {
57+
if (reply->element[0]->type != REDIS_REPLY_NIL &&
58+
reply->element[0]->type != REDIS_REPLY_NIL) {
59+
*type_p = (git_otype) atoi(reply->element[0]->str);
60+
*len_p = (size_t) atoi(reply->element[1]->str);
61+
error = GIT_OK;
62+
} else {
63+
giterr_set_str(GITERR_ODB, "Redis odb storage corrupted");
64+
error = GIT_ENOTFOUND;
65+
}
66+
} else {
67+
giterr_set_str(GITERR_ODB, "Redis odb storage error");
68+
error = GIT_ERROR;
69+
}
70+
71+
free(str_id);
72+
freeReplyObject(reply);
73+
return error;
6774
}
6875

69-
int hiredis_backend__read(void **data_p, size_t *len_p, git_otype *type_p, git_odb_backend *_backend, const git_oid *oid)
76+
int hiredis_odb_backend__read(void **data_p, size_t *len_p, git_otype *type_p, git_odb_backend *_backend, const git_oid *oid)
7077
{
71-
hiredis_backend *backend;
72-
int error;
73-
redisReply *reply;
74-
75-
assert(data_p && len_p && type_p && _backend && oid);
76-
77-
backend = (hiredis_backend *) _backend;
78-
error = GIT_ERROR;
79-
80-
reply = redisCommand(backend->db, "HMGET %b %s %s %s", oid->id, GIT_OID_RAWSZ,
81-
"type", "size", "data");
82-
83-
if (reply && reply->type == REDIS_REPLY_ARRAY) {
84-
if (reply->element[0]->type != REDIS_REPLY_NIL &&
85-
reply->element[1]->type != REDIS_REPLY_NIL &&
86-
reply->element[2]->type != REDIS_REPLY_NIL) {
87-
*type_p = (git_otype) atoi(reply->element[0]->str);
88-
*len_p = (size_t) atoi(reply->element[1]->str);
89-
*data_p = malloc(*len_p);
90-
if (*data_p == NULL) {
91-
error = GIT_ENOMEM;
92-
} else {
93-
memcpy(*data_p, reply->element[2]->str, *len_p);
94-
error = GIT_SUCCESS;
95-
}
96-
} else {
97-
error = GIT_ENOTFOUND;
98-
}
99-
} else {
100-
error = GIT_ERROR;
101-
}
102-
103-
freeReplyObject(reply);
104-
return error == GIT_SUCCESS;
78+
hiredis_odb_backend *backend;
79+
int error;
80+
redisReply *reply;
81+
char *str_id = calloc(GIT_OID_HEXSZ + 1, sizeof(char));
82+
83+
assert(data_p && len_p && type_p && _backend && oid);
84+
85+
backend = (hiredis_odb_backend *) _backend;
86+
error = GIT_ERROR;
87+
88+
git_oid_tostr(str_id, GIT_OID_HEXSZ, oid);
89+
90+
reply = redisCommand(backend->db, "HMGET %s:%s:odb:%s %s %s %s", backend->prefix, backend->repo_path, str_id,
91+
"type", "size", "data");
92+
93+
if (reply && reply->type == REDIS_REPLY_ARRAY) {
94+
if (reply->element[0]->type != REDIS_REPLY_NIL &&
95+
reply->element[1]->type != REDIS_REPLY_NIL &&
96+
reply->element[2]->type != REDIS_REPLY_NIL) {
97+
*type_p = (git_otype) atoi(reply->element[0]->str);
98+
*len_p = (size_t) atoi(reply->element[1]->str);
99+
*data_p = malloc(*len_p);
100+
if (*data_p == NULL) {
101+
error = GITERR_NOMEMORY;
102+
} else {
103+
memcpy(*data_p, reply->element[2]->str, *len_p);
104+
error = GIT_OK;
105+
}
106+
} else {
107+
giterr_set_str(GITERR_ODB, "Redis odb couldn't find object");
108+
error = GIT_ENOTFOUND;
109+
}
110+
} else {
111+
giterr_set_str(GITERR_ODB, "Redis odb storage error");
112+
error = GIT_ERROR;
113+
}
114+
115+
free(str_id);
116+
freeReplyObject(reply);
117+
return error;
105118
}
106119

107-
int hiredis_backend__read_prefix(git_oid *out_oid,
120+
int hiredis_odb_backend__read_prefix(git_oid *out_oid,
108121
void **data_p, size_t *len_p, git_otype *type_p, git_odb_backend *_backend,
109-
const git_oid *short_oid, unsigned int len)
122+
const git_oid *short_oid, size_t len)
110123
{
111124
if (len >= GIT_OID_HEXSZ) {
112125
/* Just match the full identifier */
113-
int error = hiredis_backend__read(data_p, len_p, type_p, _backend, short_oid);
114-
if (error == GIT_SUCCESS)
126+
int error = hiredis_odb_backend__read(data_p, len_p, type_p, _backend, short_oid);
127+
if (error == GIT_OK)
115128
git_oid_cpy(out_oid, short_oid);
116129

117130
return error;
118-
} else if (len < GIT_OID_HEXSZ) {
119-
/* TODO */
120-
return GIT_ENOTIMPLEMENTED;
121131
}
132+
133+
/* TODO prefix */
134+
giterr_set_str(GITERR_ODB, "Redis odb doesn't not implement oid prefix lookup");
135+
return GITERR_INVALID;
122136
}
123137

124-
int hiredis_backend__exists(git_odb_backend *_backend, const git_oid *oid)
138+
int hiredis_odb_backend__exists(git_odb_backend *_backend, const git_oid *oid)
125139
{
126-
hiredis_backend *backend;
127-
int found;
128-
redisReply *reply;
140+
hiredis_odb_backend *backend;
141+
int found;
142+
redisReply *reply;
143+
char *str_id = calloc(GIT_OID_HEXSZ + 1, sizeof(char));
144+
145+
assert(_backend && oid);
129146

130-
assert(_backend && oid);
147+
backend = (hiredis_odb_backend *) _backend;
148+
found = 0;
131149

132-
backend = (hiredis_backend *) _backend;
133-
found = 0;
150+
git_oid_tostr(str_id, GIT_OID_HEXSZ, oid);
134151

135-
reply = redisCommand(backend->db, "exists %b", oid->id, GIT_OID_RAWSZ);
136-
if (reply && reply->type != REDIS_REPLY_NIL && reply->type != REDIS_REPLY_ERROR)
137-
found = 1;
152+
reply = redisCommand(backend->db, "exists %s:%s:odb:%s", backend->prefix, backend->repo_path, str_id);
153+
if (reply->type == REDIS_REPLY_INTEGER)
154+
found = reply->integer;
138155

139-
freeReplyObject(reply);
140-
return found;
156+
free(str_id);
157+
freeReplyObject(reply);
158+
return found;
141159
}
142160

143-
int hiredis_backend__write(git_oid *id, git_odb_backend *_backend, const void *data, size_t len, git_otype type)
161+
int hiredis_odb_backend__write(git_odb_backend *_backend, const git_oid *oid, const void *data, size_t len, git_otype type)
144162
{
145-
hiredis_backend *backend;
146-
int error;
147-
redisReply *reply;
163+
hiredis_odb_backend *backend;
164+
int error;
165+
redisReply *reply;
166+
char *str_id = calloc(GIT_OID_HEXSZ + 1, sizeof(char));
148167

149-
assert(id && _backend && data);
168+
assert(oid && _backend && data);
150169

151-
backend = (hiredis_backend *) _backend;
152-
error = GIT_ERROR;
170+
backend = (hiredis_odb_backend *) _backend;
171+
error = GIT_ERROR;
153172

154-
if ((error = git_odb_hash(id, data, len, type)) < 0)
155-
return error;
173+
git_oid_tostr(str_id, GIT_OID_HEXSZ, oid);
156174

157-
reply = redisCommand(backend->db, "HMSET %b "
158-
"type %d "
159-
"size %d "
160-
"data %b ", id->id, GIT_OID_RAWSZ,
161-
(int) type, len, data, len);
175+
reply = redisCommand(backend->db, "HMSET %s:%s:odb:%s "
176+
"type %d "
177+
"size %d "
178+
"data %b ", backend->prefix, backend->repo_path, str_id,
179+
(int) type, len, data, len);
180+
free(str_id);
162181

163-
error = (reply == NULL || reply->type == REDIS_REPLY_ERROR) ? GIT_ERROR : GIT_SUCCESS;
182+
error = (reply == NULL || reply->type == REDIS_REPLY_ERROR) ? GIT_ERROR : GIT_OK;
164183

165-
freeReplyObject(reply);
166-
return error;
184+
freeReplyObject(reply);
185+
return error;
167186
}
168187

169-
void hiredis_backend__free(git_odb_backend *_backend)
188+
void hiredis_odb_backend__free(git_odb_backend *_backend)
170189
{
171-
hiredis_backend *backend;
172-
assert(_backend);
173-
backend = (hiredis_backend *) _backend;
190+
hiredis_odb_backend *backend;
174191

175-
redisFree(backend->db);
192+
assert(_backend);
193+
backend = (hiredis_odb_backend *) _backend;
176194

177-
free(backend);
195+
redisFree(backend->db);
196+
197+
free(backend);
178198
}
179199

180-
int git_odb_backend_hiredis(git_odb_backend **backend_out, const char *host, int port)
200+
int git_odb_backend_hiredis(git_odb_backend **backend_out, const char* prefix, const char* path, const char *host, int port)
181201
{
182-
hiredis_backend *backend;
202+
hiredis_odb_backend *backend;
183203

184-
backend = calloc(1, sizeof (hiredis_backend));
185-
if (backend == NULL)
186-
return GIT_ENOMEM;
204+
backend = calloc(1, sizeof (hiredis_odb_backend));
205+
if (backend == NULL)
206+
return GITERR_NOMEMORY;
187207

188-
backend->db = redisConnect(host, port);
189-
if (backend->db->err) {
208+
backend->db = redisConnect(host, port);
209+
if (backend->db->err) {
190210
free(backend);
211+
giterr_set_str(GITERR_REFERENCE, "Redis refdb storage couldn't connect to redis server");
191212
return GIT_ERROR;
192213
}
193214

194-
backend->parent.read = &hiredis_backend__read;
195-
backend->parent.read_prefix = &hiredis_backend__read_prefix;
196-
backend->parent.read_header = &hiredis_backend__read_header;
197-
backend->parent.write = &hiredis_backend__write;
198-
backend->parent.exists = &hiredis_backend__exists;
199-
backend->parent.free = &hiredis_backend__free;
215+
backend->prefix = prefix;
216+
backend->repo_path = path;
200217

201-
*backend_out = (git_odb_backend *) backend;
218+
backend->parent.version = 1;
202219

203-
return GIT_SUCCESS;
204-
}
220+
backend->parent.read = &hiredis_odb_backend__read;
221+
backend->parent.write = &hiredis_odb_backend__write;
222+
backend->parent.read_prefix = &hiredis_odb_backend__read_prefix;
223+
backend->parent.read_header = &hiredis_odb_backend__read_header;
224+
backend->parent.exists = &hiredis_odb_backend__exists;
225+
backend->parent.free = &hiredis_odb_backend__free;
226+
227+
backend->parent.writestream = NULL;
228+
backend->parent.foreach = NULL;
205229

230+
*backend_out = (git_odb_backend *) backend;
231+
232+
return GIT_OK;
233+
}

0 commit comments

Comments
 (0)