memcache/memcache.c
author Tero Marttila <terom@fixme.fi>
Thu, 28 Aug 2008 01:34:14 +0300
changeset 44 03a7e064f833
parent 41 540737bf6bac
child 46 8a832c0e01ee
permissions -rw-r--r--
stub functions and documentation

#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, MEMCACHE_CMD_FETCH_GET, 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;
}