Redis之BitSet
创始人
2025-05-29 05:16:16
前言:

BitSet是Redis中提供的一种二进制数组的数据结构, 利用这种特殊的数据结构可以实现一些特定的场景.
BitSet的数据长这样: [01010010], 存放的是boolean, 且长度为8的倍数 也就是byte的长度. 且只存true, false会自动填充.
Redisson提供的RBitSet还额外提供了 与 或 非 等api.

场景:

现需要记录一个24小时的状态图, 状态可以是: 打开/关闭; 在家/离家; 等等
每15分钟记一次状态, 也可以是10分钟, 30分钟

模型:

value格式:00010100,以每15分钟的统计结果作为1bit
不足8位会自动补0
在这里插入图片描述
写入和读取分离, 缓存实时维护, 查询也只查缓存, 不查数据源
比如说 00:16 和 01:27 检测到状态为打开, 其余时间段为关闭
那么预期的二进制数据为: 01000100

redisson提供了相关的api:

RBitSet bitSet = redissonClient.getBitSet(key);
bitSet.set(index);
bitSet.expire(7, TimeUnit.DAYS);

对应的数组索引为1和6 , 这里就是set(1), set(6). 0(false)会自动填充

BitSet工具类:
/*** Redis位图工具类* @author Lynn* @date 2023/3/13 19:38*/
@Component
public class BitMapUtil {private static RedissonClient redissonClient;@Autowiredpublic void setRedissonClient(RedissonClient redissonClient) {BitMapUtil.redissonClient = redissonClient;}private static DeviceConfigService deviceConfigService;@Autowiredpublic void setDeviceConfigService(DeviceConfigService deviceConfigService) {BitMapUtil.deviceConfigService = deviceConfigService;}public static RBitSet getBitSet(String key) {return redissonClient.getBitSet(key);}public static void mergeList(List result, RBitSet bitSet, long i) {if (i <= bitSet.size() - 1) {if (bitSet.get(i)) {StatusBo bo = StatusBo.builder().startTime(BitMapUtil.mapIndexToStartDate(i)).endTime(BitMapUtil.mapIndexToEndDate(i)).build();result.add(bo);while (i < bitSet.size() - 1 && bitSet.get(i + 1)) {bo.setEndTime(BitMapUtil.mapIndexToEndDate(i + 1));i++;}}i++;mergeList(result, bitSet, i);}}private static Date mapIndexToStartDate(long index) {Map globalConfig =deviceConfigService.queryBaseConfig(new DeviceConfigDto(), DeviceConfigDimensionEnum.GLOBAL.getCode());String config = globalConfig.get(WHOLE_DAY_PROTECT_INTERVAL);int step = StringUtils.isNoBlank(config) ? Integer.parseInt(config) / 60000 : 15;int minute = (int) (index * step);Date now = new Date();return new Date(now.getYear(), now.getMonth(), now.getDate(), minute / 60, minute % 60, 0);}private static Date mapIndexToEndDate(long index) {Map globalConfig =deviceConfigService.queryBaseConfig(new DeviceConfigDto(), DeviceConfigDimensionEnum.GLOBAL.getCode());String config = globalConfig.get(WHOLE_DAY_PROTECT_INTERVAL);int step = StringUtils.isNoBlank(config) ? Integer.parseInt(config) / 60000 : 15;int minute = (int) ((index + 1) * step);Date now = new Date();return new Date(now.getYear(), now.getMonth(), now.getDate(), minute / 60 < 24 ? minute / 60 : 23,minute / 60 < 24 ? minute % 60 : 59, 0);}public static long mapDateToIndex(Date date) {Map globalConfig =deviceConfigService.queryBaseConfig(new DeviceConfigDto(), DeviceConfigDimensionEnum.GLOBAL.getCode());String config = globalConfig.get(WHOLE_DAY_PROTECT_INTERVAL);int step = StringUtils.isNoBlank(config) ? Integer.parseInt(config) / 60000 : 15;return (date.getHours() * 60 + date.getMinutes()) / step;}
}

相关内容

热门资讯

投资者提问:请问董秘,当前中日... 投资者提问:请问董秘,当前中日关系陷入僵局乃至谷底之际,公司有规划更多使用国产光刻胶等材料来替代日系...
富德生命人寿咸阳中心支公司被罚... 12月16日金融一线消息,据咸阳金融监管分局行政处罚信息公开表显示,富德生命人寿保险股份有限公司咸阳...
市场监管总局:抓紧推进出台《互... 转自:北京日报客户端记者16日从市场监管总局获悉,市场监管总局正抓紧推进《互联网平台反垄断合规指引》...
天奇股份:锂电循环业务夯实产业... 12月16日,江西天奇金泰阁集团(简称“天奇金泰阁”)资本赋能发展大会在江西龙南举行。会上,天奇股份...
「侠客岛」他们用上了“AI分身...   炒股就看金麒麟分析师研报,权威,专业,及时,全面,助您挖掘潜力主题机会! (来源:海外网)来源...