bloom

package
v0.0.13 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: May 22, 2025 License: MIT Imports: 12 Imported by: 0

README

bloom

简介

bloom 包实现了高效的布隆过滤器(Bloom Filter),用于大规模集合的成员判定,具备极高的空间效率和可配置的误判率。支持分组、可插拔存储(内存/自定义)、多哈希函数、并发安全,适用于缓存预判、黑名单、唯一性校验等场景。

主要特性
  • 支持标准布隆过滤器接口(添加、判定、分组操作)
  • 支持自定义存储后端(内存、可扩展为 Redis 等)
  • 支持分组隔离,适合多租户/多集合场景
  • 支持误判率、元素数量等参数灵活配置
  • 并发安全,适合高并发环境
  • 采用 murmur3 哈希算法,分布均匀
  • 完善的错误处理与日志能力
  • 完整单元测试覆盖
设计理念

bloom 包遵循"高效、灵活、易用"的设计理念,核心接口与实现分离,支持多种存储后端。通过 Option 模式灵活配置,支持分组、日志、参数自定义。默认实现为高性能内存存储,便于本地高并发场景。

安装

前置条件
  • Go 版本要求:Go 1.18+
  • 依赖要求:
    • github.com/spaolacci/murmur3
    • github.com/spf13/cast
    • github.com/stretchr/testify(仅测试)
    • github.com/golang/mock/gomock(仅测试)
安装命令
go get -u github.com/fsyyft-go/kit/container/bloom

快速开始

基础用法
package main

import (
    "context"
    "fmt"
    "github.com/fsyyft-go/kit/container/bloom"
)

func main() {
    // 创建布隆过滤器,预计 10000 元素,误判率 0.01
    bf, _, err := bloom.NewBloom(
        bloom.WithName("my-bloom"),
        bloom.WithExpectedElements(10000),
        bloom.WithFalsePositiveRate(0.01),
    )
    if err != nil {
        panic(err)
    }
    ctx := context.Background()
    // 添加元素
    _ = bf.Put(ctx, "foo")
    // 判定元素
    exists, _ := bf.Contain(ctx, "foo")
    fmt.Println("foo 是否可能存在:", exists)
}
分组用法
// 支持分组隔离
_ = bf.GroupPut(ctx, "group1", "bar")
exists, _ := bf.GroupContain(ctx, "group1", "bar")
自定义存储
// 使用内存存储,指定内存块大小(字节)
store := bloom.NewMemoryStore(1024*1024) // 1MB
bf, _, _ := bloom.NewBloom(
    bloom.WithStore(store),
    bloom.WithExpectedElements(1000),
)

详细指南

核心概念
  • 布隆过滤器:空间效率极高的概率型集合判定结构,适合大数据量场景。
  • 误判率:可配置,越低则空间需求越大。
  • 分组:同一过滤器可隔离多个逻辑集合。
  • 存储后端:可插拔,默认内存实现。
  • 多哈希函数:自动根据参数计算最优数量。
常见用例
  • 缓存穿透预判
  • 黑名单/白名单判定
  • 唯一性校验
  • 分布式唯一性预过滤(可扩展 Redis 存储)
最佳实践
  • 合理设置元素数量和误判率,避免空间浪费或误判过高
  • 对于分布式场景可自定义 Store 实现
  • 并发场景下直接使用,无需额外加锁
  • 始终检查返回的 error

API 文档

主要类型
// Bloom 布隆过滤器接口
 type Bloom interface {
    Contain(ctx context.Context, value string) (bool, error)
    Put(ctx context.Context, value string) error
    GroupContain(ctx context.Context, group, value string) (bool, error)
    GroupPut(ctx context.Context, group, value string) error
}

// Store 存储后端接口
 type Store interface {
    Exist(ctx context.Context, key string, hash []uint64) (bool, error)
    Add(ctx context.Context, key string, hash []uint64) error
}

// Option 配置项类型
 type Option func(*bloom)

// NewBloom 创建布隆过滤器
func NewBloom(opts ...Option) (Bloom, func(), error)

// NewMemoryStore 创建内存存储
func NewMemoryStore(size int) Store
关键函数
  • NewBloom:创建布隆过滤器,支持 Option 配置
  • Put/Contain:添加/判定元素
  • GroupPut/GroupContain:分组添加/判定
  • NewMemoryStore:创建内存存储
配置选项
  • WithName(name string):设置过滤器名称
  • WithStore(store Store):自定义存储后端
  • WithExpectedElements(n uint64):预计元素数量
  • WithFalsePositiveRate(p float64):误判率
  • WithLogger(logger log.Logger):自定义日志

错误处理

  • 名称为空、重复、误判率参数非法等会返回详细错误
  • 存储层错误会原样返回
  • 建议所有操作均检查 error

性能指标

  • 内存存储百万级元素判定/添加操作均为 O(k),k 为哈希函数数,单次操作微秒级
  • 误判率与空间、哈希函数数量成反比

测试覆盖率

  • 单元测试覆盖所有接口、边界、异常场景
  • 使用 gomock+testify,覆盖率 100%

调试指南

  • 检查参数设置是否合理(元素量、误判率)
  • 内存存储建议根据实际场景调整 size
  • 分组键名冲突可通过 WithName 区分

相关文档

贡献指南

欢迎提交 Issue、PR 或建议,详见 贡献指南

许可证

本项目采用 MIT License 许可证。详见 LICENSE

Documentation

Overview

Package bloom 提供了布隆过滤器的接口定义和实现。 布隆过滤器是一种空间效率很高的概率型数据结构,用于判断一个元素是否在集合中。 它通过多个哈希函数将元素映射到位数组中的多个位置,从而实现高效的成员查询。

Package bloom 提供了布隆过滤器的接口定义和实现。

Package bloom 提供了布隆过滤器的接口定义和实现。 布隆过滤器是一种空间效率很高的概率型数据结构,用于判断一个元素是否在集合中。 它通过多个哈希函数将元素映射到位数组中的多个位置,从而实现高效的成员查询。

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrBloomNameEmpty                = errors.New("bloom: bloom name can't be empty")
	ErrBloomNameRepeated             = errors.New("bloom: bloom name can't repeated")
	ErrBloomFalseProbabilityThanOne  = errors.New("bloom: bloom false probability can't than 1")
	ErrBloomFalseProbabilityNegative = errors.New("bloom: bloom false probability can't be negative")
)
View Source
var (
	ErrResultTypeNotArray = errors.New("result type is not array")
)

ErrResultTypeNotArray 表示 Redis 脚本返回结果类型不是数组时的错误。 当期望返回数组类型但实际类型不符时会返回该错误。

Functions

func NewMemoryStore

func NewMemoryStore(size int) *memoryStore

NewMemoryStore 创建一个新的内存存储实例。

参数:

  • size:内存块大小,以 byte 为单位。如果为 0,则使用默认大小。

返回值:

  • *memoryStore:新的内存存储实例

func NewRedisStore

func NewRedisStore(redis kitredis.Redis) (*redisStore, error)

NewRedisStore 创建一个基于 Redis 的布隆过滤器存储实例。

参数:

  • redis:Redis 客户端实例,用于与 Redis 服务进行通信。

返回值:

  • *redisStore:Redis 存储实现的实例指针。
  • error:初始化过程中发生的错误。

Types

type Bloom

type Bloom interface {
	// Contain 判断指定元素是否可能存在于布隆过滤器中。
	//
	// 参数:
	//   - ctx:上下文对象,用于控制请求的生命周期
	//   - value:要判断是否存在的元素值
	//
	// 返回值:
	//   - bool:元素是否可能存在于布隆过滤器中
	//     - false:元素肯定不存在
	//     - true:元素可能存在(存在误判可能)
	//   - error:操作过程中发生的错误
	Contain(ctx context.Context, value string) (bool, error)

	// Put 将指定元素添加到布隆过滤器中。
	//
	// 参数:
	//   - ctx:上下文对象,用于控制请求的生命周期
	//   - value:要添加到布隆过滤器中的元素值
	//
	// 返回值:
	//   - error:添加过程中发生的错误
	Put(ctx context.Context, value string) error

	// GroupContain 判断指定分组中是否可能包含指定元素。
	//
	// 参数:
	//   - ctx:上下文对象,用于控制请求的生命周期
	//   - group:分组名称,用于区分不同的数据集合
	//   - value:要判断是否存在的元素值
	//
	// 返回值:
	//   - bool:元素是否可能存在于指定分组中
	//     - false:元素在指定分组中肯定不存在
	//     - true:元素在指定分组中可能存在(存在误判可能)
	//   - error:操作过程中发生的错误
	GroupContain(ctx context.Context, group string, value string) (bool, error)

	// GroupPut 将指定元素添加到指定分组的布隆过滤器中。
	//
	// 参数:
	//   - ctx:上下文对象,用于控制请求的生命周期
	//   - group:分组名称,用于区分不同的数据集合
	//   - value:要添加到布隆过滤器中的元素值
	//
	// 返回值:
	//   - error:添加过程中发生的错误
	GroupPut(ctx context.Context, group string, value string) error
}

Bloom 定义了布隆过滤器的核心接口。 该接口提供了基本的元素判断和添加功能,以及分组操作的支持。 布隆过滤器的主要特点是空间效率高,但可能存在误判(假阳性)。

func NewBloom

func NewBloom(opts ...Option) (Bloom, func(), error)

NewBloom 创建一个新的布隆过滤器实例。

参数:

  • opts:配置选项列表。

返回值:

  • Bloom:实现了 Bloom 接口的布隆过滤器实例。

type MockBloom

type MockBloom struct {
	// contains filtered or unexported fields
}

MockBloom 是 Bloom 接口的 mock 实现。 用于在测试中模拟布隆过滤器的行为。

func NewMockBloom

func NewMockBloom(ctrl *gomock.Controller) *MockBloom

NewMockBloom 创建一个新的 MockBloom 实例。

参数:

  • ctrl:gomock 控制器实例,用于管理 mock 对象

返回值:

  • *MockBloom:新创建的 mock 实例

func (*MockBloom) Contain

func (m *MockBloom) Contain(ctx context.Context, value string) (bool, error)

Contain 模拟了 Bloom 接口的 Contain 方法。 用于判断指定元素是否可能存在于布隆过滤器中。

参数:

  • ctx:上下文对象,用于控制请求的生命周期
  • value:要判断是否存在的元素值

返回值:

  • bool:元素是否可能存在于布隆过滤器中
  • error:操作过程中发生的错误

func (*MockBloom) EXPECT

func (m *MockBloom) EXPECT() *MockBloomMockRecorder

EXPECT 返回一个对象,允许调用者指示预期的使用。

返回值:

  • *MockBloomMockRecorder:用于设置期望的调用记录器

func (*MockBloom) GroupContain

func (m *MockBloom) GroupContain(ctx context.Context, group, value string) (bool, error)

GroupContain 模拟了 Bloom 接口的 GroupContain 方法。 用于判断指定分组中是否可能包含指定元素。

参数:

  • ctx:上下文对象,用于控制请求的生命周期
  • group:分组名称,用于区分不同的数据集合
  • value:要判断是否存在的元素值

返回值:

  • bool:元素是否可能存在于指定分组中
  • error:操作过程中发生的错误

func (*MockBloom) GroupPut

func (m *MockBloom) GroupPut(ctx context.Context, group, value string) error

GroupPut 模拟了 Bloom 接口的 GroupPut 方法。 用于将指定元素添加到指定分组的布隆过滤器中。

参数:

  • ctx:上下文对象,用于控制请求的生命周期
  • group:分组名称,用于区分不同的数据集合
  • value:要添加到布隆过滤器中的元素值

返回值:

  • error:添加过程中发生的错误

func (*MockBloom) Put

func (m *MockBloom) Put(ctx context.Context, value string) error

Put 模拟了 Bloom 接口的 Put 方法。 用于将指定元素添加到布隆过滤器中。

参数:

  • ctx:上下文对象,用于控制请求的生命周期
  • value:要添加到布隆过滤器中的元素值

返回值:

  • error:添加过程中发生的错误

type MockBloomMockRecorder

type MockBloomMockRecorder struct {
	// contains filtered or unexported fields
}

MockBloomMockRecorder 是 MockBloom 的调用记录器。 用于记录和验证对 MockBloom 的方法调用。

func (*MockBloomMockRecorder) Contain

func (mr *MockBloomMockRecorder) Contain(ctx, value interface{}) *gomock.Call

Contain 指示对 Contain 方法的预期调用。

参数:

  • ctx:上下文对象
  • value:要判断的元素值

返回值:

  • *gomock.Call:用于设置期望的调用

func (*MockBloomMockRecorder) GroupContain

func (mr *MockBloomMockRecorder) GroupContain(ctx, group, value interface{}) *gomock.Call

GroupContain 指示对 GroupContain 方法的预期调用。

参数:

  • ctx:上下文对象
  • group:分组名称
  • value:要判断的元素值

返回值:

  • *gomock.Call:用于设置期望的调用

func (*MockBloomMockRecorder) GroupPut

func (mr *MockBloomMockRecorder) GroupPut(ctx, group, value interface{}) *gomock.Call

GroupPut 指示对 GroupPut 方法的预期调用。

参数:

  • ctx:上下文对象
  • group:分组名称
  • value:要添加的元素值

返回值:

  • *gomock.Call:用于设置期望的调用

func (*MockBloomMockRecorder) Put

func (mr *MockBloomMockRecorder) Put(ctx, value interface{}) *gomock.Call

Put 指示对 Put 方法的预期调用。

参数:

  • ctx:上下文对象
  • value:要添加的元素值

返回值:

  • *gomock.Call:用于设置期望的调用

type MockStore

type MockStore struct {
	// contains filtered or unexported fields
}

MockStore 是 Store 接口的 mock 实现。 用于在测试中模拟布隆过滤器底层数据存储的行为。

func NewMockStore

func NewMockStore(ctrl *gomock.Controller) *MockStore

NewMockStore 创建一个新的 MockStore 实例。

参数:

  • ctrl:gomock 控制器实例,用于管理 mock 对象

返回值:

  • *MockStore:新创建的 mock 实例

func (*MockStore) Add

func (m *MockStore) Add(ctx context.Context, key string, hash []uint64) error

Add 模拟了 Store 接口的 Add 方法。 用于将一组 hash 值添加到指定 key 对应的存储中。

参数:

  • ctx:上下文对象,用于控制请求的生命周期
  • key:存储键名
  • hash:要添加的哈希值列表

返回值:

  • error:添加过程中发生的错误

func (*MockStore) EXPECT

func (m *MockStore) EXPECT() *MockStoreMockRecorder

EXPECT 返回一个对象,允许调用者指示预期的使用。

返回值:

  • *MockStoreMockRecorder:用于设置期望的调用记录器

func (*MockStore) Exist

func (m *MockStore) Exist(ctx context.Context, key string, hash []uint64) (bool, error)

Exist 模拟了 Store 接口的 Exist 方法。 用于判断指定 key 对应的所有 hash 值是否都已存在。

参数:

  • ctx:上下文对象,用于控制请求的生命周期
  • key:存储键名
  • hash:要判断的哈希值列表

返回值:

  • bool:所有哈希值是否都已存在
  • error:查询过程中发生的错误

type MockStoreMockRecorder

type MockStoreMockRecorder struct {
	// contains filtered or unexported fields
}

MockStoreMockRecorder 是 MockStore 的调用记录器。 用于记录和验证对 MockStore 的方法调用。

func (*MockStoreMockRecorder) Add

func (mr *MockStoreMockRecorder) Add(ctx, key, hash interface{}) *gomock.Call

Add 指示对 Add 方法的预期调用。

参数:

  • ctx:上下文对象
  • key:存储键名
  • hash:要添加的哈希值列表

返回值:

  • *gomock.Call:用于设置期望的调用

func (*MockStoreMockRecorder) Exist

func (mr *MockStoreMockRecorder) Exist(ctx, key, hash interface{}) *gomock.Call

Exist 指示对 Exist 方法的预期调用。

参数:

  • ctx:上下文对象
  • key:存储键名
  • hash:要判断的哈希值列表

返回值:

  • *gomock.Call:用于设置期望的调用

type Option

type Option func(*bloom)

Option 定义了布隆过滤器的配置选项类型。 用于在创建布隆过滤器时进行自定义配置。

func WithExpectedElements

func WithExpectedElements(n uint64) Option

WithExpectedElements 设置布隆过滤器预计要存储的元素数量。

参数:

  • n:预计元素数量。

返回值:

  • Option:配置选项函数。

func WithFalsePositiveRate

func WithFalsePositiveRate(p float64) Option

WithFalsePositiveRate 设置布隆过滤器的期望误判率。

参数:

  • p:期望误判率。

返回值:

  • Option:配置选项函数。

func WithLogger

func WithLogger(logger kitlog.Logger) Option

WithLogger 设置布隆过滤器的日志记录器。

参数:

  • logger:日志记录器实例。

返回值:

  • Option:配置选项函数。

func WithName

func WithName(name string) Option

WithName 设置布隆过滤器的名称。

参数:

  • name:布隆过滤器的名称。

返回值:

  • Option:配置选项函数。

func WithRedis

func WithRedis(redis kitredis.Redis) Option

WithRedis 设置布隆过滤器的 Redis 客户端。

参数:

  • redis:Redis 客户端实例。

返回值:

func WithStore

func WithStore(store Store) Option

WithStore 设置布隆过滤器的存储接口。

参数:

  • store:存储接口实现。

返回值:

  • Option:配置选项函数。

type Store

type Store interface {
	// Exist 判断指定 key 对应的所有 hash 值是否都已存在。
	//
	// 参数:
	//   - ctx:上下文对象,用于控制请求的生命周期
	//   - key:存储键名
	//   - hash:要判断的哈希值列表
	//
	// 返回值:
	//   - bool:所有哈希值是否都已存在
	//     - false:至少有一个哈希值不存在
	//     - true:所有哈希值都存在
	//   - error:查询过程中发生的错误
	Exist(ctx context.Context, key string, hash []uint64) (bool, error)

	// Add 将一组 hash 值添加到指定 key 对应的存储中。
	//
	// 参数:
	//   - ctx:上下文对象,用于控制请求的生命周期
	//   - key:存储键名
	//   - hash:要添加的哈希值列表
	//
	// 返回值:
	//   - error:添加过程中发生的错误
	Add(ctx context.Context, key string, hash []uint64) error
}

Store 定义了布隆过滤器底层数据存储的接口。 该接口负责实际的数据存储和查询操作。 不同的存储实现可以支持不同的后端存储系统,如内存、Redis 等。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL