|
|
|
|
|
#ifndef lmserver_lmserver_h |
|
#define lmserver_lmserver_h |
|
|
|
#ifdef HAVE_CONFIG_H |
|
#include "config.h" |
|
#endif |
|
|
|
#include <sys/types.h> |
|
#include <sys/socket.h> |
|
#include <sys/time.h> |
|
#include <netinet/in.h> |
|
#include <event.h> |
|
#include <netdb.h> |
|
|
|
#define DATA_BUFFER_SIZE 2048 |
|
#define UDP_READ_BUFFER_SIZE 65536 |
|
#define UDP_MAX_PAYLOAD_SIZE 1400 |
|
#define UDP_HEADER_SIZE 8 |
|
#define MAX_SENDBUF_SIZE (256 * 1024 * 1024) |
|
|
|
|
|
#define SUFFIX_SIZE 24 |
|
|
|
|
|
#define ITEM_LIST_INITIAL 200 |
|
|
|
|
|
#define SUFFIX_LIST_INITIAL 20 |
|
|
|
|
|
#define IOV_LIST_INITIAL 400 |
|
|
|
|
|
#define MSG_LIST_INITIAL 10 |
|
|
|
|
|
#define READ_BUFFER_HIGHWAT 8192 |
|
#define ITEM_LIST_HIGHWAT 400 |
|
#define IOV_LIST_HIGHWAT 600 |
|
#define MSG_LIST_HIGHWAT 100 |
|
|
|
|
|
#if HAVE_STDBOOL_H |
|
# include <stdbool.h> |
|
#else |
|
typedef enum {false = 0, true = 1} bool; |
|
#endif |
|
|
|
#if HAVE_STDINT_H |
|
# include <stdint.h> |
|
#else |
|
typedef unsigned char uint8_t; |
|
#endif |
|
|
|
|
|
#if HAVE_UNISTD_H |
|
# include <unistd.h> |
|
#endif |
|
|
|
|
|
typedef unsigned int rel_time_t; |
|
|
|
struct stats { |
|
unsigned int curr_items; |
|
unsigned int total_items; |
|
uint64_t curr_bytes; |
|
unsigned int curr_conns; |
|
unsigned int total_conns; |
|
unsigned int conn_structs; |
|
uint64_t get_cmds; |
|
uint64_t set_cmds; |
|
uint64_t get_hits; |
|
uint64_t get_misses; |
|
uint64_t evictions; |
|
time_t started; |
|
uint64_t bytes_read; |
|
uint64_t bytes_written; |
|
}; |
|
|
|
#define MAX_VERBOSITY_LEVEL 2 |
|
|
|
struct settings { |
|
size_t maxbytes; |
|
int maxconns; |
|
int port; |
|
int udpport; |
|
char *srilm; |
|
int srilm_order; |
|
char *inter; |
|
int verbose; |
|
rel_time_t oldest_live; |
|
bool managed; |
|
int evict_to_free; |
|
char *socketpath; |
|
int access; |
|
double factor; |
|
int chunk_size; |
|
int num_threads; |
|
char prefix_delimiter; |
|
int detail_enabled; |
|
}; |
|
|
|
extern struct stats stats; |
|
extern struct settings settings; |
|
|
|
#define ITEM_LINKED 1 |
|
#define ITEM_DELETED 2 |
|
|
|
|
|
#define ITEM_SLABBED 4 |
|
|
|
typedef struct _stritem { |
|
struct _stritem *next; |
|
struct _stritem *prev; |
|
struct _stritem *h_next; |
|
rel_time_t time; |
|
rel_time_t exptime; |
|
int nbytes; |
|
unsigned short refcount; |
|
uint8_t nsuffix; |
|
uint8_t it_flags; |
|
uint8_t slabs_clsid; |
|
uint8_t nkey; |
|
uint64_t cas_id; |
|
void * end[]; |
|
|
|
|
|
|
|
} item; |
|
|
|
#define ITEM_key(item) ((char*)&((item)->end[0])) |
|
|
|
|
|
#define ITEM_suffix(item) ((char*) &((item)->end[0]) + (item)->nkey + 1) |
|
#define ITEM_data(item) ((char*) &((item)->end[0]) + (item)->nkey + 1 + (item)->nsuffix) |
|
#define ITEM_ntotal(item) (sizeof(struct _stritem) + (item)->nkey + 1 + (item)->nsuffix + (item)->nbytes) |
|
|
|
enum conn_states { |
|
conn_listening, |
|
conn_read, |
|
conn_write, |
|
conn_nread, |
|
conn_swallow, |
|
conn_closing, |
|
conn_mwrite, |
|
}; |
|
|
|
#define NREAD_ADD 1 |
|
#define NREAD_SET 2 |
|
#define NREAD_REPLACE 3 |
|
#define NREAD_APPEND 4 |
|
#define NREAD_PREPEND 5 |
|
#define NREAD_CAS 6 |
|
|
|
typedef struct conn conn; |
|
struct conn { |
|
int sfd; |
|
int state; |
|
struct event event; |
|
short ev_flags; |
|
short which; |
|
|
|
char *rbuf; |
|
char *rcurr; |
|
int rsize; |
|
int rbytes; |
|
|
|
char *wbuf; |
|
char *wcurr; |
|
int wsize; |
|
int wbytes; |
|
int write_and_go; |
|
void *write_and_free; |
|
|
|
char *ritem; |
|
int rlbytes; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
void *item; |
|
int item_comm; |
|
|
|
|
|
int sbytes; |
|
|
|
|
|
struct iovec *iov; |
|
int iovsize; |
|
int iovused; |
|
|
|
struct msghdr *msglist; |
|
int msgsize; |
|
int msgused; |
|
int msgcurr; |
|
int msgbytes; |
|
|
|
item **ilist; |
|
int isize; |
|
item **icurr; |
|
int ileft; |
|
|
|
char **suffixlist; |
|
int suffixsize; |
|
char **suffixcurr; |
|
int suffixleft; |
|
|
|
|
|
bool udp; |
|
int request_id; |
|
struct sockaddr request_addr; |
|
socklen_t request_addr_size; |
|
unsigned char *hdrbuf; |
|
int hdrsize; |
|
|
|
int binary; |
|
int bucket; |
|
|
|
int gen; |
|
bool noreply; |
|
conn *next; |
|
}; |
|
|
|
|
|
#define MAX_BUCKETS 32768 |
|
|
|
|
|
extern volatile rel_time_t current_time; |
|
|
|
|
|
|
|
|
|
|
|
conn *do_conn_from_freelist(); |
|
bool do_conn_add_to_freelist(conn *c); |
|
conn *conn_new(const int sfd, const int init_state, const int event_flags, const int read_buffer_size, const bool is_udp, struct event_base *base); |
|
|
|
|
|
#include "stats.h" |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef USE_THREADS |
|
|
|
void thread_init(int nthreads, struct event_base *main_base); |
|
int dispatch_event_add(int thread, conn *c); |
|
void dispatch_conn_new(int sfd, int init_state, int event_flags, int read_buffer_size, int is_udp); |
|
|
|
|
|
char *mt_add_delta(conn *c, item *item, const int incr, const int64_t delta, |
|
char *buf); |
|
void mt_assoc_move_next_bucket(void); |
|
conn *mt_conn_from_freelist(void); |
|
bool mt_conn_add_to_freelist(conn *c); |
|
char *mt_suffix_from_freelist(void); |
|
bool mt_suffix_add_to_freelist(char *s); |
|
char *mt_defer_delete(item *it, time_t exptime); |
|
int mt_is_listen_thread(void); |
|
item *mt_item_alloc(char *key, size_t nkey, int flags, rel_time_t exptime, int nbytes); |
|
char *mt_item_cachedump(const unsigned int slabs_clsid, const unsigned int limit, unsigned int *bytes); |
|
void mt_item_flush_expired(void); |
|
item *mt_item_get_notedeleted(const char *key, const size_t nkey, bool *delete_locked); |
|
int mt_item_link(item *it); |
|
void mt_item_remove(item *it); |
|
int mt_item_replace(item *it, item *new_it); |
|
char *mt_item_stats(int *bytes); |
|
char *mt_item_stats_sizes(int *bytes); |
|
void mt_item_unlink(item *it); |
|
void mt_item_update(item *it); |
|
void mt_run_deferred_deletes(void); |
|
void *mt_slabs_alloc(size_t size, unsigned int id); |
|
void mt_slabs_free(void *ptr, size_t size, unsigned int id); |
|
int mt_slabs_reassign(unsigned char srcid, unsigned char dstid); |
|
char *mt_slabs_stats(int *buflen); |
|
void mt_stats_lock(void); |
|
void mt_stats_unlock(void); |
|
int mt_store_item(item *item, int comm); |
|
|
|
|
|
# define add_delta(c,x,y,z,a) mt_add_delta(c,x,y,z,a) |
|
# define assoc_move_next_bucket() mt_assoc_move_next_bucket() |
|
# define conn_from_freelist() mt_conn_from_freelist() |
|
# define conn_add_to_freelist(x) mt_conn_add_to_freelist(x) |
|
# define suffix_from_freelist() mt_suffix_from_freelist() |
|
# define suffix_add_to_freelist(x) mt_suffix_add_to_freelist(x) |
|
# define defer_delete(x,y) mt_defer_delete(x,y) |
|
# define is_listen_thread() mt_is_listen_thread() |
|
# define item_alloc(x,y,z,a,b) mt_item_alloc(x,y,z,a,b) |
|
# define item_cachedump(x,y,z) mt_item_cachedump(x,y,z) |
|
# define item_flush_expired() mt_item_flush_expired() |
|
# define item_get_notedeleted(x,y,z) mt_item_get_notedeleted(x,y,z) |
|
# define item_link(x) mt_item_link(x) |
|
# define item_remove(x) mt_item_remove(x) |
|
# define item_replace(x,y) mt_item_replace(x,y) |
|
# define item_stats(x) mt_item_stats(x) |
|
# define item_stats_sizes(x) mt_item_stats_sizes(x) |
|
# define item_update(x) mt_item_update(x) |
|
# define item_unlink(x) mt_item_unlink(x) |
|
# define run_deferred_deletes() mt_run_deferred_deletes() |
|
# define slabs_alloc(x,y) mt_slabs_alloc(x,y) |
|
# define slabs_free(x,y,z) mt_slabs_free(x,y,z) |
|
# define slabs_reassign(x,y) mt_slabs_reassign(x,y) |
|
# define slabs_stats(x) mt_slabs_stats(x) |
|
# define store_item(x,y) mt_store_item(x,y) |
|
|
|
# define STATS_LOCK() mt_stats_lock() |
|
# define STATS_UNLOCK() mt_stats_unlock() |
|
|
|
#else |
|
|
|
# define add_delta(c,x,y,z,a) do_add_delta(c,x,y,z,a) |
|
# define assoc_move_next_bucket() do_assoc_move_next_bucket() |
|
# define conn_from_freelist() do_conn_from_freelist() |
|
# define conn_add_to_freelist(x) do_conn_add_to_freelist(x) |
|
# define suffix_from_freelist() do_suffix_from_freelist() |
|
# define suffix_add_to_freelist(x) do_suffix_add_to_freelist(x) |
|
# define defer_delete(x,y) do_defer_delete(x,y) |
|
# define dispatch_conn_new(x,y,z,a,b) conn_new(x,y,z,a,b,main_base) |
|
# define dispatch_event_add(t,c) event_add(&(c)->event, 0) |
|
# define is_listen_thread() 1 |
|
# define item_alloc(x,y,z,a,b) do_item_alloc(x,y,z,a,b) |
|
# define item_cachedump(x,y,z) do_item_cachedump(x,y,z) |
|
# define item_flush_expired() do_item_flush_expired() |
|
# define item_get_notedeleted(x,y,z) do_item_get_notedeleted(x,y,z) |
|
# define item_link(x) do_item_link(x) |
|
# define item_remove(x) do_item_remove(x) |
|
# define item_replace(x,y) do_item_replace(x,y) |
|
# define item_stats(x) do_item_stats(x) |
|
# define item_stats_sizes(x) do_item_stats_sizes(x) |
|
# define item_unlink(x) do_item_unlink(x) |
|
# define item_update(x) do_item_update(x) |
|
# define run_deferred_deletes() do_run_deferred_deletes() |
|
# define slabs_alloc(x,y) do_slabs_alloc(x,y) |
|
# define slabs_free(x,y,z) do_slabs_free(x,y,z) |
|
# define slabs_reassign(x,y) do_slabs_reassign(x,y) |
|
# define slabs_stats(x) do_slabs_stats(x) |
|
# define store_item(x,y) do_store_item(x,y) |
|
# define thread_init(x,y) 0 |
|
|
|
# define STATS_LOCK() |
|
# define STATS_UNLOCK() |
|
|
|
#endif |
|
|
|
|
|
#if !defined(__GNUC__) || (__GNUC__ == 2 && __GNUC_MINOR__ < 96) |
|
#define __builtin_expect(x, expected_value) (x) |
|
#endif |
|
|
|
#define likely(x) __builtin_expect((x),1) |
|
#define unlikely(x) __builtin_expect((x),0) |
|
|
|
#endif |
|
|