213 lines
6.1 KiB
C
Executable File
213 lines
6.1 KiB
C
Executable File
/* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
|
|
/* $Id: memcached.h,v 1.21 2004/02/24 23:42:02 bradfitz Exp $ */
|
|
|
|
#define DATA_BUFFER_SIZE 2048
|
|
|
|
#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;
|
|
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 {
|
|
struct _stritem *next;
|
|
struct _stritem *prev;
|
|
struct _stritem *h_next; /* hash chain next */
|
|
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 slabs_clsid;
|
|
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
|
|
#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.
|
|
*/
|
|
|
|
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);
|
|
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 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);
|