mirror of https://mirror.osredm.com/root/redis.git
activeDefragSdsDict use scan instead of iterator and drop dictSetNext
Also delete unused function activeDefragSdsListAndDict
This commit is contained in:
parent
a67957ed98
commit
d4e9e0aebd
156
src/defrag.c
156
src/defrag.c
|
@ -149,35 +149,6 @@ luaScript *activeDefragLuaScript(luaScript *script, long *defragged) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Defrag helper for dictEntries to be used during dict iteration (called on
|
|
||||||
* each step). Returns a stat of how many pointers were moved. */
|
|
||||||
long dictIterDefragEntry(dictIterator *iter) {
|
|
||||||
/* This function is a little bit dirty since it messes with the internals
|
|
||||||
* of the dict and it's iterator, but the benefit is that it is very easy
|
|
||||||
* to use, and require no other changes in the dict. */
|
|
||||||
long defragged = 0;
|
|
||||||
/* Handle the next entry (if there is one), and update the pointer in the
|
|
||||||
* current entry. */
|
|
||||||
if (iter->nextEntry) {
|
|
||||||
dictEntry *newde = activeDefragAlloc(iter->nextEntry);
|
|
||||||
if (newde) {
|
|
||||||
defragged++;
|
|
||||||
iter->nextEntry = newde;
|
|
||||||
dictSetNext(iter->entry, newde);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* handle the case of the first entry in the hash bucket. */
|
|
||||||
if (iter->d->ht_table[iter->table][iter->index] == iter->entry) {
|
|
||||||
dictEntry *newde = activeDefragAlloc(iter->entry);
|
|
||||||
if (newde) {
|
|
||||||
iter->entry = newde;
|
|
||||||
iter->d->ht_table[iter->table][iter->index] = newde;
|
|
||||||
defragged++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return defragged;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Defrag helper for dict main allocations (dict struct, and hash tables).
|
/* Defrag helper for dict main allocations (dict struct, and hash tables).
|
||||||
* receives a pointer to the dict* and implicitly updates it when the dict
|
* receives a pointer to the dict* and implicitly updates it when the dict
|
||||||
* struct itself was moved. Returns a stat of how many pointers were moved. */
|
* struct itself was moved. Returns a stat of how many pointers were moved. */
|
||||||
|
@ -279,38 +250,49 @@ long activeDefragZsetEntry(zset *zs, dictEntry *de) {
|
||||||
#define DEFRAG_SDS_DICT_VAL_VOID_PTR 3
|
#define DEFRAG_SDS_DICT_VAL_VOID_PTR 3
|
||||||
#define DEFRAG_SDS_DICT_VAL_LUA_SCRIPT 4
|
#define DEFRAG_SDS_DICT_VAL_LUA_SCRIPT 4
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
dict *dict;
|
||||||
|
int val_type;
|
||||||
|
long defragged;
|
||||||
|
} activeDefragSdsDictData;
|
||||||
|
|
||||||
|
void activeDefragSdsDictCallback(void *privdata, const dictEntry *_de) {
|
||||||
|
dictEntry *de = (dictEntry*)_de;
|
||||||
|
activeDefragSdsDictData *data = privdata;
|
||||||
|
dict *d = data->dict;
|
||||||
|
int val_type = data->val_type;
|
||||||
|
sds sdsele = dictGetKey(de), newsds;
|
||||||
|
if ((newsds = activeDefragSds(sdsele)))
|
||||||
|
dictSetKey(d, de, newsds), data->defragged++;
|
||||||
|
/* defrag the value */
|
||||||
|
if (val_type == DEFRAG_SDS_DICT_VAL_IS_SDS) {
|
||||||
|
sdsele = dictGetVal(de);
|
||||||
|
if ((newsds = activeDefragSds(sdsele)))
|
||||||
|
dictSetVal(d, de, newsds), data->defragged++;
|
||||||
|
} else if (val_type == DEFRAG_SDS_DICT_VAL_IS_STROB) {
|
||||||
|
robj *newele, *ele = dictGetVal(de);
|
||||||
|
if ((newele = activeDefragStringOb(ele, &data->defragged)))
|
||||||
|
dictSetVal(d, de, newele);
|
||||||
|
} else if (val_type == DEFRAG_SDS_DICT_VAL_VOID_PTR) {
|
||||||
|
void *newptr, *ptr = dictGetVal(de);
|
||||||
|
if ((newptr = activeDefragAlloc(ptr)))
|
||||||
|
dictSetVal(d, de, newptr), data->defragged++;
|
||||||
|
} else if (val_type == DEFRAG_SDS_DICT_VAL_LUA_SCRIPT) {
|
||||||
|
void *newptr, *ptr = dictGetVal(de);
|
||||||
|
if ((newptr = activeDefragLuaScript(ptr, &data->defragged)))
|
||||||
|
dictSetVal(d, de, newptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Defrag a dict with sds key and optional value (either ptr, sds or robj string) */
|
/* Defrag a dict with sds key and optional value (either ptr, sds or robj string) */
|
||||||
long activeDefragSdsDict(dict* d, int val_type) {
|
long activeDefragSdsDict(dict* d, int val_type) {
|
||||||
dictIterator *di;
|
activeDefragSdsDictData data = {d, val_type, 0};
|
||||||
dictEntry *de;
|
unsigned long cursor = 0;
|
||||||
long defragged = 0;
|
do {
|
||||||
di = dictGetIterator(d);
|
cursor = dictScan(d, cursor, activeDefragSdsDictCallback,
|
||||||
while((de = dictNext(di)) != NULL) {
|
defragDictBucketCallback, &data);
|
||||||
sds sdsele = dictGetKey(de), newsds;
|
} while (cursor != 0);
|
||||||
if ((newsds = activeDefragSds(sdsele)))
|
return data.defragged;
|
||||||
dictSetKey(d, de, newsds), defragged++;
|
|
||||||
/* defrag the value */
|
|
||||||
if (val_type == DEFRAG_SDS_DICT_VAL_IS_SDS) {
|
|
||||||
sdsele = dictGetVal(de);
|
|
||||||
if ((newsds = activeDefragSds(sdsele)))
|
|
||||||
dictSetVal(d, de, newsds), defragged++;
|
|
||||||
} else if (val_type == DEFRAG_SDS_DICT_VAL_IS_STROB) {
|
|
||||||
robj *newele, *ele = dictGetVal(de);
|
|
||||||
if ((newele = activeDefragStringOb(ele, &defragged)))
|
|
||||||
dictSetVal(d, de, newele);
|
|
||||||
} else if (val_type == DEFRAG_SDS_DICT_VAL_VOID_PTR) {
|
|
||||||
void *newptr, *ptr = dictGetVal(de);
|
|
||||||
if ((newptr = activeDefragAlloc(ptr)))
|
|
||||||
dictSetVal(d, de, newptr), defragged++;
|
|
||||||
} else if (val_type == DEFRAG_SDS_DICT_VAL_LUA_SCRIPT) {
|
|
||||||
void *newptr, *ptr = dictGetVal(de);
|
|
||||||
if ((newptr = activeDefragLuaScript(ptr, &defragged)))
|
|
||||||
dictSetVal(d, de, newptr);
|
|
||||||
}
|
|
||||||
defragged += dictIterDefragEntry(di);
|
|
||||||
}
|
|
||||||
dictReleaseIterator(di);
|
|
||||||
return defragged;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Defrag a list of ptr, sds or robj string values */
|
/* Defrag a list of ptr, sds or robj string values */
|
||||||
|
@ -347,62 +329,6 @@ long activeDefragList(list *l, int val_type) {
|
||||||
return defragged;
|
return defragged;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Defrag a list of sds values and a dict with the same sds keys */
|
|
||||||
long activeDefragSdsListAndDict(list *l, dict *d, int dict_val_type) {
|
|
||||||
long defragged = 0;
|
|
||||||
sds newsds, sdsele;
|
|
||||||
listNode *ln, *newln;
|
|
||||||
dictIterator *di;
|
|
||||||
dictEntry *de;
|
|
||||||
/* Defrag the list and it's sds values */
|
|
||||||
for (ln = l->head; ln; ln = ln->next) {
|
|
||||||
if ((newln = activeDefragAlloc(ln))) {
|
|
||||||
if (newln->prev)
|
|
||||||
newln->prev->next = newln;
|
|
||||||
else
|
|
||||||
l->head = newln;
|
|
||||||
if (newln->next)
|
|
||||||
newln->next->prev = newln;
|
|
||||||
else
|
|
||||||
l->tail = newln;
|
|
||||||
ln = newln;
|
|
||||||
defragged++;
|
|
||||||
}
|
|
||||||
sdsele = ln->value;
|
|
||||||
if ((newsds = activeDefragSds(sdsele))) {
|
|
||||||
/* When defragging an sds value, we need to update the dict key */
|
|
||||||
uint64_t hash = dictGetHash(d, newsds);
|
|
||||||
dictEntry **deref = dictFindEntryRefByPtrAndHash(d, sdsele, hash);
|
|
||||||
if (deref)
|
|
||||||
dictSetKey(d, *deref, newsds);
|
|
||||||
ln->value = newsds;
|
|
||||||
defragged++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Defrag the dict values (keys were already handled) */
|
|
||||||
di = dictGetIterator(d);
|
|
||||||
while((de = dictNext(di)) != NULL) {
|
|
||||||
if (dict_val_type == DEFRAG_SDS_DICT_VAL_IS_SDS) {
|
|
||||||
sds newsds, sdsele = dictGetVal(de);
|
|
||||||
if ((newsds = activeDefragSds(sdsele)))
|
|
||||||
dictSetVal(d, de, newsds), defragged++;
|
|
||||||
} else if (dict_val_type == DEFRAG_SDS_DICT_VAL_IS_STROB) {
|
|
||||||
robj *newele, *ele = dictGetVal(de);
|
|
||||||
if ((newele = activeDefragStringOb(ele, &defragged)))
|
|
||||||
dictSetVal(d, de, newele);
|
|
||||||
} else if (dict_val_type == DEFRAG_SDS_DICT_VAL_VOID_PTR) {
|
|
||||||
void *newptr, *ptr = dictGetVal(de);
|
|
||||||
if ((newptr = activeDefragAlloc(ptr)))
|
|
||||||
dictSetVal(d, de, newptr), defragged++;
|
|
||||||
}
|
|
||||||
defragged += dictIterDefragEntry(di);
|
|
||||||
}
|
|
||||||
dictReleaseIterator(di);
|
|
||||||
|
|
||||||
return defragged;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Utility function that replaces an old key pointer in the dictionary with a
|
/* Utility function that replaces an old key pointer in the dictionary with a
|
||||||
* new pointer. Additionally, we try to defrag the dictEntry in that dict.
|
* new pointer. Additionally, we try to defrag the dictEntry in that dict.
|
||||||
* Oldkey may be a dead pointer and should not be accessed (we get a
|
* Oldkey may be a dead pointer and should not be accessed (we get a
|
||||||
|
|
|
@ -647,11 +647,6 @@ double dictIncrDoubleVal(dictEntry *de, double val) {
|
||||||
return de->v.d += val;
|
return de->v.d += val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only used when the next in hash bucket has been reallocated. */
|
|
||||||
void dictSetNext(dictEntry *de, dictEntry *next) {
|
|
||||||
de->next = next;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* A pointer to the metadata section within the dict entry. */
|
/* A pointer to the metadata section within the dict entry. */
|
||||||
void *dictMetadata(dictEntry *de) {
|
void *dictMetadata(dictEntry *de) {
|
||||||
return &de->metadata;
|
return &de->metadata;
|
||||||
|
|
|
@ -160,7 +160,6 @@ void dictSetDoubleVal(dictEntry *de, double val);
|
||||||
int64_t dictIncrSignedIntegerVal(dictEntry *de, int64_t val);
|
int64_t dictIncrSignedIntegerVal(dictEntry *de, int64_t val);
|
||||||
uint64_t dictIncrUnsignedIntegerVal(dictEntry *de, uint64_t val);
|
uint64_t dictIncrUnsignedIntegerVal(dictEntry *de, uint64_t val);
|
||||||
double dictIncrDoubleVal(dictEntry *de, double val);
|
double dictIncrDoubleVal(dictEntry *de, double val);
|
||||||
void dictSetNext(dictEntry *de, dictEntry *next);
|
|
||||||
void *dictMetadata(dictEntry *de);
|
void *dictMetadata(dictEntry *de);
|
||||||
void *dictGetKey(const dictEntry *de);
|
void *dictGetKey(const dictEntry *de);
|
||||||
void *dictGetVal(const dictEntry *de);
|
void *dictGetVal(const dictEntry *de);
|
||||||
|
|
Loading…
Reference in New Issue