wukong引擎源码分析之索引——part 2 持久化 直接set(key,docID数组)在kv存储里...
前面说过,接收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存储里...相关推荐
- wukong引擎源码分析之索引——part 1 倒排列表本质是有序数组存储
searcher.IndexDocument(0, types.DocumentIndexData{Content: "此次百度收购将成中国互联网最大并购"}) engine.go ...
- wukong引擎源码分析之索引——part 3 文档评分 无非就是将docid对应的fields信息存储起来,为搜索结果rank评分用...
之前的文章分析过,接受索引请求处理的代码在segmenter_worker.go里: func (engine *Engine) segmenterWorker() {for {request := ...
- wukong引擎源码分析之搜索——docid有序的数组里二分归并求交集,如果用跳表的话,在插入索引时会更快...
searcher.Search(types.SearchRequest{Text: "百度中国"}) // 查找满足搜索条件的文档,此函数线程安全 func (engine *En ...
- 虚幻引擎源码分析(5)
虚幻引擎源码分析(5)
- 从源码分析RocketMQ系列-RocketMQ消息持久化源码详解
导语 在上篇分析中,提到了一个概念处理器,并且在进入到最终NettyIO的时候看到了一个Pair的对象,这个对象存储了两个对象,一个是执行器,一个是处理器,在进入Runable对象的时候看到封装到 ...
- 白鹭php源码,egret 2D引擎源码分析(二) 创建播放器
本帖最后由 fightingcat 于 2016-7-16 00:26 编辑 上一篇讲到了引擎的入口runEgret为每一个播放器标签(就是index.html中看到的那个 之前web.WebPlay ...
- bleve搜索引擎源码分析之索引——mapping真复杂啊
接下来看看下面index部分的源码实现: data := struct {Name stringDes string}{Name: "hello world this is bone&quo ...
- 悟空分词与mysql结合_悟空分词的搜索和排序源码分析之——索引
转自:http://blog.codeg.cn/2016/02/02/wukong-source-code-reading/ 索引过程分析 下面我们来分析索引过程. // 将文档加入索引 // // ...
- 以太坊共识引擎源码分析
这一篇分析以太坊的共识引擎,先看一下各组件之间的关系: Engine接口定义了共识引擎需要实现的所有函数,实际上按功能可以划分为2类: 区块验证类:以Verify开头,当收到新区块时,需要先验证区块的 ...
最新文章
- 【 HihoCoder】1082 The Marshtomp has seen it all before (暴力 或 脑力)
- 普通人也能用AI拍出3D大片?这位清华博士后这么做
- sonarqube使用教程
- 新版本来袭:Apache Spark 1.5新特性介绍
- MyBatis日志到底是如何做到兼容所有常用日志框架的?
- cad 关键字被保留了?选择集关键字保留了? N S W E关键字无法用?
- mac版sublime 无法下载插件(Vue 代码无高亮问题)
- 企业级iptalbes防火墙
- 信号之sleep函数
- Unable to instantiate application com.honjane.app.MyApplication
- Object对象转JSON字符串
- 【终结版】小家电安规要求以及世界各国安规认证知识分享
- 如何写好博客——常用标点符号易错点正确用法汇总
- 靶机Who Wants To Be King 1渗透记录
- 使用Springboot+MAVEN完成SSM项目的搭建(idea)--小白面试机试题
- 2013 NMPD展示预览,第1部分
- logstash问题记录:Attempted to resurrect connection to dead ES instance, but got an error
- E. Eggfruit Cake
- HDU1788 【中国剩余定理】
- 以IM为例看58同城典型技术架构演变
热门文章
- Fiddler+willow使用指南
- VC两个线程协作运行,轮流运行的
- nginx mysql占用率高_nginx/mysql查看内存占用
- insert批量插入500ms_如何快速安全的插入千万条数据
- java 1000个线程_关于Java多线程的一个问题
- 【深度学习】利用一些API进行图像数据增广
- 【深度学习】卷积神经网络速成
- UVa 10375 Choose and divide
- 装Linux后分区丢失,找到了linux分区顺序错乱修复方法
- linux 协议栈之socket,Linux协议栈之BSD和INET socket层(一)