重构:简化查询接口

- RecordQuery.QueryOldest 和 QueryNewest 不再接收 startIdx/endIdx 参数
- 查询方法返回纯 Record 列表,状态判断移到调用方
- TopicProcessor 的查询方法负责添加状态信息
- 更新所有测试文件以适配新接口
This commit is contained in:
2025-10-04 00:10:14 +08:00
parent a421ca1d85
commit 5c028a55b3
8 changed files with 168 additions and 208 deletions

136
query.go
View File

@@ -69,38 +69,10 @@ func NewRecordQuery(logPath string, index *RecordIndex) (*RecordQuery, error) {
return rq, nil
}
// readRecordAtOffset 读取指定偏移位置的记录
func (rq *RecordQuery) readRecordAtOffset(offset int64) (*Record, error) {
if _, err := rq.fd.Seek(offset, 0); err != nil {
return nil, fmt.Errorf("seek to offset %d: %w", offset, err)
}
// 读取头部:[4B len][4B CRC][16B UUID] = 24 字节
hdr := rq.rbuf[:24]
if _, err := io.ReadFull(rq.fd, hdr); err != nil {
return nil, fmt.Errorf("read header: %w", err)
}
rec := &Record{
Len: binary.LittleEndian.Uint32(hdr[0:4]),
CRC: binary.LittleEndian.Uint32(hdr[4:8]),
}
copy(rec.UUID[:], hdr[8:24])
// 读取数据
rec.Data = make([]byte, rec.Len)
if _, err := io.ReadFull(rq.fd, rec.Data); err != nil {
return nil, fmt.Errorf("read data: %w", err)
}
return rec, nil
}
// readRecordsForward 从指定索引位置向前顺序读取记录
// startIndex: 起始记录索引
// count: 读取数量
// startIdx, endIdx: 游标窗口索引范围(用于状态判断)
func (rq *RecordQuery) readRecordsForward(startIndex, count int, startIdx, endIdx int) ([]*RecordWithStatus, error) {
func (rq *RecordQuery) readRecordsForward(startIndex, count int) ([]*Record, error) {
// 获取起始 offset
startOffset, err := rq.index.GetOffset(startIndex)
if err != nil {
@@ -111,8 +83,7 @@ func (rq *RecordQuery) readRecordsForward(startIndex, count int, startIdx, endId
return nil, fmt.Errorf("seek to offset %d: %w", startOffset, err)
}
results := make([]*RecordWithStatus, 0, count)
currentIndex := startIndex
results := make([]*Record, 0, count)
currentOffset := startOffset
for len(results) < count {
@@ -137,42 +108,25 @@ func (rq *RecordQuery) readRecordsForward(startIndex, count int, startIdx, endId
return nil, fmt.Errorf("read data at offset %d: %w", currentOffset, err)
}
results = append(results, &RecordWithStatus{
Record: rec,
Status: rq.getRecordStatus(currentIndex, startIdx, endIdx),
})
currentIndex++
results = append(results, rec)
currentOffset += 24 + int64(rec.Len)
}
return results, nil
}
// getRecordStatus 根据游标窗口索引位置获取记录状态
func (rq *RecordQuery) getRecordStatus(recordIndex, startIdx, endIdx int) RecordStatus {
if recordIndex < startIdx {
return StatusProcessed
} else if recordIndex >= startIdx && recordIndex < endIdx {
return StatusProcessing
} else {
return StatusPending
}
}
// QueryOldest 从指定索引开始查询记录(向前读取)
// startIndex: 查询起始索引
// count: 查询数量
// startIdx, endIdx: 游标窗口索引范围(用于状态判断)
// 返回的记录按时间顺序(索引递增方向)
func (rq *RecordQuery) QueryOldest(startIndex, count int, startIdx, endIdx int) ([]*RecordWithStatus, error) {
func (rq *RecordQuery) QueryOldest(startIndex, count int) ([]*Record, error) {
if count <= 0 {
return nil, fmt.Errorf("count must be greater than 0")
}
totalCount := rq.index.Count()
if totalCount == 0 {
return []*RecordWithStatus{}, nil
return []*Record{}, nil
}
// 校验起始索引
@@ -180,7 +134,7 @@ func (rq *RecordQuery) QueryOldest(startIndex, count int, startIdx, endIdx int)
startIndex = 0
}
if startIndex >= totalCount {
return []*RecordWithStatus{}, nil
return []*Record{}, nil
}
// 限制查询数量
@@ -189,27 +143,26 @@ func (rq *RecordQuery) QueryOldest(startIndex, count int, startIdx, endIdx int)
count = remainCount
}
return rq.readRecordsForward(startIndex, count, startIdx, endIdx)
return rq.readRecordsForward(startIndex, count)
}
// QueryNewest 从指定索引开始向后查询记录(索引递减方向)
// endIndex: 查询结束索引(包含,最新的记录)
// count: 查询数量
// startIdx, endIdx: 游标窗口索引范围(用于状态判断)
// 返回结果按时间倒序(最新在前,即 endIndex 对应的记录在最前)
func (rq *RecordQuery) QueryNewest(endIndex, count int, startIdx, endIdx int) ([]*RecordWithStatus, error) {
func (rq *RecordQuery) QueryNewest(endIndex, count int) ([]*Record, error) {
if count <= 0 {
return nil, fmt.Errorf("count must be greater than 0")
}
totalCount := rq.index.Count()
if totalCount == 0 {
return []*RecordWithStatus{}, nil
return []*Record{}, nil
}
// 校验结束索引
if endIndex < 0 {
return []*RecordWithStatus{}, nil
return []*Record{}, nil
}
if endIndex >= totalCount {
endIndex = totalCount - 1
@@ -223,7 +176,7 @@ func (rq *RecordQuery) QueryNewest(endIndex, count int, startIdx, endIdx int) ([
}
// 向前读取
results, err := rq.readRecordsForward(queryStartIdx, count, startIdx, endIdx)
results, err := rq.readRecordsForward(queryStartIdx, count)
if err != nil {
return nil, err
}
@@ -236,64 +189,25 @@ func (rq *RecordQuery) QueryNewest(endIndex, count int, startIdx, endIdx int) ([
return results, nil
}
// QueryAt 从指定位置查询记录
// position: 查询起始位置(文件偏移量,通常是当前处理位置)
// direction: 查询方向负数向后0 当前,正数向前)
// count: 查询数量
// startIdx, endIdx: 游标窗口索引范围(用于状态判断)
// 返回结果按时间顺序排列
func (rq *RecordQuery) QueryAt(position int64, direction int, count int, startIdx, endIdx int) ([]*RecordWithStatus, error) {
// 将 position 转换为索引
idx := rq.index.FindIndex(position)
if idx < 0 {
return nil, fmt.Errorf("position not found in index")
}
if direction >= 0 {
// 向前查询或当前位置
if direction == 0 {
count = 1
} else {
// direction > 0跳过当前位置从下一条开始
idx++
}
return rq.readRecordsForward(idx, count, startIdx, endIdx)
}
// 向后查询:使用索引
results := make([]*RecordWithStatus, 0, count)
// 向后查询(更早的记录)
for i := idx - 1; i >= 0 && len(results) < count; i-- {
offset, err := rq.index.GetOffset(i)
if err != nil {
return nil, fmt.Errorf("get offset at index %d: %w", i, err)
}
rec, err := rq.readRecordAtOffset(offset)
if err != nil {
return nil, fmt.Errorf("read record at index %d: %w", i, err)
}
results = append(results, &RecordWithStatus{
Record: rec,
Status: rq.getRecordStatus(i, startIdx, endIdx),
})
}
// 反转结果,使其按时间顺序排列
for i, j := 0, len(results)-1; i < j; i, j = i+1, j-1 {
results[i], results[j] = results[j], results[i]
}
return results, nil
}
// GetRecordCount 获取记录总数
func (rq *RecordQuery) GetRecordCount() (int, error) {
return rq.index.Count(), nil
}
// GetRecordStatus 根据游标窗口索引位置获取记录状态
// recordIndex: 记录索引
// startIdx: 窗口开始索引(已处理位置)
// endIdx: 窗口结束索引(当前读取位置)
func GetRecordStatus(recordIndex, startIdx, endIdx int) RecordStatus {
if recordIndex < startIdx {
return StatusProcessed
} else if recordIndex >= startIdx && recordIndex < endIdx {
return StatusProcessing
} else {
return StatusPending
}
}
// Close 关闭查询器
// 注意:不关闭 index因为 index 是外部管理的
func (rq *RecordQuery) Close() error {