Commit 90efd492 authored by Vitaly Arbuzov's avatar Vitaly Arbuzov
Browse files

* moved dictGetStats to db.c, removing server.h import from dict.c

* updated comments and formatting
parent 43fbf1e5
...@@ -2229,10 +2229,7 @@ int rewriteAppendOnlyFileRio(rio *aof) { ...@@ -2229,10 +2229,7 @@ int rewriteAppendOnlyFileRio(rio *aof) {
/* Record timestamp at the beginning of rewriting AOF. */ /* Record timestamp at the beginning of rewriting AOF. */
if (server.aof_timestamp_enabled) { if (server.aof_timestamp_enabled) {
sds ts = genAofTimestampAnnotationIfNeeded(1); sds ts = genAofTimestampAnnotationIfNeeded(1);
if (rioWrite(aof, ts, sdslen(ts)) == 0) { if (rioWrite(aof,ts,sdslen(ts)) == 0) { sdsfree(ts); goto werr; }
sdsfree(ts);
goto werr;
}
sdsfree(ts); sdsfree(ts);
} }
......
...@@ -341,16 +341,16 @@ robj *dbRandomKey(redisDb *db) { ...@@ -341,16 +341,16 @@ robj *dbRandomKey(redisDb *db) {
} }
} }
/* Return random non-empty dictionary from this DB, if shouldBeRehashing is set, then it ignores dicts that aren't rehashing. */ /* Return random non-empty dictionary from this DB. */
dict *getRandomDict(redisDb *db) { dict *getRandomDict(redisDb *db) {
if (db->dict_count == 1) return db->dict[0]; if (db->dict_count == 1) return db->dict[0];
int i = 0, r = 0; int i = 0, r = 0;
for (int j = 0; j < CLUSTER_SLOTS; j++) { for (int j = 0; j < CLUSTER_SLOTS; j++) {
// Skip empty dicts or if we want only rehashing dicts and the dict isn't rehashing. /* Skip empty dicts or if we want only rehashing dicts and the dict isn't rehashing. */
if (dictSize(db->dict[j]) == 0) continue; if (dictSize(db->dict[j]) == 0) continue;
if (i == 0 || (rand() % (i + 1)) == 0) { if (i == 0 || (rand() % (i + 1)) == 0) {
r = j; // Select K-th non-empty bucket with 1/K probability, this keeps balanced probabilities for all non-empty buckets. r = j; /* Select K-th non-empty bucket with 1/K probability, this keeps balanced probabilities for all non-empty buckets. */
} }
i++; i++;
} }
...@@ -2527,3 +2527,38 @@ int bitfieldGetKeys(struct redisCommand *cmd, robj **argv, int argc, getKeysResu ...@@ -2527,3 +2527,38 @@ int bitfieldGetKeys(struct redisCommand *cmd, robj **argv, int argc, getKeysResu
} }
return 1; return 1;
} }
void dbGetStats(char *buf, size_t bufsize, redisDb *db) {
size_t l;
char *orig_buf = buf;
size_t orig_bufsize = bufsize;
dictStats *mainHtStats = NULL;
dictStats *rehashHtStats = NULL;
for (int i = 0; i < db->dict_count; i++) {
dictStats *stats = dictGetStatsHt(db->dict[i], 0);
if (!mainHtStats) mainHtStats = stats;
else {
dictCombineStats(stats, mainHtStats);
dictFreeStats(stats);
}
if (dictIsRehashing(db->dict[i])) {
stats = dictGetStatsHt(db->dict[i], 1);
if (!rehashHtStats) rehashHtStats = stats;
else {
dictCombineStats(stats, rehashHtStats);
dictFreeStats(stats);
}
}
}
l = dictGetStatsMsg(buf, bufsize, mainHtStats);
dictFreeStats(mainHtStats);
buf += l;
bufsize -= l;
if (rehashHtStats && bufsize > 0) {
dictGetStatsMsg(buf, bufsize, rehashHtStats);
dictFreeStats(rehashHtStats);
}
/* Make sure there is a NULL term at the end. */
if (orig_bufsize) orig_buf[orig_bufsize - 1] = '\0';
}
...@@ -46,7 +46,7 @@ ...@@ -46,7 +46,7 @@
#include "dict.h" #include "dict.h"
#include "zmalloc.h" #include "zmalloc.h"
#include "redisassert.h" #include "redisassert.h"
#include "server.h" #include "monotonic.h"
/* Using dictEnableResize() / dictDisableResize() we make possible to disable /* Using dictEnableResize() / dictDisableResize() we make possible to disable
* resizing and rehashing of the hash table as needed. This is very important * resizing and rehashing of the hash table as needed. This is very important
...@@ -107,18 +107,6 @@ uint8_t *dictGetHashFunctionSeed(void) { ...@@ -107,18 +107,6 @@ uint8_t *dictGetHashFunctionSeed(void) {
uint64_t siphash(const uint8_t *in, const size_t inlen, const uint8_t *k); uint64_t siphash(const uint8_t *in, const size_t inlen, const uint8_t *k);
uint64_t siphash_nocase(const uint8_t *in, const size_t inlen, const uint8_t *k); uint64_t siphash_nocase(const uint8_t *in, const size_t inlen, const uint8_t *k);
typedef struct dictStats {
int htidx;
unsigned long buckets;
unsigned long maxChainLen;
unsigned long totalChainLen;
unsigned long htSize;
unsigned long htUsed;
unsigned long *clvector;
} dictStats;
size_t _dictGetStatsMsg(char *buf, size_t bufsize, dictStats *stats);
uint64_t dictGenHashFunction(const void *key, size_t len) { uint64_t dictGenHashFunction(const void *key, size_t len) {
return siphash(key,len,dict_hash_function_seed); return siphash(key,len,dict_hash_function_seed);
} }
...@@ -1521,14 +1509,14 @@ dictEntry *dictFindEntryByPtrAndHash(dict *d, const void *oldptr, uint64_t hash) ...@@ -1521,14 +1509,14 @@ dictEntry *dictFindEntryByPtrAndHash(dict *d, const void *oldptr, uint64_t hash)
/* ------------------------------- Debugging ---------------------------------*/ /* ------------------------------- Debugging ---------------------------------*/
#define DICT_STATS_VECTLEN 50 #define DICT_STATS_VECTLEN 50
void _dictFreeStats(dictStats *stats) { void dictFreeStats(dictStats *stats) {
zfree(stats->clvector); zfree(stats->clvector);
zfree(stats); zfree(stats);
} }
void _dictCombineStats(dictStats *from, dictStats *into) { void dictCombineStats(dictStats *from, dictStats *into) {
into->buckets += from->buckets; into->buckets += from->buckets;
into->maxChainLen = max(from->maxChainLen, into->maxChainLen); into->maxChainLen = (from->maxChainLen > into->maxChainLen) ? from->maxChainLen : into->maxChainLen;
into->totalChainLen += from->totalChainLen; into->totalChainLen += from->totalChainLen;
into->htSize += from->htSize; into->htSize += from->htSize;
into->htUsed += from->htUsed; into->htUsed += from->htUsed;
...@@ -1537,7 +1525,7 @@ void _dictCombineStats(dictStats *from, dictStats *into) { ...@@ -1537,7 +1525,7 @@ void _dictCombineStats(dictStats *from, dictStats *into) {
} }
} }
dictStats* _dictGetStatsHt(dict *d, int htidx) { dictStats* dictGetStatsHt(dict *d, int htidx) {
unsigned long *clvector = zcalloc(sizeof(unsigned long) * DICT_STATS_VECTLEN); unsigned long *clvector = zcalloc(sizeof(unsigned long) * DICT_STATS_VECTLEN);
dictStats *stats = zcalloc(sizeof(dictStats)); dictStats *stats = zcalloc(sizeof(dictStats));
stats->htidx = htidx; stats->htidx = htidx;
...@@ -1569,7 +1557,7 @@ dictStats* _dictGetStatsHt(dict *d, int htidx) { ...@@ -1569,7 +1557,7 @@ dictStats* _dictGetStatsHt(dict *d, int htidx) {
} }
size_t _dictGetStatsMsg(char *buf, size_t bufsize, dictStats *stats) {/* Generate human readable stats. */ size_t dictGetStatsMsg(char *buf, size_t bufsize, dictStats *stats) {/* Generate human readable stats. */
if (stats->htUsed == 0) { if (stats->htUsed == 0) {
return snprintf(buf,bufsize, return snprintf(buf,bufsize,
"No stats available for empty dictionaries\n"); "No stats available for empty dictionaries\n");
...@@ -1601,55 +1589,20 @@ size_t _dictGetStatsMsg(char *buf, size_t bufsize, dictStats *stats) {/* Generat ...@@ -1601,55 +1589,20 @@ size_t _dictGetStatsMsg(char *buf, size_t bufsize, dictStats *stats) {/* Generat
return strlen(buf); return strlen(buf);
} }
void dbGetStats(char *buf, size_t bufsize, redisDb *db) {
size_t l;
char *orig_buf = buf;
size_t orig_bufsize = bufsize;
dictStats *mainHtStats = NULL;
dictStats *rehashHtStats = NULL;
for (int i = 0; i < db->dict_count; i++) {
dictStats *stats = _dictGetStatsHt(db->dict[i], 0);
if (!mainHtStats) mainHtStats = stats;
else {
_dictCombineStats(stats, mainHtStats);
_dictFreeStats(stats);
}
if (dictIsRehashing(db->dict[i])) {
stats = _dictGetStatsHt(db->dict[i], 1);
if (!rehashHtStats) rehashHtStats = stats;
else {
_dictCombineStats(stats, rehashHtStats);
_dictFreeStats(stats);
}
}
}
l = _dictGetStatsMsg(buf, bufsize, mainHtStats);
_dictFreeStats(mainHtStats);
buf += l;
bufsize -= l;
if (rehashHtStats && bufsize > 0) {
_dictGetStatsMsg(buf, bufsize, rehashHtStats);
_dictFreeStats(rehashHtStats);
}
/* Make sure there is a NULL term at the end. */
if (orig_bufsize) orig_buf[orig_bufsize - 1] = '\0';
}
void dictGetStats(char *buf, size_t bufsize, dict *d) { void dictGetStats(char *buf, size_t bufsize, dict *d) {
size_t l; size_t l;
char *orig_buf = buf; char *orig_buf = buf;
size_t orig_bufsize = bufsize; size_t orig_bufsize = bufsize;
dictStats *mainHtStats = _dictGetStatsHt(d, 0); dictStats *mainHtStats = dictGetStatsHt(d, 0);
l = _dictGetStatsMsg(buf, bufsize, mainHtStats); l = dictGetStatsMsg(buf, bufsize, mainHtStats);
_dictFreeStats(mainHtStats); dictFreeStats(mainHtStats);
buf += l; buf += l;
bufsize -= l; bufsize -= l;
if (dictIsRehashing(d) && bufsize > 0) { if (dictIsRehashing(d) && bufsize > 0) {
dictStats *rehashHtStats = _dictGetStatsHt(d, 1); dictStats *rehashHtStats = dictGetStatsHt(d, 1);
_dictGetStatsMsg(buf, bufsize, rehashHtStats); dictGetStatsMsg(buf, bufsize, rehashHtStats);
_dictFreeStats(rehashHtStats); dictFreeStats(rehashHtStats);
} }
/* Make sure there is a NULL term at the end. */ /* Make sure there is a NULL term at the end. */
if (orig_bufsize) orig_buf[orig_bufsize-1] = '\0'; if (orig_bufsize) orig_buf[orig_bufsize-1] = '\0';
......
...@@ -113,6 +113,16 @@ typedef struct dictIterator { ...@@ -113,6 +113,16 @@ typedef struct dictIterator {
unsigned long long fingerprint; unsigned long long fingerprint;
} dictIterator; } dictIterator;
typedef struct dictStats {
int htidx;
unsigned long buckets;
unsigned long maxChainLen;
unsigned long totalChainLen;
unsigned long htSize;
unsigned long htUsed;
unsigned long *clvector;
} dictStats;
typedef void (dictScanFunction)(void *privdata, const dictEntry *de); typedef void (dictScanFunction)(void *privdata, const dictEntry *de);
typedef void *(dictDefragAllocFunction)(void *ptr); typedef void *(dictDefragAllocFunction)(void *ptr);
typedef struct { typedef struct {
...@@ -223,6 +233,11 @@ uint64_t dictGetHash(dict *d, const void *key); ...@@ -223,6 +233,11 @@ uint64_t dictGetHash(dict *d, const void *key);
dictEntry *dictFindEntryByPtrAndHash(dict *d, const void *oldptr, uint64_t hash); dictEntry *dictFindEntryByPtrAndHash(dict *d, const void *oldptr, uint64_t hash);
unsigned long rev(unsigned long v); unsigned long rev(unsigned long v);
size_t dictGetStatsMsg(char *buf, size_t bufsize, dictStats *stats);
dictStats* dictGetStatsHt(dict *d, int htidx);
void dictCombineStats(dictStats *from, dictStats *into);
void dictFreeStats(dictStats *stats);
#ifdef REDIS_TEST #ifdef REDIS_TEST
int dictTest(int argc, char *argv[], int flags); int dictTest(int argc, char *argv[], int flags);
#endif #endif
......
...@@ -2,7 +2,6 @@ ...@@ -2,7 +2,6 @@
#include "bio.h" #include "bio.h"
#include "atomicvar.h" #include "atomicvar.h"
#include "functions.h" #include "functions.h"
#include "cluster.h"
static redisAtomic size_t lazyfree_objects = 0; static redisAtomic size_t lazyfree_objects = 0;
static redisAtomic size_t lazyfreed_objects = 0; static redisAtomic size_t lazyfreed_objects = 0;
......
...@@ -3095,7 +3095,7 @@ sds keyspaceEventsFlagsToString(int flags); ...@@ -3095,7 +3095,7 @@ sds keyspaceEventsFlagsToString(int flags);
#define MEMORY_CONFIG (1<<0) /* Indicates if this value can be loaded as a memory value */ #define MEMORY_CONFIG (1<<0) /* Indicates if this value can be loaded as a memory value */
#define PERCENT_CONFIG (1<<1) /* Indicates if this value can be loaded as a percent (and stored as a negative int) */ #define PERCENT_CONFIG (1<<1) /* Indicates if this value can be loaded as a percent (and stored as a negative int) */
#define OCTAL_CONFIG (1<<2) /* This value uses octal representation */ #define OCTAL_CONFIG (1<<2) /* This value uses octal representation */
#define SLOT_MASK_SHIFT 48 #define SLOT_MASK_SHIFT 48 /* Slot id is stored in high bits of the Scan API cursor, this number defines by how many bits it's shifted. */
/* Enum Configs contain an array of configEnum objects that match a string with an integer. */ /* Enum Configs contain an array of configEnum objects that match a string with an integer. */
typedef struct configEnum { typedef struct configEnum {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment