2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								/*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Copyright  ( c )  2009 - 2010 ,  Salvatore  Sanfilippo  < antirez  at  gmail  dot  com > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  All  rights  reserved . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  Redistribution  and  use  in  source  and  binary  forms ,  with  or  without 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  modification ,  are  permitted  provided  that  the  following  conditions  are  met : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *    *  Redistributions  of  source  code  must  retain  the  above  copyright  notice , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *      this  list  of  conditions  and  the  following  disclaimer . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *    *  Redistributions  in  binary  form  must  reproduce  the  above  copyright 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *      notice ,  this  list  of  conditions  and  the  following  disclaimer  in  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *      documentation  and / or  other  materials  provided  with  the  distribution . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *    *  Neither  the  name  of  Redis  nor  the  names  of  its  contributors  may  be  used 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *      to  endorse  or  promote  products  derived  from  this  software  without 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *      specific  prior  written  permission . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  THIS  SOFTWARE  IS  PROVIDED  BY  THE  COPYRIGHT  HOLDERS  AND  CONTRIBUTORS  " AS IS " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  AND  ANY  EXPRESS  OR  IMPLIED  WARRANTIES ,  INCLUDING ,  BUT  NOT  LIMITED  TO ,  THE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  IMPLIED  WARRANTIES  OF  MERCHANTABILITY  AND  FITNESS  FOR  A  PARTICULAR  PURPOSE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  ARE  DISCLAIMED .  IN  NO  EVENT  SHALL  THE  COPYRIGHT  OWNER  OR  CONTRIBUTORS  BE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  LIABLE  FOR  ANY  DIRECT ,  INDIRECT ,  INCIDENTAL ,  SPECIAL ,  EXEMPLARY ,  OR 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  CONSEQUENTIAL  DAMAGES  ( INCLUDING ,  BUT  NOT  LIMITED  TO ,  PROCUREMENT  OF 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  SUBSTITUTE  GOODS  OR  SERVICES ;  LOSS  OF  USE ,  DATA ,  OR  PROFITS ;  OR  BUSINESS 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  INTERRUPTION )  HOWEVER  CAUSED  AND  ON  ANY  THEORY  OF  LIABILITY ,  WHETHER  IN 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  CONTRACT ,  STRICT  LIABILITY ,  OR  TORT  ( INCLUDING  NEGLIGENCE  OR  OTHERWISE ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  ARISING  IN  ANY  WAY  OUT  OF  THE  USE  OF  THIS  SOFTWARE ,  EVEN  IF  ADVISED  OF  THE 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  POSSIBILITY  OF  SUCH  DAMAGE . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "redis.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef HAVE_BACKTRACE 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <execinfo.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <ucontext.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif  /* HAVE_BACKTRACE */ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <time.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <signal.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <sys/wait.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <errno.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <assert.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <ctype.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <stdarg.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <arpa/inet.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <sys/stat.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <fcntl.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <sys/time.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <sys/resource.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <sys/uio.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <limits.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <float.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <math.h> 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  <pthread.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-16 19:28:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# include  <sys/resource.h> 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Our shared "common" objects */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  sharedObjectsStruct  shared ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Global vars that are actally used as constants. The following double
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  values  are  used  for  double  on - disk  serialization ,  and  are  initialized 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  at  runtime  to  avoid  strange  compiler  optimizations .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								double  R_Zero ,  R_PosInf ,  R_NegInf ,  R_Nan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*================================= Globals ================================= */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Global vars */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  redisServer  server ;  /* server global state */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  redisCommand  * commandTable ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 17:56:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  redisCommand  redisCommandTable [ ]  =  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 05:14:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " get " , getCommand , 2 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-23 02:35:42 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " set " , setCommand , 3 , REDIS_CMD_DENYOOM , noPreloadGetKeys , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " setnx " , setnxCommand , 3 , REDIS_CMD_DENYOOM , noPreloadGetKeys , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " setex " , setexCommand , 4 , REDIS_CMD_DENYOOM , noPreloadGetKeys , 2 , 2 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 05:14:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " append " , appendCommand , 3 , REDIS_CMD_DENYOOM , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " strlen " , strlenCommand , 2 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-23 02:35:42 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " del " , delCommand , - 2 , 0 , noPreloadGetKeys , 1 , - 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 05:14:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " exists " , existsCommand , 2 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " setbit " , setbitCommand , 4 , REDIS_CMD_DENYOOM , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " getbit " , getbitCommand , 3 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " setrange " , setrangeCommand , 4 , REDIS_CMD_DENYOOM , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " getrange " , getrangeCommand , 4 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " substr " , getrangeCommand , 4 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " incr " , incrCommand , 2 , REDIS_CMD_DENYOOM , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " decr " , decrCommand , 2 , REDIS_CMD_DENYOOM , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " mget " , mgetCommand , - 2 , 0 , NULL , 1 , - 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-15 22:35:27 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " rpush " , rpushCommand , - 3 , REDIS_CMD_DENYOOM , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " lpush " , lpushCommand , - 3 , REDIS_CMD_DENYOOM , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 05:14:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " rpushx " , rpushxCommand , 3 , REDIS_CMD_DENYOOM , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " lpushx " , lpushxCommand , 3 , REDIS_CMD_DENYOOM , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " linsert " , linsertCommand , 5 , REDIS_CMD_DENYOOM , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " rpop " , rpopCommand , 2 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " lpop " , lpopCommand , 2 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " brpop " , brpopCommand , - 3 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " brpoplpush " , brpoplpushCommand , 4 , REDIS_CMD_DENYOOM , NULL , 1 , 2 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-23 02:35:42 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " blpop " , blpopCommand , - 3 , 0 , NULL , 1 , - 2 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 05:14:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " llen " , llenCommand , 2 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " lindex " , lindexCommand , 3 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " lset " , lsetCommand , 4 , REDIS_CMD_DENYOOM , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " lrange " , lrangeCommand , 4 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " ltrim " , ltrimCommand , 4 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " lrem " , lremCommand , 4 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " rpoplpush " , rpoplpushCommand , 3 , REDIS_CMD_DENYOOM , NULL , 1 , 2 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-16 00:08:32 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " sadd " , saddCommand , - 3 , REDIS_CMD_DENYOOM , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-19 23:37:03 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " srem " , sremCommand , - 3 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 05:14:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " smove " , smoveCommand , 4 , 0 , NULL , 1 , 2 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " sismember " , sismemberCommand , 3 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " scard " , scardCommand , 2 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " spop " , spopCommand , 2 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " srandmember " , srandmemberCommand , 2 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " sinter " , sinterCommand , - 2 , REDIS_CMD_DENYOOM , NULL , 1 , - 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " sinterstore " , sinterstoreCommand , - 3 , REDIS_CMD_DENYOOM , NULL , 2 , - 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " sunion " , sunionCommand , - 2 , REDIS_CMD_DENYOOM , NULL , 1 , - 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " sunionstore " , sunionstoreCommand , - 3 , REDIS_CMD_DENYOOM , NULL , 2 , - 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " sdiff " , sdiffCommand , - 2 , REDIS_CMD_DENYOOM , NULL , 1 , - 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " sdiffstore " , sdiffstoreCommand , - 3 , REDIS_CMD_DENYOOM , NULL , 2 , - 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " smembers " , sinterCommand , 2 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " zadd " , zaddCommand , 4 , REDIS_CMD_DENYOOM , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " zincrby " , zincrbyCommand , 4 , REDIS_CMD_DENYOOM , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " zrem " , zremCommand , 3 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " zremrangebyscore " , zremrangebyscoreCommand , 4 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " zremrangebyrank " , zremrangebyrankCommand , 4 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-23 02:35:42 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " zunionstore " , zunionstoreCommand , - 4 , REDIS_CMD_DENYOOM , zunionInterGetKeys , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " zinterstore " , zinterstoreCommand , - 4 , REDIS_CMD_DENYOOM , zunionInterGetKeys , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 05:14:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " zrange " , zrangeCommand , - 4 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " zrangebyscore " , zrangebyscoreCommand , - 4 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " zrevrangebyscore " , zrevrangebyscoreCommand , - 4 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " zcount " , zcountCommand , 4 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " zrevrange " , zrevrangeCommand , - 4 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " zcard " , zcardCommand , 2 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " zscore " , zscoreCommand , 3 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " zrank " , zrankCommand , 3 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " zrevrank " , zrevrankCommand , 3 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " hset " , hsetCommand , 4 , REDIS_CMD_DENYOOM , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " hsetnx " , hsetnxCommand , 4 , REDIS_CMD_DENYOOM , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " hget " , hgetCommand , 3 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " hmset " , hmsetCommand , - 4 , REDIS_CMD_DENYOOM , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " hmget " , hmgetCommand , - 3 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " hincrby " , hincrbyCommand , 4 , REDIS_CMD_DENYOOM , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-19 23:07:55 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " hdel " , hdelCommand , - 3 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 05:14:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " hlen " , hlenCommand , 2 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " hkeys " , hkeysCommand , 2 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " hvals " , hvalsCommand , 2 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " hgetall " , hgetallCommand , 2 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " hexists " , hexistsCommand , 3 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " incrby " , incrbyCommand , 3 , REDIS_CMD_DENYOOM , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " decrby " , decrbyCommand , 3 , REDIS_CMD_DENYOOM , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " getset " , getsetCommand , 3 , REDIS_CMD_DENYOOM , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " mset " , msetCommand , - 3 , REDIS_CMD_DENYOOM , NULL , 1 , - 1 , 2 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " msetnx " , msetnxCommand , - 3 , REDIS_CMD_DENYOOM , NULL , 1 , - 1 , 2 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " randomkey " , randomkeyCommand , 1 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " select " , selectCommand , 2 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " move " , moveCommand , 3 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-23 02:35:42 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " rename " , renameCommand , 3 , 0 , renameGetKeys , 1 , 2 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " renamenx " , renamenxCommand , 3 , 0 , renameGetKeys , 1 , 2 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " expire " , expireCommand , 3 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " expireat " , expireatCommand , 3 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 05:14:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " keys " , keysCommand , 2 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " dbsize " , dbsizeCommand , 1 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " auth " , authCommand , 2 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " ping " , pingCommand , 1 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " echo " , echoCommand , 2 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " save " , saveCommand , 1 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " bgsave " , bgsaveCommand , 1 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " bgrewriteaof " , bgrewriteaofCommand , 1 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " shutdown " , shutdownCommand , 1 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " lastsave " , lastsaveCommand , 1 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " type " , typeCommand , 2 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " multi " , multiCommand , 1 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-24 01:09:17 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " exec " , execCommand , 1 , REDIS_CMD_DENYOOM , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 05:14:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " discard " , discardCommand , 1 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " sync " , syncCommand , 1 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " flushdb " , flushdbCommand , 1 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " flushall " , flushallCommand , 1 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " sort " , sortCommand , - 2 , REDIS_CMD_DENYOOM , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " info " , infoCommand , - 1 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " monitor " , monitorCommand , 1 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " ttl " , ttlCommand , 2 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " persist " , persistCommand , 2 , 0 , NULL , 1 , 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " slaveof " , slaveofCommand , 3 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " debug " , debugCommand , - 2 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " config " , configCommand , - 2 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " subscribe " , subscribeCommand , - 2 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " unsubscribe " , unsubscribeCommand , - 1 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " psubscribe " , psubscribeCommand , - 2 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " punsubscribe " , punsubscribeCommand , - 1 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " publish " , publishCommand , 3 , REDIS_CMD_FORCE_REPLICATION , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-23 02:35:42 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " watch " , watchCommand , - 2 , 0 , noPreloadGetKeys , 1 , - 1 , 1 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-29 23:51:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " unwatch " , unwatchCommand , 1 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " cluster " , clusterCommand , - 2 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-02 00:59:28 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " restore " , restoreCommand , 4 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " migrate " , migrateCommand , 6 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-06 18:19:45 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " dump " , dumpCommand , 2 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-21 21:38:02 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    { " object " , objectCommand , - 2 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { " client " , clientCommand , - 2 , 0 , NULL , 0 , 0 , 0 , 0 , 0 } 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*============================ Utility functions ============================ */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-02-09 17:10:35 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Low level logging. To use only for very big messages, otherwise
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  redisLog ( )  is  to  prefer .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  redisLogRaw ( int  level ,  const  char  * msg )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-10 00:10:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    const  int  syslogLevelMap [ ]  =  {  LOG_DEBUG ,  LOG_INFO ,  LOG_NOTICE ,  LOG_WARNING  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  char  * c  =  " .-*# " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    time_t  now  =  time ( NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    FILE  * fp ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-23 05:31:40 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    char  buf [ 64 ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-13 16:58:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    int  rawmode  =  ( level  &  REDIS_LOG_RAW ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-23 05:31:40 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-04-13 16:58:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    level  & =  0xff ;  /* clear flags */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-23 05:31:40 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( level  <  server . verbosity )  return ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    fp  =  ( server . logfile  = =  NULL )  ?  stdout  :  fopen ( server . logfile , " a " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! fp )  return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-04-13 16:58:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( rawmode )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        fprintf ( fp , " %s " , msg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        strftime ( buf , sizeof ( buf ) , " %d %b %H:%M:%S " , localtime ( & now ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        fprintf ( fp , " [%d] %s %c %s \n " , ( int ) getpid ( ) , buf , c [ level ] , msg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-10 00:10:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    fflush ( fp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    if  ( server . logfile )  fclose ( fp ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-10 00:10:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( server . syslog_enabled )  syslog ( syslogLevelMap [ level ] ,  " %s " ,  msg ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-02-09 17:10:35 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Like redisLogRaw() but with printf-alike support. This is the funciton that
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  is  used  across  the  code .  The  raw  version  is  only  used  in  order  to  dump 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  the  INFO  output  on  crash .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  redisLog ( int  level ,  const  char  * fmt ,  . . . )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    va_list  ap ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    char  msg [ REDIS_MAX_LOGMSG_LEN ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-04-13 16:58:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ( level & 0xff )  <  server . verbosity )  return ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-09 17:10:35 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    va_start ( ap ,  fmt ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    vsnprintf ( msg ,  sizeof ( msg ) ,  fmt ,  ap ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    va_end ( ap ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    redisLogRaw ( level , msg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								/* Redis generally does not try to recover from out of memory conditions
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  when  allocating  objects  or  strings ,  it  is  not  clear  if  it  will  be  possible 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  to  report  this  condition  to  the  client  since  the  networking  layer  itself 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  is  based  on  heap  allocation  for  send  buffers ,  so  we  simply  abort . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  At  least  the  code  will  be  simpler  to  read . . .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  oom ( const  char  * msg )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    redisLog ( REDIS_WARNING ,  " %s: Out of memory \n " , msg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sleep ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    abort ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 18:46:34 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Return the UNIX time in microseconds */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								long  long  ustime ( void )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  timeval  tv ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    long  long  ust ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    gettimeofday ( & tv ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ust  =  ( ( long  long ) tv . tv_sec ) * 1000000 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ust  + =  tv . tv_usec ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ust ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								/*====================== Hash table type implementation  ==================== */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* This is an hash table type that uses the SDS dynamic strings libary as
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  keys  and  radis  objects  as  values  ( objects  can  hold  SDS  strings , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  lists ,  sets ) .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  dictVanillaFree ( void  * privdata ,  void  * val ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    DICT_NOTUSED ( privdata ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    zfree ( val ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  dictListDestructor ( void  * privdata ,  void  * val ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    DICT_NOTUSED ( privdata ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    listRelease ( ( list * ) val ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  dictSdsKeyCompare ( void  * privdata ,  const  void  * key1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  void  * key2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  l1 , l2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    DICT_NOTUSED ( privdata ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    l1  =  sdslen ( ( sds ) key1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    l2  =  sdslen ( ( sds ) key2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( l1  ! =  l2 )  return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  memcmp ( key1 ,  key2 ,  l1 )  = =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-03 18:23:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* A case insensitive version used for the command lookup table. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  dictSdsKeyCaseCompare ( void  * privdata ,  const  void  * key1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  void  * key2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    DICT_NOTUSED ( privdata ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  strcasecmp ( key1 ,  key2 )  = =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								void  dictRedisObjectDestructor ( void  * privdata ,  void  * val ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    DICT_NOTUSED ( privdata ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( val  = =  NULL )  return ;  /* Values of swapped out keys as set to NULL */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    decrRefCount ( val ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  dictSdsDestructor ( void  * privdata ,  void  * val ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    DICT_NOTUSED ( privdata ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sdsfree ( val ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  dictObjKeyCompare ( void  * privdata ,  const  void  * key1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  void  * key2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  robj  * o1  =  key1 ,  * o2  =  key2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  dictSdsKeyCompare ( privdata , o1 - > ptr , o2 - > ptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								unsigned  int  dictObjHash ( const  void  * key )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    const  robj  * o  =  key ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  dictGenHashFunction ( o - > ptr ,  sdslen ( ( sds ) o - > ptr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								unsigned  int  dictSdsHash ( const  void  * key )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  dictGenHashFunction ( ( unsigned  char * ) key ,  sdslen ( ( char * ) key ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-03 18:23:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								unsigned  int  dictSdsCaseHash ( const  void  * key )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  dictGenCaseHashFunction ( ( unsigned  char * ) key ,  sdslen ( ( char * ) key ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								int  dictEncObjKeyCompare ( void  * privdata ,  const  void  * key1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        const  void  * key2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								{ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    robj  * o1  =  ( robj * )  key1 ,  * o2  =  ( robj * )  key2 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  cmp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( o1 - > encoding  = =  REDIS_ENCODING_INT  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        o2 - > encoding  = =  REDIS_ENCODING_INT ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return  o1 - > ptr  = =  o2 - > ptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    o1  =  getDecodedObject ( o1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    o2  =  getDecodedObject ( o2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    cmp  =  dictSdsKeyCompare ( privdata , o1 - > ptr , o2 - > ptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    decrRefCount ( o1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    decrRefCount ( o2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  cmp ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								unsigned  int  dictEncObjHash ( const  void  * key )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    robj  * o  =  ( robj * )  key ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( o - > encoding  = =  REDIS_ENCODING_RAW )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  dictGenHashFunction ( o - > ptr ,  sdslen ( ( sds ) o - > ptr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( o - > encoding  = =  REDIS_ENCODING_INT )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            char  buf [ 32 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            int  len ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            len  =  ll2string ( buf , 32 , ( long ) o - > ptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return  dictGenHashFunction ( ( unsigned  char * ) buf ,  len ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            unsigned  int  hash ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            o  =  getDecodedObject ( o ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            hash  =  dictGenHashFunction ( o - > ptr ,  sdslen ( ( sds ) o - > ptr ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            decrRefCount ( o ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return  hash ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-01 00:32:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Sets type and diskstore negative caching hash table */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								dictType  setDictType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictEncObjHash ,             /* hash function */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    NULL ,                       /* key dup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    NULL ,                       /* val dup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictEncObjKeyCompare ,       /* key compare */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictRedisObjectDestructor ,  /* key destructor */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    NULL                        /* val destructor */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Sorted sets hash (note: a skiplist is used in addition to the hash table) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								dictType  zsetDictType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictEncObjHash ,             /* hash function */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    NULL ,                       /* key dup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    NULL ,                       /* val dup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictEncObjKeyCompare ,       /* key compare */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictRedisObjectDestructor ,  /* key destructor */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-04 02:49:53 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    NULL                        /* val destructor */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Db->dict, keys are sds strings, vals are Redis objects. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								dictType  dbDictType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictSdsHash ,                 /* hash function */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    NULL ,                        /* key dup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    NULL ,                        /* val dup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictSdsKeyCompare ,           /* key compare */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictSdsDestructor ,           /* key destructor */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictRedisObjectDestructor    /* val destructor */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Db->expires */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								dictType  keyptrDictType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictSdsHash ,                /* hash function */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    NULL ,                       /* key dup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    NULL ,                       /* val dup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictSdsKeyCompare ,          /* key compare */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    NULL ,                       /* key destructor */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    NULL                        /* val destructor */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-03 18:23:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Command table. sds string -> command struct pointer. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								dictType  commandTableDictType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictSdsCaseHash ,            /* hash function */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    NULL ,                       /* key dup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    NULL ,                       /* val dup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictSdsKeyCaseCompare ,      /* key compare */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictSdsDestructor ,          /* key destructor */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    NULL                        /* val destructor */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								/* Hash type hash table (note that small hashes are represented with zimpaps) */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								dictType  hashDictType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictEncObjHash ,              /* hash function */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    NULL ,                        /* key dup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    NULL ,                        /* val dup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictEncObjKeyCompare ,        /* key compare */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictRedisObjectDestructor ,   /* key destructor */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictRedisObjectDestructor    /* val destructor */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Keylist hash table type has unencoded redis objects as keys and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  lists  as  values .  It ' s  used  for  blocking  operations  ( BLPOP )  and  to 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  map  swapped  keys  to  a  list  of  clients  waiting  for  this  keys  to  be  loaded .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								dictType  keylistDictType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictObjHash ,                 /* hash function */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    NULL ,                        /* key dup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    NULL ,                        /* val dup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictObjKeyCompare ,           /* key compare */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictRedisObjectDestructor ,   /* key destructor */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictListDestructor           /* val destructor */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-03-29 23:51:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Cluster nodes hash table, mapping nodes addresses 1.2.3.4:6379 to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  clusterNode  structures .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								dictType  clusterNodesDictType  =  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictSdsHash ,                 /* hash function */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    NULL ,                        /* key dup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    NULL ,                        /* val dup */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictSdsKeyCompare ,           /* key compare */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dictSdsDestructor ,           /* key destructor */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    NULL                         /* val destructor */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								int  htNeedsResize ( dict  * dict )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    long  long  size ,  used ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    size  =  dictSlots ( dict ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    used  =  dictSize ( dict ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ( size  & &  used  & &  size  >  DICT_HT_INITIAL_SIZE  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ( used * 100 / size  <  REDIS_HT_MINFILL ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* If the percentage of used slots in the HT reaches REDIS_HT_MINFILL
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  we  resize  the  hash  table  to  save  memory  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  tryResizeHashTables ( void )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  j ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( j  =  0 ;  j  <  server . dbnum ;  j + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( htNeedsResize ( server . db [ j ] . dict ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            dictResize ( server . db [ j ] . dict ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( htNeedsResize ( server . db [ j ] . expires ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            dictResize ( server . db [ j ] . expires ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Our hash table implementation performs rehashing incrementally while
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  we  write / read  from  the  hash  table .  Still  if  the  server  is  idle ,  the  hash 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  table  will  use  two  tables  for  a  long  time .  So  we  try  to  use  1  millisecond 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  of  CPU  time  at  every  serverCron ( )  loop  in  order  to  rehash  some  key .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  incrementallyRehash ( void )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  j ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( j  =  0 ;  j  <  server . dbnum ;  j + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( dictIsRehashing ( server . db [ j ] . dict ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            dictRehashMilliseconds ( server . db [ j ] . dict , 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            break ;  /* already used our millisecond for this loop... */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* This function is called once a background process of some kind terminates,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  as  we  want  to  avoid  resizing  the  hash  tables  when  there  is  a  child  in  order 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  to  play  well  with  copy - on - write  ( otherwise  when  a  resize  happens  lots  of 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  memory  pages  are  copied ) .  The  goal  of  this  function  is  to  update  the  ability 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  for  dict . c  to  resize  the  hash  tables  accordingly  to  the  fact  we  have  o  not 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  running  childs .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  updateDictResizePolicy ( void )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( server . bgsavechildpid  = =  - 1  & &  server . bgrewritechildpid  = =  - 1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        dictEnableResize ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        dictDisableResize ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* ======================= Cron: called every 100 ms ======================== */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-08-03 00:13:39 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Try to expire a few timed out keys. The algorithm used is adaptive and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  will  use  few  CPU  cycles  if  there  are  few  expiring  keys ,  otherwise 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  it  will  get  more  aggressive  to  avoid  that  too  much  memory  is  used  by 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  keys  that  can  be  removed  from  the  keyspace .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  activeExpireCycle ( void )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  j ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( j  =  0 ;  j  <  server . dbnum ;  j + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        int  expired ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        redisDb  * db  =  server . db + j ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        /* Continue to expire if at the end of the cycle more than 25%
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         *  of  the  keys  were  expired .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        do  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            long  num  =  dictSize ( db - > expires ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            time_t  now  =  time ( NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            expired  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( num  >  REDIS_EXPIRELOOKUPS_PER_CRON ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                num  =  REDIS_EXPIRELOOKUPS_PER_CRON ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            while  ( num - - )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                dictEntry  * de ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                time_t  t ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                if  ( ( de  =  dictGetRandomKey ( db - > expires ) )  = =  NULL )  break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                t  =  ( time_t )  dictGetEntryVal ( de ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                if  ( now  >  t )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    sds  key  =  dictGetEntryKey ( de ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    robj  * keyobj  =  createStringObject ( key , sdslen ( key ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    propagateExpire ( db , keyobj ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    dbDelete ( db , keyobj ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    decrRefCount ( keyobj ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    expired + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    server . stat_expiredkeys + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  while  ( expired  >  REDIS_EXPIRELOOKUPS_PER_CRON / 4 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 03:22:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  updateLRUClock ( void )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . lruclock  =  ( time ( NULL ) / REDIS_LRU_CLOCK_RESOLUTION )  & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                                REDIS_LRU_CLOCK_MAX ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-03 00:13:39 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								int  serverCron ( struct  aeEventLoop  * eventLoop ,  long  long  id ,  void  * clientData )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-20 20:18:23 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    int  j ,  loops  =  server . cronloops ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    REDIS_NOTUSED ( eventLoop ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    REDIS_NOTUSED ( id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    REDIS_NOTUSED ( clientData ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* We take a cached value of the unix time in the global state because
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  with  virtual  memory  and  aging  there  is  to  store  the  current  time 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  in  objects  at  every  object  access ,  and  accuracy  is  not  needed . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  To  access  a  global  var  is  faster  than  calling  time ( NULL )  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . unixtime  =  time ( NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-14 19:52:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* We have just 22 bits per object for LRU information.
 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 03:22:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								     *  So  we  use  an  ( eventually  wrapping )  LRU  clock  with  10  seconds  resolution . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  2 ^ 22  bits  with  10  seconds  resoluton  is  more  or  less  1.5  years . 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								     * 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 03:22:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								     *  Note  that  even  if  this  will  wrap  after  1.5  years  it ' s  not  a  problem , 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-14 19:52:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								     *  everything  will  still  work  but  just  some  object  will  appear  younger 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 03:22:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								     *  to  Redis .  But  for  this  to  happen  a  given  object  should  never  be  touched 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  for  1.5  years . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  Note  that  you  can  change  the  resolution  altering  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  REDIS_LRU_CLOCK_RESOLUTION  define . 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								     */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 03:22:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    updateLRUClock ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-04-21 16:49:52 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Record the max memory used since the server was started. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( zmalloc_used_memory ( )  >  server . stat_peak_memory ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        server . stat_peak_memory  =  zmalloc_used_memory ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    /* We received a SIGTERM, shutting down here in a safe way, as it is
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  not  ok  doing  so  inside  the  signal  handler .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( server . shutdown_asap )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( prepareForShutdown ( )  = =  REDIS_OK )  exit ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        redisLog ( REDIS_WARNING , " SIGTERM received but errors trying to shut down the server, check the logs for more information " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Show some info about non-empty databases */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( j  =  0 ;  j  <  server . dbnum ;  j + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        long  long  size ,  used ,  vkeys ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        size  =  dictSlots ( server . db [ j ] . dict ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        used  =  dictSize ( server . db [ j ] . dict ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        vkeys  =  dictSize ( server . db [ j ] . expires ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! ( loops  %  50 )  & &  ( used  | |  vkeys ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            redisLog ( REDIS_VERBOSE , " DB %d: %lld keys (%lld volatile) in %lld slots HT. " , j , used , vkeys , size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            /* dictPrintStats(server.dict); */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* We don't want to resize the hash tables while a bacground saving
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  is  in  progress :  the  saving  child  is  created  using  fork ( )  that  is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  implemented  with  a  copy - on - write  semantic  in  most  modern  systems ,  so 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  if  we  resize  the  HT  while  there  is  the  saving  child  at  work  actually 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  a  lot  of  memory  movements  in  the  parent  will  cause  a  lot  of  pages 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  copied .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( server . bgsavechildpid  = =  - 1  & &  server . bgrewritechildpid  = =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! ( loops  %  10 ) )  tryResizeHashTables ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( server . activerehashing )  incrementallyRehash ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Show information about connected clients */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! ( loops  %  50 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        redisLog ( REDIS_VERBOSE , " %d clients connected (%d slaves), %zu bytes in use " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            listLength ( server . clients ) - listLength ( server . slaves ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            listLength ( server . slaves ) , 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-02 19:09:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            zmalloc_used_memory ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Close connections of timedout clients */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-06 21:05:01 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ( server . maxidletime  & &  ! ( loops  %  100 ) )  | |  server . bpop_blocked_clients ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        closeTimedoutClients ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-08 06:41:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Check if a background saving or AOF rewrite in progress terminated. */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    if  ( server . bgsavechildpid  ! =  - 1  | |  server . bgrewritechildpid  ! =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        int  statloc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        pid_t  pid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ( pid  =  wait3 ( & statloc , WNOHANG , NULL ) )  ! =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-08 01:15:14 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            int  exitcode  =  WEXITSTATUS ( statloc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            int  bysignal  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( WIFSIGNALED ( statloc ) )  bysignal  =  WTERMSIG ( statloc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								            if  ( pid  = =  server . bgsavechildpid )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-08 01:15:14 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                backgroundSaveDoneHandler ( exitcode , bysignal ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								            }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-08 01:15:14 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                backgroundRewriteDoneHandler ( exitcode , bysignal ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            updateDictResizePolicy ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-08 06:41:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    }  else  if  ( server . bgsavethread  ! =  ( pthread_t )  - 1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-08 01:15:14 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( server . bgsavethread  ! =  ( pthread_t )  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            int  state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pthread_mutex_lock ( & server . bgsavethread_mutex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            state  =  server . bgsavethread_state ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            pthread_mutex_unlock ( & server . bgsavethread_mutex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-08 02:31:42 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( state  = =  REDIS_BGSAVE_THREAD_DONE_OK  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                state  = =  REDIS_BGSAVE_THREAD_DONE_ERR ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-08 01:15:14 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                backgroundSaveDoneHandler ( 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-08 02:31:42 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    ( state  = =  REDIS_BGSAVE_THREAD_DONE_OK )  ?  0  :  1 ,  0 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-08 01:15:14 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-31 00:53:28 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    }  else  if  ( ! server . ds_enabled )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        /* If there is not a background saving in progress check if
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         *  we  have  to  save  now  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         time_t  now  =  time ( NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         for  ( j  =  0 ;  j  <  server . saveparamslen ;  j + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            struct  saveparam  * sp  =  server . saveparams + j ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( server . dirty  > =  sp - > changes  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                now - server . lastsave  >  sp - > seconds )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                redisLog ( REDIS_NOTICE , " %d changes in %d seconds. Saving... " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    sp - > changes ,  sp - > seconds ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                rdbSaveBackground ( server . dbfilename ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								         } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-08-03 00:13:39 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Expire a few keys per cycle, only if this is a master.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  On  slaves  we  wait  for  DEL  operations  synthesized  by  the  master 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  in  order  to  guarantee  a  strict  consistency .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( server . masterhost  = =  NULL )  activeExpireCycle ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-12-28 22:20:20 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Remove a few cached objects from memory if we are over the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  configured  memory  limit  */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-30 05:18:20 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( server . ds_enabled )  cacheCron ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-05 00:29:53 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Replication cron function -- used to reconnect to master and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  to  detect  transfer  failures .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-05 00:35:03 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( ! ( loops  %  10 ) )  replicationCron ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-05 00:29:53 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-03-29 23:51:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Run other sub-systems specific cron jobs */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( server . cluster_enabled  & &  ! ( loops  %  10 ) )  clusterCron ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-20 20:18:23 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . cronloops + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    return  100 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* This function gets called every time Redis is entering the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  main  loop  of  the  event  driven  library ,  that  is ,  before  to  sleep 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  for  ready  file  descriptors .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  beforeSleep ( struct  aeEventLoop  * eventLoop )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    REDIS_NOTUSED ( eventLoop ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-06 23:39:39 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    listNode  * ln ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    redisClient  * c ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-12-28 22:20:20 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Awake clients that got all the on disk keys they requested */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( server . ds_enabled  & &  listLength ( server . io_ready_clients ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        listIter  li ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        listRewind ( server . io_ready_clients , & li ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        while ( ( ln  =  listNext ( & li ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-06 23:39:39 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            c  =  ln - > value ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								            struct  redisCommand  * cmd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            /* Resume the client. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            listDelNode ( server . io_ready_clients , ln ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            c - > flags  & =  ( ~ REDIS_IO_WAIT ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-28 22:20:20 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            server . cache_blocked_clients - - ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								            aeCreateFileEvent ( server . el ,  c - > fd ,  AE_READABLE , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                readQueryFromClient ,  c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            cmd  =  lookupCommand ( c - > argv [ 0 ] - > ptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            redisAssert ( cmd  ! =  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            call ( c , cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            resetClient ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            /* There may be more data to process in the input buffer. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( c - > querybuf  & &  sdslen ( c - > querybuf )  >  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                processInputBuffer ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-06 23:39:39 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Try to process pending commands for clients that were just unblocked. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    while  ( listLength ( server . unblocked_clients ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ln  =  listFirst ( server . unblocked_clients ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        redisAssert ( ln  ! =  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        c  =  ln - > value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        listDelNode ( server . unblocked_clients , ln ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-17 17:03:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        c - > flags  & =  ~ REDIS_UNBLOCKED ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-06 23:39:39 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        /* Process remaining data in the input buffer. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( c - > querybuf  & &  sdslen ( c - > querybuf )  >  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            processInputBuffer ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    /* Write the AOF buffer on disk */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    flushAppendOnlyFile ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* =========================== Server initialization ======================== */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  createSharedObjects ( void )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  j ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . crlf  =  createObject ( REDIS_STRING , sdsnew ( " \r \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . ok  =  createObject ( REDIS_STRING , sdsnew ( " +OK \r \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . err  =  createObject ( REDIS_STRING , sdsnew ( " -ERR \r \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . emptybulk  =  createObject ( REDIS_STRING , sdsnew ( " $0 \r \n \r \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . czero  =  createObject ( REDIS_STRING , sdsnew ( " :0 \r \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . cone  =  createObject ( REDIS_STRING , sdsnew ( " :1 \r \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . cnegone  =  createObject ( REDIS_STRING , sdsnew ( " :-1 \r \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . nullbulk  =  createObject ( REDIS_STRING , sdsnew ( " $-1 \r \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . nullmultibulk  =  createObject ( REDIS_STRING , sdsnew ( " *-1 \r \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . emptymultibulk  =  createObject ( REDIS_STRING , sdsnew ( " *0 \r \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . pong  =  createObject ( REDIS_STRING , sdsnew ( " +PONG \r \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . queued  =  createObject ( REDIS_STRING , sdsnew ( " +QUEUED \r \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . wrongtypeerr  =  createObject ( REDIS_STRING , sdsnew ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        " -ERR Operation against a key holding the wrong kind of value \r \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . nokeyerr  =  createObject ( REDIS_STRING , sdsnew ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        " -ERR no such key \r \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . syntaxerr  =  createObject ( REDIS_STRING , sdsnew ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        " -ERR syntax error \r \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . sameobjecterr  =  createObject ( REDIS_STRING , sdsnew ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        " -ERR source and destination objects are the same \r \n " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . outofrangeerr  =  createObject ( REDIS_STRING , sdsnew ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        " -ERR index out of range \r \n " ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-08 18:52:03 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    shared . loadingerr  =  createObject ( REDIS_STRING , sdsnew ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        " -LOADING Redis is loading the dataset in memory \r \n " ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    shared . space  =  createObject ( REDIS_STRING , sdsnew ( "   " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . colon  =  createObject ( REDIS_STRING , sdsnew ( " : " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . plus  =  createObject ( REDIS_STRING , sdsnew ( " + " ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . select0  =  createStringObject ( " select 0 \r \n " , 10 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . select1  =  createStringObject ( " select 1 \r \n " , 10 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . select2  =  createStringObject ( " select 2 \r \n " , 10 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . select3  =  createStringObject ( " select 3 \r \n " , 10 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . select4  =  createStringObject ( " select 4 \r \n " , 10 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . select5  =  createStringObject ( " select 5 \r \n " , 10 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . select6  =  createStringObject ( " select 6 \r \n " , 10 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . select7  =  createStringObject ( " select 7 \r \n " , 10 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . select8  =  createStringObject ( " select 8 \r \n " , 10 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . select9  =  createStringObject ( " select 9 \r \n " , 10 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . messagebulk  =  createStringObject ( " $7 \r \n message \r \n " , 13 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . pmessagebulk  =  createStringObject ( " $8 \r \n pmessage \r \n " , 14 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . subscribebulk  =  createStringObject ( " $9 \r \n subscribe \r \n " , 15 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . unsubscribebulk  =  createStringObject ( " $11 \r \n unsubscribe \r \n " , 18 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . psubscribebulk  =  createStringObject ( " $10 \r \n psubscribe \r \n " , 17 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . punsubscribebulk  =  createStringObject ( " $12 \r \n punsubscribe \r \n " , 19 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . mbulk3  =  createStringObject ( " *3 \r \n " , 4 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    shared . mbulk4  =  createStringObject ( " *4 \r \n " , 4 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( j  =  0 ;  j  <  REDIS_SHARED_INTEGERS ;  j + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        shared . integers [ j ]  =  createObject ( REDIS_STRING , ( void * ) ( long ) j ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        shared . integers [ j ] - > encoding  =  REDIS_ENCODING_INT ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  initServerConfig ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . port  =  REDIS_SERVERPORT ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-03 19:33:12 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . bindaddr  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:17:56 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . unixsocket  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-03 19:33:12 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . ipfd  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . sofd  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . dbnum  =  REDIS_DEFAULT_DBNUM ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    server . verbosity  =  REDIS_VERBOSE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . maxidletime  =  REDIS_MAXIDLETIME ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . saveparams  =  NULL ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-08 18:52:03 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . loading  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    server . logfile  =  NULL ;  /* NULL = log on standard output */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-10 00:10:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . syslog_enabled  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . syslog_ident  =  zstrdup ( " redis " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . syslog_facility  =  LOG_LOCAL0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    server . daemonize  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . appendonly  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . appendfsync  =  APPENDFSYNC_EVERYSEC ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . no_appendfsync_on_rewrite  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . lastfsync  =  time ( NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . appendfd  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . appendseldb  =  - 1 ;  /* Make sure the first time will not match */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . pidfile  =  zstrdup ( " /var/run/redis.pid " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . dbfilename  =  zstrdup ( " dump.rdb " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . appendfilename  =  zstrdup ( " appendonly.aof " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . requirepass  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . rdbcompression  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . activerehashing  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . maxclients  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-06 21:05:01 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . bpop_blocked_clients  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    server . maxmemory  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 03:22:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . maxmemory_policy  =  REDIS_MAXMEMORY_VOLATILE_LRU ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . maxmemory_samples  =  3 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-28 22:20:20 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . ds_enabled  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-30 23:41:36 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . ds_path  =  sdsnew ( " /tmp/redis.ds " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-28 22:20:20 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . cache_max_memory  =  64LL * 1024 * 1024 ;  /* 64 MB of RAM */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . cache_blocked_clients  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    server . hash_max_zipmap_entries  =  REDIS_HASH_MAX_ZIPMAP_ENTRIES ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . hash_max_zipmap_value  =  REDIS_HASH_MAX_ZIPMAP_VALUE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . list_max_ziplist_entries  =  REDIS_LIST_MAX_ZIPLIST_ENTRIES ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . list_max_ziplist_value  =  REDIS_LIST_MAX_ZIPLIST_VALUE ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-03 01:57:12 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . set_max_intset_entries  =  REDIS_SET_MAX_INTSET_ENTRIES ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-09 21:01:57 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . zset_max_ziplist_entries  =  REDIS_ZSET_MAX_ZIPLIST_ENTRIES ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . zset_max_ziplist_value  =  REDIS_ZSET_MAX_ZIPLIST_VALUE ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    server . shutdown_asap  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-03 05:27:26 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . cache_flush_delay  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-29 23:51:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . cluster_enabled  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-30 23:41:13 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . cluster . configfile  =  zstrdup ( " nodes.conf " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 18:22:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    updateLRUClock ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    resetServerSaveParams ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    appendServerSaveParams ( 60 * 60 , 1 ) ;   /* save after 1 hour and 1 change */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    appendServerSaveParams ( 300 , 100 ) ;   /* save after 5 minutes and 100 changes */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    appendServerSaveParams ( 60 , 10000 ) ;  /* save after 1 minute and 10000 changes */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Replication related */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . isslave  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . masterauth  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . masterhost  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . masterport  =  6379 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . master  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . replstate  =  REDIS_REPL_NONE ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-05 02:59:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . repl_serve_stale_data  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Double constants initialization */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    R_Zero  =  0.0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    R_PosInf  =  1.0 / R_Zero ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    R_NegInf  =  - 1.0 / R_Zero ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    R_Nan  =  R_Zero / R_Zero ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-03 19:14:36 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Command table -- we intiialize it here as it is part of the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  initial  configuration ,  since  command  names  may  be  changed  via 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  redis . conf  using  the  rename - command  directive .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . commands  =  dictCreate ( & commandTableDictType , NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    populateCommandTable ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . delCommand  =  lookupCommandByCString ( " del " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . multiCommand  =  lookupCommandByCString ( " multi " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  initServer ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  j ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    signal ( SIGHUP ,  SIG_IGN ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    signal ( SIGPIPE ,  SIG_IGN ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-07 00:49:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    setupSignalHandlers ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-12-10 00:10:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( server . syslog_enabled )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        openlog ( server . syslog_ident ,  LOG_PID  |  LOG_NDELAY  |  LOG_NOWAIT , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            server . syslog_facility ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-07-22 19:08:02 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . mainthread  =  pthread_self ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    server . clients  =  listCreate ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . slaves  =  listCreate ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . monitors  =  listCreate ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-06 23:39:39 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . unblocked_clients  =  listCreate ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-02 04:35:56 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . cache_io_queue  =  listCreate ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-30 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    createSharedObjects ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . el  =  aeCreateEventLoop ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . db  =  zmalloc ( sizeof ( redisDb ) * server . dbnum ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-07 19:52:01 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-02-07 20:43:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( server . port  ! =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-07 19:52:01 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        server . ipfd  =  anetTcpServer ( server . neterr , server . port , server . bindaddr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-07 20:43:29 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( server . ipfd  = =  ANET_ERR )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            redisLog ( REDIS_WARNING ,  " Opening port: %s " ,  server . neterr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            exit ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-03 19:33:12 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:17:56 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( server . unixsocket  ! =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        unlink ( server . unixsocket ) ;  /* don't care if this fails */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        server . sofd  =  anetUnixServer ( server . neterr , server . unixsocket ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-03 19:33:12 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( server . sofd  = =  ANET_ERR )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            redisLog ( REDIS_WARNING ,  " Opening socket: %s " ,  server . neterr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            exit ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-02 04:55:24 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-03 19:33:12 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( server . ipfd  <  0  & &  server . sofd  <  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        redisLog ( REDIS_WARNING ,  " Configured to not listen anywhere, exiting. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        exit ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( j  =  0 ;  j  <  server . dbnum ;  j + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        server . db [ j ] . dict  =  dictCreate ( & dbDictType , NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        server . db [ j ] . expires  =  dictCreate ( & keyptrDictType , NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        server . db [ j ] . blocking_keys  =  dictCreate ( & keylistDictType , NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        server . db [ j ] . watched_keys  =  dictCreate ( & keylistDictType , NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-01 00:32:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( server . ds_enabled )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								            server . db [ j ] . io_keys  =  dictCreate ( & keylistDictType , NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-01 00:32:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            server . db [ j ] . io_negcache  =  dictCreate ( & setDictType , NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-02 04:35:56 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            server . db [ j ] . io_queued  =  dictCreate ( & setDictType , NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-01 00:32:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        server . db [ j ] . id  =  j ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . pubsub_channels  =  dictCreate ( & keylistDictType , NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . pubsub_patterns  =  listCreate ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    listSetFreeMethod ( server . pubsub_patterns , freePubsubPattern ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    listSetMatchMethod ( server . pubsub_patterns , listMatchPubsubPattern ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . cronloops  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . bgsavechildpid  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . bgrewritechildpid  =  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-08 01:15:14 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . bgsavethread_state  =  REDIS_BGSAVE_THREAD_UNACTIVE ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . bgsavethread  =  ( pthread_t )  - 1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    server . bgrewritebuf  =  sdsempty ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . aofbuf  =  sdsempty ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . lastsave  =  time ( NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . dirty  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . stat_numcommands  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . stat_numconnections  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . stat_expiredkeys  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-19 22:15:08 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . stat_evictedkeys  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    server . stat_starttime  =  time ( NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 18:19:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . stat_keyspace_misses  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . stat_keyspace_hits  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-21 16:49:52 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    server . stat_peak_memory  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    server . unixtime  =  time ( NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    aeCreateTimeEvent ( server . el ,  1 ,  serverCron ,  NULL ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-03 19:33:12 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( server . ipfd  >  0  & &  aeCreateFileEvent ( server . el , server . ipfd , AE_READABLE , 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-14 00:34:24 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        acceptTcpHandler , NULL )  = =  AE_ERR )  oom ( " creating file event " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-03 19:33:12 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( server . sofd  >  0  & &  aeCreateFileEvent ( server . el , server . sofd , AE_READABLE , 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-14 00:34:24 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        acceptUnixHandler , NULL )  = =  AE_ERR )  oom ( " creating file event " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( server . appendonly )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        server . appendfd  =  open ( server . appendfilename , O_WRONLY | O_APPEND | O_CREAT , 0644 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( server . appendfd  = =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            redisLog ( REDIS_WARNING ,  " Can't open the append-only file: %s " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                strerror ( errno ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            exit ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-12-28 22:20:20 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( server . ds_enabled )  dsInit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-29 23:51:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( server . cluster_enabled )  clusterInit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-22 07:03:03 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    srand ( time ( NULL ) ^ getpid ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-03 18:23:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								/* Populates the Redis Command Table starting from the hard coded list
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  we  have  on  top  of  redis . c  file .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  populateCommandTable ( void )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  j ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 17:56:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    int  numcommands  =  sizeof ( redisCommandTable ) / sizeof ( struct  redisCommand ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-03 18:23:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( j  =  0 ;  j  <  numcommands ;  j + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 17:56:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        struct  redisCommand  * c  =  redisCommandTable + j ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-03 18:23:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        int  retval ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-03 18:23:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        retval  =  dictAdd ( server . commands ,  sdsnew ( c - > name ) ,  c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        assert ( retval  = =  DICT_OK ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 17:56:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  resetCommandTableStats ( void )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  numcommands  =  sizeof ( redisCommandTable ) / sizeof ( struct  redisCommand ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  j ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( j  =  0 ;  j  <  numcommands ;  j + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        struct  redisCommand  * c  =  redisCommandTable + j ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        c - > microseconds  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        c - > calls  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								/* ====================== Commands lookup and execution ===================== */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-03 18:23:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								struct  redisCommand  * lookupCommand ( sds  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  dictFetchValue ( server . commands ,  name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								struct  redisCommand  * lookupCommandByCString ( char  * s )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  redisCommand  * cmd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sds  name  =  sdsnew ( s ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    cmd  =  dictFetchValue ( server . commands ,  name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sdsfree ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  cmd ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Call() is the core of Redis execution of a command */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  call ( redisClient  * c ,  struct  redisCommand  * cmd )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 18:46:34 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    long  long  dirty ,  start  =  ustime ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dirty  =  server . dirty ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    cmd - > proc ( c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    dirty  =  server . dirty - dirty ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 18:46:34 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    cmd - > microseconds  + =  ustime ( ) - start ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 05:14:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    cmd - > calls + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( server . appendonly  & &  dirty ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        feedAppendOnlyFile ( cmd , c - > db - > id , c - > argv , c - > argc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( dirty  | |  cmd - > flags  &  REDIS_CMD_FORCE_REPLICATION )  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        listLength ( server . slaves ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        replicationFeedSlaves ( server . slaves , c - > db - > id , c - > argv , c - > argc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( listLength ( server . monitors ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        replicationFeedMonitors ( server . monitors , c - > db - > id , c - > argv , c - > argc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    server . stat_numcommands + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* If this function gets called we already read a whole
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  command ,  argments  are  in  the  client  argv / argc  fields . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  processCommand ( )  execute  the  command  or  prepare  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  server  for  a  bulk  read  from  the  client . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  If  1  is  returned  the  client  is  still  alive  and  valid  and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  and  other  operations  can  be  performed  by  the  caller .  Otherwise 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  if  0  is  returned  the  client  was  destroied  ( i . e .  after  QUIT ) .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  processCommand ( redisClient  * c )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    struct  redisCommand  * cmd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 17:25:40 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* The QUIT command is handled separately. Normal command procs will
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  go  through  checking  for  replication  and  QUIT  will  cause  trouble 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  when  FORCE_REPLICATION  is  enabled  and  would  be  implemented  in 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  a  regular  command  proc .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! strcasecmp ( c - > argv [ 0 ] - > ptr , " quit " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 17:25:40 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        addReply ( c , shared . ok ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-28 22:07:45 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        c - > flags  | =  REDIS_CLOSE_AFTER_REPLY ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 21:40:25 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  REDIS_ERR ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Now lookup the command and check ASAP about trivial error conditions
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  such  wrong  arity ,  bad  command  name  and  so  forth .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    cmd  =  lookupCommand ( c - > argv [ 0 ] - > ptr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! cmd )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-03 01:52:24 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        addReplyErrorFormat ( c , " unknown command '%s' " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ( char * ) c - > argv [ 0 ] - > ptr ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 21:40:25 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  REDIS_OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    }  else  if  ( ( cmd - > arity  >  0  & &  cmd - > arity  ! =  c - > argc )  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								               ( c - > argc  <  - cmd - > arity ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-03 01:52:24 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        addReplyErrorFormat ( c , " wrong number of arguments for '%s' command " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            cmd - > name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 21:40:25 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  REDIS_OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Check if the user is authenticated */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( server . requirepass  & &  ! c - > authenticated  & &  cmd - > proc  ! =  authCommand )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-03 01:52:24 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        addReplyError ( c , " operation not permitted " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 21:40:25 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  REDIS_OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-03-29 23:51:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* If cluster is enabled, redirect here */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( server . cluster_enabled  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ! ( cmd - > getkeys_proc  = =  NULL  & &  cmd - > firstkey  = =  0 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        int  hashslot ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( server . cluster . state  ! =  REDIS_CLUSTER_OK )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            addReplyError ( c , " The cluster is down. Check with CLUSTER INFO for more information " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return  REDIS_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            clusterNode  * n  =  getNodeByQuery ( c , cmd , c - > argv , c - > argc , & hashslot ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( n  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                addReplyError ( c , " Invalid cross-node request " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                return  REDIS_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            }  else  if  ( n  ! =  server . cluster . myself )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                addReplySds ( c , sdscatprintf ( sdsempty ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    " -MOVED %d %s:%d \r \n " , hashslot , n - > ip , n - > port ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                return  REDIS_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-10-11 19:05:09 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Handle the maxmemory directive.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  First  we  try  to  free  some  memory  if  possible  ( if  there  are  volatile 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  keys  in  the  dataset ) .  If  there  are  not  the  only  thing  we  can  do 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  is  returning  an  error .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( server . maxmemory )  freeMemoryIfNeeded ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    if  ( server . maxmemory  & &  ( cmd - > flags  &  REDIS_CMD_DENYOOM )  & & 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-02 19:09:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        zmalloc_used_memory ( )  >  server . maxmemory ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-03 01:52:24 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        addReplyError ( c , " command not allowed when used memory > 'maxmemory' " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 21:40:25 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  REDIS_OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Only allow SUBSCRIBE and UNSUBSCRIBE in the context of Pub/Sub */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( dictSize ( c - > pubsub_channels )  >  0  | |  listLength ( c - > pubsub_patterns )  >  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        cmd - > proc  ! =  subscribeCommand  & &  cmd - > proc  ! =  unsubscribeCommand  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        cmd - > proc  ! =  psubscribeCommand  & &  cmd - > proc  ! =  punsubscribeCommand )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-03 01:52:24 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        addReplyError ( c , " only (P)SUBSCRIBE / (P)UNSUBSCRIBE / QUIT allowed in this context " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 21:40:25 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        return  REDIS_OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-05 02:59:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Only allow INFO and SLAVEOF when slave-serve-stale-data is no and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  we  are  a  slave  with  a  broken  link  with  master .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( server . masterhost  & &  server . replstate  ! =  REDIS_REPL_CONNECTED  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        server . repl_serve_stale_data  = =  0  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        cmd - > proc  ! =  infoCommand  & &  cmd - > proc  ! =  slaveofCommand ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        addReplyError ( c , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " link with MASTER is down and slave-serve-stale-data is set to no " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  REDIS_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-08 18:52:03 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Loading DB? Return an error if the command is not INFO */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( server . loading  & &  cmd - > proc  ! =  infoCommand )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        addReply ( c ,  shared . loadingerr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  REDIS_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    /* Exec the command */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( c - > flags  &  REDIS_MULTI  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        cmd - > proc  ! =  execCommand  & &  cmd - > proc  ! =  discardCommand  & & 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        cmd - > proc  ! =  multiCommand  & &  cmd - > proc  ! =  watchCommand ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        queueMultiCommand ( c , cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        addReply ( c , shared . queued ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-28 22:20:20 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( server . ds_enabled  & &  blockClientOnSwappedKeys ( c , cmd ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return  REDIS_ERR ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        call ( c , cmd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 21:40:25 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    return  REDIS_OK ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*================================== Shutdown =============================== */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  prepareForShutdown ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    redisLog ( REDIS_WARNING , " User requested shutdown, saving DB... " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Kill the saving child if there is a background saving in progress.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								       We  want  to  avoid  race  conditions ,  for  instance  our  saving  child  may 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								       overwrite  the  synchronous  saving  did  by  SHUTDOWN .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( server . bgsavechildpid  ! =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        redisLog ( REDIS_WARNING , " There is a live saving child. Killing it! " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        kill ( server . bgsavechildpid , SIGKILL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        rdbRemoveTempFile ( server . bgsavechildpid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-30 22:55:24 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( server . ds_enabled )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        /* FIXME: flush all objects on disk */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  if  ( server . appendonly )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        /* Append only file: fsync() the AOF and exit */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        aof_fsync ( server . appendfd ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-01 02:53:34 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    }  else  if  ( server . saveparamslen  >  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        /* Snapshotting. Perform a SYNC SAVE and exit */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-24 23:09:25 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( rdbSave ( server . dbfilename )  ! =  REDIS_OK )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								            /* Ooops.. error saving! The best we can do is to continue
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             *  operating .  Note  that  if  there  was  a  background  saving  process , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             *  in  the  next  cron ( )  Redis  will  be  notified  that  the  background 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             *  saving  aborted ,  handling  special  stuff  like  slaves  pending  for 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								             *  synchronization . . .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            redisLog ( REDIS_WARNING , " Error trying to save the DB, can't exit " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            return  REDIS_ERR ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-01 02:53:34 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        redisLog ( REDIS_WARNING , " Not saving DB. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-24 23:09:25 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( server . daemonize )  unlink ( server . pidfile ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    redisLog ( REDIS_WARNING , " Server exit now, bye bye... " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  REDIS_OK ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/*================================== Commands =============================== */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  authCommand ( redisClient  * c )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! server . requirepass  | |  ! strcmp ( c - > argv [ 1 ] - > ptr ,  server . requirepass ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      c - > authenticated  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      addReply ( c , shared . ok ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								      c - > authenticated  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-03 01:52:24 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								      addReplyError ( c , " invalid password " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  pingCommand ( redisClient  * c )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    addReply ( c , shared . pong ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  echoCommand ( redisClient  * c )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    addReplyBulk ( c , c - > argv [ 1 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Convert an amount of bytes into a human readable string in the form
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  of  100 B ,  2 G ,  100 M ,  4 K ,  and  so  forth .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  bytesToHuman ( char  * s ,  unsigned  long  long  n )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    double  d ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( n  <  1024 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        /* Bytes */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        sprintf ( s , " %lluB " , n ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  if  ( n  <  ( 1024 * 1024 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        d  =  ( double ) n / ( 1024 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        sprintf ( s , " %.2fK " , d ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  if  ( n  <  ( 1024LL * 1024 * 1024 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        d  =  ( double ) n / ( 1024 * 1024 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        sprintf ( s , " %.2fM " , d ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  if  ( n  <  ( 1024LL * 1024 * 1024 * 1024 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        d  =  ( double ) n / ( 1024LL * 1024 * 1024 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        sprintf ( s , " %.2fG " , d ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* Create the string returned by the INFO command. This is decoupled
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  by  the  INFO  command  itself  as  we  need  to  report  the  same  information 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  on  memory  corruption  problems .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								sds  genRedisInfoString ( char  * section )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sds  info  =  sdsempty ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    time_t  uptime  =  time ( NULL ) - server . stat_starttime ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 18:46:34 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    int  j ,  numcommands ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-16 19:28:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    struct  rusage  self_ru ,  c_ru ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-14 17:20:02 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    unsigned  long  lol ,  bib ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    int  allsections  =  0 ,  defsections  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  sections  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( section )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        allsections  =  strcasecmp ( section , " all " )  = =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 05:14:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        defsections  =  strcasecmp ( section , " default " )  = =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2010-09-16 19:28:58 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    getrusage ( RUSAGE_SELF ,  & self_ru ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    getrusage ( RUSAGE_CHILDREN ,  & c_ru ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-14 17:20:02 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    getClientsMaxBuffers ( & lol , & bib ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Server */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( allsections  | |  defsections  | |  ! strcasecmp ( section , " server " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( sections + + )  info  =  sdscat ( info , " \r \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        info  =  sdscatprintf ( info , 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            " # Server \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " redis_version:%s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " redis_git_sha1:%s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " redis_git_dirty:%d \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " arch_bits:%s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " multiplexing_api:%s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " process_id:%ld \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " tcp_port:%d \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " uptime_in_seconds:%ld \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " uptime_in_days:%ld \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " lru_clock:%ld \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            REDIS_VERSION , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            redisGitSHA1 ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            strtol ( redisGitDirty ( ) , NULL , 10 )  >  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ( sizeof ( long )  = =  8 )  ?  " 64 "  :  " 32 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            aeGetApiName ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ( long )  getpid ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            server . port , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            uptime , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            uptime / ( 3600 * 24 ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ( unsigned  long )  server . lruclock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Clients */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( allsections  | |  defsections  | |  ! strcasecmp ( section , " clients " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( sections + + )  info  =  sdscat ( info , " \r \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        info  =  sdscatprintf ( info , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " # Clients \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " connected_clients:%d \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " client_longest_output_list:%lu \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " client_biggest_input_buf:%lu \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " blocked_clients:%d \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            listLength ( server . clients ) - listLength ( server . slaves ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            lol ,  bib , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            server . bpop_blocked_clients ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Memory */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( allsections  | |  defsections  | |  ! strcasecmp ( section , " memory " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-21 16:49:52 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        char  hmem [ 64 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        char  peak_hmem [ 64 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        bytesToHuman ( hmem , zmalloc_used_memory ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        bytesToHuman ( peak_hmem , server . stat_peak_memory ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( sections + + )  info  =  sdscat ( info , " \r \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        info  =  sdscatprintf ( info , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " # Memory \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " used_memory:%zu \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " used_memory_human:%s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " used_memory_rss:%zu \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-21 16:49:52 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            " used_memory_peak:%zu \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " used_memory_peak_human:%s \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            " mem_fragmentation_ratio:%.2f \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " use_tcmalloc:%d \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            zmalloc_used_memory ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            hmem , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            zmalloc_get_rss ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-21 16:49:52 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            server . stat_peak_memory , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            peak_hmem , 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            zmalloc_get_fragmentation_ratio ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # ifdef USE_TCMALLOC 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # else 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    # endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-05 01:50:23 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 05:14:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Allocation statistics */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( allsections  | |  ! strcasecmp ( section , " allocstats " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( sections + + )  info  =  sdscat ( info , " \r \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        info  =  sdscat ( info ,  " # Allocstats \r \n allocation_stats: " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        for  ( j  =  0 ;  j  < =  ZMALLOC_MAX_ALLOC_STAT ;  j + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            size_t  count  =  zmalloc_allocations_for_size ( j ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( count )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                if  ( info [ sdslen ( info ) - 1 ]  ! =  ' : ' )  info  =  sdscatlen ( info , " , " , 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                info  =  sdscatprintf ( info , " %s%d=%zu " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    ( j  = =  ZMALLOC_MAX_ALLOC_STAT )  ?  " >= "  :  " " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    j , count ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-05 01:50:23 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 05:14:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        info  =  sdscat ( info , " \r \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Persistence */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( allsections  | |  defsections  | |  ! strcasecmp ( section , " persistence " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( sections + + )  info  =  sdscat ( info , " \r \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        info  =  sdscatprintf ( info , 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            " # Persistence \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " loading:%d \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " aof_enabled:%d \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " changes_since_last_save:%lld \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " bgsave_in_progress:%d \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " last_save_time:%ld \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " bgrewriteaof_in_progress:%d \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            server . loading , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            server . appendonly , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            server . dirty , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                server . bgsavechildpid  ! =  - 1  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                server . bgsavethread  ! =  ( pthread_t )  - 1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            server . lastsave , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            server . bgrewritechildpid  ! =  - 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( server . loading )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            double  perc ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            time_t  eta ,  elapsed ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            off_t  remaining_bytes  =  server . loading_total_bytes - 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                                    server . loading_loaded_bytes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            perc  =  ( ( double ) server . loading_loaded_bytes  / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                   server . loading_total_bytes )  *  100 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            elapsed  =  time ( NULL ) - server . loading_start_time ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( elapsed  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                eta  =  1 ;  /* A fake 1 second figure if we don't have
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                            enough  info  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                eta  =  ( elapsed * remaining_bytes ) / server . loading_loaded_bytes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            info  =  sdscatprintf ( info , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                " loading_start_time:%ld \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                " loading_total_bytes:%llu \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                " loading_loaded_bytes:%llu \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                " loading_loaded_perc:%.2f \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                " loading_eta_seconds:%ld \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                , ( unsigned  long )  server . loading_start_time , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ( unsigned  long  long )  server . loading_total_bytes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ( unsigned  long  long )  server . loading_loaded_bytes , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                perc , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                eta 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Diskstore */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( allsections  | |  defsections  | |  ! strcasecmp ( section , " diskstore " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( sections + + )  info  =  sdscat ( info , " \r \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        info  =  sdscatprintf ( info , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " # Diskstore \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " ds_enabled:%d \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            server . ds_enabled  ! =  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( server . ds_enabled )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            lockThreadedIO ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            info  =  sdscatprintf ( info , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                " cache_max_memory:%llu \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                " cache_blocked_clients:%lu \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-25 17:59:57 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                " cache_io_queue_len:%lu \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                " cache_io_jobs_new:%lu \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                " cache_io_jobs_processing:%lu \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                " cache_io_jobs_processed:%lu \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                " cache_io_ready_clients:%lu \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                , ( unsigned  long  long )  server . cache_max_memory , 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-25 17:59:57 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                ( unsigned  long )  server . cache_blocked_clients , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ( unsigned  long )  listLength ( server . cache_io_queue ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ( unsigned  long )  listLength ( server . io_newjobs ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ( unsigned  long )  listLength ( server . io_processing ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ( unsigned  long )  listLength ( server . io_processed ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ( unsigned  long )  listLength ( server . io_ready_clients ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            unlockThreadedIO ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-08 18:52:03 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-08 18:52:03 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Stats */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( allsections  | |  defsections  | |  ! strcasecmp ( section , " stats " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( sections + + )  info  =  sdscat ( info , " \r \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-08 18:52:03 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        info  =  sdscatprintf ( info , 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            " # Stats \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " total_connections_received:%lld \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " total_commands_processed:%lld \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " expired_keys:%lld \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " evicted_keys:%lld \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " keyspace_hits:%lld \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " keyspace_misses:%lld \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " pubsub_channels:%ld \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " pubsub_patterns:%u \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            server . stat_numconnections , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            server . stat_numcommands , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            server . stat_expiredkeys , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            server . stat_evictedkeys , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            server . stat_keyspace_hits , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            server . stat_keyspace_misses , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            dictSize ( server . pubsub_channels ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            listLength ( server . pubsub_patterns ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-08 18:52:03 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-09 22:56:50 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Replication */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( allsections  | |  defsections  | |  ! strcasecmp ( section , " replication " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( sections + + )  info  =  sdscat ( info , " \r \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        info  =  sdscatprintf ( info , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " # Replication \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " role:%s \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            server . masterhost  = =  NULL  ?  " master "  :  " slave " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( server . masterhost )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            info  =  sdscatprintf ( info , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                " master_host:%s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                " master_port:%d \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                " master_link_status:%s \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                " master_last_io_seconds_ago:%d \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                " master_sync_in_progress:%d \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                , server . masterhost , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                server . masterport , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ( server . replstate  = =  REDIS_REPL_CONNECTED )  ? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    " up "  :  " down " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                server . master  ? 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ( ( int ) ( time ( NULL ) - server . master - > lastinteraction ) )  :  - 1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                server . replstate  = =  REDIS_REPL_TRANSFER 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( server . replstate  = =  REDIS_REPL_TRANSFER )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                info  =  sdscatprintf ( info , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    " master_sync_left_bytes:%ld \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    " master_sync_last_io_seconds_ago:%d \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    , ( long ) server . repl_transfer_left , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    ( int ) ( time ( NULL ) - server . repl_transfer_lastio ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-09 22:56:50 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        info  =  sdscatprintf ( info , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            " connected_slaves:%d \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            listLength ( server . slaves ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-09 22:56:50 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 05:14:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* CPU */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( allsections  | |  defsections  | |  ! strcasecmp ( section , " cpu " ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        if  ( sections + + )  info  =  sdscat ( info , " \r \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        info  =  sdscatprintf ( info , 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 05:14:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        " # CPU \r \n " 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        " used_cpu_sys:%.2f \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        " used_cpu_user:%.2f \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        " used_cpu_sys_childrens:%.2f \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        " used_cpu_user_childrens:%.2f \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ( float ) self_ru . ru_utime . tv_sec + ( float ) self_ru . ru_utime . tv_usec / 1000000 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ( float ) self_ru . ru_stime . tv_sec + ( float ) self_ru . ru_stime . tv_usec / 1000000 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ( float ) c_ru . ru_utime . tv_sec + ( float ) c_ru . ru_utime . tv_usec / 1000000 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ( float ) c_ru . ru_stime . tv_sec + ( float ) c_ru . ru_stime . tv_usec / 1000000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 05:14:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 05:14:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* cmdtime */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( allsections  | |  ! strcasecmp ( section , " commandstats " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( sections + + )  info  =  sdscat ( info , " \r \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        info  =  sdscatprintf ( info ,  " # Commandstats \r \n " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 17:56:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        numcommands  =  sizeof ( redisCommandTable ) / sizeof ( struct  redisCommand ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        for  ( j  =  0 ;  j  <  numcommands ;  j + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 17:56:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            struct  redisCommand  * c  =  redisCommandTable + j ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 05:14:15 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-24 17:56:06 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            if  ( ! c - > calls )  continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            info  =  sdscatprintf ( info , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                " cmdstat_%s:calls=%lld,usec=%lld,usec_per_call=%.2f \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                c - > name ,  c - > calls ,  c - > microseconds , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                ( c - > calls  = =  0 )  ?  0  :  ( ( float ) c - > microseconds / c - > calls ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 18:46:34 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-04-11 22:39:39 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Clusetr */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( allsections  | |  defsections  | |  ! strcasecmp ( section , " cluster " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( sections + + )  info  =  sdscat ( info , " \r \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        info  =  sdscatprintf ( info , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        " # Cluster \r \n " 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        " cluster_enabled:%d \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        server . cluster_enabled ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Key space */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( allsections  | |  defsections  | |  ! strcasecmp ( section , " keyspace " ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( sections + + )  info  =  sdscat ( info , " \r \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        info  =  sdscatprintf ( info ,  " # Keyspace \r \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        for  ( j  =  0 ;  j  <  server . dbnum ;  j + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            long  long  keys ,  vkeys ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            keys  =  dictSize ( server . db [ j ] . dict ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            vkeys  =  dictSize ( server . db [ j ] . expires ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( keys  | |  vkeys )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                info  =  sdscatprintf ( info ,  " db%d:keys=%lld,expires=%lld \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    j ,  keys ,  vkeys ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  info ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  infoCommand ( redisClient  * c )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    char  * section  =  c - > argc  = =  2  ?  c - > argv [ 1 ] - > ptr  :  " default " ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( c - > argc  >  2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        addReply ( c , shared . syntaxerr ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sds  info  =  genRedisInfoString ( section ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    addReplySds ( c , sdscatprintf ( sdsempty ( ) , " $%lu \r \n " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ( unsigned  long ) sdslen ( info ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    addReplySds ( c , info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    addReply ( c , shared . crlf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  monitorCommand ( redisClient  * c )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* ignore MONITOR if aleady slave or in monitor mode */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( c - > flags  &  REDIS_SLAVE )  return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    c - > flags  | =  ( REDIS_SLAVE | REDIS_MONITOR ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    c - > slaveseldb  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    listAddNodeTail ( server . monitors , c ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    addReply ( c , shared . ok ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* ============================ Maxmemory directive  ======================== */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* This function gets called when 'maxmemory' is set on the config file to limit
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  the  max  memory  used  by  the  server ,  and  we  are  out  of  memory . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  This  function  will  try  to ,  in  order : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  -  Free  objects  from  the  free  list 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  -  Try  to  remove  keys  with  an  EXPIRE  set 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  It  is  not  possible  to  free  enough  memory  to  reach  used - memory  <  maxmemory 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  the  server  will  start  refusing  commands  that  will  enlarge  even  more  the 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 *  memory  usage . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  freeMemoryIfNeeded ( void )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 03:22:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* Remove keys accordingly to the active policy as long as we are
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  over  the  memory  limit .  */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-08 23:12:16 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( server . maxmemory_policy  = =  REDIS_MAXMEMORY_NO_EVICTION )  return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-11-02 19:09:59 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    while  ( server . maxmemory  & &  zmalloc_used_memory ( )  >  server . maxmemory )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        int  j ,  k ,  freed  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 03:22:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        for  ( j  =  0 ;  j  <  server . dbnum ;  j + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-02 18:15:09 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            long  bestval  =  0 ;  /* just to prevent warning */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 03:22:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            sds  bestkey  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            struct  dictEntry  * de ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            redisDb  * db  =  server . db + j ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            dict  * dict ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( server . maxmemory_policy  = =  REDIS_MAXMEMORY_ALLKEYS_LRU  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                server . maxmemory_policy  = =  REDIS_MAXMEMORY_ALLKEYS_RANDOM ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                dict  =  server . db [ j ] . dict ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                dict  =  server . db [ j ] . expires ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( dictSize ( dict )  = =  0 )  continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            /* volatile-random and allkeys-random policy */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( server . maxmemory_policy  = =  REDIS_MAXMEMORY_ALLKEYS_RANDOM  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                server . maxmemory_policy  = =  REDIS_MAXMEMORY_VOLATILE_RANDOM ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                de  =  dictGetRandomKey ( dict ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                bestkey  =  dictGetEntryKey ( de ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            /* volatile-lru and allkeys-lru policy */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            else  if  ( server . maxmemory_policy  = =  REDIS_MAXMEMORY_ALLKEYS_LRU  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                server . maxmemory_policy  = =  REDIS_MAXMEMORY_VOLATILE_LRU ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                for  ( k  =  0 ;  k  <  server . maxmemory_samples ;  k + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    sds  thiskey ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    long  thisval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    robj  * o ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    de  =  dictGetRandomKey ( dict ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    thiskey  =  dictGetEntryKey ( de ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-11-11 20:19:17 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    /* When policy is volatile-lru we need an additonal lookup
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                     *  to  locate  the  real  key ,  as  dict  is  set  to  db - > expires .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    if  ( server . maxmemory_policy  = =  REDIS_MAXMEMORY_VOLATILE_LRU ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                        de  =  dictFind ( db - > dict ,  thiskey ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 03:22:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                    o  =  dictGetEntryVal ( de ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    thisval  =  estimateObjectIdleTime ( o ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    /* Higher idle time is better candidate for deletion */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    if  ( bestkey  = =  NULL  | |  thisval  >  bestval )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                        bestkey  =  thiskey ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                        bestval  =  thisval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            /* volatile-ttl */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            else  if  ( server . maxmemory_policy  = =  REDIS_MAXMEMORY_VOLATILE_TTL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                for  ( k  =  0 ;  k  <  server . maxmemory_samples ;  k + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    sds  thiskey ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    long  thisval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    de  =  dictGetRandomKey ( dict ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    thiskey  =  dictGetEntryKey ( de ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    thisval  =  ( long )  dictGetEntryVal ( de ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    /* Expire sooner (minor expire unix timestamp) is better
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                     *  candidate  for  deletion  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    if  ( bestkey  = =  NULL  | |  thisval  <  bestval )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                        bestkey  =  thiskey ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                        bestval  =  thisval ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            /* Finally remove the selected key. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            if  ( bestkey )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                robj  * keyobj  =  createStringObject ( bestkey , sdslen ( bestkey ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-27 23:52:37 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                propagateExpire ( db , keyobj ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 03:22:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                dbDelete ( db , keyobj ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-19 22:15:08 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                server . stat_evictedkeys + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-15 03:22:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								                decrRefCount ( keyobj ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								                freed + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( ! freed )  return ;  /* nothing to free... */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* =================================== Main! ================================ */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef __linux__ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								int  linuxOvercommitMemoryValue ( void )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    FILE  * fp  =  fopen ( " /proc/sys/vm/overcommit_memory " , " r " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    char  buf [ 64 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ! fp )  return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( fgets ( buf , 64 , fp )  = =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        fclose ( fp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        return  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    fclose ( fp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  atoi ( buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  linuxOvercommitMemoryWarning ( void )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( linuxOvercommitMemoryValue ( )  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        redisLog ( REDIS_WARNING , " WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif  /* __linux__ */ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-08-24 23:09:25 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  createPidFile ( void )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Try to write the pid file in a best-effort way. */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    FILE  * fp  =  fopen ( server . pidfile , " w " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( fp )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-23 19:25:56 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        fprintf ( fp , " %d \n " , ( int ) getpid ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-24 23:09:25 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        fclose ( fp ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								void  daemonize ( void )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  fd ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( fork ( )  ! =  0 )  exit ( 0 ) ;  /* parent exits */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    setsid ( ) ;  /* create a new session */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Every output goes to /dev/null. If Redis is daemonized but
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  the  ' logfile '  is  set  to  ' stdout '  in  the  configuration  file 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  it  will  not  log  at  all .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( ( fd  =  open ( " /dev/null " ,  O_RDWR ,  0 ) )  ! =  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        dup2 ( fd ,  STDIN_FILENO ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        dup2 ( fd ,  STDOUT_FILENO ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        dup2 ( fd ,  STDERR_FILENO ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( fd  >  STDERR_FILENO )  close ( fd ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  version ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    printf ( " Redis server version %s (%s:%d) \n " ,  REDIS_VERSION , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        redisGitSHA1 ( ) ,  atoi ( redisGitDirty ( ) )  >  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    exit ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								void  usage ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    fprintf ( stderr , " Usage: ./redis-server [/path/to/redis.conf] \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    fprintf ( stderr , "        ./redis-server - (read config from stdin) \n " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    exit ( 1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-04-13 16:58:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  redisAsciiArt ( void )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# include  "asciilogo.h" 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    char  * buf  =  zmalloc ( 1024 * 16 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    snprintf ( buf , 1024 * 16 , ascii_logo , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        REDIS_VERSION , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        redisGitSHA1 ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        strtol ( redisGitDirty ( ) , NULL , 10 )  >  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ( sizeof ( long )  = =  8 )  ?  " 64 "  :  " 32 " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        server . cluster_enabled  ?  " cluster "  :  " stand alone " , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        server . port , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        ( long )  getpid ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    redisLogRaw ( REDIS_NOTICE | REDIS_LOG_RAW , buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    zfree ( buf ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								int  main ( int  argc ,  char  * * argv )  { 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-28 22:31:54 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    long  long  start ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    initServerConfig ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( argc  = =  2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( strcmp ( argv [ 1 ] ,  " -v " )  = =  0  | | 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								            strcmp ( argv [ 1 ] ,  " --version " )  = =  0 )  version ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( strcmp ( argv [ 1 ] ,  " --help " )  = =  0 )  usage ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        resetServerSaveParams ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        loadServerConfig ( argv [ 1 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  if  ( ( argc  >  2 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        usage ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        redisLog ( REDIS_WARNING , " Warning: no config file specified, using the default config. In order to specify a config file use 'redis-server /path/to/redis.conf' " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( server . daemonize )  daemonize ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    initServer ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-24 23:09:25 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( server . daemonize )  createPidFile ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-04-13 16:58:21 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    redisAsciiArt ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    redisLog ( REDIS_NOTICE , " Server started, Redis version  "  REDIS_VERSION ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef __linux__ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    linuxOvercommitMemoryWarning ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-28 22:31:54 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    start  =  ustime ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-30 06:00:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( server . ds_enabled )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-30 06:08:18 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        redisLog ( REDIS_NOTICE , " DB not loaded (running with disk back end) " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-12-30 06:00:00 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    }  else  if  ( server . appendonly )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								        if  ( loadAppendOnlyFile ( server . appendfilename )  = =  REDIS_OK ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-28 22:31:54 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            redisLog ( REDIS_NOTICE , " DB loaded from append only file: %.3f seconds " , ( float ) ( ustime ( ) - start ) / 1000000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        if  ( rdbLoad ( server . dbfilename )  = =  REDIS_OK ) 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-28 22:31:54 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								            redisLog ( REDIS_NOTICE , " DB loaded from disk: %.3f seconds " , ( float ) ( ustime ( ) - start ) / 1000000 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-03 19:33:12 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( server . ipfd  >  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        redisLog ( REDIS_NOTICE , " The server is now ready to accept connections on port %d " ,  server . port ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( server . sofd  >  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-13 23:17:56 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								        redisLog ( REDIS_NOTICE , " The server is now ready to accept connections at %s " ,  server . unixsocket ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    aeSetBeforeSleepProc ( server . el , beforeSleep ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    aeMain ( server . el ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    aeDeleteEventLoop ( server . el ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# ifdef HAVE_BACKTRACE 
 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-07 00:49:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  * getMcontextEip ( ucontext_t  * uc )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								# if defined(__FreeBSD__) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ( void * )  uc - > uc_mcontext . mc_eip ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# elif defined(__dietlibc__) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ( void * )  uc - > uc_mcontext . eip ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# elif defined(__APPLE__) && !defined(MAC_OS_X_VERSION_10_6) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  # if __x86_64__ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ( void * )  uc - > uc_mcontext - > __ss . __rip ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  # else 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ( void * )  uc - > uc_mcontext - > __ss . __eip ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  # endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# elif defined(__APPLE__) && defined(MAC_OS_X_VERSION_10_6) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  # if defined(_STRUCT_X86_THREAD_STATE64) && !defined(__i386__) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ( void * )  uc - > uc_mcontext - > __ss . __rip ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  # else 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ( void * )  uc - > uc_mcontext - > __ss . __eip ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								  # endif 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-07-02 03:13:38 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# elif defined(__i386__) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ( void * )  uc - > uc_mcontext . gregs [ 14 ] ;  /* Linux 32 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# elif defined(__X86_64__) || defined(__x86_64__) 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ( void * )  uc - > uc_mcontext . gregs [ 16 ] ;  /* Linux 64 */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								# elif defined(__ia64__)  /* Linux IA64 */ 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  ( void * )  uc - > uc_mcontext . sc_ip ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# else 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-03-07 00:49:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  sigsegvHandler ( int  sig ,  siginfo_t  * info ,  void  * secret )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    void  * trace [ 100 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    char  * * messages  =  NULL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    int  i ,  trace_size  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    ucontext_t  * uc  =  ( ucontext_t * )  secret ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sds  infostring ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-23 05:30:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    struct  sigaction  act ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    REDIS_NOTUSED ( info ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    redisLog ( REDIS_WARNING , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        " ======= Ooops! Redis %s got signal: -%d- ======= " ,  REDIS_VERSION ,  sig ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-01-23 23:41:07 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    infostring  =  genRedisInfoString ( " all " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-02-09 17:10:35 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    redisLogRaw ( REDIS_WARNING ,  infostring ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    /* It's not safe to sdsfree() the returned string under memory
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  corruption  conditions .  Let  it  leak  as  we  are  going  to  abort  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    trace_size  =  backtrace ( trace ,  100 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* overwrite sigaction with caller's address */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    if  ( getMcontextEip ( uc )  ! =  NULL )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        trace [ 1 ]  =  getMcontextEip ( uc ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    messages  =  backtrace_symbols ( trace ,  trace_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    for  ( i = 1 ;  i < trace_size ;  + + i ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								        redisLog ( REDIS_WARNING , " %s " ,  messages [ i ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* free(messages); Don't call free() with possibly corrupted memory. */ 
							 
						 
					
						
							
								
									
										
										
										
											2010-08-24 23:09:25 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    if  ( server . daemonize )  unlink ( server . pidfile ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-10-23 05:30:48 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* Make sure we exit with the right signal at the end. So for instance
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  the  core  will  be  dumped  if  enabled .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sigemptyset  ( & act . sa_mask ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    /* When the SA_SIGINFO flag is set in sa_flags then sa_sigaction
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  is  used .  Otherwise ,  sa_handler  is  used  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    act . sa_flags  =  SA_NODEFER  |  SA_ONSTACK  |  SA_RESETHAND ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    act . sa_handler  =  SIG_DFL ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sigaction  ( sig ,  & act ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    kill ( getpid ( ) , sig ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-07 00:49:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# endif  /* HAVE_BACKTRACE */ 
 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-03-07 00:49:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								static  void  sigtermHandler ( int  sig )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    REDIS_NOTUSED ( sig ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-03-07 00:49:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    redisLog ( REDIS_WARNING , " Received SIGTERM, scheduling shutdown... " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    server . shutdown_asap  =  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-03-07 00:49:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								void  setupSignalHandlers ( void )  { 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    struct  sigaction  act ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-03-07 00:49:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    /* When the SA_SIGINFO flag is set in sa_flags then sa_sigaction is used.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								     *  Otherwise ,  sa_handler  is  used .  */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sigemptyset ( & act . sa_mask ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								    act . sa_flags  =  SA_NODEFER  |  SA_ONSTACK  |  SA_RESETHAND ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    act . sa_handler  =  sigtermHandler ; 
							 
						 
					
						
							
								
									
										
										
										
											2011-03-07 00:49:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								    sigaction ( SIGTERM ,  & act ,  NULL ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2011-03-07 00:49:22 +08:00 
										
									 
								 
							 
							
								
									
										 
									 
								
							 
							
								 
							 
							
							
								# ifdef HAVE_BACKTRACE 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sigemptyset ( & act . sa_mask ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    act . sa_flags  =  SA_NODEFER  |  SA_ONSTACK  |  SA_RESETHAND  |  SA_SIGINFO ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    act . sa_sigaction  =  sigsegvHandler ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sigaction ( SIGSEGV ,  & act ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sigaction ( SIGBUS ,  & act ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sigaction ( SIGFPE ,  & act ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    sigaction ( SIGILL ,  & act ,  NULL ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								# endif 
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								    return ; 
							 
						 
					
						
							
								
									
										
										
										
											2010-06-22 06:07:48 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							 
							
							
								} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							 
							
							
								/* The End */