使用bitmap实现可回收自增id

news2024/11/23 15:50:16

需求描述

设计一个方法,每次调用返回一个自增id,同时需要满足以下要求。

  1. 可更新id的状态为已使用,已使用的id下次调用时不再返回
  2. 可修改某个id的状态为未使用,下次调用时设为未使用状态的id可重新被返回

思路

思路一:如果数据量非常小,直接使用一个集合存储已使用的id,使用循环和维护这个集合即可,但数据量大了,此方法返回数据的时间复杂度和占用的空间都是比较大的。

思路二(推荐):建立一个(位图)bitmap,初始时bitmap的每一位都为0,0代表未使用,1代表已使用。每次请求获取id时从此bitmap的第0位开始返回一个未使用的index即可。

以一个bitmap长度为65536的bitmap为例,示意图如下:

初始时每一个bit位值都为0

012345678……1024……65535
000000000……0……0

此时请求id返回的值为:0

012345678……1024……65535
111110111……1……0

如经过一段时间后,索引位置为5的数据变成了0未使用
此时请求id返回的值应为:5

具体实现

BitSet VS RoaringBitmap

解决思路有了,接下来就是代码实现。这里以java代码为例,可以直接使用jdk自带的java.util.BitSet实现,不过自带的BitSet在数据稀疏的场景下占用空间较大,且提供的原生方法较少。

这里推荐直接使用由2016年由几位大佬论文而开发的RoaringBitmap,可移步它的官网详细学习一把。https://roaringbitmap.org/about/
roaringBitmap

RoaringBitmap有java、go、c\c++、rust、swift等多个版本的实现,同时其时间与空间复杂度低,提供的方法也非常丰富。
github地址如下:https://github.com/RoaringBitmap

java代码实现

以下为《使用bitmap实现可回收自增id》的示例代码

引入依赖

		<dependency>
			<groupId>org.roaringbitmap</groupId>
			<artifactId>RoaringBitmap</artifactId>
			<version>1.0.0</version>
		</dependency>

示例代码:

    public static void main(String[] args) {
        RoaringBitmap rr = new RoaringBitmap();
        long l = rr.nextAbsentValue(0);
        System.out.println(l);//print 0
        rr.add(0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 1024, 1025);

        l = rr.nextAbsentValue(0);
        System.out.println(l);//print 5
        // index 5 set true(1)
        rr.add(5);
        l = rr.nextAbsentValue(0);
        System.out.println(l);//print 11
    }

输出结果:

0
5
11

以上代码使用new RoaringBitmap()定义了一个可以自动扩容的bitmap,add方法的入参代表将某个bit位设为1,nextAbsentValue方法返回从某个index位开始出现的第一个bit位为0的索引值

分布式自增可回收id实现方案

RoaringBitmap还有一大特点:支持序列化与反序列化。
roaringWithKryo

凭借这一特点,如需要在分布式场景下使用RoaringBitmap,则仅需稍微修改代码即可快速实现。

如将RoaringBitmap序列化为二进制存储在数据库中。

比如在mongodb中使用Binary data数据类型、mysql中使用blob数据类型、oracle中使用BLOB这些二进制类型存储RoaringBitmap即可。

实现时每次先将RoaringBitmap读取到程序中,再进行逻辑操作,修改后再写回数据库中。


总结一下

RoaringBitmap YYDS

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1190306.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

毅速丨为什么不锈钢材料在金属3D打印中应用广泛

不锈钢材料作为一种常见材料&#xff0c;在金属3D打印中应用广泛&#xff0c;可以说是目前使用率最高的材料&#xff0c;为什么不锈钢大受欢迎&#xff0c;主要由几点原因。 第一、工艺适合性 金属3D打印的工艺&#xff0c;如直接金属激光烧结&#xff08;DMLS&#xff09;或选…

spring boot+netty 搭建MQTT broken

一、项目结构 二、安装依赖 <!-- netty包 --><dependency><groupId>io.netty</groupId><artifactId>netty-all</artifactId><version>4.1.75.Final</version></dependency><!-- 常用JSON工具包 --><…

双十一成交千万级!伊能静疗愈直播人-货-场洞察

近日&#xff0c;伊能静在小红书的疗愈直播火了。10月28日&#xff0c;小红书美护买手伊能静的第二场直播观看人数166万&#xff0c;粉丝人均观看时间12分52秒&#xff0c;11家在国内声量不大的国际品牌单品在直播间售罄。就此&#xff0c;也让我们看到了疗愈经济的可能性。 一…

clang插件对llvm源码插桩,分析函数调用日志(2)--google镜像

tick_plot__compile.ipynb clang插件对llvm源码插桩&#xff0c;分析函数调用日志(1) 分析 进出、链、出 df进出df[ df[tickKind].isin( [FuncEnter,FuncReturn] ) ]#代码中&#xff0c;只有在函数进入时&#xff0c;计算了链条长度 并写磁盘 df入df[ df[tickKind].isin…

linux如何实现免密登录

shigen日更文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 十一月是比较特殊的月份&#xff0c;因为很多云资源都是在这个时候过期&#xff0c;包括我自己买的云服务器。作…

安装pr提示VCRUNTIME140.dll丢失的修复方法,3个有效的方法

在学习和工作中&#xff0c;我们经常需要使用到PR和PS。然而&#xff0c;在安装这些软件时&#xff0c;有时会遇到一些错误提示&#xff0c;其中之一就是“VCRUNTIME140.dll丢失”&#xff0c;无法运行启动软件程序。那么&#xff0c;如何解决VCRUNTIME140.dll丢失的问题呢&…

无人机航迹规划:七种智能优化算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划--提供MATLAB代码

一、七种算法&#xff08;DBO、LO、SWO、COA、LSO、KOA、GRO&#xff09;简介 1、蜣螂优化算法DBO 蜣螂优化算法&#xff08;Dung beetle optimizer&#xff0c;DBO&#xff09;由Jiankai Xue和Bo Shen于2022年提出&#xff0c;该算法主要受蜣螂的滚球、跳舞、觅食、偷窃和繁…

栈的顺序存储实现(C语言)(数据结构与算法)

栈的顺序存储实现通常使用数组来完成。实现方法包括定义一个固定大小的数组&#xff0c;以及一个指向栈顶的指针。当元素入栈时&#xff0c;指针加一并将元素存储在相应位置&#xff1b;当元素出栈时&#xff0c;指针减一并返回相应位置的元素。 1. 顺序栈定义 #define MaxSi…

C++ 之多态(一)

什么是虚函数 在类的定义中&#xff0c;前面有 virtual 关键字的成员函数称为虚函数&#xff1b;virtual 关键字只用在类定义里的函数声明中&#xff0c;写函数体时不用。 class Base {virtual int Fun() ; // 虚函数 };int Base::Fun() // virtual 字段不用在函数体时定义 …

python- os模块

一、文件与目录相关的操作 1、删除文件/文件夹 2、os.stat("path/filename"): 获取文件/目录信息的结构说明 3、os.listdir 和 os.path.join 在Python中&#xff0c;os.listdir()和os.path.join()是操作系统模块&#xff08;os模块&#xff09;的两个函数&#x…

运维相关(一) - Vue项目配置WebSocket连接{ws、wss 连接方式}

Vue项目配置WebSocket连接 ws、wss 两种方式 1. 写作背景2. 晒出代码2.1 前端 vue.config.js 的代码2.2 Vue项目路由配置代码3.3 服务器Nginx配置 3. 使用方式3.1 前端代码3.2 后端代码 4. 测试使用 1. 写作背景 项目使用的是ruoyi的前后端分离框架项目需要使用到 websocket , …

上市公司-赫芬达尔指数(2000-2022年)(数据+2种结果)

上市公司-赫芬达尔指数&#xff08;HHI&#xff09;可衡量一个公司在市场中的相对份额或集中度。它是由每家公司在市场中份额的平方和得到的。指数值越高&#xff0c;表示该市场或行业的集中度越高&#xff0c;竞争可能相对较小&#xff1b;而指数值越低&#xff0c;则意味着该…

如何让群晖Audio Station公开共享的本地音频公网可访问?

文章目录 1. 本教程使用环境&#xff1a;2. 制作音频分享链接3. 制作永久固定音频分享链接&#xff1a; 之前文章我详细介绍了如何在公网环境下使用pc和移动端访问群晖Audio Station&#xff1a; 公网访问群晖audiostation听歌 - cpolar 极点云 群晖套件不仅能读写本地文件&a…

公众号开发实践:用PHP实现通过接口自定义微信公众号菜单

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月CSDN上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师…

Apache DolphinScheduler如何完全设置东八区?

默认情况 为了兼容全世界不同时区&#xff0c;Apache DolphinScheduler 使用的是 UTC 0 时区&#xff0c;包括保存到数据库表中的数据时区&#xff0c;以及展示到页面上的时区。 如果我们想在页面上看到东八区时间&#xff0c;则需要在页面上手动选择上海时区&#xff0c;如下…

小程序订单中心path设置本次审核不通过,审核原因:小程序尚未发布,无法审核。

小程序尚未发布&#xff0c;无法审核。 先按照这篇文章把小程序审核通过&#xff0c;小程序版本审核未通过&#xff0c;需在开发者后台「版本管理—提交审核——小程序订单中心path」设置订单中心页path&#xff0c;请设置后再提交代码审核 小程序审核通过后&#xff0c;发布…

2023.11.09 homework

4年级数学&#xff1a;不会做就作图&#xff0c;画出来&#xff0c;简单化就容易懂 2023.11.09 homework &#xff08;2&#xff09;-CSDN博客

MySQL代码子查询续集

dept表&#xff1a; emp表&#xff1a; -- 查询每个部门的信息(包括&#xff1a;部门名&#xff0c;编号&#xff0c;地址)和人员数量 -- 1.将两张表结合起来&#xff0c;筛选出部门名&#xff0c;编号&#xff0c;地址 tips: 表.* 表示将该表所有列都显示出来&#xff…

基于SpringBoot+Vue的婚恋相亲交友系统

基于SpringBootVue的婚恋相亲交友系统~ 开发语言&#xff1a;Java数据库&#xff1a;MySQL技术&#xff1a;SpringBootMyBatisVue工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系统展示 主页 管理员界面 摘要 基于SpringBootVue的婚恋相亲交友系统是一个现代化的、高效的交…