/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */ #define PACKAGE "memcachedb" #define VERSION "0.0.3" /* Default path for a database, and its env home */ #define DBFILE "default.db" #define DBHOME "/data1/memcachedb" #define DATA_BUFFER_SIZE 512 #if defined(TCP_CORK) && !defined(TCP_NOPUSH) #define TCP_NOPUSH TCP_CORK #endif 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 port; struct in_addr interface; int verbose; }; extern struct stats stats; extern struct settings settings; #define END_LEN 128 #define END_LEN_STR "127" typedef struct _stritem { int nbytes; /* size of data */ int nkey; char end[END_LEN]; } 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) 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 #define NREAD_REPLACE 3 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. */ item item; 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 */ 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; /* * 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). */ /* event handling, network IO */ void event_handler(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); void settings_init(void); void cleanup_dbt(void); static void closedb(void); static void db_checkpoint(void); void sig_handler(int sig);