This commit is contained in:
Alex Yang
2026-04-12 21:40:22 +08:00
parent 7abc2b5339
commit f9e2e5a6bc
52 changed files with 3388 additions and 368846 deletions
+51 -18
View File
@@ -12,6 +12,7 @@ import (
"time"
"dns-server/logger"
_ "github.com/mattn/go-sqlite3"
)
@@ -20,7 +21,7 @@ type ArchiveQueryEngine struct {
mainStore *SQLiteStore
archiveMgr *ArchiveManager
config *QueryLogConfig
// 临时目录管理
tempDirs map[string]string
tempDirsMu sync.Mutex
@@ -51,24 +52,43 @@ func (aqe *ArchiveQueryEngine) QueryLogs(filter LogFilter, page PageParams) ([]Q
mainTotal = 0
}
// 2. 智能优化:如果主库数据足够且是第一页,直接返回
if page.Offset == 0 && len(mainLogs) >= page.Limit {
return mainLogs, mainTotal, nil
// 2. 智能优化:如果主库数据足够,直接返回
if len(mainLogs) > page.Offset {
// 计算主库中需要返回的数据范围
start := page.Offset
end := start + page.Limit
if end > len(mainLogs) {
end = len(mainLogs)
}
return mainLogs[start:end], mainTotal, nil
}
// 3. 查询所有归档库
archiveLogs, archiveTotal, err := aqe.queryArchives(filter, page)
// 3. 计算需要从归档中获取的数据量
// 注意:归档库查询时,offset 应该始终为 0,因为我们需要从归档的开头开始查询,然后与主库数据合并后再进行分页
remainingLimit := page.Offset + page.Limit - len(mainLogs)
if remainingLimit < 0 {
remainingLimit = 0
}
archivePage := PageParams{
Limit: remainingLimit,
Offset: 0,
SortField: page.SortField,
SortDirection: page.SortDirection,
}
// 4. 查询归档库
archiveLogs, archiveTotal, err := aqe.queryArchives(filter, archivePage)
if err != nil {
logger.Error("查询归档失败", "error", err)
archiveLogs = []QueryLog{}
archiveTotal = 0
}
// 4. 合并结果
// 5. 合并结果
allLogs := append(mainLogs, archiveLogs...)
total := mainTotal + archiveTotal
// 5. 排序(默认按时间倒序)
// 6. 排序(默认按时间倒序)
if page.SortField == "" || page.SortField == "timestamp" {
if page.SortDirection == "" || page.SortDirection == "desc" {
sort.Slice(allLogs, func(i, j int) bool {
@@ -81,13 +101,9 @@ func (aqe *ArchiveQueryEngine) QueryLogs(filter LogFilter, page PageParams) ([]Q
}
}
// 6. 分页
start := page.Offset
if start >= len(allLogs) {
return []QueryLog{}, total, nil
}
end := start + page.Limit
// 7. 分页
start := 0
end := page.Limit
if end > len(allLogs) {
end = len(allLogs)
}
@@ -101,8 +117,16 @@ func (aqe *ArchiveQueryEngine) queryMainStore(filter LogFilter, page PageParams)
return []QueryLog{}, 0, nil
}
// 注意:查询主库时,不使用 offset,只使用 limit + offset,这样可以获取足够的数据与归档库数据合并后再进行分页
mainPage := PageParams{
Limit: page.Offset + page.Limit,
Offset: 0,
SortField: page.SortField,
SortDirection: page.SortDirection,
}
// 使用 SQLiteStore 的查询方法
return aqe.mainStore.QueryLogs(filter, page)
return aqe.mainStore.QueryLogs(filter, mainPage)
}
// queryArchives 查询所有归档库
@@ -121,15 +145,24 @@ func (aqe *ArchiveQueryEngine) queryArchives(filter LogFilter, page PageParams)
var allLogs []QueryLog
var totalCount int64 = 0
// 计算需要从归档中获取的总数据量
requiredTotal := int64(page.Offset + page.Limit)
// 从新到旧遍历归档
for _, archive := range archives {
// 如果已经有足够的数据,提前退出
if int64(len(allLogs)) >= int64(page.Limit) && page.Offset == 0 {
if int64(len(allLogs)) >= requiredTotal {
break
}
// 计算当前归档需要查询的数据量
remaining := requiredTotal - int64(len(allLogs))
archivePage := page
archivePage.Limit = int(remaining)
archivePage.Offset = 0
// 查询单个归档
logs, count, err := aqe.querySingleArchive(&archive, filter, page)
logs, count, err := aqe.querySingleArchive(&archive, filter, archivePage)
if err != nil {
logger.Warn("查询归档失败", "file", archive.FilePath, "error", err)
continue