Compute the dataset digest. Since keys, sets elements, hashes elements * are not ordered, we use a trick: every aggregate digest is the xor * of the digests of their elements. This way the order will not change * the result. For list instead we use a feedback entering the output digest * as input in order to ensure that a different ordered list will result in * a different digest. */
| 293 | * as input in order to ensure that a different ordered list will result in |
| 294 | * a different digest. */ |
| 295 | void computeDatasetDigest(unsigned char *final) { |
| 296 | int j; |
| 297 | uint32_t aux; |
| 298 | |
| 299 | memset(final,0,20); /* Start with a clean result */ |
| 300 | |
| 301 | for (j = 0; j < cserver.dbnum; j++) { |
| 302 | redisDb *db = g_pserver->db[j]; |
| 303 | |
| 304 | if (db->size() == 0) continue; |
| 305 | |
| 306 | /* hash the DB id, so the same dataset moved in a different |
| 307 | * DB will lead to a different digest */ |
| 308 | aux = htonl(j); |
| 309 | mixDigest(final,&aux,sizeof(aux)); |
| 310 | |
| 311 | /* Iterate this DB writing every entry */ |
| 312 | db->iterate_threadsafe([final](const char *key, robj_roptr o)->bool { |
| 313 | unsigned char digest[20]; |
| 314 | robj *keyobj; |
| 315 | |
| 316 | memset(digest,0,20); /* This key-val digest */ |
| 317 | keyobj = createStringObject(key,sdslen(key)); |
| 318 | |
| 319 | mixDigest(digest,key,sdslen(key)); |
| 320 | |
| 321 | xorObjectDigest(digest,o); |
| 322 | |
| 323 | /* We can finally xor the key-val digest to the final digest */ |
| 324 | xorDigest(final,digest,20); |
| 325 | decrRefCount(keyobj); |
| 326 | return true; |
| 327 | }); |
| 328 | } |
| 329 | } |
| 330 | |
| 331 | #ifdef USE_JEMALLOC |
| 332 | void mallctl_int(client *c, robj **argv, int argc) { |
no test coverage detected