Help us shape the future of Go! Take the 2026 Go Developer Survey

storage

package
v0.2.0 Latest Latest
Warning

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

Go to latest
Published: Nov 1, 2026 License: MIT Imports: 7 Imported by: 0

Documentation

Overview

Package storage 定义 JSON 记录和追加日志的读写接口。

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func PrefixRange

func PrefixRange(prefix RecordKey) (RecordKey, RecordKey)

PrefixRange 返回覆盖指定前缀的 [start, end) 范围。

Types

type Direction

type Direction string

Direction 是 Record 与 Log 读取的方向。

const (
	// DirectionAsc 按排序依据从小到大读取。
	DirectionAsc Direction = "asc"
	// DirectionDesc 按排序依据从大到小读取。
	DirectionDesc Direction = "desc"
)

func (Direction) WithDefault

func (d Direction) WithDefault() (Direction, error)

WithDefault 补齐并检查读取方向。

type ListLogEntriesRequest

type ListLogEntriesRequest struct {
	Path     StreamPath
	StreamID StreamID
	Order    Direction
	// Cursor 为 0 时从这个方向的起点读;非零时从它之后读,不含它本身。
	Cursor Ordinal
	Limit  int
}

ListLogEntriesRequest 是一次日志分页读取的条件;日志只按 Ordinal 排序。

type ListRecordsRequest

type ListRecordsRequest struct {
	Namespace string
	// Start 是 Key 范围下界(含),两种排序都生效;为空时没有下界。
	Start RecordKey
	// End 是 Key 范围上界(不含);为空时没有上界。
	End    RecordKey
	Order  Order
	Cursor RecordCursor
	Limit  int
	// Filter 先筛选再排序分页;整组与 Key 范围及游标取 AND。
	Filter RecordFilter
}

ListRecordsRequest 是在一个 namespace 里按 Key 范围、排序和游标分页读取的条件。

type LogEntry

type LogEntry struct {
	Ordinal Ordinal
	// UpdatedAt 是追加时的 Unix 毫秒,由 LogStorage 分配;日志追加后不再修改,这个时间就是保存时间。
	UpdatedAt int64
	Payload   json.RawMessage
}

LogEntry 是 Stream 中一条已追加的 JSON Payload。

type LogEntryInfo

type LogEntryInfo struct {
	Ordinal   Ordinal
	UpdatedAt int64
}

LogEntryInfo 是刚追加的一条日志分到的顺序号和追加时间。

type LogStorage

type LogStorage interface {
	// Append 把一批 Payload(至少一条)一次写入并 fsync,按顺序返回分到的顺序号和追加时间,同一批的追加时间相同;
	// 崩溃时可能只写入这批的一部分。
	Append(ctx context.Context, path StreamPath, streamID StreamID, payloads ...json.RawMessage) ([]LogEntryInfo, error)
	// Delete 删除指定路径下的一条 Stream;Stream 不存在时什么都不做。
	Delete(ctx context.Context, path StreamPath, streamID StreamID) error
	// DeletePath 删除 path 下全部 Stream;path 不存在时什么都不做。
	DeletePath(ctx context.Context, path StreamPath) error
	// List 按方向分页;这个方向还有更多时 Next 为本页最后一个 Ordinal,否则为 0。
	List(ctx context.Context, request ListLogEntriesRequest) (Page[LogEntry, Ordinal], error)
	// GetStreamPaths 返回含有这个 StreamID 的全部 Path,按字节序升序;一个都没有时返回空切片。
	GetStreamPaths(ctx context.Context, streamID StreamID) ([]StreamPath, error)
}

LogStorage 保存按 Stream 追加的 JSON Payload,并按请求方向读取。

type Order

type Order struct {
	By        OrderBy   `json:"by,omitempty"`
	Direction Direction `json:"direction,omitempty"`
}

Order 描述 Record 的排序:按什么、往哪个方向;零值表示按 Key 升序。

func (Order) WithDefaults

func (o Order) WithDefaults() (Order, error)

WithDefaults 补齐并检查排序字段和方向。

type OrderBy

type OrderBy string

OrderBy 是 Record 的排序依据。

const (
	// OrderByKey 按 Key 字节序排序,是默认依据。
	OrderByKey OrderBy = "key"
	// OrderByUpdatedAt 按最后写入时间排序,时间相同再按 Key。
	OrderByUpdatedAt OrderBy = "updated_at"
)

type Ordinal

type Ordinal uint64

Ordinal 是 Stream 内从 1 开始、由 LogStorage 分配的严格顺序;0 只用于初始游标。

type Page

type Page[T any, C comparable] struct {
	Items []T
	Next  C
}

Page 是一页结果;Next 为零值表示没有更多。

type Record

type Record struct {
	Key RecordKey
	// UpdatedAt 是最后一次写入的 Unix 毫秒,由写入方给出。
	UpdatedAt int64
	Payload   json.RawMessage
}

Record 是一条已保存的 JSON Record。

type RecordCursor

type RecordCursor struct {
	Key       RecordKey
	UpdatedAt int64
}

RecordCursor 是上一页最后一条 Record 的位置;零值表示从起点开始。 按 Key 排序只用 Key;按 UpdatedAt 排序用 (UpdatedAt, Key)。按 UpdatedAt 倒序翻页期间被更新的 Record 会排到最前面, 之后的页里不再出现:还没读到的就跳过了,读过的也不会重复。

type RecordField

type RecordField struct {
	Name            string
	PayloadJSONPath []string
}

RecordField 声明 Payload 内允许筛选的字符串字段;路径逐段表示 JSON 对象键,不解释通配符或数组下标。

type RecordFilter

type RecordFilter struct {
	Logic      RecordFilterLogic
	Conditions []RecordFilterCondition
}

RecordFilter 组合一组条件;空 Conditions 不筛选,Logic 零值按 AND,不支持嵌套分组。

type RecordFilterCondition

type RecordFilterCondition struct {
	Field    string
	Operator RecordFilterOperator
	// Values 在 in 时至少一项,命中任意一项即匹配;contains 时恰好一项,按普通子串匹配。
	Values []string
}

RecordFilterCondition 筛选一个已声明字段;缺失、null 或非字符串值不匹配。

type RecordFilterLogic

type RecordFilterLogic string

RecordFilterLogic 指定筛选组内各条件按 AND 还是 OR 组合。

const (
	RecordFilterAnd RecordFilterLogic = "and"
	RecordFilterOr  RecordFilterLogic = "or"
)

type RecordFilterOperator

type RecordFilterOperator string

RecordFilterOperator 指定字符串字段的匹配方式,均区分大小写。

const (
	RecordFilterIn       RecordFilterOperator = "in"
	RecordFilterContains RecordFilterOperator = "contains"
)

type RecordKey

type RecordKey string

RecordKey 是 Record 在一个 namespace 里的 Key,按字节序排列。

type RecordNamespace

type RecordNamespace struct {
	Name   string
	Fields []RecordField
	// IndexedFields 里每个字段都建立字段值、UpdatedAt、Key 的联合索引,字段必须已在 Fields 里声明。
	IndexedFields []string
}

RecordNamespace 声明一组记录及可以筛选的字段。

type RecordStorage

type RecordStorage interface {
	// Set 原样保存 record 的 Key、UpdatedAt 和 Payload;UpdatedAt 由调用方给出,必须大于 0。
	Set(ctx context.Context, namespace string, record Record) error
	// MSet 批量写入同一 namespace,每条使用自己的 UpdatedAt;同一批里重复的 Key 以后一条为准;失败时可能已经写入部分记录。
	MSet(ctx context.Context, namespace string, records []Record) error
	// Get 读取指定记录,同时返回是否找到。
	Get(ctx context.Context, namespace string, key RecordKey) (Record, bool, error)
	// MGet 返回找到的 Record;不同 Key 的结果可能来自不同写入时刻。
	MGet(ctx context.Context, namespace string, keys []RecordKey) (map[RecordKey]Record, error)
	// Delete 删除指定记录,记录不存在时不报错。
	Delete(ctx context.Context, namespace string, key RecordKey) error
	// DeleteRange 删除 [start, end) 内的记录,end 为空时不设上界。
	DeleteRange(ctx context.Context, namespace string, start, end RecordKey) error
	// List 按 Order 分页;还有下一页时 Next 为本页最后一条的位置。
	List(ctx context.Context, request ListRecordsRequest) (Page[Record, RecordCursor], error)
}

RecordStorage 保存按 namespace 和 Key 定位的 JSON Record。

type StagedLogStorage

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

StagedLogStorage 把指定 Stream 的日志先写在 staging,其余 Stream 直接读写 target; Persist 把暂存日志搬到 target 后,全部读写 target。 staging 必须是只由本实例写入的空库;搬运前暂存的 Stream 只读 staging,不合并 target 中的日志。

func NewStagedLogStorage

func NewStagedLogStorage(staging, target LogStorage, stagedStreamIDs ...StreamID) *StagedLogStorage

NewStagedLogStorage 创建指定 Stream 的暂存存储。

func (*StagedLogStorage) Append

func (s *StagedLogStorage) Append(ctx context.Context, path StreamPath, streamID StreamID, payloads ...json.RawMessage) ([]LogEntryInfo, error)

Append 向当前存储追加日志。

func (*StagedLogStorage) Delete

func (s *StagedLogStorage) Delete(ctx context.Context, path StreamPath, streamID StreamID) error

Delete 从当前存储删除指定 Stream。

func (*StagedLogStorage) DeletePath

func (s *StagedLogStorage) DeletePath(ctx context.Context, path StreamPath) error

DeletePath 删除 staging 和 target 中指定路径下的全部 Stream。

func (*StagedLogStorage) GetStreamPaths

func (s *StagedLogStorage) GetStreamPaths(ctx context.Context, streamID StreamID) ([]StreamPath, error)

GetStreamPaths 从当前存储列出包含指定 Stream 的路径。

func (*StagedLogStorage) IsPersisted

func (s *StagedLogStorage) IsPersisted() bool

IsPersisted 暂存数据已经全部写入 target 了吗?

func (*StagedLogStorage) List

List 从当前存储分页读取日志。

func (*StagedLogStorage) Persist

func (s *StagedLogStorage) Persist(ctx context.Context) error

Persist 把暂存的日志按顺序追加到 target,全部成功后读写都改走 target。

type StagedRecordStorage

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

StagedRecordStorage 把指定分组的记录先写在 staging,其余分组直接读写 target; Persist 把暂存记录搬到 target 后,全部读写 target。 staging 必须是只由本实例写入的空库;搬运前暂存的分组只读 staging,不合并 target 中的记录。

func NewStagedRecordStorage

func NewStagedRecordStorage(staging, target RecordStorage, stagedNamespaces ...string) *StagedRecordStorage

NewStagedRecordStorage 创建指定记录分组的暂存存储。

func (*StagedRecordStorage) Delete

func (s *StagedRecordStorage) Delete(ctx context.Context, namespace string, key RecordKey) error

Delete 从当前存储删除一条记录。

func (*StagedRecordStorage) DeleteRange

func (s *StagedRecordStorage) DeleteRange(ctx context.Context, namespace string, start, end RecordKey) error

DeleteRange 从当前存储删除指定 Key 范围内的记录。

func (*StagedRecordStorage) Get

func (s *StagedRecordStorage) Get(ctx context.Context, namespace string, key RecordKey) (Record, bool, error)

Get 从当前存储读取一条记录。

func (*StagedRecordStorage) IsPersisted

func (s *StagedRecordStorage) IsPersisted() bool

IsPersisted 暂存数据已经全部写入 target 了吗?

func (*StagedRecordStorage) List

List 从当前存储分页读取记录。

func (*StagedRecordStorage) MGet

func (s *StagedRecordStorage) MGet(ctx context.Context, namespace string, keys []RecordKey) (map[RecordKey]Record, error)

MGet 从当前存储批量读取记录。

func (*StagedRecordStorage) MSet

func (s *StagedRecordStorage) MSet(ctx context.Context, namespace string, records []Record) error

MSet 向当前存储批量写入记录。

func (*StagedRecordStorage) Persist

func (s *StagedRecordStorage) Persist(ctx context.Context) error

Persist 把暂存的记录原样写入 target,全部成功后读写都改走 target。

func (*StagedRecordStorage) Set

func (s *StagedRecordStorage) Set(ctx context.Context, namespace string, record Record) error

Set 向当前存储写入一条记录。

type StreamID

type StreamID string

StreamID 标识 Path 内的一条 Stream;只允许字母、数字、`_` 和 `-`。

type StreamPath

type StreamPath string

StreamPath 是 Stream 所在的一级目录,例如对话 ID;只允许字母、数字、`_` 和 `-`。

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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