Defrag a list of sds values and a dict with the same sds keys */
| 347 | |
| 348 | /* Defrag a list of sds values and a dict with the same sds keys */ |
| 349 | long activeDefragSdsListAndDict(list *l, dict *d, int dict_val_type) { |
| 350 | long defragged = 0; |
| 351 | sds newsds, sdsele; |
| 352 | listNode *ln, *newln; |
| 353 | dictIterator *di; |
| 354 | dictEntry *de; |
| 355 | /* Defrag the list and it's sds values */ |
| 356 | for (ln = l->head; ln; ln = ln->next) { |
| 357 | if ((newln = (listNode*)activeDefragAlloc(ln))) { |
| 358 | if (newln->prev) |
| 359 | newln->prev->next = newln; |
| 360 | else |
| 361 | l->head = newln; |
| 362 | if (newln->next) |
| 363 | newln->next->prev = newln; |
| 364 | else |
| 365 | l->tail = newln; |
| 366 | ln = newln; |
| 367 | defragged++; |
| 368 | } |
| 369 | sdsele = (sds)ln->value; |
| 370 | if ((newsds = activeDefragSds(sdsele))) { |
| 371 | /* When defragging an sds value, we need to update the dict key */ |
| 372 | uint64_t hash = dictGetHash(d, newsds); |
| 373 | dictEntry **deref = dictFindEntryRefByPtrAndHash(d, sdsele, hash); |
| 374 | if (deref) |
| 375 | (*deref)->key = newsds; |
| 376 | ln->value = newsds; |
| 377 | defragged++; |
| 378 | } |
| 379 | } |
| 380 | |
| 381 | /* Defrag the dict values (keys were already handled) */ |
| 382 | di = dictGetIterator(d); |
| 383 | while((de = dictNext(di)) != NULL) { |
| 384 | if (dict_val_type == DEFRAG_SDS_DICT_VAL_IS_SDS) { |
| 385 | sds newsds, sdsele = (sds)dictGetVal(de); |
| 386 | if ((newsds = activeDefragSds(sdsele))) |
| 387 | de->v.val = newsds, defragged++; |
| 388 | } else if (dict_val_type == DEFRAG_SDS_DICT_VAL_IS_STROB) { |
| 389 | robj *newele, *ele = (robj*)dictGetVal(de); |
| 390 | if ((newele = activeDefragStringOb(ele, &defragged))) |
| 391 | de->v.val = newele, defragged++; |
| 392 | } else if (dict_val_type == DEFRAG_SDS_DICT_VAL_VOID_PTR) { |
| 393 | void *newptr, *ptr = dictGetVal(de); |
| 394 | if ((newptr = activeDefragAlloc(ptr))) |
| 395 | de->v.val = newptr, defragged++; |
| 396 | } |
| 397 | defragged += dictIterDefragEntry(di); |
| 398 | } |
| 399 | dictReleaseIterator(di); |
| 400 | |
| 401 | return defragged; |
| 402 | } |
| 403 | |
| 404 | /* Utility function that replaces an old key pointer in the dictionary with a |
| 405 | * new pointer. Additionally, we try to defrag the dictEntry in that dict. |
no test coverage detected