当前位置:首页 > 文章列表 > Golang > Go教程 > Go roaring 怎样用范围操作加入连续整数

Go roaring 怎样用范围操作加入连续整数

来源:17golang原创 2026-10-31 08:43:51 0浏览 收藏

Go roaring 怎样用范围操作加入连续整数

Go roaring 可以用 bm.AddRange(start, end) 一次加入连续整数,区间为左闭右开 [start, end)。例如加入100到109应写 AddRange(100, 110)。它修改当前位图,保留原有元素,重复添加已有整数不会产生重复项。

项目官方地址:https://github.com/RoaringBitmap/roaring。本文固定使用无 /v2 后缀的 v1.9.4 模块,示例讨论32位 Bitmap。下面提供读者可自行运行的小实验,本文没有执行这些代码,也没有提供性能实测数据。

准备依赖并确定半开区间

在已有 Go module 的目录中安装本文版本,把后面的完整示例保存为 main.go。若项目已采用其他主版本,应以对应版本的导入路径和文档为准,不要把不同主版本的代码混用。

# 在已有Go模块中固定本文使用的版本
go get github.com/RoaringBitmap/roaring@v1.9.4
# 保存后面的main.go后运行小集合示例
go run .

AddRange 的两个参数是 uint64,但 Bitmap 的元素仍是 uint32。参数较宽是为了容纳右端点 2^32:要包含最大元素4294967295,排除式右端点就需要4294967296。不能据此认为32位 Bitmap 能保存任意64位整数。

AddRange半开区间与32位整数域的静态关系
结构图:起点包含、终点排除;uint64端点用于表达uint32元素域的边界。

在小集合上加入连续整数

package main

import (
    "fmt"
    "github.com/RoaringBitmap/roaring"
)

func main() {
    bm := roaring.New()
    // 加入100至109,不包含右端点110。
    bm.AddRange(100, 110)
    fmt.Println("数量:", bm.GetCardinality())
    fmt.Println("包含100:", bm.Contains(100))
    fmt.Println("包含110:", bm.Contains(110))
    // 与已有范围重叠时,重复元素不会增加计数。
    bm.AddRange(105, 115)
    fmt.Println("合并后的数量:", bm.GetCardinality())
    // 仅对这个小集合展开;大范围不要直接ToArray。
    fmt.Println("元素:", bm.ToArray())
}

按区间语义推导,第一次添加得到10个整数,100存在、110不存在;第二次添加后,集合覆盖100至114,共15个整数。这里的数字是集合计算的预期值,不是本机终端输出。重复部分105至109只计一次,不应把两次区间长度直接相加。

小实验可以展开 ToArray 观察元素,但大范围不要照搬这个展示方式。位图的压缩表示和把所有元素复制到切片是两件事;大量连续整数即使能紧凑表示,展开后仍需要为每个元素分配空间。

处理闭区间和uint32最大值

如果上游业务给的是“从 first 到 last 都包含”,要把闭区间转换成半开区间。不能先在 uint32 上执行 last+1,再转换成 uint64:当 last 是最大 uint32 时,加法已经溢出,后续转换无法挽回。

下面的辅助函数与上面的示例使用同一组导入,在 main 之外定义即可。错误由调用方接收处理。

// AddClosed 将uint32闭区间转换为AddRange使用的半开区间。
func AddClosed(bm *roaring.Bitmap, first, last uint32) error {
    if bm == nil {
        return fmt.Errorf("位图不能为nil")
    }
    if first > last {
        return fmt.Errorf("闭区间起点大于终点")
    }
    // 先提升类型再加1,避免last为最大uint32时溢出。
    bm.AddRange(uint64(first), uint64(last)+1)
    return nil
}

例如 first 和 last 都为4294967295时,转换后是 [4294967295, 4294967296),只包含一个元素。不要为了观察这个边界而建立整个32位整数全集,更不要将全集调用 ToArray 展开。

业务要求传给AddRange的范围含义
100至109[100,110)10个整数
只加入7[7,8)1个整数
空区间[7,7)不新增元素
最大uint32元素[4294967295,4294967296)右端点需要uint64表达

把外部范围封装成明确错误

v1.9.4 的 AddRange 没有 error 返回值;实现对起点不小于终点的情况直接返回,对非空越界范围可能触发 panic。面向外部输入时,建议在应用边界明确检查,再把合法参数交给库。

// AddHalfOpen 校验外部传入的uint64半开区间。
func AddHalfOpen(bm *roaring.Bitmap, start, end uint64) error {
    const limit uint64 = 1  end || start > limit || end > limit {
        return fmt.Errorf("范围必须满足0 

这个函数选择把反向区间作为错误,与库的静默返回行为有意区分。它还接受位于上界的合法空区间,但不接受超过上界的参数。若输入原本是有符号整数,必须在转换成 uint64 前检查负数;上面的函数接收无符号值,不负责恢复转换前的原始含义。

已有元素与范围成员在同一位图内去重的静态集合关系
说明图:AddRange添加范围成员并保留原集合,重叠元素在结果集合中只出现一次。

扩展实验与使用边界

可在独立小位图上尝试三组实验:重复加入同一范围,观察元素数量保持不变;加入相邻范围,观察边界两侧的 Contains;加入有重叠的范围,用并集计算预期数量。每组都重新创建位图,避免前一组数据影响判断。这里只使用内存对象,没有文件或网络资源需要关闭。

AddRange会先清空已有内容吗?不会,它是添加操作。需要新集合时创建新 Bitmap,避免误把添加理解为替换。

AddRange和Flip能互换吗?不能。Flip会翻转范围内成员的存在状态,已存在的值可能被删除;重复调用的含义与添加不同。

连续范围一定更省内存吗?不要把“连续”直接变成具体内存或速度承诺。RunOptimize 可尝试优化连续段的表示,但不改变集合成员;实际收益要按数据分布和应用负载衡量。本文不编造优化前后的数字。

批量加入连续整数时,最关键的是先统一半开区间约定、保持端点运算的类型宽度,并在业务入口处理非法范围。这样既能减少逐个构造元素的代码,也能把常见的末端漏值和溢出问题限制在清晰的函数边界内。

参考:v1.9.4接口文档;范围操作实现。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
Go roaring 怎样计算压缩位图的交集Go roaring 怎样计算压缩位图的交集
上一篇
Go roaring 怎样计算压缩位图的交集
Go roaring 怎样把Roaring位图序列化到字节流
下一篇
Go roaring 怎样把Roaring位图序列化到字节流
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    806次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    797次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    885次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    856次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    684次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码