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