]> git.saurik.com Git - redis.git/blame - src/redis.h
Fixed a crash loading the AOF file containing MULTI/EXEC, a result of WATCH implement...
[redis.git] / src / redis.h
CommitLineData
e2641e09 1#ifndef __REDIS_H
2#define __REDIS_H
3
4#include "fmacros.h"
5#include "config.h"
6
7#if defined(__sun)
8#include "solarisfixes.h"
9#endif
10
11#include <stdio.h>
12#include <stdlib.h>
13#include <string.h>
14#include <time.h>
15#include <limits.h>
16#include <unistd.h>
17#include <errno.h>
3688d7f3 18#include <inttypes.h>
e2641e09 19
20#include "ae.h" /* Event driven programming library */
21#include "sds.h" /* Dynamic safe strings */
22#include "dict.h" /* Hash tables */
23#include "adlist.h" /* Linked lists */
24#include "zmalloc.h" /* total memory usage aware version of malloc/free */
25#include "anet.h" /* Networking the easy way */
26#include "zipmap.h" /* Compact string -> string data structure */
27#include "ziplist.h" /* Compact list data structure */
28#include "version.h"
29
30/* Error codes */
31#define REDIS_OK 0
32#define REDIS_ERR -1
33
34/* Static server configuration */
35#define REDIS_SERVERPORT 6379 /* TCP port */
36#define REDIS_MAXIDLETIME (60*5) /* default client timeout */
37#define REDIS_IOBUF_LEN 1024
38#define REDIS_LOADBUF_LEN 1024
39#define REDIS_STATIC_ARGS 8
40#define REDIS_DEFAULT_DBNUM 16
41#define REDIS_CONFIGLINE_MAX 1024
42#define REDIS_OBJFREELIST_MAX 1000000 /* Max number of objects to cache */
43#define REDIS_MAX_SYNC_TIME 60 /* Slave can't take more to sync */
44#define REDIS_EXPIRELOOKUPS_PER_CRON 10 /* lookup 10 expires per loop */
45#define REDIS_MAX_WRITE_PER_EVENT (1024*64)
46#define REDIS_REQUEST_MAX_SIZE (1024*1024*256) /* max bytes in inline command */
47#define REDIS_SHARED_INTEGERS 10000
48
49/* If more then REDIS_WRITEV_THRESHOLD write packets are pending use writev */
50#define REDIS_WRITEV_THRESHOLD 3
51/* Max number of iovecs used for each writev call */
52#define REDIS_WRITEV_IOVEC_COUNT 256
53
54/* Hash table parameters */
55#define REDIS_HT_MINFILL 10 /* Minimal hash table fill 10% */
56
57/* Command flags */
58#define REDIS_CMD_BULK 1 /* Bulk write command */
59#define REDIS_CMD_INLINE 2 /* Inline command */
60/* REDIS_CMD_DENYOOM reserves a longer comment: all the commands marked with
61 this flags will return an error when the 'maxmemory' option is set in the
62 config file and the server is using more than maxmemory bytes of memory.
63 In short this commands are denied on low memory conditions. */
64#define REDIS_CMD_DENYOOM 4
65#define REDIS_CMD_FORCE_REPLICATION 8 /* Force replication even if dirty is 0 */
66
67/* Object types */
68#define REDIS_STRING 0
69#define REDIS_LIST 1
70#define REDIS_SET 2
71#define REDIS_ZSET 3
72#define REDIS_HASH 4
73#define REDIS_VMPOINTER 8
74
75/* Objects encoding. Some kind of objects like Strings and Hashes can be
76 * internally represented in multiple ways. The 'encoding' field of the object
77 * is set to one of this fields for this object. */
78#define REDIS_ENCODING_RAW 0 /* Raw representation */
79#define REDIS_ENCODING_INT 1 /* Encoded as integer */
80#define REDIS_ENCODING_HT 2 /* Encoded as hash table */
81#define REDIS_ENCODING_ZIPMAP 3 /* Encoded as zipmap */
82#define REDIS_ENCODING_LINKEDLIST 4 /* Encoded as regular linked list */
83#define REDIS_ENCODING_ZIPLIST 5 /* Encoded as ziplist */
84
85/* Object types only used for dumping to disk */
86#define REDIS_EXPIRETIME 253
87#define REDIS_SELECTDB 254
88#define REDIS_EOF 255
89
90/* Defines related to the dump file format. To store 32 bits lengths for short
91 * keys requires a lot of space, so we check the most significant 2 bits of
92 * the first byte to interpreter the length:
93 *
94 * 00|000000 => if the two MSB are 00 the len is the 6 bits of this byte
95 * 01|000000 00000000 => 01, the len is 14 byes, 6 bits + 8 bits of next byte
96 * 10|000000 [32 bit integer] => if it's 01, a full 32 bit len will follow
97 * 11|000000 this means: specially encoded object will follow. The six bits
98 * number specify the kind of object that follows.
99 * See the REDIS_RDB_ENC_* defines.
100 *
101 * Lenghts up to 63 are stored using a single byte, most DB keys, and may
102 * values, will fit inside. */
103#define REDIS_RDB_6BITLEN 0
104#define REDIS_RDB_14BITLEN 1
105#define REDIS_RDB_32BITLEN 2
106#define REDIS_RDB_ENCVAL 3
107#define REDIS_RDB_LENERR UINT_MAX
108
109/* When a length of a string object stored on disk has the first two bits
110 * set, the remaining two bits specify a special encoding for the object
111 * accordingly to the following defines: */
112#define REDIS_RDB_ENC_INT8 0 /* 8 bit signed integer */
113#define REDIS_RDB_ENC_INT16 1 /* 16 bit signed integer */
114#define REDIS_RDB_ENC_INT32 2 /* 32 bit signed integer */
115#define REDIS_RDB_ENC_LZF 3 /* string compressed with FASTLZ */
116
117/* Virtual memory object->where field. */
118#define REDIS_VM_MEMORY 0 /* The object is on memory */
119#define REDIS_VM_SWAPPED 1 /* The object is on disk */
120#define REDIS_VM_SWAPPING 2 /* Redis is swapping this object on disk */
121#define REDIS_VM_LOADING 3 /* Redis is loading this object from disk */
122
123/* Virtual memory static configuration stuff.
124 * Check vmFindContiguousPages() to know more about this magic numbers. */
125#define REDIS_VM_MAX_NEAR_PAGES 65536
126#define REDIS_VM_MAX_RANDOM_JUMP 4096
127#define REDIS_VM_MAX_THREADS 32
128#define REDIS_THREAD_STACK_SIZE (1024*1024*4)
129/* The following is the *percentage* of completed I/O jobs to process when the
130 * handelr is called. While Virtual Memory I/O operations are performed by
131 * threads, this operations must be processed by the main thread when completed
132 * in order to take effect. */
133#define REDIS_MAX_COMPLETED_JOBS_PROCESSED 1
134
135/* Client flags */
136#define REDIS_SLAVE 1 /* This client is a slave server */
137#define REDIS_MASTER 2 /* This client is a master server */
138#define REDIS_MONITOR 4 /* This client is a slave monitor, see MONITOR */
139#define REDIS_MULTI 8 /* This client is in a MULTI context */
140#define REDIS_BLOCKED 16 /* The client is waiting in a blocking operation */
141#define REDIS_IO_WAIT 32 /* The client is waiting for Virtual Memory I/O */
142#define REDIS_DIRTY_CAS 64 /* Watched keys modified. EXEC will fail. */
143
144/* Slave replication state - slave side */
145#define REDIS_REPL_NONE 0 /* No active replication */
146#define REDIS_REPL_CONNECT 1 /* Must connect to master */
147#define REDIS_REPL_CONNECTED 2 /* Connected to master */
148
149/* Slave replication state - from the point of view of master
150 * Note that in SEND_BULK and ONLINE state the slave receives new updates
151 * in its output queue. In the WAIT_BGSAVE state instead the server is waiting
152 * to start the next background saving in order to send updates to it. */
153#define REDIS_REPL_WAIT_BGSAVE_START 3 /* master waits bgsave to start feeding it */
154#define REDIS_REPL_WAIT_BGSAVE_END 4 /* master waits bgsave to start bulk DB transmission */
155#define REDIS_REPL_SEND_BULK 5 /* master is sending the bulk DB */
156#define REDIS_REPL_ONLINE 6 /* bulk DB already transmitted, receive updates */
157
158/* List related stuff */
159#define REDIS_HEAD 0
160#define REDIS_TAIL 1
161
162/* Sort operations */
163#define REDIS_SORT_GET 0
164#define REDIS_SORT_ASC 1
165#define REDIS_SORT_DESC 2
166#define REDIS_SORTKEY_MAX 1024
167
168/* Log levels */
169#define REDIS_DEBUG 0
170#define REDIS_VERBOSE 1
171#define REDIS_NOTICE 2
172#define REDIS_WARNING 3
173
174/* Anti-warning macro... */
175#define REDIS_NOTUSED(V) ((void) V)
176
177#define ZSKIPLIST_MAXLEVEL 32 /* Should be enough for 2^32 elements */
178#define ZSKIPLIST_P 0.25 /* Skiplist P = 1/4 */
179
180/* Append only defines */
181#define APPENDFSYNC_NO 0
182#define APPENDFSYNC_ALWAYS 1
183#define APPENDFSYNC_EVERYSEC 2
184
185/* Zip structure related defaults */
186#define REDIS_HASH_MAX_ZIPMAP_ENTRIES 64
187#define REDIS_HASH_MAX_ZIPMAP_VALUE 512
188#define REDIS_LIST_MAX_ZIPLIST_ENTRIES 1024
189#define REDIS_LIST_MAX_ZIPLIST_VALUE 32
190
191/* Sets operations codes */
192#define REDIS_OP_UNION 0
193#define REDIS_OP_DIFF 1
194#define REDIS_OP_INTER 2
195
196/* We can print the stacktrace, so our assert is defined this way: */
197#define redisAssert(_e) ((_e)?(void)0 : (_redisAssert(#_e,__FILE__,__LINE__),_exit(1)))
198#define redisPanic(_e) _redisPanic(#_e,__FILE__,__LINE__),_exit(1)
199void _redisAssert(char *estr, char *file, int line);
200void _redisPanic(char *msg, char *file, int line);
201
202/*-----------------------------------------------------------------------------
203 * Data types
204 *----------------------------------------------------------------------------*/
205
206/* A redis object, that is a type able to hold a string / list / set */
207
208/* The actual Redis Object */
209typedef struct redisObject {
210 unsigned type:4;
211 unsigned storage:2; /* REDIS_VM_MEMORY or REDIS_VM_SWAPPING */
212 unsigned encoding:4;
213 unsigned lru:22; /* lru time (relative to server.lruclock) */
214 int refcount;
215 void *ptr;
216 /* VM fields are only allocated if VM is active, otherwise the
217 * object allocation function will just allocate
218 * sizeof(redisObjct) minus sizeof(redisObjectVM), so using
219 * Redis without VM active will not have any overhead. */
220} robj;
221
222/* The VM pointer structure - identifies an object in the swap file.
223 *
224 * This object is stored in place of the value
225 * object in the main key->value hash table representing a database.
226 * Note that the first fields (type, storage) are the same as the redisObject
227 * structure so that vmPointer strucuters can be accessed even when casted
228 * as redisObject structures.
229 *
230 * This is useful as we don't know if a value object is or not on disk, but we
231 * are always able to read obj->storage to check this. For vmPointer
232 * structures "type" is set to REDIS_VMPOINTER (even if without this field
233 * is still possible to check the kind of object from the value of 'storage').*/
234typedef struct vmPointer {
235 unsigned type:4;
236 unsigned storage:2; /* REDIS_VM_SWAPPED or REDIS_VM_LOADING */
237 unsigned notused:26;
238 unsigned int vtype; /* type of the object stored in the swap file */
239 off_t page; /* the page at witch the object is stored on disk */
240 off_t usedpages; /* number of pages used on disk */
241} vmpointer;
242
243/* Macro used to initalize a Redis object allocated on the stack.
244 * Note that this macro is taken near the structure definition to make sure
245 * we'll update it when the structure is changed, to avoid bugs like
246 * bug #85 introduced exactly in this way. */
247#define initStaticStringObject(_var,_ptr) do { \
248 _var.refcount = 1; \
249 _var.type = REDIS_STRING; \
250 _var.encoding = REDIS_ENCODING_RAW; \
251 _var.ptr = _ptr; \
252 _var.storage = REDIS_VM_MEMORY; \
253} while(0);
254
255typedef struct redisDb {
256 dict *dict; /* The keyspace for this DB */
257 dict *expires; /* Timeout of keys with a timeout set */
258 dict *blocking_keys; /* Keys with clients waiting for data (BLPOP) */
259 dict *io_keys; /* Keys with clients waiting for VM I/O */
260 dict *watched_keys; /* WATCHED keys for MULTI/EXEC CAS */
261 int id;
262} redisDb;
263
264/* Client MULTI/EXEC state */
265typedef struct multiCmd {
266 robj **argv;
267 int argc;
268 struct redisCommand *cmd;
269} multiCmd;
270
271typedef struct multiState {
272 multiCmd *commands; /* Array of MULTI commands */
273 int count; /* Total number of MULTI commands */
274} multiState;
275
276/* With multiplexing we need to take per-clinet state.
277 * Clients are taken in a liked list. */
278typedef struct redisClient {
279 int fd;
280 redisDb *db;
281 int dictid;
282 sds querybuf;
283 robj **argv, **mbargv;
284 int argc, mbargc;
285 int bulklen; /* bulk read len. -1 if not in bulk read mode */
286 int multibulk; /* multi bulk command format active */
287 list *reply;
288 int sentlen;
289 time_t lastinteraction; /* time of the last interaction, used for timeout */
290 int flags; /* REDIS_SLAVE | REDIS_MONITOR | REDIS_MULTI ... */
291 int slaveseldb; /* slave selected db, if this client is a slave */
292 int authenticated; /* when requirepass is non-NULL */
293 int replstate; /* replication state if this is a slave */
294 int repldbfd; /* replication DB file descriptor */
295 long repldboff; /* replication DB file offset */
296 off_t repldbsize; /* replication DB file size */
297 multiState mstate; /* MULTI/EXEC state */
298 robj **blocking_keys; /* The key we are waiting to terminate a blocking
299 * operation such as BLPOP. Otherwise NULL. */
300 int blocking_keys_num; /* Number of blocking keys */
301 time_t blockingto; /* Blocking operation timeout. If UNIX current time
302 * is >= blockingto then the operation timed out. */
303 list *io_keys; /* Keys this client is waiting to be loaded from the
304 * swap file in order to continue. */
305 list *watched_keys; /* Keys WATCHED for MULTI/EXEC CAS */
306 dict *pubsub_channels; /* channels a client is interested in (SUBSCRIBE) */
307 list *pubsub_patterns; /* patterns a client is interested in (SUBSCRIBE) */
308} redisClient;
309
310struct saveparam {
311 time_t seconds;
312 int changes;
313};
314
315struct sharedObjectsStruct {
316 robj *crlf, *ok, *err, *emptybulk, *czero, *cone, *cnegone, *pong, *space,
317 *colon, *nullbulk, *nullmultibulk, *queued,
318 *emptymultibulk, *wrongtypeerr, *nokeyerr, *syntaxerr, *sameobjecterr,
319 *outofrangeerr, *plus,
320 *select0, *select1, *select2, *select3, *select4,
321 *select5, *select6, *select7, *select8, *select9,
322 *messagebulk, *pmessagebulk, *subscribebulk, *unsubscribebulk, *mbulk3,
323 *mbulk4, *psubscribebulk, *punsubscribebulk,
324 *integers[REDIS_SHARED_INTEGERS];
325};
326
327/* Global server state structure */
328struct redisServer {
329 int port;
330 int fd;
331 redisDb *db;
332 long long dirty; /* changes to DB from the last save */
333 list *clients;
334 list *slaves, *monitors;
335 char neterr[ANET_ERR_LEN];
336 aeEventLoop *el;
337 int cronloops; /* number of times the cron function run */
338 list *objfreelist; /* A list of freed objects to avoid malloc() */
339 time_t lastsave; /* Unix time of last save succeeede */
340 /* Fields used only for stats */
341 time_t stat_starttime; /* server start time */
342 long long stat_numcommands; /* number of processed commands */
343 long long stat_numconnections; /* number of connections received */
344 long long stat_expiredkeys; /* number of expired keys */
345 /* Configuration */
346 int verbosity;
347 int glueoutputbuf;
348 int maxidletime;
349 int dbnum;
350 int daemonize;
351 int appendonly;
352 int appendfsync;
353 int no_appendfsync_on_rewrite;
354 int shutdown_asap;
355 time_t lastfsync;
356 int appendfd;
357 int appendseldb;
358 char *pidfile;
359 pid_t bgsavechildpid;
360 pid_t bgrewritechildpid;
361 sds bgrewritebuf; /* buffer taken by parent during oppend only rewrite */
362 sds aofbuf; /* AOF buffer, written before entering the event loop */
363 struct saveparam *saveparams;
364 int saveparamslen;
365 char *logfile;
366 char *bindaddr;
367 char *dbfilename;
368 char *appendfilename;
369 char *requirepass;
370 int rdbcompression;
371 int activerehashing;
372 /* Replication related */
373 int isslave;
374 char *masterauth;
375 char *masterhost;
376 int masterport;
377 redisClient *master; /* client that is master for this slave */
378 int replstate;
379 unsigned int maxclients;
380 unsigned long long maxmemory;
381 unsigned int blpop_blocked_clients;
382 unsigned int vm_blocked_clients;
383 /* Sort parameters - qsort_r() is only available under BSD so we
384 * have to take this state global, in order to pass it to sortCompare() */
385 int sort_desc;
386 int sort_alpha;
387 int sort_bypattern;
388 /* Virtual memory configuration */
389 int vm_enabled;
390 char *vm_swap_file;
391 off_t vm_page_size;
392 off_t vm_pages;
393 unsigned long long vm_max_memory;
394 /* Zip structure config */
395 size_t hash_max_zipmap_entries;
396 size_t hash_max_zipmap_value;
397 size_t list_max_ziplist_entries;
398 size_t list_max_ziplist_value;
399 /* Virtual memory state */
400 FILE *vm_fp;
401 int vm_fd;
402 off_t vm_next_page; /* Next probably empty page */
403 off_t vm_near_pages; /* Number of pages allocated sequentially */
404 unsigned char *vm_bitmap; /* Bitmap of free/used pages */
405 time_t unixtime; /* Unix time sampled every second. */
406 /* Virtual memory I/O threads stuff */
407 /* An I/O thread process an element taken from the io_jobs queue and
408 * put the result of the operation in the io_done list. While the
409 * job is being processed, it's put on io_processing queue. */
410 list *io_newjobs; /* List of VM I/O jobs yet to be processed */
411 list *io_processing; /* List of VM I/O jobs being processed */
412 list *io_processed; /* List of VM I/O jobs already processed */
413 list *io_ready_clients; /* Clients ready to be unblocked. All keys loaded */
414 pthread_mutex_t io_mutex; /* lock to access io_jobs/io_done/io_thread_job */
415 pthread_mutex_t obj_freelist_mutex; /* safe redis objects creation/free */
416 pthread_mutex_t io_swapfile_mutex; /* So we can lseek + write */
417 pthread_attr_t io_threads_attr; /* attributes for threads creation */
418 int io_active_threads; /* Number of running I/O threads */
419 int vm_max_threads; /* Max number of I/O threads running at the same time */
420 /* Our main thread is blocked on the event loop, locking for sockets ready
421 * to be read or written, so when a threaded I/O operation is ready to be
422 * processed by the main thread, the I/O thread will use a unix pipe to
423 * awake the main thread. The followings are the two pipe FDs. */
424 int io_ready_pipe_read;
425 int io_ready_pipe_write;
426 /* Virtual memory stats */
427 unsigned long long vm_stats_used_pages;
428 unsigned long long vm_stats_swapped_objects;
429 unsigned long long vm_stats_swapouts;
430 unsigned long long vm_stats_swapins;
431 /* Pubsub */
432 dict *pubsub_channels; /* Map channels to list of subscribed clients */
433 list *pubsub_patterns; /* A list of pubsub_patterns */
434 /* Misc */
435 FILE *devnull;
436 unsigned lruclock:22; /* clock incrementing every minute, for LRU */
437 unsigned lruclock_padding:10;
438};
439
440typedef struct pubsubPattern {
441 redisClient *client;
442 robj *pattern;
443} pubsubPattern;
444
445typedef void redisCommandProc(redisClient *c);
446typedef void redisVmPreloadProc(redisClient *c, struct redisCommand *cmd, int argc, robj **argv);
447struct redisCommand {
448 char *name;
449 redisCommandProc *proc;
450 int arity;
451 int flags;
452 /* Use a function to determine which keys need to be loaded
453 * in the background prior to executing this command. Takes precedence
454 * over vm_firstkey and others, ignored when NULL */
455 redisVmPreloadProc *vm_preload_proc;
456 /* What keys should be loaded in background when calling this command? */
457 int vm_firstkey; /* The first argument that's a key (0 = no keys) */
458 int vm_lastkey; /* THe last argument that's a key */
459 int vm_keystep; /* The step between first and last key */
460};
461
462struct redisFunctionSym {
463 char *name;
464 unsigned long pointer;
465};
466
467typedef struct _redisSortObject {
468 robj *obj;
469 union {
470 double score;
471 robj *cmpobj;
472 } u;
473} redisSortObject;
474
475typedef struct _redisSortOperation {
476 int type;
477 robj *pattern;
478} redisSortOperation;
479
480/* ZSETs use a specialized version of Skiplists */
481
482typedef struct zskiplistNode {
483 struct zskiplistNode **forward;
484 struct zskiplistNode *backward;
485 unsigned int *span;
486 double score;
487 robj *obj;
488} zskiplistNode;
489
490typedef struct zskiplist {
491 struct zskiplistNode *header, *tail;
492 unsigned long length;
493 int level;
494} zskiplist;
495
496typedef struct zset {
497 dict *dict;
498 zskiplist *zsl;
499} zset;
500
501/* VM threaded I/O request message */
502#define REDIS_IOJOB_LOAD 0 /* Load from disk to memory */
503#define REDIS_IOJOB_PREPARE_SWAP 1 /* Compute needed pages */
504#define REDIS_IOJOB_DO_SWAP 2 /* Swap from memory to disk */
505typedef struct iojob {
506 int type; /* Request type, REDIS_IOJOB_* */
507 redisDb *db;/* Redis database */
508 robj *key; /* This I/O request is about swapping this key */
509 robj *id; /* Unique identifier of this job:
510 this is the object to swap for REDIS_IOREQ_*_SWAP, or the
511 vmpointer objct for REDIS_IOREQ_LOAD. */
512 robj *val; /* the value to swap for REDIS_IOREQ_*_SWAP, otherwise this
513 * field is populated by the I/O thread for REDIS_IOREQ_LOAD. */
514 off_t page; /* Swap page where to read/write the object */
515 off_t pages; /* Swap pages needed to save object. PREPARE_SWAP return val */
516 int canceled; /* True if this command was canceled by blocking side of VM */
517 pthread_t thread; /* ID of the thread processing this entry */
518} iojob;
519
520/* Structure to hold list iteration abstraction. */
521typedef struct {
522 robj *subject;
523 unsigned char encoding;
524 unsigned char direction; /* Iteration direction */
525 unsigned char *zi;
526 listNode *ln;
527} listTypeIterator;
528
529/* Structure for an entry while iterating over a list. */
530typedef struct {
531 listTypeIterator *li;
532 unsigned char *zi; /* Entry in ziplist */
533 listNode *ln; /* Entry in linked list */
534} listTypeEntry;
535
536/* Structure to hold hash iteration abstration. Note that iteration over
537 * hashes involves both fields and values. Because it is possible that
538 * not both are required, store pointers in the iterator to avoid
539 * unnecessary memory allocation for fields/values. */
540typedef struct {
541 int encoding;
542 unsigned char *zi;
543 unsigned char *zk, *zv;
544 unsigned int zklen, zvlen;
545
546 dictIterator *di;
547 dictEntry *de;
548} hashTypeIterator;
549
550#define REDIS_HASH_KEY 1
551#define REDIS_HASH_VALUE 2
552
553/*-----------------------------------------------------------------------------
554 * Extern declarations
555 *----------------------------------------------------------------------------*/
556
557extern struct redisServer server;
558extern struct sharedObjectsStruct shared;
559extern dictType setDictType;
560extern dictType zsetDictType;
561extern double R_Zero, R_PosInf, R_NegInf, R_Nan;
562dictType hashDictType;
563
564/*-----------------------------------------------------------------------------
565 * Functions prototypes
566 *----------------------------------------------------------------------------*/
567
568/* networking.c -- Networking and Client related operations */
569redisClient *createClient(int fd);
570void closeTimedoutClients(void);
571void freeClient(redisClient *c);
572void resetClient(redisClient *c);
573void sendReplyToClient(aeEventLoop *el, int fd, void *privdata, int mask);
574void sendReplyToClientWritev(aeEventLoop *el, int fd, void *privdata, int mask);
575void addReply(redisClient *c, robj *obj);
576void addReplySds(redisClient *c, sds s);
577void processInputBuffer(redisClient *c);
578void acceptHandler(aeEventLoop *el, int fd, void *privdata, int mask);
579void readQueryFromClient(aeEventLoop *el, int fd, void *privdata, int mask);
580void addReplyBulk(redisClient *c, robj *obj);
581void addReplyBulkCString(redisClient *c, char *s);
582void acceptHandler(aeEventLoop *el, int fd, void *privdata, int mask);
583void addReply(redisClient *c, robj *obj);
584void addReplySds(redisClient *c, sds s);
585void addReplyDouble(redisClient *c, double d);
586void addReplyLongLong(redisClient *c, long long ll);
587void addReplyUlong(redisClient *c, unsigned long ul);
588void *dupClientReplyValue(void *o);
589
590/* List data type */
591void listTypeTryConversion(robj *subject, robj *value);
592void listTypePush(robj *subject, robj *value, int where);
593robj *listTypePop(robj *subject, int where);
594unsigned long listTypeLength(robj *subject);
595listTypeIterator *listTypeInitIterator(robj *subject, int index, unsigned char direction);
596void listTypeReleaseIterator(listTypeIterator *li);
597int listTypeNext(listTypeIterator *li, listTypeEntry *entry);
598robj *listTypeGet(listTypeEntry *entry);
599void listTypeInsert(listTypeEntry *entry, robj *value, int where);
600int listTypeEqual(listTypeEntry *entry, robj *o);
601void listTypeDelete(listTypeEntry *entry);
602void listTypeConvert(robj *subject, int enc);
603void unblockClientWaitingData(redisClient *c);
604int handleClientsWaitingListPush(redisClient *c, robj *key, robj *ele);
605void popGenericCommand(redisClient *c, int where);
606
607/* MULTI/EXEC/WATCH... */
608void unwatchAllKeys(redisClient *c);
609void initClientMultiState(redisClient *c);
610void freeClientMultiState(redisClient *c);
611void queueMultiCommand(redisClient *c, struct redisCommand *cmd);
612void touchWatchedKey(redisDb *db, robj *key);
613void touchWatchedKeysOnFlush(int dbid);
614
615/* Redis object implementation */
616void decrRefCount(void *o);
617void incrRefCount(robj *o);
618void freeStringObject(robj *o);
619void freeListObject(robj *o);
620void freeSetObject(robj *o);
621void freeZsetObject(robj *o);
622void freeHashObject(robj *o);
623robj *createObject(int type, void *ptr);
624robj *createStringObject(char *ptr, size_t len);
625robj *dupStringObject(robj *o);
626robj *tryObjectEncoding(robj *o);
627robj *getDecodedObject(robj *o);
628size_t stringObjectLen(robj *o);
629int tryFreeOneObjectFromFreelist(void);
630robj *createStringObjectFromLongLong(long long value);
631robj *createListObject(void);
632robj *createZiplistObject(void);
633robj *createSetObject(void);
634robj *createHashObject(void);
635robj *createZsetObject(void);
636int getLongFromObjectOrReply(redisClient *c, robj *o, long *target, const char *msg);
637int checkType(redisClient *c, robj *o, int type);
638int getLongLongFromObjectOrReply(redisClient *c, robj *o, long long *target, const char *msg);
639int getDoubleFromObjectOrReply(redisClient *c, robj *o, double *target, const char *msg);
640int getLongLongFromObject(robj *o, long long *target);
641char *strEncoding(int encoding);
642int compareStringObjects(robj *a, robj *b);
643int equalStringObjects(robj *a, robj *b);
644
645/* Replication */
646void replicationFeedSlaves(list *slaves, int dictid, robj **argv, int argc);
647void replicationFeedMonitors(list *monitors, int dictid, robj **argv, int argc);
648int syncWithMaster(void);
649void updateSlavesWaitingBgsave(int bgsaveerr);
650
651/* RDB persistence */
652int rdbLoad(char *filename);
653int rdbSaveBackground(char *filename);
654void rdbRemoveTempFile(pid_t childpid);
655int rdbSave(char *filename);
656int rdbSaveObject(FILE *fp, robj *o);
657off_t rdbSavedObjectPages(robj *o, FILE *fp);
658off_t rdbSavedObjectLen(robj *o, FILE *fp);
659robj *rdbLoadObject(int type, FILE *fp);
660void backgroundSaveDoneHandler(int statloc);
661
662/* AOF persistence */
663void flushAppendOnlyFile(void);
664void feedAppendOnlyFile(struct redisCommand *cmd, int dictid, robj **argv, int argc);
665void aofRemoveTempFile(pid_t childpid);
666int rewriteAppendOnlyFileBackground(void);
667int loadAppendOnlyFile(char *filename);
668void stopAppendOnly(void);
669int startAppendOnly(void);
670void backgroundRewriteDoneHandler(int statloc);
671
672/* Sorted sets data type */
673zskiplist *zslCreate(void);
674void zslFree(zskiplist *zsl);
675void zslInsert(zskiplist *zsl, double score, robj *obj);
676
677/* Core functions */
678void freeMemoryIfNeeded(void);
679int processCommand(redisClient *c);
680void setupSigSegvAction(void);
681struct redisCommand *lookupCommand(char *name);
682void call(redisClient *c, struct redisCommand *cmd);
683int prepareForShutdown();
684void redisLog(int level, const char *fmt, ...);
685void usage();
686void updateDictResizePolicy(void);
687int htNeedsResize(dict *dict);
688void oom(const char *msg);
689
690/* Virtual Memory */
691void vmInit(void);
692void vmMarkPagesFree(off_t page, off_t count);
693robj *vmLoadObject(robj *o);
694robj *vmPreviewObject(robj *o);
695int vmSwapOneObjectBlocking(void);
696int vmSwapOneObjectThreaded(void);
697int vmCanSwapOut(void);
698void vmThreadedIOCompletedJob(aeEventLoop *el, int fd, void *privdata, int mask);
699void vmCancelThreadedIOJob(robj *o);
700void lockThreadedIO(void);
701void unlockThreadedIO(void);
702int vmSwapObjectThreaded(robj *key, robj *val, redisDb *db);
703void freeIOJob(iojob *j);
704void queueIOJob(iojob *j);
705int vmWriteObjectOnSwap(robj *o, off_t page);
706robj *vmReadObjectFromSwap(off_t page, int type);
707void waitEmptyIOJobsQueue(void);
708void vmReopenSwapFile(void);
709int vmFreePage(off_t page);
710void zunionInterBlockClientOnSwappedKeys(redisClient *c, struct redisCommand *cmd, int argc, robj **argv);
711void execBlockClientOnSwappedKeys(redisClient *c, struct redisCommand *cmd, int argc, robj **argv);
712int blockClientOnSwappedKeys(redisClient *c, struct redisCommand *cmd);
713int dontWaitForSwappedKey(redisClient *c, robj *key);
714void handleClientsBlockedOnSwappedKey(redisDb *db, robj *key);
715vmpointer *vmSwapObjectBlocking(robj *val);
716
717/* Hash data type */
718void convertToRealHash(robj *o);
719void hashTypeTryConversion(robj *subject, robj **argv, int start, int end);
720void hashTypeTryObjectEncoding(robj *subject, robj **o1, robj **o2);
721robj *hashTypeGet(robj *o, robj *key);
722int hashTypeExists(robj *o, robj *key);
723int hashTypeSet(robj *o, robj *key, robj *value);
724int hashTypeDelete(robj *o, robj *key);
725unsigned long hashTypeLength(robj *o);
726hashTypeIterator *hashTypeInitIterator(robj *subject);
727void hashTypeReleaseIterator(hashTypeIterator *hi);
728int hashTypeNext(hashTypeIterator *hi);
729robj *hashTypeCurrent(hashTypeIterator *hi, int what);
730robj *hashTypeLookupWriteOrCreate(redisClient *c, robj *key);
731
732/* Pub / Sub */
733int pubsubUnsubscribeAllChannels(redisClient *c, int notify);
734int pubsubUnsubscribeAllPatterns(redisClient *c, int notify);
735void freePubsubPattern(void *p);
736int listMatchPubsubPattern(void *a, void *b);
737
738/* Utility functions */
739int stringmatchlen(const char *pattern, int patternLen,
740 const char *string, int stringLen, int nocase);
741int stringmatch(const char *pattern, const char *string, int nocase);
742long long memtoll(const char *p, int *err);
743int ll2string(char *s, size_t len, long long value);
744int isStringRepresentableAsLong(sds s, long *longval);
745
746/* Configuration */
747void loadServerConfig(char *filename);
748void appendServerSaveParams(time_t seconds, int changes);
749void resetServerSaveParams();
750
751/* db.c -- Keyspace access API */
752int removeExpire(redisDb *db, robj *key);
753int expireIfNeeded(redisDb *db, robj *key);
754int deleteIfVolatile(redisDb *db, robj *key);
755time_t getExpire(redisDb *db, robj *key);
756int setExpire(redisDb *db, robj *key, time_t when);
757robj *lookupKey(redisDb *db, robj *key);
758robj *lookupKeyRead(redisDb *db, robj *key);
759robj *lookupKeyWrite(redisDb *db, robj *key);
760robj *lookupKeyReadOrReply(redisClient *c, robj *key, robj *reply);
761robj *lookupKeyWriteOrReply(redisClient *c, robj *key, robj *reply);
762int dbAdd(redisDb *db, robj *key, robj *val);
763int dbReplace(redisDb *db, robj *key, robj *val);
764int dbExists(redisDb *db, robj *key);
765robj *dbRandomKey(redisDb *db);
766int dbDelete(redisDb *db, robj *key);
767long long emptyDb();
768int selectDb(redisClient *c, int id);
769
770/* Git SHA1 */
771char *redisGitSHA1(void);
772char *redisGitDirty(void);
773
774/* Commands prototypes */
775void authCommand(redisClient *c);
776void pingCommand(redisClient *c);
777void echoCommand(redisClient *c);
778void setCommand(redisClient *c);
779void setnxCommand(redisClient *c);
780void setexCommand(redisClient *c);
781void getCommand(redisClient *c);
782void delCommand(redisClient *c);
783void existsCommand(redisClient *c);
784void incrCommand(redisClient *c);
785void decrCommand(redisClient *c);
786void incrbyCommand(redisClient *c);
787void decrbyCommand(redisClient *c);
788void selectCommand(redisClient *c);
789void randomkeyCommand(redisClient *c);
790void keysCommand(redisClient *c);
791void dbsizeCommand(redisClient *c);
792void lastsaveCommand(redisClient *c);
793void saveCommand(redisClient *c);
794void bgsaveCommand(redisClient *c);
795void bgrewriteaofCommand(redisClient *c);
796void shutdownCommand(redisClient *c);
797void moveCommand(redisClient *c);
798void renameCommand(redisClient *c);
799void renamenxCommand(redisClient *c);
800void lpushCommand(redisClient *c);
801void rpushCommand(redisClient *c);
802void lpushxCommand(redisClient *c);
803void rpushxCommand(redisClient *c);
804void linsertCommand(redisClient *c);
805void lpopCommand(redisClient *c);
806void rpopCommand(redisClient *c);
807void llenCommand(redisClient *c);
808void lindexCommand(redisClient *c);
809void lrangeCommand(redisClient *c);
810void ltrimCommand(redisClient *c);
811void typeCommand(redisClient *c);
812void lsetCommand(redisClient *c);
813void saddCommand(redisClient *c);
814void sremCommand(redisClient *c);
815void smoveCommand(redisClient *c);
816void sismemberCommand(redisClient *c);
817void scardCommand(redisClient *c);
818void spopCommand(redisClient *c);
819void srandmemberCommand(redisClient *c);
820void sinterCommand(redisClient *c);
821void sinterstoreCommand(redisClient *c);
822void sunionCommand(redisClient *c);
823void sunionstoreCommand(redisClient *c);
824void sdiffCommand(redisClient *c);
825void sdiffstoreCommand(redisClient *c);
826void syncCommand(redisClient *c);
827void flushdbCommand(redisClient *c);
828void flushallCommand(redisClient *c);
829void sortCommand(redisClient *c);
830void lremCommand(redisClient *c);
831void rpoplpushcommand(redisClient *c);
832void infoCommand(redisClient *c);
833void mgetCommand(redisClient *c);
834void monitorCommand(redisClient *c);
835void expireCommand(redisClient *c);
836void expireatCommand(redisClient *c);
837void getsetCommand(redisClient *c);
838void ttlCommand(redisClient *c);
839void slaveofCommand(redisClient *c);
840void debugCommand(redisClient *c);
841void msetCommand(redisClient *c);
842void msetnxCommand(redisClient *c);
843void zaddCommand(redisClient *c);
844void zincrbyCommand(redisClient *c);
845void zrangeCommand(redisClient *c);
846void zrangebyscoreCommand(redisClient *c);
847void zcountCommand(redisClient *c);
848void zrevrangeCommand(redisClient *c);
849void zcardCommand(redisClient *c);
850void zremCommand(redisClient *c);
851void zscoreCommand(redisClient *c);
852void zremrangebyscoreCommand(redisClient *c);
853void multiCommand(redisClient *c);
854void execCommand(redisClient *c);
855void discardCommand(redisClient *c);
856void blpopCommand(redisClient *c);
857void brpopCommand(redisClient *c);
858void appendCommand(redisClient *c);
859void substrCommand(redisClient *c);
860void zrankCommand(redisClient *c);
861void zrevrankCommand(redisClient *c);
862void hsetCommand(redisClient *c);
863void hsetnxCommand(redisClient *c);
864void hgetCommand(redisClient *c);
865void hmsetCommand(redisClient *c);
866void hmgetCommand(redisClient *c);
867void hdelCommand(redisClient *c);
868void hlenCommand(redisClient *c);
869void zremrangebyrankCommand(redisClient *c);
870void zunionstoreCommand(redisClient *c);
871void zinterstoreCommand(redisClient *c);
872void hkeysCommand(redisClient *c);
873void hvalsCommand(redisClient *c);
874void hgetallCommand(redisClient *c);
875void hexistsCommand(redisClient *c);
876void configCommand(redisClient *c);
877void hincrbyCommand(redisClient *c);
878void subscribeCommand(redisClient *c);
879void unsubscribeCommand(redisClient *c);
880void psubscribeCommand(redisClient *c);
881void punsubscribeCommand(redisClient *c);
882void publishCommand(redisClient *c);
883void watchCommand(redisClient *c);
884void unwatchCommand(redisClient *c);
885
886#endif