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) {
/* Record timestamp at the beginning of rewriting AOF. */
if (server.aof_timestamp_enabled) {
sds ts = genAofTimestampAnnotationIfNeeded(1);
if (rioWrite(aof, ts, sdslen(ts)) == 0) {
sdsfree(ts);
goto werr;
}
if (rioWrite(aof,ts,sdslen(ts)) == 0) { sdsfree(ts); goto werr; }
sdsfree(ts);
}
......
......@@ -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) {
if (db->dict_count == 1) return db->dict[0];
int i = 0, r = 0;
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 (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++;
}
......@@ -2527,3 +2527,38 @@ int bitfieldGetKeys(struct redisCommand *cmd, robj **argv, int argc, getKeysResu
}
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 @@
#include "dict.h"
#include "zmalloc.h"
#include "redisassert.h"
#include "server.h"
#include "monotonic.h"
/* Using dictEnableResize() / dictDisableResize() we make possible to disable
* resizing and rehashing of the hash table as needed. This is very important
......@@ -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_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) {
return siphash(key,len,dict_hash_function_seed);
}
......@@ -1521,14 +1509,14 @@ dictEntry *dictFindEntryByPtrAndHash(dict *d, const void *oldptr, uint64_t hash)
/* ------------------------------- Debugging ---------------------------------*/
#define DICT_STATS_VECTLEN 50
void _dictFreeStats(dictStats *stats) {
void dictFreeStats(dictStats *stats) {
zfree(stats->clvector);
zfree(stats);
}
void _dictCombineStats(dictStats *from, dictStats *into) {
void dictCombineStats(dictStats *from, dictStats *into) {
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->htSize += from->htSize;
into->htUsed += from->htUsed;
......@@ -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);
dictStats *stats = zcalloc(sizeof(dictStats));
stats->htidx = 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) {
return snprintf(buf,bufsize,
"No stats available for empty dictionaries\n");
......@@ -1601,55 +1589,20 @@ size_t _dictGetStatsMsg(char *buf, size_t bufsize, dictStats *stats) {/* Generat
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) {
size_t l;
char *orig_buf = buf;
size_t orig_bufsize = bufsize;
dictStats *mainHtStats = _dictGetStatsHt(d, 0);
l = _dictGetStatsMsg(buf, bufsize, mainHtStats);
_dictFreeStats(mainHtStats);
dictStats *mainHtStats = dictGetStatsHt(d, 0);
l = dictGetStatsMsg(buf, bufsize, mainHtStats);
dictFreeStats(mainHtStats);
buf += l;
bufsize -= l;
if (dictIsRehashing(d) && bufsize > 0) {
dictStats *rehashHtStats = _dictGetStatsHt(d, 1);
_dictGetStatsMsg(buf, bufsize, rehashHtStats);
_dictFreeStats(rehashHtStats);
dictStats *rehashHtStats = dictGetStatsHt(d, 1);
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';
......
......@@ -113,6 +113,16 @@ typedef struct dictIterator {
unsigned long long fingerprint;
} 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 *(dictDefragAllocFunction)(void *ptr);
typedef struct {
......@@ -223,6 +233,11 @@ uint64_t dictGetHash(dict *d, const void *key);
dictEntry *dictFindEntryByPtrAndHash(dict *d, const void *oldptr, uint64_t hash);
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
int dictTest(int argc, char *argv[], int flags);
#endif
......
......@@ -2,7 +2,6 @@
#include "bio.h"
#include "atomicvar.h"
#include "functions.h"
#include "cluster.h"
static redisAtomic size_t lazyfree_objects = 0;
static redisAtomic size_t lazyfreed_objects = 0;
......
......@@ -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 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 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. */
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