没有合适的资源?快使用搜索试试~ 我知道了~
2. FST Node , 表 示 FST 图 的 一 个 节 点 , 有 两 种 实 现 类 型 , 4. FST HashMap,一个使用探测法实现的 Ha
资源详情
资源评论
资源推荐
Lucene FST 算法流程
FST 简介
FST(Finite State Transducer,一种有限自动机,或者称为 Mealy
machine)是 lucene 中的一个核心算法,用于检索 term 信息存储的位
置。在 lucene 中,term 按照其字典顺序排序(term 在存储时称为
input), term 相关的信息按照 term 排序的次序存储在磁盘上(其存
储的位置为 outPut), <input,output>二元组将以 FST 的形式存储在内
存中(input 和 output 都是有序的)。检索时,根据 input,通过计算
FST 中的路径上的权值信息,获取到 output 数据,最终在磁盘上定位
term 的其它附加信息。同时 FST 还能够快速的判断一个 term 是否在
lucene 中。
实际上 FST 相当于 term 在内存中的一个索引,lucene 使用 FST 能够
快速确定系统中是否存在查询的 term,如果存在,能够快速定位其
信息存放的具体位置。
FST 与 trie tree 结构提供相似的功能,但是,在内存中存储更高效。
输入到 FST 中的数据为:
String inputValues[] = {"mop","moth","pop","star","stop","top"};
long outputValues[] = {0,1,2,3,4,5};
生成的 FST 图为:
S
13
23
11
7
t
E
s/3
p
t/1
o
m
o/1
h
r
9
p/2
t/5
o
p
2
21
15
a
从图中可以计算 stop:
s->23 的弧线 s/3,
23->21 的弧线 t,
21->11 的弧线 o/1,
11->E(E 表示终止状态) 的弧线 p
将所有弧线的权值加起来 3+0+1+0 = 4;因此 stop 对应的 output 为 4.
FST 的构建
数据结构:
1. FST bytes,FST 中的 bytes 数组,存储 FST 数据信息。FST bytes 存
储了 FST 图的完整信息(通过 FST bytes,可以构建一个 FST 图)。
2. FST Node ,表示 FST 图 的 一 个 节 点 , 有 两 种 实 现 类 型 ,
UnCompiledNode (尚未存放到 FST bytes 中的节点)和
CompiledNode(已经存放到 FST bytes 中的节点)。
3. FST arc,用于表示 Node 间的弧线。
4. FST HashMap,一个使用探测法实现的 HashMap,key 是 FST Node
生成的 hash 值,value 是 FST node 存放在 FST bytes 数组中的下标。
(FST HashMap 不是 FST 必须的组成部分,但是,HashMap 能够加
快判断某个节点是否已经在 FST bytes 中,HashMap 仅用于 FST 的
构建过程)。
5. Frontier 是一个数组,用于存放未转换到 FST byte 数组中的数据信
息;
Hash 算法:
Hash 算法并不是 FST 中必不可缺的部分,在构建过程中 FST 使用
HashMap 来快速判断测试节点是否已经被写入到 FST bytes 中。
HashMap 的 value 是 node 在 FST bytes 中的实际存储位置(数组的下
标)。
HashMap 中的 key 通过计算节点中所有的 arcs 信息生成的。其中,
每个 arc 被考虑的属性包括,label(字符)、targetNode(下一个节点
的地址)、outPut(节点输出)、isFinal(是否是终止弧线)、nextFinal
(下一个终止弧线—这个参数在测试过程中没有发现被赋值)。
将 node1 添加到 FST bytes 时,先通过 hash 算法计算 node1 对应
的 key,如果 key 在 Hashmap 中已经有对应的值 value,那么这个 value
就是与 node1 hash 值相同的节点(称为 node2)存储在 FST bytes 中
的实际数组下标,FST 从 bytes 数组中转换出 node2,判断 node1 和
node2 是否相等(所有的 arc 值是否相等),如果相等,node1 就没有
必要再添加到 FST bytes 中(相当于 FST 的尾部进行了归并)。
参考:org.apache.lucene.util.fst.NodeHash<T>
算法基本步骤:
1. 对于新的输入 NInput(new input),首先要计算其与上次输出
的 LInput(Lastest input,LInput 数据存放在 Frontier 中)之间
的公共前缀 prefix,之后调用 freezeTail,将 LInput 的后缀部分
转换到 FST bytes 数组中(注意,LInput 的 prefix 的直接后缀那
个元素没有存放到 FST bytes 中)。
2. 在 freezeTail 过程中,会将 LInput 的后缀,从后向前的顺序逐
个存储到 FST bytes 中,在存储前,node 通过 Hash 算法判断其
是否已经在 bytes 中,如果不存在就保存,并更新 HashMap;
如果已经存在,通过 HashMap 会返回节点在 bytes 数组中的实
际位置 pos,通过这个 pos,可以在 bytes 中转换出一个先前存
入的 preNode,比较 preNode 和 node,如果相同,直接返回
preNode 的存储位置,如果不同,需要生成一个新的 HashKey,
重复上面的判断(探测法的 hashmap)直到
a) HashMap 中找不到 key 对应的 value,将新节点添加到 FST
bytes 中(添加节点,实际是将节点包含的所有 arc 都写入
到 FST bytes 中,并不是将节点本身写入 FST bytes 中);
b) HashMap 中找到 key 对应的 value,并且转换出的 preNode
与当前 node 的值相等,直接返回 preNode 的存储位置 pos,
相当于尾部节点的合并。
剩余15页未读,继续阅读
芊暖
- 粉丝: 22
- 资源: 340
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功
评论0