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