## 主要变更 ### 架构改进 - 明确索引(Index)与偏移(Offset)的职责分离 - Index: 记录序号(逻辑概念),用于状态判断 - Offset: 文件字节位置(物理概念),仅用于 I/O 操作 ### API 变更 - 删除所有 Position 相关方法: - `LogCursor.StartPos()/EndPos()` - `LogTailer.GetStartPos()/GetEndPos()` - `TopicProcessor.GetProcessingPosition()/GetReadPosition()` - `Seqlog.GetProcessingPosition()/GetReadPosition()` - 新增索引方法: - `LogCursor.StartIndex()/EndIndex()` - `LogTailer.GetStartIndex()/GetEndIndex()` - `TopicProcessor.GetProcessingIndex()/GetReadIndex()` - `Seqlog.GetProcessingIndex()/GetReadIndex()` - `Seqlog.GetProcessor()` - 获取 processor 实例以访问 Index ### 查询接口变更 - `RecordQuery.QueryOldest(startIndex, count, startIdx, endIdx)` - 使用索引参数 - `RecordQuery.QueryNewest(endIndex, count, startIdx, endIdx)` - 使用索引参数 - `RecordQuery.QueryAt(position, direction, count, startIdx, endIdx)` - startIdx/endIdx 用于状态判断 ### 性能优化 - 状态判断改用整数比较,不再需要计算偏移量 - 减少不必要的索引到偏移的转换 - 只在实际文件 I/O 时才获取 offset ### 测试更新 - 更新所有测试用例使用新的 Index API - 更新示例代码(topic_processor_example.go, webapp/main.go) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
117 lines
3.0 KiB
Go
117 lines
3.0 KiB
Go
package main
|
||
|
||
import (
|
||
"fmt"
|
||
"log"
|
||
"log/slog"
|
||
|
||
"code.tczkiot.com/seqlog"
|
||
)
|
||
|
||
func main() {
|
||
// ===== TopicProcessor 作为聚合器使用 =====
|
||
fmt.Println("=== TopicProcessor 聚合器示例 ===\n")
|
||
|
||
// 创建 TopicProcessor(提供空 handler)
|
||
logger := slog.Default()
|
||
tp, err := seqlog.NewTopicProcessor("test_seqlog", "app", logger, &seqlog.TopicConfig{
|
||
Handler: func(rec *seqlog.Record) error {
|
||
return nil // 示例中不需要处理
|
||
},
|
||
})
|
||
if err != nil {
|
||
log.Fatalf("创建 TopicProcessor 失败: %v", err)
|
||
}
|
||
|
||
// ===== 1. 写入数据 =====
|
||
fmt.Println("1. 写入数据:")
|
||
for i := 1; i <= 5; i++ {
|
||
data := fmt.Sprintf("消息 #%d", i)
|
||
offset, err := tp.Write([]byte(data))
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
fmt.Printf(" 写入成功: offset=%d, data=%s\n", offset, data)
|
||
}
|
||
fmt.Println()
|
||
|
||
// ===== 2. 获取记录总数 =====
|
||
fmt.Println("2. 查询记录总数:")
|
||
count := tp.GetRecordCount()
|
||
fmt.Printf(" 总共 %d 条记录\n\n", count)
|
||
|
||
// ===== 3. 获取索引 =====
|
||
fmt.Println("3. 使用索引:")
|
||
index := tp.Index()
|
||
fmt.Printf(" 索引记录数: %d\n", index.Count())
|
||
fmt.Printf(" 最后偏移: %d\n\n", index.LastOffset())
|
||
|
||
// ===== 4. 使用查询器查询 =====
|
||
fmt.Println("4. 查询记录:")
|
||
|
||
// 查询最老的 3 条记录(从索引 0 开始)
|
||
oldest, err := tp.QueryOldest(0, 3)
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
fmt.Println(" 查询最老的 3 条:")
|
||
for i, rws := range oldest {
|
||
fmt.Printf(" [%d] 状态=%s, 数据=%s\n", i, rws.Status, string(rws.Record.Data))
|
||
}
|
||
|
||
// 查询最新的 2 条记录(从最后一条开始)
|
||
totalCount := tp.GetRecordCount()
|
||
newest, err := tp.QueryNewest(totalCount-1, 2)
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
fmt.Println(" 查询最新的 2 条:")
|
||
for i, rws := range newest {
|
||
fmt.Printf(" [%d] 状态=%s, 数据=%s\n", i, rws.Status, string(rws.Record.Data))
|
||
}
|
||
fmt.Println()
|
||
|
||
// ===== 5. 使用游标读取 =====
|
||
fmt.Println("5. 使用游标读取:")
|
||
cursor, err := tp.Cursor()
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
defer cursor.Close()
|
||
|
||
// 读取 3 条记录
|
||
records, err := cursor.NextRange(3)
|
||
if err != nil {
|
||
log.Fatal(err)
|
||
}
|
||
fmt.Printf(" 读取了 %d 条记录:\n", len(records))
|
||
for i, rec := range records {
|
||
fmt.Printf(" [%d] %s\n", i, string(rec.Data))
|
||
}
|
||
|
||
// 提交游标位置
|
||
cursor.Commit()
|
||
fmt.Printf(" 游标位置: start=%d, end=%d\n\n", cursor.StartIndex(), cursor.EndIndex())
|
||
|
||
// ===== 6. 继续写入 =====
|
||
fmt.Println("6. 继续写入:")
|
||
for i := 6; i <= 8; i++ {
|
||
data := fmt.Sprintf("消息 #%d", i)
|
||
offset, _ := tp.Write([]byte(data))
|
||
fmt.Printf(" 写入成功: offset=%d, data=%s\n", offset, data)
|
||
}
|
||
fmt.Println()
|
||
|
||
// ===== 7. 再次查询总数 =====
|
||
fmt.Println("7. 更新后的记录总数:")
|
||
count = tp.GetRecordCount()
|
||
fmt.Printf(" 总共 %d 条记录\n\n", count)
|
||
|
||
// ===== 8. 获取统计信息 =====
|
||
fmt.Println("8. 统计信息:")
|
||
stats := tp.GetStats()
|
||
fmt.Printf(" 写入: %d 条, %d 字节\n", stats.WriteCount, stats.WriteBytes)
|
||
|
||
fmt.Println("\n=== 所有示例完成 ===")
|
||
}
|