Skip to content


Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tree: 8f30621f8e
Fetching contributors…

Cannot retrieve contributors at this time

220 lines (175 sloc) 6.098 kb
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/* $Id$ */
#define DATA_BUFFER_SIZE 2048
#define PARTSIZE 40
#if defined(TCP_CORK) && !defined(TCP_NOPUSH)
struct stats {
unsigned int curr_items;
unsigned int total_items;
unsigned long long curr_bytes;
unsigned int curr_conns;
unsigned int total_conns;
unsigned int conn_structs;
unsigned int get_cmds;
unsigned int set_cmds;
unsigned int get_hits;
unsigned int get_misses;
time_t started; /* when the process was started */
unsigned long long bytes_read;
unsigned long long bytes_written;
struct settings {
unsigned int maxbytes;
int maxconns;
int synctimer;
int port;
int maxexptime;
int expdelay;
struct in_addr interface;
int verbose;
time_t oldest_live; /* ignore existing items older than this */
int evict_to_free;
extern struct stats stats;
extern struct settings settings;
#define ITEM_LINKED 1
#define ITEM_DELETED 2
/* temp */
#define ITEM_SLABBED 4
typedef struct _stritem {
unsigned short refcount;
unsigned short flags;
int nbytes; /* size of data */
time_t time; /* least recent access */
time_t exptime; /* expire time */
unsigned char it_flags; /* ITEM_* above */
unsigned char nkey; /* key length, with terminating null and padding */
unsigned char dummy1;
void *end[0];
} item;
#define ITEM_key(item) ((char*)&((item)->end[0]))
/* warning: don't use these macros with a function, as it evals its arg twice */
#define ITEM_data(item) ((char*) &((item)->end[0]) + (item)->nkey)
#define ITEM_ntotal(item) (sizeof(struct _stritem) + (item)->nkey + (item)->nbytes)
enum conn_states {
conn_listening, /* the socket which listens for connections */
conn_read, /* reading in a command line */
conn_write, /* writing out a simple response */
conn_nread, /* reading in a fixed number of bytes */
conn_swallow, /* swallowing unnecessary bytes w/o storing */
conn_closing, /* closing this connection */
conn_mwrite /* writing out many items sequentially */
#define NREAD_ADD 1
#define NREAD_SET 2
typedef struct {
int sfd;
int state;
struct event event;
short ev_flags;
short which; /* which events were just triggered */
char *rbuf;
int rsize;
int rbytes;
char *wbuf;
char *wcurr;
int wsize;
int wbytes;
int write_and_go; /* which state to go into after finishing current write */
void *write_and_free; /* free this memory after finishing writing */
char is_corked; /* boolean, connection is corked */
char *rcurr;
int rlbytes;
/* data for the nread state */
* item is used to hold an item structure created after reading the command
* line of set/add/replace commands, but before we finished reading the actual
* data. The data is read into ITEM_data(item) to avoid extra copying.
void *item; /* for commands set/add/replace */
int item_comm; /* which one is it: set/add/replace */
/* data for the swallow state */
int sbytes; /* how many bytes to swallow */
/* data for the mwrite state */
item **ilist; /* list of items to write out */
int isize;
item **icurr;
int ileft;
int ipart; /* 1 if we're writing a VALUE line, 2 if we're writing data */
char ibuf[300]; /* for VALUE lines */
char *iptr;
int ibytes;
} conn;
/* listening socket */
extern int l_socket;
/* temporary hack */
/* #define assert(x) if(!(x)) { printf("assert failure: %s\n", #x); pre_gdb(); }
void pre_gdb (); */
* Functions
* given time value that's either unix time or delta from current unix time, return
* unix time. Use the fact that delta can't exceed one month (and real time value can't
* be that low).
time_t realtime(time_t exptime);
/* slabs memory allocation */
/* Init the subsystem. The argument is the limit on no. of bytes to allocate, 0 if no limit */
void slabs_init(unsigned int limit);
/* Given object size, return id to use when allocating/freeing memory for object */
/* 0 means error: can't store such a large object */
unsigned int slabs_clsid(unsigned int size);
/* Allocate object of given length. 0 on error */
void *slabs_alloc(unsigned int size);
/* Free previously allocated object */
void slabs_free(void *ptr, unsigned int size);
/* Fill buffer with stats */
char *slabs_stats(int *buflen);
/* Request some slab be moved between classes
1 = success
0 = fail
-1 = tried. busy. send again shortly. */
int slabs_reassign(unsigned char srcid, unsigned char dstid);
/* event handling, network IO */
void event_handler(int fd, short which, void *arg);
void start_expire(int fd, short which, void *arg);
conn *conn_new(int sfd, int init_state, int event_flags);
void conn_close(conn * c);
void conn_init(void);
void drive_machine(conn * c);
int new_socket(void);
int server_socket(int port);
int update_event(conn * c, int new_flags);
int try_read_command(conn * c);
int try_read_network(conn * c);
void complete_nread(conn * c);
void process_command(conn * c, char *command);
/* stats */
void stats_reset(void);
void stats_init(void);
/* defaults */
void settings_init(void);
/* associative array */
void assoc_init(void);
item *assoc_find(char *key);
int assoc_insert(char *key, item * item);
void assoc_delete(char *key);
void item_init(void);
item *item_alloc(char *key, int flags, time_t exptime, int nbytes);
void item_free(item * it);
int item_link(item * it); /* may fail if transgresses limits */
void item_unlink(item * it);
void item_remove(item * it);
void cleanup_dbt(void);
void expire_step(void);
void item_update(item * it); /* update LRU time to current and reposition */
int item_replace(item * it, item * new_it);
char *item_cachedump(unsigned int slabs_clsid, unsigned int limit,
unsigned int *bytes);
char *item_stats_sizes(int *bytes);
void item_stats(char *buffer, int buflen);
void syncdb(void);
Jump to Line
Something went wrong with that request. Please try again.