Defrag helper for robj and/or string objects * * returns NULL in case the allocation wasn't moved. * when it returns a non-null value, the old pointer was already released * and should NOT be accessed. */
| 92 | * when it returns a non-null value, the old pointer was already released |
| 93 | * and should NOT be accessed. */ |
| 94 | robj *activeDefragStringOb(robj* ob, long *defragged) { |
| 95 | robj *ret = NULL; |
| 96 | if (ob->refcount!=1) |
| 97 | return NULL; |
| 98 | |
| 99 | /* try to defrag robj (only if not an EMBSTR type (handled below). */ |
| 100 | if (ob->type!=OBJ_STRING || ob->encoding!=OBJ_ENCODING_EMBSTR) { |
| 101 | if ((ret = activeDefragAlloc(ob))) { |
| 102 | ob = ret; |
| 103 | (*defragged)++; |
| 104 | } |
| 105 | } |
| 106 | |
| 107 | /* try to defrag string object */ |
| 108 | if (ob->type == OBJ_STRING) { |
| 109 | if(ob->encoding==OBJ_ENCODING_RAW) { |
| 110 | sds newsds = activeDefragSds((sds)ob->ptr); |
| 111 | if (newsds) { |
| 112 | ob->ptr = newsds; |
| 113 | (*defragged)++; |
| 114 | } |
| 115 | } else if (ob->encoding==OBJ_ENCODING_EMBSTR) { |
| 116 | /* The sds is embedded in the object allocation, calculate the |
| 117 | * offset and update the pointer in the new allocation. */ |
| 118 | long ofs = (intptr_t)ob->ptr - (intptr_t)ob; |
| 119 | if ((ret = activeDefragAlloc(ob))) { |
| 120 | ret->ptr = (void*)((intptr_t)ret + ofs); |
| 121 | (*defragged)++; |
| 122 | } |
| 123 | } else if (ob->encoding!=OBJ_ENCODING_INT) { |
| 124 | serverPanic("Unknown string encoding"); |
| 125 | } |
| 126 | } |
| 127 | return ret; |
| 128 | } |
| 129 | |
| 130 | /* Defrag helper for dictEntries to be used during dict iteration (called on |
| 131 | * each step). Returns a stat of how many pointers were moved. */ |
no test coverage detected