redis中list长度

          我们使用redis , 其中经常需要得到一个list长度,那么这个list长度是否存储了还是每次都需要遍历整个list呢? 

          看了下源码

  78 unsigned long listTypeLength(robj *subject) {
  79     if (subject->encoding == REDIS_ENCODING_ZIPLIST) {
  80         return ziplistLen(subject->ptr);
  81     } else if (subject->encoding == REDIS_ENCODING_LINKEDLIST) {
  82         return listLength((list*)subject->ptr);
  83     } else {
  84         redisPanic("Unknown list encoding");
  85     }
  86 }

          list 采用两种实现方式,一个ziplist,另外一个linkedlist 


          我们先来看看这个ziplist           

 732 /* Return length of ziplist. */
 733 unsigned int ziplistLen(unsigned char *zl) {
 734     unsigned int len = 0;
 735     if (ZIPLIST_LENGTH(zl) < UINT16_MAX) {
 736         len = ZIPLIST_LENGTH(zl);
 737     } else {
 738         unsigned char *p = zl+ZIPLIST_HEADER_SIZE;
 739         while (*p != ZIP_END) {
 740             p += zipRawEntryLength(p);
 741             len++;
 742         }
 743         
 744         /* Re-store length if small enough */
 745         if (len < UINT16_MAX) ZIPLIST_LENGTH(zl) = len;
 746     }
 747     return len;
 748 }

          使用固定地方存放list长度,但是如果超过了最大值,那么就需要遍历

          所以使用ziplist,最好长度不要超过  2^16 -2  = 65534 ,否则严重影响效率


        我们再来看看linkedlist,实现在 adlist.c中

 47 typedef struct list {
 48     listNode *head;
 49     listNode *tail;
 50     void *(*dup)(void *ptr);
 51     void (*free)(void *ptr);
 52     int (*match)(void *ptr, void *key);
 53     unsigned int len;
 54 } list;
 55 
 56 /* Functions implemented as macros */
 57 #define listLength(l) ((l)->len)
从上面的代码可以看出,在list结构体中有个len字段,得到长度的时候,直接返回这个字段。






评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值