Chinaunix首页 | 论坛 | 博客
  • 博客拜谒
  • 博文数量: 54
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 612
  • 用 户 组: 普通用户
  • 注册时间: 2016-12-21 22:26
小我简介

90后空巢老码农

文章分类

全部博文(54)

文章存档

2019年(6)

2018年(47)

2017年(1)

我的朋友
相关博文
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·
  • ·

分类: NOSQL

2019-02-12 18:09:02

此日来讲讲redis当中set的一种实现形式intset,其应用场景只是在会合当中只蕴涵整数值并且元素数量不多时,博猫娱乐注册网站。望文生义。
其存储组织如下所示:

点击(此处)折叠或掀开

  1. typedef struct intset {
  2. uint32_t encoding; // 编码规则,整体见上面三个宏定义
  3. uint32_t length; // 所存元素个数
  4. int8_t contents[]; // 元素存储职位地方
  5. } intset;
  6. #define INTSET_ENC_INT16 (sizeof(int16_t))
  7. #define INTSET_ENC_INT32 (sizeof(int32_t))
  8. #define INTSET_ENC_INT64 (sizeof(int64_t))
其中三个宏定义表示的是encoding字段的可以或许取值,32位整数,博猫娱乐注册网站。区分对应intset中的contents数组的三种不同的解析方式(16位整数。 这里须要留心的是由于不同的机器当地 的endian可以或许 不同。在contents中寄存的实际数字时遵循从小到大的顺序排列好的。
整个intset里面对比好玩的就是拔出元素了。由于有三种不同的编码方式,博猫娱乐注册网站。将原有的inset的encoding变为须要的,太阳gg客户登陆。intset就会根据新拔出的值得大小,大到目前intset自身的编码无法承载这一数据的时候,当拔出的新元素所占的空间较大。
  1. 根据拔出的元素类型,适当扩展intset所占的空间
  2. 在保持低层数组存储数据不变的来源根基上,遵循从后到前的顺序(防止掩盖)拷贝到新的职位地方上
  3. 将新添加的元素拔出到intset当中
其中拔出代码如下所示:

点击(此处)折叠或掀开

  1. /* Insert an integer in the intset */
  2. intset *intsetAdd(intset *is, int64_t value, uint8_t *success) {
  3. uint8_t valenc = _intsetValueEncoding(value);
  4. uint32_t pos;
  5. if (success) *success = 1;

  6. /* Upgrade encoding if necessary. If we need to upgrade, we know that
  7. * this value should be either appended (if > 0) or prepended (if < 0),
  8. * because it lies outside the range of existing values. */
  9. if (valenc > intrev32ifbe(is->encoding)) {
  10. /* This always succeeds, so we don't need to curry *success. */
  11. return intsetUpgradeAndAdd(is,value);
  12. } else {
  13. /* Abort if the value is already present in the set.
  14. * This call will populate "pos" with the right position to insert
  15. * the value when it cannot be found. */
  16. if (intsetSearch(is,value,&pos)) {
  17. if (success) *success = 0;
  18. return is;
  19. }

  20. is = intsetResize(is,intrev32ifbe(is->length)+1);
  21. if (pos < intrev32ifbe(is->length)) intsetMoveTail(is,pos,pos+1);
  22. }

  23. _intsetSet(is,pos,value);
  24. is->length = intrev32ifbe(intrev32ifbe(is->length)+1);
  25. return is;
  26. }
在这个函数当中,若该当分配较大的空间,新宝gg平台。首先判断了拔出值的编码。

点击(此处)折叠或掀开

  1. /* Upgrades the intset to a larger encoding and inserts the given integer. */
  2. static intset *intsetUpgradeAndAdd(intset *is, int64_t value) {
  3. uint8_t curenc = intrev32ifbe(is->encoding);
  4. uint8_t newenc = _intsetValueEncoding(value);
  5. int length = intrev32ifbe(is->length);
  6. int prepend = value < 0 ? 1 : 0;

  7. /* First set new encoding and resize */
  8. is->encoding = intrev32ifbe(newenc);
  9. is = intsetResize(is,intrev32ifbe(is->length)+1);

  10. /* Upgrade back-to-front so we don't overwrite values.
  11. * Note that the "prepend" variable is used to make sure we have an empty
  12. * space at either the beginning or the end of the intset.
  13. * 通俗的支吾是对新拔出的元素。/
  14. while(length--)
  15. _intsetSet(is,length+prepend,_intsetGetEncoded(is,length,curenc));

  16. /* Set the value at the beginning or the end. */
  17. if (prepend)
  18. _intsetSet(is,0,value);
  19. else
  20. _intsetSet(is,intrev32ifbe(is->length),value);
  21. is->length = intrev32ifbe(intrev32ifbe(is->length)+1);
  22. return is;
  23. }
如果现在intset当中曾经有该元素的话,挪动转移其后头的元素,新宝6平台。须要找到该当拔出的职位地方,间接前往。若没有。
删除操作的话,就间接将后头的元素挪动转移过去,若找到的话,逻辑就是能否找到。

点击(此处)折叠或掀开

  1. /* Delete integer from intset */
  2. intset *intsetRemove(intset *is, int64_t value, int *success) {
  3. uint8_t valenc = _intsetValueEncoding(value);
  4. uint32_t pos;
  5. if (success) *success = 0;

  6. if (valenc <= intrev32ifbe(is->encoding) && intsetSearch(is,value,&pos)) {
  7. uint32_t len = intrev32ifbe(is->length);

  8. /* We know we can delete */
  9. if (success) *success = 1;

  10. /* Overwrite value with tail and update length */
  11. if (pos < (len-1)) intsetMoveTail(is,pos+1,pos);
  12. is = intsetResize(is,len-1);
  13. is->length = intrev32ifbe(len-1);
  14. }
  15. return is;
  16. }
这里面须要提醒诸位的是: 删除元素的时候没有升级操作!!!小我探求的原由于:如果删除一个元素就要从头到尾搜检现在的encoding是否过大的话,新宝6登录。就会形成不用要的消费。新宝6主管。
阅读(28) | 评论(0) | 转发(0) |
0

上一篇:redis源码阅读之zipmap

下一篇:没有了

给仆人留下些什么吧!~~
评论热议
请登录后评论。

登录 注册

百度搜索 百度搜索 百度搜索 百度搜索 百度搜索 新宝GG 华宇娱乐