Skip to content

Commit

Permalink
add a field in request struct to chain to response(s), so we can avoi…
Browse files Browse the repository at this point in the history
…d allocating memory dynamically to keep track of req/rsp pointers (#157)
  • Loading branch information
Yao Yue authored Apr 20, 2018
1 parent 80fbc5f commit 48270ca
Show file tree
Hide file tree
Showing 4 changed files with 24 additions and 50 deletions.
1 change: 1 addition & 0 deletions src/protocol/data/memcache/request.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ request_reset(struct request *req)

req->nremain = 0;
req->reserved = NULL;
req->rsp = NULL;

req->partial = 0;
req->first = 0;
Expand Down
3 changes: 3 additions & 0 deletions src/protocol/data/memcache/request.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ typedef enum request_state {
REQ_DONE
} request_state_t;

struct response;

/*
* NOTE(yao): we store key and value as location in rbuf, this assumes the data
* will not be overwritten before the current request is completed.
Expand All @@ -91,6 +93,7 @@ struct request {

uint32_t nremain;
void *reserved; /* storage reserved for partial value */
struct response *rsp; /* response object(s) reserved */

unsigned partial:1; /* partial value received? */
unsigned first:1; /* first segment? */
Expand Down
67 changes: 20 additions & 47 deletions src/server/twemcache/data/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,6 @@ typedef enum put_rstatus {
PUT_ERROR,
} put_rstatus_t;

/* the data pointer in the process functions is of type `struct data **' */
struct data {
struct request *req;
struct response *rsp;
};

static bool process_init = false;
static process_metrics_st *process_metrics = NULL;
static bool allow_flush = ALLOW_FLUSH;
Expand Down Expand Up @@ -626,54 +620,36 @@ _cleanup(struct request *req, struct response *rsp)
response_return_all(&nr);
}
response_reset(rsp);
}

static inline struct data *
_data_create(void)
{
struct data *data;
struct request *req;
struct response *rsp;

req = request_borrow();
rsp = response_borrow();
data = cc_alloc(sizeof(struct data));

if (req == NULL || rsp == NULL || data == NULL) {
request_return(&req);
response_return(&rsp);
cc_free(data); /* cc_free(data) is a macro that sets data to NULL */
} else {
data->req = req;
data->rsp = rsp;
}

return data;
req->rsp = rsp;
}

int
twemcache_process_read(struct buf **rbuf, struct buf **wbuf, void **data)
{
parse_rstatus_t status;
struct data *state;
struct request *req;
struct request *req; /* data should be NULL or hold a req pointer */
struct response *rsp;

log_verb("post-read processing");

/* deal with the stateful part: request and response */
if (*data == NULL) {
if ((*data = _data_create()) == NULL) {
/* TODO(yao): simply return for now, better to respond with OOM */
log_error("cannot process request: OOM");
INCR(process_metrics, process_ex);
req = (*data != NULL) ? *data : request_borrow();
if (req == NULL) {
/* TODO(yao): simply return for now, better to respond with OOM */
log_error("cannot process request: OOM");
INCR(process_metrics, process_ex);

return -1;
}
return -1;
}
rsp = (req->rsp != NULL) ? req->rsp : response_borrow();
if (rsp == NULL) {
request_return(&req);
/* TODO(yao): simply return for now, better to respond with OOM */
log_error("cannot process request: OOM");
INCR(process_metrics, process_ex);

return -1;
}
state = (struct data *)*data;
req = state->req;
rsp = state->rsp;

/* keep parse-process-compose until running out of data in rbuf */
while (buf_rsize(*rbuf) > 0) {
Expand Down Expand Up @@ -782,8 +758,7 @@ twemcache_process_write(struct buf **rbuf, struct buf **wbuf, void **data)
int
twemcache_process_error(struct buf **rbuf, struct buf **wbuf, void **data)
{
struct data *state = (struct data *)*data;
struct request *req;
struct request *req = *data;
struct response *rsp;

log_verb("post-error processing");
Expand All @@ -795,15 +770,13 @@ twemcache_process_error(struct buf **rbuf, struct buf **wbuf, void **data)
dbuf_shrink(wbuf);

/* release request data & associated reserved data */
if (state != NULL) {
req = state->req;
rsp = state->rsp;
if (req != NULL) {
rsp = req->rsp;
if (req->reserved != NULL) {
item_release((struct item **)&req->reserved);
}
request_return(&req);
response_return_all(&rsp);
cc_free(state);
}

return 0;
Expand Down
3 changes: 0 additions & 3 deletions test/integration/twemcache/seq-1
Original file line number Diff line number Diff line change
@@ -1,5 +1,2 @@
>>> get foo
<<< END

>>> quit
+++ request_free +1

0 comments on commit 48270ca

Please sign in to comment.