|
1 | 1 | #include "server.h" |
2 | 2 | #include "bio.h" |
3 | 3 | #include "atomicvar.h" |
| 4 | +#include "cluster.h" |
4 | 5 |
|
5 | 6 | static size_t lazyfree_objects = 0; |
6 | 7 | pthread_mutex_t lazyfree_objects_mutex = PTHREAD_MUTEX_INITIALIZER; |
@@ -75,9 +76,51 @@ int dbAsyncDelete(redisDb *db, robj *key) { |
75 | 76 | } |
76 | 77 | } |
77 | 78 |
|
78 | | -/* Implementation of function to release a single object called from the |
79 | | - * lazyfree thread from bio.c. */ |
| 79 | +/* Empty a Redis DB asynchronously. What the function does actually is to |
| 80 | + * create a new empty set of hash tables and scheduling the old ones for |
| 81 | + * lazy freeing. */ |
| 82 | +void emptyDbAsync(redisDb *db) { |
| 83 | + dict *oldht1 = db->dict, *oldht2 = db->expires; |
| 84 | + db->dict = dictCreate(&dbDictType,NULL); |
| 85 | + db->expires = dictCreate(&keyptrDictType,NULL); |
| 86 | + atomicIncr(lazyfree_objects,dictSize(oldht1), |
| 87 | + &lazyfree_objects_mutex); |
| 88 | + bioCreateBackgroundJob(BIO_LAZY_FREE,NULL,oldht1,oldht2); |
| 89 | +} |
| 90 | + |
| 91 | +/* Empty the slots-keys map of Redis CLuster by creating a new empty one |
| 92 | + * and scheduiling the old for lazy freeing. */ |
| 93 | +void slotToKeyFlushAsync(void) { |
| 94 | + zskiplist *oldsl = server.cluster->slots_to_keys; |
| 95 | + server.cluster->slots_to_keys = zslCreate(); |
| 96 | + atomicIncr(lazyfree_objects,oldsl->length, |
| 97 | + &lazyfree_objects_mutex); |
| 98 | + bioCreateBackgroundJob(BIO_LAZY_FREE,NULL,NULL,oldsl); |
| 99 | +} |
| 100 | + |
| 101 | +/* Release objects from the lazyfree thread. It's just decrRefCount() |
| 102 | + * updating the count of objects to release. */ |
80 | 103 | void lazyfreeFreeObjectFromBioThread(robj *o) { |
81 | 104 | decrRefCount(o); |
82 | 105 | atomicDecr(lazyfree_objects,1,&lazyfree_objects_mutex); |
83 | 106 | } |
| 107 | + |
| 108 | +/* Release a database from the lazyfree thread. The 'db' pointer is the |
| 109 | + * database which was substitutied with a fresh one in the main thread |
| 110 | + * when the database was logically deleted. 'sl' is a skiplist used by |
| 111 | + * Redis Cluster in order to take the hash slots -> keys mapping. This |
| 112 | + * may be NULL if Redis Cluster is disabled. */ |
| 113 | +void lazyfreeFreeDatabaseFromBioThread(dict *ht1, dict *ht2) { |
| 114 | + size_t numkeys = dictSize(ht1); |
| 115 | + dictRelease(ht1); |
| 116 | + dictRelease(ht2); |
| 117 | + atomicDecr(lazyfree_objects,numkeys,&lazyfree_objects_mutex); |
| 118 | +} |
| 119 | + |
| 120 | +/* Release the skiplist mapping Redis Cluster keys to slots in the |
| 121 | + * lazyfree thread. */ |
| 122 | +void lazyfreeFreeSlotsMapFromBioThread(zskiplist *sl) { |
| 123 | + size_t len = sl->length; |
| 124 | + zslFree(sl); |
| 125 | + atomicDecr(lazyfree_objects,len,&lazyfree_objects_mutex); |
| 126 | +} |
0 commit comments