#include <stdlib.h>
#include "memcache.h"
#include "server.h"
#include "request.h"
#include "../common.h"
struct memcache *memcache_alloc (memcache_cb cb_fn) {
struct memcache *mc = NULL;
if ((mc = calloc(1, sizeof(*mc))) == NULL)
ERROR("calloc");
// store callback
mc->cb_fn = cb_fn;
// init server list
LIST_INIT(&mc->server_list);
// success
return mc;
error:
if (mc)
free(mc);
return NULL;
}
int memcache_add_server (struct memcache *mc, struct config_endpoint *endpoint, int max_connections) {
struct memcache_server *server = NULL;
// alloc the server
if ((server = memcache_server_alloc(endpoint, max_connections)) == NULL)
goto error;
// enlist it
LIST_INSERT_HEAD(&mc->server_list, server, serverlist_node);
// done
return 0;
error:
return -1;
}
struct memcache_server *memcache_choose_server (struct memcache *mc, const struct memcache_key *key) {
// XXX: support multiple servers
return mc->server_list.lh_first;
}
static struct memcache_req *_memcache_req (struct memcache *mc, enum memcache_command cmd, const struct memcache_key *key, const struct memcache_obj *obj, const struct memcache_buf *buf, void *cb_arg) {
struct memcache_req *req = NULL;
struct memcache_server *server = NULL;
// alloc the request
if ((req = memcache_req_alloc(mc, cmd, key, obj, buf, cb_arg)) == NULL)
ERROR("failed to allocate request");
// pick a server
if ((server = memcache_choose_server(mc, key)) == NULL)
ERROR("failed to find a server to use");
// enqueue it!
if (memcache_server_add_req(server, req))
ERROR("failed to hand over the request for processing");
// success!
return req;
error:
if (req)
memcache_req_free(req);
return NULL;
}
struct memcache_req *memcache_fetch (struct memcache *mc, const struct memcache_key *key, void *cb_arg) {
return _memcache_req(mc, MEMCACHE_CMD_FETCH_GET, key, NULL, NULL, cb_arg);
}
struct memcache_req *memcache_store (struct memcache *mc, enum memcache_command cmd, const struct memcache_key *key, const struct memcache_obj *obj, const struct memcache_buf *buf, void *cb_arg) {
if (
(cmd != MEMCACHE_CMD_STORE_SET)
&& (cmd != MEMCACHE_CMD_STORE_ADD)
&& (cmd != MEMCACHE_CMD_STORE_REPLACE)
&& (cmd != MEMCACHE_CMD_STORE_APPEND)
&& (cmd != MEMCACHE_CMD_STORE_PREPEND)
&& (cmd != MEMCACHE_CMD_STORE_CAS)
)
ERROR("invalid command for store");
return _memcache_req(mc, cmd, key, obj, buf, cb_arg);
error:
return NULL;
}