Redis入门到通关之数据结构解析-IntSet

本文涉及的产品
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
云数据库 Tair(兼容Redis),内存型 2GB
云解析 DNS,旗舰版 1个月
简介: Redis入门到通关之数据结构解析-IntSet

概述


IntSetRedis中set集合的一种实现方式,基于 整数数组 来实现,并且具备长度可变、有序等特征。

结构如下:

// intset 结构体定义
typedef struct intset {
    uint32_t encoding;   // 编码方式,用于表示存储的整数类型
    uint32_t length;     // intset 中包含的元素个数
    int8_t contents[];   // 存储整数的数组
} intset;

其中的 encoding 包含三种模式,表示存储的整数大小不同:

为了方便查找,Redis 会将 intset 中所有的整数按照 升序 依次保存在contents数组中,结构如图:


IntSet升级


假如现在,数组中每个数字都在 int16_t 的范围内,因此采用的编码方式是 INTSET_ENC_INT16,每部分占用的字节大小为:

encoding:4字节

length:4字节

contents:2字节 * 3 = 6字节

我们向该其中添加一个数字:50000,这个数字超出了 int16_t 的范围,intset 会自动 升级 编码方式到合适的大小。

以当前案例来说流程如下:


  • 升级编码为 INTSET_ENC_INT32, 每个整数占4字节,并按照新的编码方式及元素个数扩容数组
  • 倒序 依次将数组中的元素拷贝到扩容后的正确位置
  • 将待添加的元素放入数组末尾
  • 最后,将 inset 的 encoding 属性改为 INTSET_ENC_INT32 ,将 length 属性改为4


简易源码


#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

// intset 结构体定义
typedef struct intset {
    uint32_t encoding;   // 编码方式,用于表示存储的整数类型
    uint32_t length;     // intset 中包含的元素个数
    int8_t contents[];   // 存储整数的数组
} intset;

// 创建一个新的 intset
intset *intset_new() {
    intset *is = malloc(sizeof(intset));
    if (!is) return NULL;
    is->encoding = 0;   // 初始编码方式为 0
    is->length = 0;
    return is;
}

// 添加整数到 intset
intset *intset_add(intset *is, int64_t value) {
    // 添加元素的逻辑实现省略
    return is;
}

// 检查整数是否存在于 intset
int intset_contains(const intset *is, int64_t value) {
    // 检查元素是否存在的逻辑实现省略
    return 0;
}

// 删除整数从 intset
intset *intset_remove(intset *is, int64_t value) {
    // 删除元素的逻辑实现省略
    return is;
}

// 打印 intset 中的元素
void intset_print(const intset *is) {
    printf("Intset Length: %d\n", is->length);
    printf("Intset Elements: ");
    for (int i = 0; i < is->length; ++i) {
        printf("%lld ", (long long)is->contents[i]);
    }
    printf("\n");
}

int main() {
    intset *is = intset_new();
    if (!is) {
        printf("Error: Unable to create intset.\n");
        return 1;
    }

    is = intset_add(is, 5);
    is = intset_add(is, 10);
    is = intset_add(is, 15);

    intset_print(is);

    // 检查元素是否存在
    if (intset_contains(is, 10)) {
        printf("Element 10 exists in the intset.\n");
    } else {
        printf("Element 10 does not exist in the intset.\n");
    }

    is = intset_remove(is, 10);
    intset_print(is);

    free(is);
    return 0;
}


总结


Intset可以看做是特殊的整数数组,具备一些特点:

  • Redis会确保Intset中的元素唯一、有序
  • 具备类型升级机制,可以节省内存空间
  • 底层采用二分查找方式来查询
相关文章
|
2月前
|
消息中间件 NoSQL Redis
redis数据结构-List
redis数据结构-List
33 1
|
2月前
|
存储 缓存 NoSQL
redis数据结构-字符串
redis数据结构-字符串
32 1
|
2月前
|
缓存 NoSQL Java
Redis深度解析:解锁高性能缓存的终极武器,让你的应用飞起来
【8月更文挑战第29天】本文从基本概念入手,通过实战示例、原理解析和高级使用技巧,全面讲解Redis这一高性能键值对数据库。Redis基于内存存储,支持多种数据结构,如字符串、列表和哈希表等,常用于数据库、缓存及消息队列。文中详细介绍了如何在Spring Boot项目中集成Redis,并展示了其工作原理、缓存实现方法及高级特性,如事务、发布/订阅、Lua脚本和集群等,帮助读者从入门到精通Redis,大幅提升应用性能与可扩展性。
60 0
|
6天前
|
存储 JSON NoSQL
redis基本数据结构(String,Hash,Set,List,SortedSet)【学习笔记】
这篇文章是关于Redis基本数据结构的学习笔记,包括了String、Hash、Set、List和SortedSet的介绍和常用命令。文章解释了每种数据结构的特点和使用场景,并通过命令示例演示了如何在Redis中操作这些数据结构。此外,还提供了一些练习示例,帮助读者更好地理解和应用这些数据结构。
redis基本数据结构(String,Hash,Set,List,SortedSet)【学习笔记】
|
2月前
|
XML 存储 网络安全
ROS入门(二):launch文件解析
该文章是关于ROS入门的第二篇教程,详细解析了ROS中的launch文件,包括其运行方式、XML格式规范、标签使用、参数替代、条件属性以及通过简单和复杂案例来演示launch文件的使用,最后介绍了如何在参数服务器上设置参数。
ROS入门(二):launch文件解析
|
3天前
|
存储 缓存 NoSQL
Redis 过期删除策略与内存淘汰策略的区别及常用命令解析
Redis 过期删除策略与内存淘汰策略的区别及常用命令解析
10 0
|
2月前
|
存储 监控 NoSQL
redis数据结构-HyperLogLog
redis数据结构-HyperLogLog
32 1
|
2月前
|
存储 NoSQL Redis
redis数据结构-ziplist
redis数据结构-ziplist
16 2
|
2月前
|
数据库 Windows
超详细步骤解析:从零开始,手把手教你使用 Visual Studio 打造你的第一个 Windows Forms 应用程序,菜鸟也能轻松上手的编程入门指南来了!
【8月更文挑战第31天】创建你的第一个Windows Forms (WinForms) 应用程序是一个激动人心的过程,尤其适合编程新手。本指南将带你逐步完成一个简单WinForms 应用的开发。首先,在Visual Studio 中创建一个“Windows Forms App (.NET)”项目,命名为“我的第一个WinForms 应用”。接着,在空白窗体中添加一个按钮和一个标签控件,并设置按钮文本为“点击我”。然后,为按钮添加点击事件处理程序`button1_Click`,实现点击按钮后更新标签文本为“你好,你刚刚点击了按钮!”。
99 0
|
2月前
|
存储 NoSQL 数据处理
redis数据结构-Bitmaps
redis数据结构-Bitmaps
29 0

推荐镜像

更多
下一篇
无影云桌面