Skip to content

Commit

Permalink
odb--daemon: implement get-parent command
Browse files Browse the repository at this point in the history
Implement a basic version of the get-parent command in the ODB daemon
that will simply call the `get_parent` function that is being routed
over the IPC channel with the same arguments.

This will get us a simple working proof of concept.

Signed-off-by: Matthew John Cheetham <[email protected]>
  • Loading branch information
mjcheetham committed Apr 23, 2024
1 parent 40800dd commit 0f60ce0
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 2 deletions.
56 changes: 56 additions & 0 deletions builtin/odb--daemon.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "builtin.h"
#include "config.h"
#include "object-file.h"
#include "object-name.h"
#include "object-store.h"
#include "oidmap.h"
#include "parse-options.h"
Expand Down Expand Up @@ -211,6 +212,49 @@ static int odb_ipc_cb__hash_object(struct my_odb_ipc_state *state,
return 0;
}

static int odb_ipc_cb__get_parent(struct my_odb_ipc_state *state,
const char *command, size_t command_len,
ipc_server_reply_cb *reply_cb,
struct ipc_server_reply_data *reply_data)
{
struct odb_over_ipc__get_parent__request *req;
struct odb_over_ipc__get_parent__response *resp;
const char *name;
size_t name_len;
int ret;

if (command_len < sizeof(*req))
BUG("incorrect size for binary data");

req = (struct odb_over_ipc__get_parent__request *)command;

name = command + sizeof(*req);
name_len = command_len - sizeof(*req);

if (req->name_len != name_len)
BUG("incorrect data length");

resp = xmalloc(sizeof(*resp));
memcpy(&resp->key.key, "get-parent", 11);

ret = get_parent(the_repository, name, name_len, &resp->oid, req->idx);

if (ret != FOUND)
goto fail;

reply_cb(reply_data, (const char *)resp, sizeof(*resp));

return 0;

fail:
/*
* Send the client an error response to force it to do
* the work itself.
*/
reply_cb(reply_data, "error", 6);
return 0;
}

/*
* This callback handles IPC requests from clients. We run on an
* arbitrary thread.
Expand Down Expand Up @@ -277,6 +321,18 @@ static int odb_ipc_cb(void *data,
return 0;
}

if (!strcmp(command, "get-parent")) {
/*
* A client has requested that we find the parent of a given
* object.
*/
trace2_region_enter("odb-daemon", "get-parent", NULL);
ret = odb_ipc_cb__get_parent(state, command, command_len,
reply_cb, reply_data);
trace2_region_leave("odb-daemon", "get-parent", NULL);
return 0;
}

// TODO respond to other requests from client.
//
// TODO decide how to return an error for unknown commands.
Expand Down
9 changes: 7 additions & 2 deletions object-name.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "commit-reach.h"
#include "date.h"
#include "object-file-convert.h"
#include "odb-over-ipc.h"

static int get_oid_oneline(struct repository *r, const char *, struct object_id *, struct commit_list *);

Expand Down Expand Up @@ -1086,13 +1087,17 @@ enum get_oid_result get_parent(struct repository *r,
struct object_id *result, int idx)
{
struct object_id oid;
enum get_oid_result ret = get_oid_1(r, name, len, &oid,
GET_OID_COMMITTISH);
enum get_oid_result ret;
struct commit *commit;
struct commit_list *p;

if (odb_over_ipc__get_parent(r, name, len, idx, result) == 0)
return FOUND;

ret = get_oid_1(r, name, len, &oid, GET_OID_COMMITTISH);
if (ret)
return ret;

commit = lookup_commit_reference(r, &oid);
if (repo_parse_commit(r, commit))
return MISSING_OBJECT;
Expand Down
47 changes: 47 additions & 0 deletions odb-over-ipc.c
Original file line number Diff line number Diff line change
Expand Up @@ -264,4 +264,51 @@ int odb_over_ipc__hash_object(struct repository *r, struct object_id *oid,
return ret;
}

int odb_over_ipc__get_parent(struct repository *r, const char *name, int len,
int idx, struct object_id *result)
{
struct odb_over_ipc__get_parent__request req;
struct odb_over_ipc__get_parent__response *resp;
struct strbuf msg = STRBUF_INIT;
struct strbuf answer = STRBUF_INIT;
int ret;

if (is_daemon)
return -1;

if (!core_use_odb_over_ipc)
return -1;

if (r != the_repository) // TODO not dealing with this
return -1;

memset(&req, 0, sizeof(req));
memcpy(req.key.key, "get-parent", 10);
req.idx = idx;
req.name_len = len;

/* Append the name at the end of the request */
strbuf_init(&msg, sizeof(req) + len);
strbuf_add(&msg, &req, sizeof(req));
strbuf_add(&msg, name, len);

ret = odb_over_ipc__command((const char *)msg.buf, msg.len, &answer);
if (ret)
return ret;

if (!strncmp(answer.buf, "error", 5)) {
trace2_printf("odb-over-ipc: failed");
return -1;
}

if (answer.len != sizeof(*resp))
BUG("incorrect size for binary data");
resp = (struct odb_over_ipc__get_parent__response *)answer.buf;

oidcpy(result, &resp->oid);

strbuf_release(&answer);
return ret;
}

#endif /* SUPPORTS_SIMPLE_IPC */
16 changes: 16 additions & 0 deletions odb-over-ipc.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,19 @@ struct odb_over_ipc__hash_object__response
struct object_id oid;
};

struct odb_over_ipc__get_parent__request
{
struct odb_over_ipc__key key;
int idx;
int name_len;
};

struct odb_over_ipc__get_parent__response
{
struct odb_over_ipc__key key;
struct object_id oid;
};

/*
* Connect to an existing `git odb--daemon` process and ask it for
* an object. This is intended to be inserted into the client
Expand All @@ -100,6 +113,9 @@ int odb_over_ipc__get_oid(struct repository *r, const struct object_id *oid,
int odb_over_ipc__hash_object(struct repository *r, struct object_id *oid,
int fd, enum object_type type, unsigned flags);

int odb_over_ipc__get_parent(struct repository *r, const char *name, int len,
int idx, struct object_id *result);

/*
* Explicitly shutdown IPC connection to the `git odb--daemon` process.
* The connection is implicitly created upon the first request and we
Expand Down

0 comments on commit 0f60ce0

Please sign in to comment.