前面说过,接收indexerRequest的代码在index_worker.go里:

func (engine *Engine) indexerAddDocumentWorker(shard int) {for {request := <-engine.indexerAddDocumentChannels[shard] //关键addInvertedIndex := engine.indexers[shard].AddDocument(request.document, request.dealDocInfoChan) // 向反向索引表(数组)中加入一个文档// saveif engine.initOptions.UsePersistentStorage {for k, v := range addInvertedIndex {engine.persistentStorageIndexDocumentChannels[shard] <- persistentStorageIndexDocumentRequest{typ:            "index",keyword:        k,keywordIndices: v,}}}atomic.AddUint64(&engine.numTokenIndexAdded,uint64(len(request.document.Keywords)))atomic.AddUint64(&engine.numDocumentsIndexed, 1)}
} 

持久化的代码:engine/persistent_storage_worker.go

package engineimport ("bytes""encoding/binary""encoding/gob""github.com/huichen/wukong/core""github.com/huichen/wukong/types""sync""sync/atomic"
)type persistentStorageIndexDocumentRequest struct {typ string //"info"or"index"// typ=="info"时,以下两个字段有效
    docId   uint64docInfo *types.DocInfo// typ=="index"时,以下两个字段有效keyword        stringkeywordIndices *types.KeywordIndices
}func (engine *Engine) persistentStorageIndexDocumentWorker(shard int) {for {request := <-engine.persistentStorageIndexDocumentChannels[shard]switch request.typ {case "info":// 得到keyb := make([]byte, 10)length := binary.PutUvarint(b, request.docId)// 得到valuevar buf bytes.Bufferenc := gob.NewEncoder(&buf)err := enc.Encode(request.docInfo)if err != nil {atomic.AddUint64(&engine.numDocumentsStored, 1)return}// 将key-value写入数据库engine.dbs[shard][getDB(request.typ)].Set(b[0:length], buf.Bytes())atomic.AddUint64(&engine.numDocumentsStored, 1)case "index":// 得到keyb := []byte(request.keyword)// 得到valuevar buf bytes.Bufferenc := gob.NewEncoder(&buf)err := enc.Encode(request.keywordIndices)if err != nil {return}// 将key-value写入数据库
            engine.dbs[shard][getDB(request.typ)].Set(b, buf.Bytes())}}
}func (engine *Engine) persistentStorageRemoveDocumentWorker(docId uint64, shard int) {// 得到keyb := make([]byte, 10)length := binary.PutUvarint(b, docId)// 从数据库删除该keyengine.dbs[shard][getDB("info")].Delete(b[0:length])
}func (engine *Engine) persistentStorageInitWorker(shard int) {var finish sync.WaitGroupfinish.Add(2)// 恢复docInfo
    go func() {defer finish.Add(-1)engine.dbs[shard][getDB("info")].ForEach(func(k, v []byte) error {key, value := k, v// 得到docIDdocId, _ := binary.Uvarint(key)// 得到databuf := bytes.NewReader(value)dec := gob.NewDecoder(buf)var data types.DocInfoerr := dec.Decode(&data)if err == nil {// 添加索引core.AddDocInfo(shard, docId, &data)}return nil})}()// 恢复invertedIndex
    go func() {defer finish.Add(-1)engine.dbs[shard][getDB("index")].ForEach(func(k, v []byte) error {key, value := k, v// 得到keywordkeyword := string(key)// 得到databuf := bytes.NewReader(value)dec := gob.NewDecoder(buf)var data types.KeywordIndiceserr := dec.Decode(&data)if err == nil {// 添加索引core.AddKeywordIndices(shard, keyword, &data)}return nil})}()finish.Wait()engine.persistentStorageInitChannel <- true
}

可以看到,倒排索引存在DB里是丑陋的,直接set(key, value) 其中,key是倒排列表的关键字,而value是doc id list也就是数组。

如果索引比较多,每次去DB set是非常耗时的,尤其针对同一个keyword有doc id插入时!

总之,wukong对于持久化的做法很丑陋!

转载于:https://www.cnblogs.com/bonelee/p/6582163.html

wukong引擎源码分析之索引——part 2 持久化 直接set(key,docID数组)在kv存储里...相关推荐

  1. wukong引擎源码分析之索引——part 1 倒排列表本质是有序数组存储

    searcher.IndexDocument(0, types.DocumentIndexData{Content: "此次百度收购将成中国互联网最大并购"}) engine.go ...

  2. wukong引擎源码分析之索引——part 3 文档评分 无非就是将docid对应的fields信息存储起来,为搜索结果rank评分用...

    之前的文章分析过,接受索引请求处理的代码在segmenter_worker.go里: func (engine *Engine) segmenterWorker() {for {request := ...

  3. wukong引擎源码分析之搜索——docid有序的数组里二分归并求交集,如果用跳表的话,在插入索引时会更快...

    searcher.Search(types.SearchRequest{Text: "百度中国"}) // 查找满足搜索条件的文档,此函数线程安全 func (engine *En ...

  4. 虚幻引擎源码分析(5)

    虚幻引擎源码分析(5)

  5. 从源码分析RocketMQ系列-RocketMQ消息持久化源码详解

    导语   在上篇分析中,提到了一个概念处理器,并且在进入到最终NettyIO的时候看到了一个Pair的对象,这个对象存储了两个对象,一个是执行器,一个是处理器,在进入Runable对象的时候看到封装到 ...

  6. 白鹭php源码,egret 2D引擎源码分析(二) 创建播放器

    本帖最后由 fightingcat 于 2016-7-16 00:26 编辑 上一篇讲到了引擎的入口runEgret为每一个播放器标签(就是index.html中看到的那个 之前web.WebPlay ...

  7. bleve搜索引擎源码分析之索引——mapping真复杂啊

    接下来看看下面index部分的源码实现: data := struct {Name stringDes string}{Name: "hello world this is bone&quo ...

  8. 悟空分词与mysql结合_悟空分词的搜索和排序源码分析之——索引

    转自:http://blog.codeg.cn/2016/02/02/wukong-source-code-reading/ 索引过程分析 下面我们来分析索引过程. // 将文档加入索引 // // ...

  9. 以太坊共识引擎源码分析

    这一篇分析以太坊的共识引擎,先看一下各组件之间的关系: Engine接口定义了共识引擎需要实现的所有函数,实际上按功能可以划分为2类: 区块验证类:以Verify开头,当收到新区块时,需要先验证区块的 ...

最新文章

  1. 【 HihoCoder】1082 The Marshtomp has seen it all before (暴力 或 脑力)
  2. 普通人也能用AI拍出3D大片?这位清华博士后这么做
  3. sonarqube使用教程
  4. 新版本来袭:Apache Spark 1.5新特性介绍
  5. MyBatis日志到底是如何做到兼容所有常用日志框架的?
  6. cad 关键字被保留了?选择集关键字保留了? N S W E关键字无法用?
  7. mac版sublime 无法下载插件(Vue 代码无高亮问题)
  8. 企业级iptalbes防火墙
  9. 信号之sleep函数
  10. Unable to instantiate application com.honjane.app.MyApplication
  11. Object对象转JSON字符串
  12. 【终结版】小家电安规要求以及世界各国安规认证知识分享
  13. 如何写好博客——常用标点符号易错点正确用法汇总
  14. 靶机Who Wants To Be King 1渗透记录
  15. 使用Springboot+MAVEN完成SSM项目的搭建(idea)--小白面试机试题
  16. 2013 NMPD展示预览,第1部分
  17. logstash问题记录:Attempted to resurrect connection to dead ES instance, but got an error
  18. E. Eggfruit Cake
  19. HDU1788 【中国剩余定理】
  20. 以IM为例看58同城典型技术架构演变

热门文章

  1. Fiddler+willow使用指南
  2. VC两个线程协作运行,轮流运行的
  3. nginx mysql占用率高_nginx/mysql查看内存占用
  4. insert批量插入500ms_如何快速安全的插入千万条数据
  5. java 1000个线程_关于Java多线程的一个问题
  6. 【深度学习】利用一些API进行图像数据增广
  7. 【深度学习】卷积神经网络速成
  8. UVa 10375 Choose and divide
  9. 装Linux后分区丢失,找到了linux分区顺序错乱修复方法
  10. linux 协议栈之socket,Linux协议栈之BSD和INET socket层(一)