这里主要是摘要算法,我曾写过md5sum, sha, 虽然不懂数学原理。
- void xorStringObjectDigest(unsigned char *digest, robj *o) {
-     o = getDecodedObject(o);
-     xorDigest(digest,o->ptr,sdslen(o->ptr));
-     decrRefCount(o);
- }
-  
- /* This function instead of just computing the SHA1 and xoring it
-  * against digest, also perform the digest of "digest" itself and
-  * replace the old value with the new one.
-  *
-  * So the final digest will be:
-  *
-  * digest = SHA1(digest xor SHA1(data))
-  *
-  * This function is used every time we want to preserve the order so
-  * that digest(a,b,c,d) will be different than digest(b,c,d,a)
-  *
-  * Also note that mixdigest("foo") followed by mixdigest("bar")
-  * will lead to a different digest compared to "fo", "obar".
-  */
- void mixDigest(unsigned char *digest, void *ptr, size_t len) {
-     SHA1_CTX ctx;
-     char *s = ptr;
-  
-     xorDigest(digest,s,len);
-     SHA1Init(&ctx);
-     SHA1Update(&ctx,digest,20);
-     SHA1Final(digest,&ctx);
- }
-  
- void mixStringObjectDigest(unsigned char *digest, robj *o) {
-     o = getDecodedObject(o);
-     mixDigest(digest,o->ptr,sdslen(o->ptr));
-     decrRefCount(o);
- }
-  
- /* This function computes the digest of a data structure stored in the
-  * object 'o'. It is the core of the DEBUG DIGEST command: when taking the
-  * digest of a whole dataset, we take the digest of the key and the value
-  * pair, and xor all those together.
-  *
-  * Note that this function does not reset the initial 'digest' passed, it
-  * will continue mixing this object digest to anything that was already
-  * present. */
- void xorObjectDigest(redisDb *db, robj *keyobj, unsigned char *digest, robj *o) {
-     uint32_t aux = htonl(o->type);
-     mixDigest(digest,&aux,sizeof(aux));
-     long long expiretime = getExpire(db,keyobj);
-     char buf[128];
-  
-     /* Save the key and associated value */
-     if (o->type == OBJ_STRING) {
-         mixStringObjectDigest(digest,o);
-     } else if (o->type == OBJ_LIST) {
-         listTypeIterator *li = listTypeInitIterator(o,0,LIST_TAIL);
-         listTypeEntry entry;
-         while(listTypeNext(li,&entry)) {
-             robj *eleobj = listTypeGet(&entry);
-             mixStringObjectDigest(digest,eleobj);
-             decrRefCount(eleobj);
-         }
-         listTypeReleaseIterator(li);
-     } else if (o->type == OBJ_SET) {
-         setTypeIterator *si = setTypeInitIterator(o);
-         sds sdsele;
-         while((sdsele = setTypeNextObject(si)) != NULL) {
-             xorDigest(digest,sdsele,sdslen(sdsele));
-             sdsfree(sdsele);
-         }
-         setTypeReleaseIterator(si);
-     } else if (o->type == OBJ_ZSET) {
-         unsigned char eledigest[20];
-  
-         if (o->encoding == OBJ_ENCODING_ZIPLIST) {
-             unsigned char *zl = o->ptr;
-             unsigned char *eptr, *sptr;
-             unsigned char *vstr;
-             unsigned int vlen;
-             long long vll;
-             double score;
-  
-             eptr = ziplistIndex(zl,0);
-             serverAssert(eptr != NULL);
-             sptr = ziplistNext(zl,eptr);
-             serverAssert(sptr != NULL);
-  
-             while (eptr != NULL) {
-                 serverAssert(ziplistGet(eptr,&vstr,&vlen,&vll));
-                 score = zzlGetScore(sptr);
-  
-                 memset(eledigest,0,20);
-                 if (vstr != NULL) {
-                     mixDigest(eledigest,vstr,vlen);
-                 } else {
-                     ll2string(buf,sizeof(buf),vll);
-                     mixDigest(eledigest,buf,strlen(buf));
-                 }
-  
-                 snprintf(buf,sizeof(buf),"%.17g",score);
-                 mixDigest(eledigest,buf,strlen(buf));
-                 xorDigest(digest,eledigest,20);
-                 zzlNext(zl,&eptr,&sptr);
-             }
-         } else if (o->encoding == OBJ_ENCODING_SKIPLIST) {
-             zset *zs = o->ptr;
-             dictIterator *di = dictGetIterator(zs->dict);
-             dictEntry *de;
-  
-             while((de = dictNext(di)) != NULL) {
-                 sds sdsele = dictGetKey(de);
-                 double *score = dictGetVal(de);
-  
-                 snprintf(buf,sizeof(buf),"%.17g",*score);
-                 memset(eledigest,0,20);
-                 mixDigest(eledigest,sdsele,sdslen(sdsele));
-                 mixDigest(eledigest,buf,strlen(buf));
-                 xorDigest(digest,eledigest,20);
-             }
-             dictReleaseIterator(di);
-         } else {
-             serverPanic("Unknown sorted set encoding");
-         }
-     } else if (o->type == OBJ_HASH) {
-         hashTypeIterator *hi = hashTypeInitIterator(o);
-         while (hashTypeNext(hi) != C_ERR) {
-             unsigned char eledigest[20];
-             sds sdsele;
-  
-             memset(eledigest,0,20);
-             sdsele = hashTypeCurrentObjectNewSds(hi,OBJ_HASH_KEY);
-             mixDigest(eledigest,sdsele,sdslen(sdsele));
-             sdsfree(sdsele);
-             sdsele = hashTypeCurrentObjectNewSds(hi,OBJ_HASH_VALUE);
-             mixDigest(eledigest,sdsele,sdslen(sdsele));
-             sdsfree(sdsele);
-             xorDigest(digest,eledigest,20);
-         }
-         hashTypeReleaseIterator(hi);
-     } else if (o->type == OBJ_STREAM) {
-         streamIterator si;
-         streamIteratorStart(&si,o->ptr,NULL,NULL,0);
-         streamID id;
-         int64_t numfields;
-  
-         while(streamIteratorGetID(&si,&id,&numfields)) {
-             sds itemid = sdscatfmt(sdsempty(),"%U.%U",id.ms,id.seq);
-             mixDigest(digest,itemid,sdslen(itemid));
-             sdsfree(itemid);
-  
-             while(numfields--) {
-                 unsigned char *field, *value;
-                 int64_t field_len, value_len;
-                 streamIteratorGetField(&si,&field,&value,
-                                            &field_len,&value_len);
-                 mixDigest(digest,field,field_len);
-                 mixDigest(digest,value,value_len);
-             }
-         }
-         streamIteratorStop(&si);
-     } else if (o->type == OBJ_MODULE) {
-         RedisModuleDigest md = {{0},{0}};
-         moduleValue *mv = o->ptr;
-         moduleType *mt = mv->type;
-         moduleInitDigestContext(md);
-         if (mt->digest) {
-             mt->digest(&md,mv->value);
-             xorDigest(digest,md.x,sizeof(md.x));
-         }
-     } else {
-         serverPanic("Unknown object type");
-     }
-     /* If the key has an expire, add it to the mix */
-     if (expiretime != -1) xorDigest(digest,"!!expire!!",10);
- }
-  
- /* 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. */
- void computeDatasetDigest(unsigned char *final) {
-     unsigned char digest[20];
-     dictIterator *di = NULL;
-     dictEntry *de;
-     int j;
-     uint32_t aux;
-  
-     memset(final,0,20); /* Start with a clean result */
-  
-     for (j = 0; j < server.dbnum; j++) {
-         redisDb *db = server.db+j;
-  
-         if (dictSize(db->dict) == 0) continue;
-         di = dictGetSafeIterator(db->dict);
-  
-         /* hash the DB id, so the same dataset moved in a different
-          * DB will lead to a different digest */
-         aux = htonl(j);
-         mixDigest(final,&aux,sizeof(aux));
-  
-         /* Iterate this DB writing every entry */
-         while((de = dictNext(di)) != NULL) {
-             sds key;
-             robj *keyobj, *o;
-  
-             memset(digest,0,20); /* This key-val digest */
-             key = dictGetKey(de);
-             keyobj = createStringObject(key,sdslen(key));
-  
-             mixDigest(digest,key,sdslen(key));
-  
-             o = dictGetVal(de);
-             xorObjectDigest(db,keyobj,digest,o);
-  
-             /* We can finally xor the key-val digest to the final digest */
-             xorDigest(final,digest,20);
-             decrRefCount(keyobj);
-         }
-         dictReleaseIterator(di);
-     }
- }

 
                

















