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 */
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
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
54 /* Hash table parameters */
55 #define REDIS_HT_MINFILL 10 /* Minimal hash table fill 10% */
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 */
68 #define REDIS_STRING 0
73 #define REDIS_VMPOINTER 8
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 */
85 /* Object types only used for dumping to disk */
86 #define REDIS_EXPIRETIME 253
87 #define REDIS_SELECTDB 254
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:
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.
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
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 */
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 */
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
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. */
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 */
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 */
158 /* List related stuff */
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
169 #define REDIS_DEBUG 0
170 #define REDIS_VERBOSE 1
171 #define REDIS_NOTICE 2
172 #define REDIS_WARNING 3
174 /* Anti-warning macro... */
175 #define REDIS_NOTUSED(V) ((void) V)
177 #define ZSKIPLIST_MAXLEVEL 32 /* Should be enough for 2^32 elements */
178 #define ZSKIPLIST_P 0.25 /* Skiplist P = 1/4 */
180 /* Append only defines */
181 #define APPENDFSYNC_NO 0
182 #define APPENDFSYNC_ALWAYS 1
183 #define APPENDFSYNC_EVERYSEC 2
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
191 /* Sets operations codes */
192 #define REDIS_OP_UNION 0
193 #define REDIS_OP_DIFF 1
194 #define REDIS_OP_INTER 2
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)
199 void _redisAssert(char *estr
, char *file
, int line
);
200 void _redisPanic(char *msg
, char *file
, int line
);
202 /*-----------------------------------------------------------------------------
204 *----------------------------------------------------------------------------*/
206 /* A redis object, that is a type able to hold a string / list / set */
208 /* The actual Redis Object */
209 typedef struct redisObject
{
211 unsigned storage
:2; /* REDIS_VM_MEMORY or REDIS_VM_SWAPPING */
213 unsigned lru
:22; /* lru time (relative to server.lruclock) */
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. */
222 /* The VM pointer structure - identifies an object in the swap file.
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.
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').*/
234 typedef struct vmPointer
{
236 unsigned storage
:2; /* REDIS_VM_SWAPPED or REDIS_VM_LOADING */
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 */
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 { \
249 _var.type = REDIS_STRING; \
250 _var.encoding = REDIS_ENCODING_RAW; \
252 _var.storage = REDIS_VM_MEMORY; \
255 typedef 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 */
264 /* Client MULTI/EXEC state */
265 typedef struct multiCmd
{
268 struct redisCommand
*cmd
;
271 typedef struct multiState
{
272 multiCmd
*commands
; /* Array of MULTI commands */
273 int count
; /* Total number of MULTI commands */
276 /* With multiplexing we need to take per-clinet state.
277 * Clients are taken in a liked list. */
278 typedef struct redisClient
{
283 robj
**argv
, **mbargv
;
285 int bulklen
; /* bulk read len. -1 if not in bulk read mode */
286 int multibulk
; /* multi bulk command format active */
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) */
315 struct 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
];
327 /* Global server state structure */
332 long long dirty
; /* changes to DB from the last save */
334 list
*slaves
, *monitors
;
335 char neterr
[ANET_ERR_LEN
];
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 */
353 int no_appendfsync_on_rewrite
;
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
;
368 char *appendfilename
;
372 /* Replication related */
377 redisClient
*master
; /* client that is master for this slave */
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() */
388 /* Virtual memory configuration */
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 */
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
;
432 dict
*pubsub_channels
; /* Map channels to list of subscribed clients */
433 list
*pubsub_patterns
; /* A list of pubsub_patterns */
436 unsigned lruclock
:22; /* clock incrementing every minute, for LRU */
437 unsigned lruclock_padding
:10;
440 typedef struct pubsubPattern
{
445 typedef void redisCommandProc(redisClient
*c
);
446 typedef void redisVmPreloadProc(redisClient
*c
, struct redisCommand
*cmd
, int argc
, robj
**argv
);
447 struct redisCommand
{
449 redisCommandProc
*proc
;
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 */
462 struct redisFunctionSym
{
464 unsigned long pointer
;
467 typedef struct _redisSortObject
{
475 typedef struct _redisSortOperation
{
478 } redisSortOperation
;
480 /* ZSETs use a specialized version of Skiplists */
482 typedef struct zskiplistNode
{
483 struct zskiplistNode
**forward
;
484 struct zskiplistNode
*backward
;
490 typedef struct zskiplist
{
491 struct zskiplistNode
*header
, *tail
;
492 unsigned long length
;
496 typedef struct zset
{
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 */
505 typedef 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 */
520 /* Structure to hold list iteration abstraction. */
523 unsigned char encoding
;
524 unsigned char direction
; /* Iteration direction */
529 /* Structure for an entry while iterating over a list. */
531 listTypeIterator
*li
;
532 unsigned char *zi
; /* Entry in ziplist */
533 listNode
*ln
; /* Entry in linked list */
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. */
543 unsigned char *zk
, *zv
;
544 unsigned int zklen
, zvlen
;
550 #define REDIS_HASH_KEY 1
551 #define REDIS_HASH_VALUE 2
553 /*-----------------------------------------------------------------------------
554 * Extern declarations
555 *----------------------------------------------------------------------------*/
557 extern struct redisServer server
;
558 extern struct sharedObjectsStruct shared
;
559 extern dictType setDictType
;
560 extern dictType zsetDictType
;
561 extern double R_Zero
, R_PosInf
, R_NegInf
, R_Nan
;
562 dictType hashDictType
;
564 /*-----------------------------------------------------------------------------
565 * Functions prototypes
566 *----------------------------------------------------------------------------*/
568 /* networking.c -- Networking and Client related operations */
569 redisClient
*createClient(int fd
);
570 void closeTimedoutClients(void);
571 void freeClient(redisClient
*c
);
572 void resetClient(redisClient
*c
);
573 void sendReplyToClient(aeEventLoop
*el
, int fd
, void *privdata
, int mask
);
574 void sendReplyToClientWritev(aeEventLoop
*el
, int fd
, void *privdata
, int mask
);
575 void addReply(redisClient
*c
, robj
*obj
);
576 void addReplySds(redisClient
*c
, sds s
);
577 void processInputBuffer(redisClient
*c
);
578 void acceptHandler(aeEventLoop
*el
, int fd
, void *privdata
, int mask
);
579 void readQueryFromClient(aeEventLoop
*el
, int fd
, void *privdata
, int mask
);
580 void addReplyBulk(redisClient
*c
, robj
*obj
);
581 void addReplyBulkCString(redisClient
*c
, char *s
);
582 void acceptHandler(aeEventLoop
*el
, int fd
, void *privdata
, int mask
);
583 void addReply(redisClient
*c
, robj
*obj
);
584 void addReplySds(redisClient
*c
, sds s
);
585 void addReplyDouble(redisClient
*c
, double d
);
586 void addReplyLongLong(redisClient
*c
, long long ll
);
587 void addReplyUlong(redisClient
*c
, unsigned long ul
);
588 void *dupClientReplyValue(void *o
);
591 void listTypeTryConversion(robj
*subject
, robj
*value
);
592 void listTypePush(robj
*subject
, robj
*value
, int where
);
593 robj
*listTypePop(robj
*subject
, int where
);
594 unsigned long listTypeLength(robj
*subject
);
595 listTypeIterator
*listTypeInitIterator(robj
*subject
, int index
, unsigned char direction
);
596 void listTypeReleaseIterator(listTypeIterator
*li
);
597 int listTypeNext(listTypeIterator
*li
, listTypeEntry
*entry
);
598 robj
*listTypeGet(listTypeEntry
*entry
);
599 void listTypeInsert(listTypeEntry
*entry
, robj
*value
, int where
);
600 int listTypeEqual(listTypeEntry
*entry
, robj
*o
);
601 void listTypeDelete(listTypeEntry
*entry
);
602 void listTypeConvert(robj
*subject
, int enc
);
603 void unblockClientWaitingData(redisClient
*c
);
604 int handleClientsWaitingListPush(redisClient
*c
, robj
*key
, robj
*ele
);
605 void popGenericCommand(redisClient
*c
, int where
);
607 /* MULTI/EXEC/WATCH... */
608 void unwatchAllKeys(redisClient
*c
);
609 void initClientMultiState(redisClient
*c
);
610 void freeClientMultiState(redisClient
*c
);
611 void queueMultiCommand(redisClient
*c
, struct redisCommand
*cmd
);
612 void touchWatchedKey(redisDb
*db
, robj
*key
);
613 void touchWatchedKeysOnFlush(int dbid
);
615 /* Redis object implementation */
616 void decrRefCount(void *o
);
617 void incrRefCount(robj
*o
);
618 void freeStringObject(robj
*o
);
619 void freeListObject(robj
*o
);
620 void freeSetObject(robj
*o
);
621 void freeZsetObject(robj
*o
);
622 void freeHashObject(robj
*o
);
623 robj
*createObject(int type
, void *ptr
);
624 robj
*createStringObject(char *ptr
, size_t len
);
625 robj
*dupStringObject(robj
*o
);
626 robj
*tryObjectEncoding(robj
*o
);
627 robj
*getDecodedObject(robj
*o
);
628 size_t stringObjectLen(robj
*o
);
629 int tryFreeOneObjectFromFreelist(void);
630 robj
*createStringObjectFromLongLong(long long value
);
631 robj
*createListObject(void);
632 robj
*createZiplistObject(void);
633 robj
*createSetObject(void);
634 robj
*createHashObject(void);
635 robj
*createZsetObject(void);
636 int getLongFromObjectOrReply(redisClient
*c
, robj
*o
, long *target
, const char *msg
);
637 int checkType(redisClient
*c
, robj
*o
, int type
);
638 int getLongLongFromObjectOrReply(redisClient
*c
, robj
*o
, long long *target
, const char *msg
);
639 int getDoubleFromObjectOrReply(redisClient
*c
, robj
*o
, double *target
, const char *msg
);
640 int getLongLongFromObject(robj
*o
, long long *target
);
641 char *strEncoding(int encoding
);
642 int compareStringObjects(robj
*a
, robj
*b
);
643 int equalStringObjects(robj
*a
, robj
*b
);
646 void replicationFeedSlaves(list
*slaves
, int dictid
, robj
**argv
, int argc
);
647 void replicationFeedMonitors(list
*monitors
, int dictid
, robj
**argv
, int argc
);
648 int syncWithMaster(void);
649 void updateSlavesWaitingBgsave(int bgsaveerr
);
651 /* RDB persistence */
652 int rdbLoad(char *filename
);
653 int rdbSaveBackground(char *filename
);
654 void rdbRemoveTempFile(pid_t childpid
);
655 int rdbSave(char *filename
);
656 int rdbSaveObject(FILE *fp
, robj
*o
);
657 off_t
rdbSavedObjectPages(robj
*o
, FILE *fp
);
658 off_t
rdbSavedObjectLen(robj
*o
, FILE *fp
);
659 robj
*rdbLoadObject(int type
, FILE *fp
);
660 void backgroundSaveDoneHandler(int statloc
);
662 /* AOF persistence */
663 void flushAppendOnlyFile(void);
664 void feedAppendOnlyFile(struct redisCommand
*cmd
, int dictid
, robj
**argv
, int argc
);
665 void aofRemoveTempFile(pid_t childpid
);
666 int rewriteAppendOnlyFileBackground(void);
667 int loadAppendOnlyFile(char *filename
);
668 void stopAppendOnly(void);
669 int startAppendOnly(void);
670 void backgroundRewriteDoneHandler(int statloc
);
672 /* Sorted sets data type */
673 zskiplist
*zslCreate(void);
674 void zslFree(zskiplist
*zsl
);
675 void zslInsert(zskiplist
*zsl
, double score
, robj
*obj
);
678 void freeMemoryIfNeeded(void);
679 int processCommand(redisClient
*c
);
680 void setupSigSegvAction(void);
681 struct redisCommand
*lookupCommand(char *name
);
682 void call(redisClient
*c
, struct redisCommand
*cmd
);
683 int prepareForShutdown();
684 void redisLog(int level
, const char *fmt
, ...);
686 void updateDictResizePolicy(void);
687 int htNeedsResize(dict
*dict
);
688 void oom(const char *msg
);
692 void vmMarkPagesFree(off_t page
, off_t count
);
693 robj
*vmLoadObject(robj
*o
);
694 robj
*vmPreviewObject(robj
*o
);
695 int vmSwapOneObjectBlocking(void);
696 int vmSwapOneObjectThreaded(void);
697 int vmCanSwapOut(void);
698 void vmThreadedIOCompletedJob(aeEventLoop
*el
, int fd
, void *privdata
, int mask
);
699 void vmCancelThreadedIOJob(robj
*o
);
700 void lockThreadedIO(void);
701 void unlockThreadedIO(void);
702 int vmSwapObjectThreaded(robj
*key
, robj
*val
, redisDb
*db
);
703 void freeIOJob(iojob
*j
);
704 void queueIOJob(iojob
*j
);
705 int vmWriteObjectOnSwap(robj
*o
, off_t page
);
706 robj
*vmReadObjectFromSwap(off_t page
, int type
);
707 void waitEmptyIOJobsQueue(void);
708 void vmReopenSwapFile(void);
709 int vmFreePage(off_t page
);
710 void zunionInterBlockClientOnSwappedKeys(redisClient
*c
, struct redisCommand
*cmd
, int argc
, robj
**argv
);
711 void execBlockClientOnSwappedKeys(redisClient
*c
, struct redisCommand
*cmd
, int argc
, robj
**argv
);
712 int blockClientOnSwappedKeys(redisClient
*c
, struct redisCommand
*cmd
);
713 int dontWaitForSwappedKey(redisClient
*c
, robj
*key
);
714 void handleClientsBlockedOnSwappedKey(redisDb
*db
, robj
*key
);
715 vmpointer
*vmSwapObjectBlocking(robj
*val
);
718 void convertToRealHash(robj
*o
);
719 void hashTypeTryConversion(robj
*subject
, robj
**argv
, int start
, int end
);
720 void hashTypeTryObjectEncoding(robj
*subject
, robj
**o1
, robj
**o2
);
721 robj
*hashTypeGet(robj
*o
, robj
*key
);
722 int hashTypeExists(robj
*o
, robj
*key
);
723 int hashTypeSet(robj
*o
, robj
*key
, robj
*value
);
724 int hashTypeDelete(robj
*o
, robj
*key
);
725 unsigned long hashTypeLength(robj
*o
);
726 hashTypeIterator
*hashTypeInitIterator(robj
*subject
);
727 void hashTypeReleaseIterator(hashTypeIterator
*hi
);
728 int hashTypeNext(hashTypeIterator
*hi
);
729 robj
*hashTypeCurrent(hashTypeIterator
*hi
, int what
);
730 robj
*hashTypeLookupWriteOrCreate(redisClient
*c
, robj
*key
);
733 int pubsubUnsubscribeAllChannels(redisClient
*c
, int notify
);
734 int pubsubUnsubscribeAllPatterns(redisClient
*c
, int notify
);
735 void freePubsubPattern(void *p
);
736 int listMatchPubsubPattern(void *a
, void *b
);
738 /* Utility functions */
739 int stringmatchlen(const char *pattern
, int patternLen
,
740 const char *string
, int stringLen
, int nocase
);
741 int stringmatch(const char *pattern
, const char *string
, int nocase
);
742 long long memtoll(const char *p
, int *err
);
743 int ll2string(char *s
, size_t len
, long long value
);
744 int isStringRepresentableAsLong(sds s
, long *longval
);
747 void loadServerConfig(char *filename
);
748 void appendServerSaveParams(time_t seconds
, int changes
);
749 void resetServerSaveParams();
751 /* db.c -- Keyspace access API */
752 int removeExpire(redisDb
*db
, robj
*key
);
753 int expireIfNeeded(redisDb
*db
, robj
*key
);
754 int deleteIfVolatile(redisDb
*db
, robj
*key
);
755 time_t getExpire(redisDb
*db
, robj
*key
);
756 int setExpire(redisDb
*db
, robj
*key
, time_t when
);
757 robj
*lookupKey(redisDb
*db
, robj
*key
);
758 robj
*lookupKeyRead(redisDb
*db
, robj
*key
);
759 robj
*lookupKeyWrite(redisDb
*db
, robj
*key
);
760 robj
*lookupKeyReadOrReply(redisClient
*c
, robj
*key
, robj
*reply
);
761 robj
*lookupKeyWriteOrReply(redisClient
*c
, robj
*key
, robj
*reply
);
762 int dbAdd(redisDb
*db
, robj
*key
, robj
*val
);
763 int dbReplace(redisDb
*db
, robj
*key
, robj
*val
);
764 int dbExists(redisDb
*db
, robj
*key
);
765 robj
*dbRandomKey(redisDb
*db
);
766 int dbDelete(redisDb
*db
, robj
*key
);
768 int selectDb(redisClient
*c
, int id
);
771 char *redisGitSHA1(void);
772 char *redisGitDirty(void);
774 /* Commands prototypes */
775 void authCommand(redisClient
*c
);
776 void pingCommand(redisClient
*c
);
777 void echoCommand(redisClient
*c
);
778 void setCommand(redisClient
*c
);
779 void setnxCommand(redisClient
*c
);
780 void setexCommand(redisClient
*c
);
781 void getCommand(redisClient
*c
);
782 void delCommand(redisClient
*c
);
783 void existsCommand(redisClient
*c
);
784 void incrCommand(redisClient
*c
);
785 void decrCommand(redisClient
*c
);
786 void incrbyCommand(redisClient
*c
);
787 void decrbyCommand(redisClient
*c
);
788 void selectCommand(redisClient
*c
);
789 void randomkeyCommand(redisClient
*c
);
790 void keysCommand(redisClient
*c
);
791 void dbsizeCommand(redisClient
*c
);
792 void lastsaveCommand(redisClient
*c
);
793 void saveCommand(redisClient
*c
);
794 void bgsaveCommand(redisClient
*c
);
795 void bgrewriteaofCommand(redisClient
*c
);
796 void shutdownCommand(redisClient
*c
);
797 void moveCommand(redisClient
*c
);
798 void renameCommand(redisClient
*c
);
799 void renamenxCommand(redisClient
*c
);
800 void lpushCommand(redisClient
*c
);
801 void rpushCommand(redisClient
*c
);
802 void lpushxCommand(redisClient
*c
);
803 void rpushxCommand(redisClient
*c
);
804 void linsertCommand(redisClient
*c
);
805 void lpopCommand(redisClient
*c
);
806 void rpopCommand(redisClient
*c
);
807 void llenCommand(redisClient
*c
);
808 void lindexCommand(redisClient
*c
);
809 void lrangeCommand(redisClient
*c
);
810 void ltrimCommand(redisClient
*c
);
811 void typeCommand(redisClient
*c
);
812 void lsetCommand(redisClient
*c
);
813 void saddCommand(redisClient
*c
);
814 void sremCommand(redisClient
*c
);
815 void smoveCommand(redisClient
*c
);
816 void sismemberCommand(redisClient
*c
);
817 void scardCommand(redisClient
*c
);
818 void spopCommand(redisClient
*c
);
819 void srandmemberCommand(redisClient
*c
);
820 void sinterCommand(redisClient
*c
);
821 void sinterstoreCommand(redisClient
*c
);
822 void sunionCommand(redisClient
*c
);
823 void sunionstoreCommand(redisClient
*c
);
824 void sdiffCommand(redisClient
*c
);
825 void sdiffstoreCommand(redisClient
*c
);
826 void syncCommand(redisClient
*c
);
827 void flushdbCommand(redisClient
*c
);
828 void flushallCommand(redisClient
*c
);
829 void sortCommand(redisClient
*c
);
830 void lremCommand(redisClient
*c
);
831 void rpoplpushcommand(redisClient
*c
);
832 void infoCommand(redisClient
*c
);
833 void mgetCommand(redisClient
*c
);
834 void monitorCommand(redisClient
*c
);
835 void expireCommand(redisClient
*c
);
836 void expireatCommand(redisClient
*c
);
837 void getsetCommand(redisClient
*c
);
838 void ttlCommand(redisClient
*c
);
839 void slaveofCommand(redisClient
*c
);
840 void debugCommand(redisClient
*c
);
841 void msetCommand(redisClient
*c
);
842 void msetnxCommand(redisClient
*c
);
843 void zaddCommand(redisClient
*c
);
844 void zincrbyCommand(redisClient
*c
);
845 void zrangeCommand(redisClient
*c
);
846 void zrangebyscoreCommand(redisClient
*c
);
847 void zcountCommand(redisClient
*c
);
848 void zrevrangeCommand(redisClient
*c
);
849 void zcardCommand(redisClient
*c
);
850 void zremCommand(redisClient
*c
);
851 void zscoreCommand(redisClient
*c
);
852 void zremrangebyscoreCommand(redisClient
*c
);
853 void multiCommand(redisClient
*c
);
854 void execCommand(redisClient
*c
);
855 void discardCommand(redisClient
*c
);
856 void blpopCommand(redisClient
*c
);
857 void brpopCommand(redisClient
*c
);
858 void appendCommand(redisClient
*c
);
859 void substrCommand(redisClient
*c
);
860 void zrankCommand(redisClient
*c
);
861 void zrevrankCommand(redisClient
*c
);
862 void hsetCommand(redisClient
*c
);
863 void hsetnxCommand(redisClient
*c
);
864 void hgetCommand(redisClient
*c
);
865 void hmsetCommand(redisClient
*c
);
866 void hmgetCommand(redisClient
*c
);
867 void hdelCommand(redisClient
*c
);
868 void hlenCommand(redisClient
*c
);
869 void zremrangebyrankCommand(redisClient
*c
);
870 void zunionstoreCommand(redisClient
*c
);
871 void zinterstoreCommand(redisClient
*c
);
872 void hkeysCommand(redisClient
*c
);
873 void hvalsCommand(redisClient
*c
);
874 void hgetallCommand(redisClient
*c
);
875 void hexistsCommand(redisClient
*c
);
876 void configCommand(redisClient
*c
);
877 void hincrbyCommand(redisClient
*c
);
878 void subscribeCommand(redisClient
*c
);
879 void unsubscribeCommand(redisClient
*c
);
880 void psubscribeCommand(redisClient
*c
);
881 void punsubscribeCommand(redisClient
*c
);
882 void publishCommand(redisClient
*c
);
883 void watchCommand(redisClient
*c
);
884 void unwatchCommand(redisClient
*c
);