I am trying to learn how memcached works by reading its testcase step by step
To run the testapp, I need to build testapp, memcached-debug, memcached, timedrun
memcached is built using -DNDBUG, means not in debug mode
------------------------------------------------------------------------------------------------------------------------
Part I Cache
cache.h and cache.c could be used for other purpose
layout of an object in debug mode:
| red zone | object | red zone | | red zone | object | red zone | |
in no-debug mode -DNDBUG, the layout is
| object | object | object |
1. create cache,
2. allocate new object
void *ptr = cache_alloc(cache)
If cache->freecurr == 0, means no cache entry could be freed. Then need to use malloc to allocate a new block
If cache->freecurr > 0, means some cache entry could be freed, then return an entry which could be freed.
3. indicate an object in the cache could be freed
for (int ii = 0; ii < ITERATIONS; ++ii) {
ptr[ii] = cache_alloc(cache);
memset(ptr[ii], 0xff, datasize);
}
for (int ii = 0; ii < ITERATIONS; ++ii) {
cache_free(cache, ptr[ii]);
}
Each time cache_free called, register ptr into cache->ptr table, and increment cache->freecur. If cache->freecur == cache->freetotal, increase cache->ptr table
------------------------------------------------------------------------------------------------------------------------
Part II util.c
strtoull string to unsigned 64 bit
strtoll string to signed 64 bit
strtoul string to unsigned 32 bit
strtol string to singed 32 bit
-----------------------------------------------------------------------------------------------------------------------
Part III initialize and start memcached server
stats_init();
assoc_init(hashpower_init) //by default, init a hash table with hash power of 16 in assoc.c
slab_init()
create socket: memcached.c
if (settings.port && server_sockets(settings.port, tcp_transport,
portnumber_file)) {
vperror("failed to listen on TCP port %d", settings.port);
exit(EX_OSERR);
}
/**
* Create a socket and bind it to a specific port number
* @param interface the interface to bind to
* @param port the port number to bind to
* @param transport the transport protocol (TCP / UDP)
* @param portnumber_file A filepointer to write the port numbers to
* when they are successfully added to the list of ports we
* listen on.
*/
static int server_socket(const char *interface,
int port,
enum network_transport transport,
FILE *portnumber_file) {
then bind to socket, and goes to event_base_loop
http://www.wangafu.net/~nickm/libevent-book/Ref3_eventloop.html
-------------------------------------------------------------------------------------------------------------------------------------------------
Part IV processing command lines
* get
item_get(key_token->value, key_token->length) (memcached.c) --> hv = hash(key, nkey), item_get (key, nkey) (thread.c) --> do_item_get (items.c) --> assoc_find (key, nkey, hv) (assoc.c)