package main import ( "fmt" "log" "code.tczkiot.com/seqlog" ) func main() { logPath := "test_seqlog/app.log" // ===== 示例 1:使用带索引的写入器 ===== fmt.Println("=== 示例 1:带索引的写入器 ===") // 创建索引 index, err := seqlog.NewRecordIndex(logPath) if err != nil { log.Fatal(err) } defer index.Close() // 创建写入器(使用共享索引) writer, err := seqlog.NewLogWriter(logPath, index) if err != nil { log.Fatal(err) } // 写入日志时,索引会自动更新 var lastOffset int64 for i := 1; i <= 10; i++ { data := fmt.Sprintf("日志记录 #%d", i) offset, err := writer.Append([]byte(data)) if err != nil { log.Fatal(err) } lastOffset = offset fmt.Printf("写入: offset=%d, data=%s\n", offset, data) } writer.Close() fmt.Printf("索引文件已创建: %s.idx\n\n", logPath) // ===== 示例 2:使用索引进行快速查询 ===== fmt.Println("=== 示例 2:带索引的查询器 ===") // 先获取索引(由 writer 创建) index2, err := seqlog.NewRecordIndex(logPath) if err != nil { log.Fatal(err) } defer index2.Close() // 创建查询器(使用外部索引) query, err := seqlog.NewRecordQuery(logPath, index2) if err != nil { log.Fatal(err) } defer query.Close() // 获取记录总数(直接从索引读取,O(1)) count, err := query.GetRecordCount() if err != nil { log.Fatal(err) } fmt.Printf("记录总数: %d\n", count) // 从第 5 条记录开始查询 startIndex := 5 fmt.Printf("从第 %d 条记录开始查询\n", startIndex) // 向索引递减方向查询(查询更早的记录) // QueryNewest(4, 3) 查询索引 2, 3, 4,返回按索引递增排序 backward, err := query.QueryNewest(startIndex-1, 3) if err != nil { log.Fatal(err) } fmt.Printf("向索引递减方向查询 3 条记录(索引 2-4):\n") for i, rec := range backward { fmt.Printf(" [%d] 数据=%s\n", i, string(rec.Data)) } // 向索引递增方向查询(查询更新的记录) // QueryOldest(5, 3) 查询索引 5, 6, 7,返回按索引递增排序 forward, err := query.QueryOldest(startIndex, 3) if err != nil { log.Fatal(err) } fmt.Printf("向索引递增方向查询 3 条记录(索引 5-7):\n") for i, rec := range forward { fmt.Printf(" [%d] 数据=%s\n", i, string(rec.Data)) } fmt.Println() // ===== 示例 3:索引的自动恢复和重建 ===== fmt.Println("=== 示例 3:索引恢复 ===") // 如果索引文件存在,会自动加载 // 如果索引文件不存在或损坏,会自动重建 index3, err := seqlog.NewRecordIndex(logPath) if err != nil { log.Fatal(err) } fmt.Printf("索引已加载: %d 条记录\n", index3.Count()) fmt.Printf("最后一条记录偏移: %d\n", index3.LastOffset()) // 二分查找:根据偏移量查找索引位置 idx := index3.FindIndex(lastOffset) fmt.Printf("偏移量 %d 对应的索引位置: %d\n\n", lastOffset, idx) index3.Close() // ===== 示例 4:追加写入(索引自动更新)===== fmt.Println("=== 示例 4:追加写入 ===") // 重新打开索引和写入器,追加新数据 index5, err := seqlog.NewRecordIndex(logPath) if err != nil { log.Fatal(err) } defer index5.Close() writer, err = seqlog.NewLogWriter(logPath, index5) if err != nil { log.Fatal(err) } for i := 11; i <= 15; i++ { data := fmt.Sprintf("追加记录 #%d", i) offset, err := writer.Append([]byte(data)) if err != nil { log.Fatal(err) } fmt.Printf("追加: offset=%d, data=%s\n", offset, data) } writer.Close() // 验证索引已更新 index4, err := seqlog.NewRecordIndex(logPath) if err != nil { log.Fatal(err) } defer index4.Close() fmt.Printf("索引已更新: 现有 %d 条记录\n", index4.Count()) fmt.Println("\n=== 所有示例完成 ===") }