forked from pikiwidb/rediscache
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
52 changed files
with
30,877 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
/* adlist.h - A generic doubly linked list implementation | ||
* | ||
* Copyright (c) 2006-2012, 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. | ||
*/ | ||
|
||
#ifndef __ADLIST_H__ | ||
#define __ADLIST_H__ | ||
|
||
/* Node, List, and Iterator are the only data structures used currently. */ | ||
|
||
typedef struct listNode { | ||
struct listNode *prev; | ||
struct listNode *next; | ||
void *value; | ||
} listNode; | ||
|
||
typedef struct listIter { | ||
listNode *next; | ||
int direction; | ||
} listIter; | ||
|
||
typedef struct list { | ||
listNode *head; | ||
listNode *tail; | ||
void *(*dup)(void *ptr); | ||
void (*free)(void *ptr); | ||
int (*match)(void *ptr, void *key); | ||
unsigned long len; | ||
} list; | ||
|
||
/* Functions implemented as macros */ | ||
#define listLength(l) ((l)->len) | ||
#define listFirst(l) ((l)->head) | ||
#define listLast(l) ((l)->tail) | ||
#define listPrevNode(n) ((n)->prev) | ||
#define listNextNode(n) ((n)->next) | ||
#define listNodeValue(n) ((n)->value) | ||
|
||
#define listSetDupMethod(l,m) ((l)->dup = (m)) | ||
#define listSetFreeMethod(l,m) ((l)->free = (m)) | ||
#define listSetMatchMethod(l,m) ((l)->match = (m)) | ||
|
||
#define listGetDupMethod(l) ((l)->dup) | ||
#define listGetFreeMethod(l) ((l)->free) | ||
#define listGetMatchMethod(l) ((l)->match) | ||
|
||
/* Prototypes */ | ||
list *listCreate(void); | ||
void listRelease(list *list); | ||
void listEmpty(list *list); | ||
list *listAddNodeHead(list *list, void *value); | ||
list *listAddNodeTail(list *list, void *value); | ||
list *listInsertNode(list *list, listNode *old_node, void *value, int after); | ||
void listDelNode(list *list, listNode *node); | ||
listIter *listGetIterator(list *list, int direction); | ||
listNode *listNext(listIter *iter); | ||
void listReleaseIterator(listIter *iter); | ||
list *listDup(list *orig); | ||
listNode *listSearchKey(list *list, void *key); | ||
listNode *listIndex(list *list, long index); | ||
void listRewind(list *list, listIter *li); | ||
void listRewindTail(list *list, listIter *li); | ||
void listRotateTailToHead(list *list); | ||
void listRotateHeadToTail(list *list); | ||
void listJoin(list *l, list *o); | ||
void listInitNode(listNode *node, void *value); | ||
void listLinkNodeHead(list *list, listNode *node); | ||
void listLinkNodeTail(list *list, listNode *node); | ||
void listUnlinkNode(list *list, listNode *node); | ||
|
||
/* Directions for iterators */ | ||
#define AL_START_HEAD 0 | ||
#define AL_START_TAIL 1 | ||
|
||
#endif /* __ADLIST_H__ */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
/* This file implements atomic counters using __atomic or __sync macros if | ||
* available, otherwise synchronizing different threads using a mutex. | ||
* | ||
* The exported interaface is composed of three macros: | ||
* | ||
* atomicIncr(var,count) -- Increment the atomic counter | ||
* atomicGetIncr(var,oldvalue_var,count) -- Get and increment the atomic counter | ||
* atomicDecr(var,count) -- Decrement the atomic counter | ||
* atomicGet(var,dstvar) -- Fetch the atomic counter value | ||
* atomicSet(var,value) -- Set the atomic counter value | ||
* | ||
* The variable 'var' should also have a declared mutex with the same | ||
* name and the "_mutex" postfix, for instance: | ||
* | ||
* long myvar; | ||
* pthread_mutex_t myvar_mutex; | ||
* atomicSet(myvar,12345); | ||
* | ||
* If atomic primitives are availble (tested in config.h) the mutex | ||
* is not used. | ||
* | ||
* Never use return value from the macros, instead use the AtomicGetIncr() | ||
* if you need to get the current value and increment it atomically, like | ||
* in the followign example: | ||
* | ||
* long oldvalue; | ||
* atomicGetIncr(myvar,oldvalue,1); | ||
* doSomethingWith(oldvalue); | ||
* | ||
* ---------------------------------------------------------------------------- | ||
* | ||
* Copyright (c) 2015, 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 <pthread.h> | ||
|
||
#ifndef __ATOMIC_VAR_H | ||
#define __ATOMIC_VAR_H | ||
|
||
/* To test Redis with Helgrind (a Valgrind tool) it is useful to define | ||
* the following macro, so that __sync macros are used: those can be detected | ||
* by Helgrind (even if they are less efficient) so that no false positive | ||
* is reported. */ | ||
// #define __ATOMIC_VAR_FORCE_SYNC_MACROS | ||
|
||
#if !defined(__ATOMIC_VAR_FORCE_SYNC_MACROS) && defined(__ATOMIC_RELAXED) && !defined(__sun) && (!defined(__clang__) || !defined(__APPLE__) || __apple_build_version__ > 4210057) | ||
/* Implementation using __atomic macros. */ | ||
|
||
#define atomicIncr(var,count) __atomic_add_fetch(&var,(count),__ATOMIC_RELAXED) | ||
#define atomicGetIncr(var,oldvalue_var,count) do { \ | ||
oldvalue_var = __atomic_fetch_add(&var,(count),__ATOMIC_RELAXED); \ | ||
} while(0) | ||
#define atomicDecr(var,count) __atomic_sub_fetch(&var,(count),__ATOMIC_RELAXED) | ||
#define atomicGet(var,dstvar) do { \ | ||
dstvar = __atomic_load_n(&var,__ATOMIC_RELAXED); \ | ||
} while(0) | ||
#define atomicSet(var,value) __atomic_store_n(&var,value,__ATOMIC_RELAXED) | ||
#define REDIS_ATOMIC_API "atomic-builtin" | ||
|
||
#elif defined(HAVE_ATOMIC) | ||
/* Implementation using __sync macros. */ | ||
|
||
#define atomicIncr(var,count) __sync_add_and_fetch(&var,(count)) | ||
#define atomicGetIncr(var,oldvalue_var,count) do { \ | ||
oldvalue_var = __sync_fetch_and_add(&var,(count)); \ | ||
} while(0) | ||
#define atomicDecr(var,count) __sync_sub_and_fetch(&var,(count)) | ||
#define atomicGet(var,dstvar) do { \ | ||
dstvar = __sync_sub_and_fetch(&var,0); \ | ||
} while(0) | ||
#define atomicSet(var,value) do { \ | ||
while(!__sync_bool_compare_and_swap(&var,var,value)); \ | ||
} while(0) | ||
#define REDIS_ATOMIC_API "sync-builtin" | ||
|
||
#else | ||
/* Implementation using pthread mutex. */ | ||
|
||
#define atomicIncr(var,count) do { \ | ||
pthread_mutex_lock(&var ## _mutex); \ | ||
var += (count); \ | ||
pthread_mutex_unlock(&var ## _mutex); \ | ||
} while(0) | ||
#define atomicGetIncr(var,oldvalue_var,count) do { \ | ||
pthread_mutex_lock(&var ## _mutex); \ | ||
oldvalue_var = var; \ | ||
var += (count); \ | ||
pthread_mutex_unlock(&var ## _mutex); \ | ||
} while(0) | ||
#define atomicDecr(var,count) do { \ | ||
pthread_mutex_lock(&var ## _mutex); \ | ||
var -= (count); \ | ||
pthread_mutex_unlock(&var ## _mutex); \ | ||
} while(0) | ||
#define atomicGet(var,dstvar) do { \ | ||
pthread_mutex_lock(&var ## _mutex); \ | ||
dstvar = var; \ | ||
pthread_mutex_unlock(&var ## _mutex); \ | ||
} while(0) | ||
#define atomicSet(var,value) do { \ | ||
pthread_mutex_lock(&var ## _mutex); \ | ||
var = value; \ | ||
pthread_mutex_unlock(&var ## _mutex); \ | ||
} while(0) | ||
#define REDIS_ATOMIC_API "pthread-mutex" | ||
|
||
#endif | ||
#endif /* __ATOMIC_VAR_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,144 @@ | ||
#ifndef __COMMON_DEF_H__ | ||
#define __COMMON_DEF_H__ | ||
|
||
#include <stdlib.h> | ||
|
||
typedef long long mstime_t; /* millisecond time type. */ | ||
|
||
/* Error codes */ | ||
#define C_OK 0 | ||
#define C_ERR -1 | ||
#define REDIS_INVALID_ARG -2 | ||
#define REDIS_KEY_NOT_EXIST -3 | ||
#define REDIS_INVALID_TYPE -4 | ||
#define REDIS_OVERFLOW -5 | ||
#define REDIS_ITEM_NOT_EXIST -6 | ||
#define REDIS_NO_KEYS -7 | ||
|
||
/* The actual Redis Object */ | ||
#define OBJ_STRING 0 | ||
#define OBJ_LIST 1 | ||
#define OBJ_SET 2 | ||
#define OBJ_ZSET 3 | ||
#define OBJ_HASH 4 | ||
|
||
/* Objects encoding. Some kind of objects like Strings and Hashes can be | ||
* internally represented in multiple ways. The 'encoding' field of the object | ||
* is set to one of this fields for this object. */ | ||
#define OBJ_ENCODING_RAW 0 /* Raw representation */ | ||
#define OBJ_ENCODING_INT 1 /* Encoded as integer */ | ||
#define OBJ_ENCODING_HT 2 /* Encoded as hash table */ | ||
#define OBJ_ENCODING_ZIPMAP 3 /* Encoded as zipmap */ | ||
#define OBJ_ENCODING_LINKEDLIST 4 /* No longer used: old list encoding. */ | ||
#define OBJ_ENCODING_ZIPLIST 5 /* Encoded as ziplist */ | ||
#define OBJ_ENCODING_INTSET 6 /* Encoded as intset */ | ||
#define OBJ_ENCODING_SKIPLIST 7 /* Encoded as skiplist */ | ||
#define OBJ_ENCODING_EMBSTR 8 /* Embedded sds string encoding */ | ||
#define OBJ_ENCODING_QUICKLIST 9 /* Encoded as linked list of ziplists */ | ||
|
||
/* Redis maxmemory strategies. Instead of using just incremental number | ||
* for this defines, we use a set of flags so that testing for certain | ||
* properties common to multiple policies is faster. */ | ||
#define MAXMEMORY_FLAG_LRU (1<<0) | ||
#define MAXMEMORY_FLAG_LFU (1<<1) | ||
#define MAXMEMORY_FLAG_ALLKEYS (1<<2) | ||
#define MAXMEMORY_FLAG_NO_SHARED_INTEGERS (MAXMEMORY_FLAG_LRU|MAXMEMORY_FLAG_LFU) | ||
|
||
#define MAXMEMORY_VOLATILE_LRU ((0<<8)|MAXMEMORY_FLAG_LRU) | ||
#define MAXMEMORY_VOLATILE_LFU ((1<<8)|MAXMEMORY_FLAG_LFU) | ||
#define MAXMEMORY_VOLATILE_TTL (2<<8) | ||
#define MAXMEMORY_VOLATILE_RANDOM (3<<8) | ||
#define MAXMEMORY_ALLKEYS_LRU ((4<<8)|MAXMEMORY_FLAG_LRU|MAXMEMORY_FLAG_ALLKEYS) | ||
#define MAXMEMORY_ALLKEYS_LFU ((5<<8)|MAXMEMORY_FLAG_LFU|MAXMEMORY_FLAG_ALLKEYS) | ||
#define MAXMEMORY_ALLKEYS_RANDOM ((6<<8)|MAXMEMORY_FLAG_ALLKEYS) | ||
#define MAXMEMORY_NO_EVICTION (7<<8) | ||
|
||
/* LRU */ | ||
#define LRU_BITS 24 | ||
#define LRU_CLOCK_MAX ((1<<LRU_BITS)-1) /* Max value of obj->lru */ | ||
#define LRU_CLOCK_RESOLUTION 1000 /* LRU clock resolution in ms */ | ||
|
||
#define ACTIVE_EXPIRE_CYCLE_LOOKUPS_PER_LOOP 16 /* Loopkups per loop. */ | ||
#define ACTIVE_EXPIRE_CYCLE_FAST_DURATION 1000 /* Microseconds */ | ||
#define ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC 25 /* CPU max % for keys collection */ | ||
#define ACTIVE_EXPIRE_CYCLE_SLOW 0 | ||
#define ACTIVE_EXPIRE_CYCLE_FAST 1 | ||
|
||
#define OBJ_SHARED_REFCOUNT INT_MAX | ||
#define LONG_STR_SIZE 21 /* Bytes needed for long -> str + '\0' */ | ||
#define OBJ_SHARED_INTEGERS 10000 | ||
|
||
/* Units */ | ||
#define UNIT_SECONDS 0 | ||
#define UNIT_MILLISECONDS 1 | ||
|
||
/* Static server configuration */ | ||
#define CONFIG_DEFAULT_MAXMEMORY (10 * 1024 * 1024 * 1024LL) // 10G | ||
#define CONFIG_DEFAULT_MAXMEMORY_POLICY MAXMEMORY_ALLKEYS_LRU | ||
#define CONFIG_DEFAULT_MAXMEMORY_SAMPLES 5 | ||
#define CONFIG_DEFAULT_LFU_LOG_FACTOR 10 | ||
#define CONFIG_DEFAULT_LFU_DECAY_TIME 1 | ||
|
||
/* Zip structure related defaults */ | ||
#define OBJ_HASH_MAX_ZIPLIST_ENTRIES 512 | ||
#define OBJ_HASH_MAX_ZIPLIST_VALUE 64 | ||
#define OBJ_SET_MAX_INTSET_ENTRIES 512 | ||
#define OBJ_ZSET_MAX_ZIPLIST_ENTRIES 0 | ||
#define OBJ_ZSET_MAX_ZIPLIST_VALUE 0 | ||
|
||
/* Hash structure related defaults */ | ||
#define OBJ_HASH_KEY 1 | ||
#define OBJ_HASH_VALUE 2 | ||
|
||
/* Hash table parameters */ | ||
#define HASHTABLE_MIN_FILL 10 /* Minimal hash table fill 10% */ | ||
|
||
/* List defaults */ | ||
#define OBJ_LIST_MAX_ZIPLIST_SIZE -2 | ||
#define OBJ_LIST_COMPRESS_DEPTH 0 | ||
|
||
/* List related stuff */ | ||
#define REDIS_LIST_HEAD 0 | ||
#define REDIS_LIST_TAIL 1 | ||
|
||
/* Sorted sets data type */ | ||
|
||
/* Input flags. */ | ||
#define ZADD_NONE 0 | ||
#define ZADD_INCR (1<<0) /* Increment the score instead of setting it. */ | ||
#define ZADD_NX (1<<1) /* Don't touch elements not already existing. */ | ||
#define ZADD_XX (1<<2) /* Only touch elements already exisitng. */ | ||
|
||
/* Output flags. */ | ||
#define ZADD_NOP (1<<3) /* Operation not performed because of conditionals.*/ | ||
#define ZADD_NAN (1<<4) /* Only touch elements already exisitng. */ | ||
#define ZADD_ADDED (1<<5) /* The element was new and was added. */ | ||
#define ZADD_UPDATED (1<<6) /* The element already existed, score updated. */ | ||
|
||
/* Flags only used by the ZADD command but not by zsetAdd() API: */ | ||
#define ZADD_CH (1<<16) /* Return num of elements added or updated. */ | ||
|
||
/* Bit pos offset */ | ||
#define BIT_POS_NO_OFFSET 0 | ||
#define BIT_POS_START_OFFSET 1 | ||
#define BIT_POS_START_END_OFFSET 2 | ||
|
||
|
||
// redisdb config | ||
typedef struct _db_config { | ||
unsigned long long maxmemory; /* Can used max memory */ | ||
int maxmemory_policy; /* Policy for key eviction */ | ||
int maxmemory_samples; /* Pricision of random sampling */ | ||
int lfu_decay_time; /* LFU counter decay factor. */ | ||
} db_config; | ||
|
||
// redisdb status | ||
typedef struct _db_status { | ||
long long stat_evictedkeys; /* Number of evicted keys (maxmemory) */ | ||
long long stat_expiredkeys; /* Number of expired keys */ | ||
long long stat_keyspace_hits; /* Number of successful lookups of keys */ | ||
long long stat_keyspace_misses; /* Number of failed lookups of keys */ | ||
size_t stat_peak_memory; /* Max used memory record */ | ||
} db_status; | ||
|
||
#endif |
Oops, something went wrong.