memcache(3) - C API to memcached(8)

This is the homepage for memcache(3) (a.k.a. libmemcache), the C API for
memcached(8). If you are unfamiliar with memcached(8), visit its homepage at:

http://www.danga.com/memcached/

The current version is 1.4.0.rc2.

Contents

  * Bugs, questions, comments, patches, or feedback
  * Contents
  * Errata
  * Examples
  * Features
  * License
  * Performance
  * Requirements

Requirements

If you find any requirements that aren't documented here, please send me an
email letting me know.

  * Compiler: TenDRA or GCC. Preferred GCC compiler is gcc 3.4. Works with gcc
    2.95.4 and up.

Features

  * Support for Multiple Memory Contexts. This is primarily used for programs
    that need to use memcache(3) inside of Apache where both Apache and PHP
    have their own memory management systems.
  * Callback Interface. Using the callback interface, it's possible to lump
    many gets together into a single get request with a great deal of ease.
  * Multiple Client Side Hashes. memcache(3) supports multiple hashing methods
    to distribute load across multiple servers.
  * Multiple Servers. memcache(3) supports multiple servers.
  * Support for Garbage Collection. memcache(3) was written with the Bohem
    Garbage Collector in mind.
  * MIT Licensed. memcache(3) is as Open Source as it gets and can be embedded
    in anything (commercial software, open source, etc). May the GPL and its
    users rot in hell for their stupidity.

Performance

memcache(3) is fast. Very fast. On an AMD64 machine, the test program uses only
25.6% of the CPU, the remaining processing time going to the kernel and three
memcached(8) instances. With that slice of time, the test client can run 29,358
get or set requests a second. Assuming a client can get 100% of the CPU, one
could assume it can handle around 120K requests a second, probably more.

Errata

There are no known client issues at this time.

Bugs, Questions, Comments, Patches, or Feedback

If you have bugs, questions, comments, patches, or feedback, please send me an
email at seanc@FreeBSD.org. If you would like me to integrate memcached(8) or
memcache(3) into your application (website, PostgreSQL, DNS server, mail
server, desktop application, etc.), I do provide commercial support for both
memcache(3) and memcached(8).

What happened to 1.3.X? My mythical 2.0 version of memcache(3) had most of its
new implementation dropped into the 1.3 branch... though I preserved APIs,
which was something I wasn't even going to come close to claiming for the 2.0
release. 2.0 had prelim support to proxy connections to other memcache servers
and a host of other features that I never completed, but I digress. Now, with
nearly 5K in changes on the 1.3.0rcX branch, I opted to bump the version to 1.4
and called it a day: the mystery of the day has now been put to rest.

Examples

Look in test/ for further examples. memcache.h is very well commented and the
best place to look for documentation (for now). The following examples use the
single memory context API (what most programs will use), but could easily be
converted to the multi-memory context API. See memcache.h.in for details.

/* Create a new memcache instance */
struct memcache *mc = mc_new();

/* Add a few servers */
mc_server_add(mc, "127.0.0.1", "11211");
mc_server_add(mc, "127.0.0.1", "11212");
mc_server_add4(mc, "127.0.0.1:11213");

/* Add a key */
mc_add(mc, key, keylen, val, bytes, expire, flags);

/* Get a key, caller has to free(3) memory */
void *blah = mc_aget(mc, key, keylen);
free(blah);

/* Perform a multi-key request */
struct memcache_req *req = mc_req_new();
mc_req_add(req, key1, key1_len);
mc_req_add(req, key2, key2_len);
mc_get(mc, req);
/* Process the results (need a better interface to looping through results) */

/* Perform a multi-key request the easy way (this is my preferred way of getting data): */
req = mc_req_new();
res1 = mc_req_add(req, key1, key1_len);
res2 = mc_req_add(req, key2, key2_len);
mc_get(mc, req);
/* Play with res1/res2 w/o any looping through req */


/* Complex multi-key get example: */
/* Grab the response object that will be used to store a given key */
struct memcache_res *res = mc_req_add(req, key3, key3_len);
res->size = 1024;                               /* Allocate our own memory a head of time (useful for loops) */
res->val = malloc(res->size);
mc_res_free_on_delete(res, 1);

/* Perform the get */
mc_get(mc, req);
mc_res_free(req, res);

/* Get stats from the whole cluster */
struct memcache_server_stats *s = mc_stats(mc);
mc_server_stats_free(s);

/* Storage commands: */
mc_add(mc, key, key_len, val, bytes, expire, flags);
mc_replace(mc, key, key_len, val, bytes, expire, flags);
mc_set(mc, key, key_len, val, bytes, expire, flags);

/* Delete commands: */
mc_delete(mc, key, key_len, hold_timer);

/* Atomic opts: */
mc_incr(mc, key, key_len, 1);
mc_decr(mc, key, key_len, 1);

mc_free(mc);

License and Copyright

Copyright (C) 2004-2005 Sean Chittenden <seanc@FreeBSD.org>

Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

