up
This commit is contained in:
+40
-14
@@ -12,6 +12,7 @@ import (
|
|||||||
"encoding/json" // JSON 序列化/反序列化
|
"encoding/json" // JSON 序列化/反序列化
|
||||||
"fmt" // 格式化错误信息
|
"fmt" // 格式化错误信息
|
||||||
"io" // io.EOF 常量
|
"io" // io.EOF 常量
|
||||||
|
"log" // 日志输出
|
||||||
"os" // 操作系统功能(创建目录等)
|
"os" // 操作系统功能(创建目录等)
|
||||||
"path/filepath" // 路径拼接
|
"path/filepath" // 路径拼接
|
||||||
|
|
||||||
@@ -188,22 +189,47 @@ func (d *DB) SetIndex(keyword string, entries []IndexEntry) error {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// BatchSetIndex 在一次事务中批量写入多个关键词→条目列表的映射。
|
// BatchSetIndex 分批写入多个关键词→条目列表的映射。
|
||||||
// 比多次调用 SetIndex 效率更高(减少事务开销)。
|
// 大数据量时拆分为多个小事务,避免单个大事务导致的长时间阻塞。
|
||||||
func (d *DB) BatchSetIndex(batch map[string][]IndexEntry) error {
|
func (d *DB) BatchSetIndex(batch map[string][]IndexEntry) error {
|
||||||
return d.db.Update(func(tx *bolt.Tx) error {
|
const batchSize = 1000
|
||||||
b := tx.Bucket(bucketIndex)
|
items := make([]struct {
|
||||||
for keyword, entries := range batch {
|
keyword string
|
||||||
data, err := marshalCompress(entries)
|
entries []IndexEntry
|
||||||
if err != nil {
|
}, 0, len(batch))
|
||||||
return err
|
for k, v := range batch {
|
||||||
}
|
items = append(items, struct {
|
||||||
if err := b.Put([]byte(keyword), data); err != nil {
|
keyword string
|
||||||
return err
|
entries []IndexEntry
|
||||||
}
|
}{k, v})
|
||||||
|
}
|
||||||
|
totalBatches := (len(items) + batchSize - 1) / batchSize
|
||||||
|
for i := 0; i < len(items); i += batchSize {
|
||||||
|
end := i + batchSize
|
||||||
|
if end > len(items) {
|
||||||
|
end = len(items)
|
||||||
}
|
}
|
||||||
return nil
|
batchNum := i/batchSize + 1
|
||||||
})
|
if err := d.db.Update(func(tx *bolt.Tx) error {
|
||||||
|
b := tx.Bucket(bucketIndex)
|
||||||
|
for _, item := range items[i:end] {
|
||||||
|
data, err := marshalCompress(item.entries)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := b.Put([]byte(item.keyword), data); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if totalBatches > 1 {
|
||||||
|
log.Printf("[storage] BatchSetIndex progress: batch %d/%d (%d keys)", batchNum, totalBatches, end)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// ForEachIndex 遍历倒排索引中所有关键词及其关联条目,对每个条目调用 fn。
|
// ForEachIndex 遍历倒排索引中所有关键词及其关联条目,对每个条目调用 fn。
|
||||||
|
|||||||
Reference in New Issue
Block a user