// 使用近似 LRU 算法,计算出给定对象的闲置时长 unsigned long long estimateObjectIdleTime(robj *o) { unsigned long long lruclock = LRU_CLOCK(); if (lruclock >= o->lru) { return (lruclock - o->lru) * REDIS_LRU_CLOCK_RESOLUTION; } else { return (lruclock + (REDIS_LRU_CLOCK_MAX - o->lru)) * REDIS_LRU_CLOCK_RESOLUTION; } }
/// 返回obj的限制时间 unsigned long long estimateObjectIdleTime(robj *o) { unsigned long long lruclock = LRU_CLOCK(); if (lruclock >= o->lru) { return (lruclock - o->lru) * REDIS_LRU_CLOCK_RESOLUTION; } else { /// 因为LRU_CLOCK最大为0xFFFFFF,时间戳大大超过这个值,所以会rollback return (lruclock + (REDIS_LRU_CLOCK_MAX - o->lru)) * REDIS_LRU_CLOCK_RESOLUTION; } }
robj *createObject(int type, void *ptr) { robj *o = zmalloc(sizeof(*o)); o->type = type; o->encoding = OBJ_ENCODING_RAW; o->ptr = ptr; o->refcount = 1; /* Set the LRU to the current lruclock (minutes resolution). */ o->lru = LRU_CLOCK(); return o; }
robj *createObject(int type, void *ptr) { //创建一个默认的对象 robj *o = zmalloc(sizeof(*o)); //分配空间 o->type = type; //设置对象类型 o->encoding = OBJ_ENCODING_RAW; //设置默认的编码方式 o->ptr = ptr; //设置 o->refcount = 1; //引用计数为1 /* Set the LRU to the current lruclock (minutes resolution). */ o->lru = LRU_CLOCK(); //计算设置当前LRU时间 return o; }
robj *lookupKey(redisDb *db, robj *key) { dictEntry *de = dictFind(db->dict,key->ptr); if (de) { robj *val = dictGetVal(de); /* Update the access time for the ageing algorithm. * Don't do it if we have a saving child, as this will trigger * a copy on write madness. */ if (server.rdb_child_pid == -1 && server.aof_child_pid == -1) val->lru = LRU_CLOCK(); return val; } else { return NULL; } }
// 创建一个 REDIS_ENCODING_EMBSTR 编码的字符对象 // 这个字符串对象中的 sds 会和字符串对象的 redisObject 结构一起分配 // 因此这个字符也是不可修改的 robj *createEmbeddedStringObject(char *ptr, size_t len) { robj *o = zmalloc(sizeof(robj)+sizeof(struct sdshdr)+len+1); struct sdshdr *sh = (void*)(o+1); o->type = REDIS_STRING; o->encoding = REDIS_ENCODING_EMBSTR; o->ptr = sh+1; o->refcount = 1; o->lru = LRU_CLOCK(); sh->len = len; sh->free = 0; if (ptr) { memcpy(sh->buf,ptr,len); sh->buf[len] = '\0'; } else { memset(sh->buf,0,len+1); } return o; }
//创建一个embstr编码的字符串对象 robj *createEmbeddedStringObject(const char *ptr, size_t len) { robj *o = zmalloc(sizeof(robj)+sizeof(struct sdshdr8)+len+1); //分配空间 struct sdshdr8 *sh = (void*)(o+1); //o+1刚好就是struct sdshdr8的地址 o->type = OBJ_STRING; //类型为字符串对象 o->encoding = OBJ_ENCODING_EMBSTR; //设置编码类型OBJ_ENCODING_EMBSTR o->ptr = sh+1; //指向分配的sds对象,分配的len+1的空间首地址 o->refcount = 1; //设置引用计数 o->lru = LRU_CLOCK(); //计算设置当前LRU时间 sh->len = len; //设置字符串长度 sh->alloc = len; //设置最大容量 sh->flags = SDS_TYPE_8; //设置sds的类型 if (ptr) { //如果传了字符串参数 memcpy(sh->buf,ptr,len); //将传进来的ptr保存到对象中 sh->buf[len] = '\0'; //结束符标志 } else { memset(sh->buf,0,len+1); //否则将对象的空间初始化为0 } return o; }