DocFieldProcessor类的任务
1 按顺序存储所有的field和对应的fieldinfo
2 为当前这篇doc的field按照fieldname来建立hash索引
3 调用InvertedDocConsumer类(抽象),对field的内容分词和建立内存索引
DocFieldProcessor类主要用到的其他类
DocFieldProcessorPerField类的对象负责存放一个fieldinfo和其对应的field(可能是多个,他们的fieldinfo相同),next成员可以指向下一个DocFieldProcessorPerField类对象,构成链表(用于解决fieldhash冲突)
DocInverterPerField是DocFieldProcessorPerField内用到的类,负责解析同一个fieldinfo里的field,建立索引
final class DocFieldProcessor extends DocConsumer {

  final DocFieldConsumer consumer;
final StoredFieldsConsumer storedConsumer;
final Codec codec; // 存储doc里所有的DocFieldProcessorPerField(这个类里面会存放多个fieldinfo相同的field),位置按顺序存储,一个位置里面放一个
DocFieldProcessorPerField[] fields = new DocFieldProcessorPerField[1];
int fieldCount; // 存储doc里所有的DocFieldProcessorPerField(这个类里面会存放多个fieldinfo相同的field),位置按fieldname的hash来存放,一个位置可能匹配多个,以链表结构存放
DocFieldProcessorPerField[] fieldHash = new DocFieldProcessorPerField[2];
int hashMask = 1;
int totalFieldCount; int fieldGen;
//浅拷贝 要分析的doument
final DocumentsWriterPerThread.DocState docState; final Counter bytesUsed;

DocFieldProcessor ::processDocument(FieldInfos.Builder fieldInfos)是DocFieldProcessor类主要功能的实现函数

  public void processDocument(FieldInfos.Builder fieldInfos) throws IOException {

    consumer.startDocument();
storedConsumer.startDocument(); fieldCount = 0; final int thisFieldGen = fieldGen++; //循环doc里的field,合并同fieldinfo的field进入一个DocFieldProcessorPerField,并且如果此轮循环有新创建的DocFieldProcessorPerField对象,则加入到顺序数组和hash数组里面
for(IndexableField field : docState.doc) {
final String fieldName = field.name(); //计算fieldname在hash数组里对应的位置
final int hashPos = fieldName.hashCode() & hashMask; DocFieldProcessorPerField fp = fieldHash[hashPos];
//查找对应位置下fieldname符合当前field的DocFieldProcessorPerField对象
while(fp != null && !fp.fieldInfo.name.equals(fieldName)) {
fp = fp.next;
} if (fp == null) {
//表示该fieldinfo是第一次出现,把field的info信息添加到fieldinfos里面,并且创建对应的fieldinfo对象
FieldInfo fi = fieldInfos.addOrUpdate(fieldName, field.fieldType());
//创建一个DocFieldProcessorPerField
fp = new DocFieldProcessorPerField(this, fi); //加入到hash链表里面
fp.next = fieldHash[hashPos];
fieldHash[hashPos] = fp;
totalFieldCount++; //hash表快满了,重新做hash
if (totalFieldCount >= fieldHash.length/2) {
rehash();
}
} else {
//更新fieldinfo对象
FieldInfo fi = fieldInfos.addOrUpdate(fieldName, field.fieldType());
assert fi == fp.fieldInfo : "should only have updated an existing FieldInfo instance";
} if (thisFieldGen != fp.lastGen) {
//说明这个fieldinfo是第一次出现,即本次循环new了DocFieldProcessorPerField
fp.fieldCount = 0; //判断顺序数组是不是满了
if (fieldCount == fields.length) {
final int newSize = fields.length*2;
DocFieldProcessorPerField newArray[] = new DocFieldProcessorPerField[newSize];
System.arraycopy(fields, 0, newArray, 0, fieldCount);
fields = newArray;
} fields[fieldCount++] = fp;
fp.lastGen = thisFieldGen;
}
//把field加入到fp中,同fieldinfo的field会加入到同一个fp里面
fp.addField(field); storedConsumer.addField(docState.docID, field, fp.fieldInfo);
}
//遍历顺序数组里的DocFieldProcessorPerField,调用DocInverterPerField对其里面的field进行分词建立索引之类的操作
ArrayUtil.introSort(fields, 0, fieldCount, fieldsComp);
for(int i=0;i<fieldCount;i++) {
final DocFieldProcessorPerField perField = fields[i];
perField.consumer.processFields(perField.fields, perField.fieldCount);
}
}

Lucene的DocFieldProcessor类的更多相关文章

  1. lucene.net helper类 【结合盘古分词进行搜索的小例子(分页功能)】

      转自:http://blog.csdn.net/pukuimin1226/article/details/17558247 添加:2013-12-25 更新:2013-12-26 新增分页功能. ...

  2. Lucene的Query类介绍

    把Lucene的查询当成sql的查询,也许会笼统的明白些query的真相了. 查询分为大致两类,1:精准查询.2,模糊查询. 创建测试数据. private Directory directory; ...

  3. 全文检索解决方案(lucene工具类以及sphinx相关资料)

    介绍两种全文检索的技术. 1.  lucene+ 中文分词(IK) 关于lucene的原理,在这里可以得到很好的学习. http://www.blogjava.net/zhyiwww/archive/ ...

  4. lucene 基础知识点

    部分知识点的梳理,参考<lucene实战>及网络资料 1.基本概念 lucence 可以认为分为两大组件: 1)索引组件 a.内容获取:即将原始的内容材料,可以是数据库.网站(爬虫).文本 ...

  5. lucene全文检索---打酱油的日子

    检索内容,一般的程序员第一时间想到的是sql的like来做模糊查询,其实这样的搜索是比较耗时的.已经有lucene帮我们 封装好了,lucene采用的是分词检索等策略. 1.lucene中的类描述 I ...

  6. 【转载】Lucene.Net入门教程及示例

    本人看到这篇非常不错的Lucene.Net入门基础教程,就转载分享一下给大家来学习,希望大家在工作实践中可以用到. 一.简单的例子 //索引Private void Index(){    Index ...

  7. Lucene.net站内搜索—3、最简单搜索引擎代码

    目录 Lucene.net站内搜索—1.SEO优化 Lucene.net站内搜索—2.Lucene.Net简介和分词Lucene.net站内搜索—3.最简单搜索引擎代码Lucene.net站内搜索—4 ...

  8. 通过lucene的StandardAnalyzer分析器来了解分词

    本文转载http://blog.csdn.net/jspamd/article/details/8194919 不同的Lucene分析器Analyzer,它对TokenStream进行分词的方法是不同 ...

  9. Lucene 基础理论 (zhuan)

    http://www.blogjava.net/hoojo/archive/2012/09/06/387140.html**************************************** ...

随机推荐

  1. 用js完成blog项目

    //前台调用 var $ = function (args) { return new Base(args); } //基础库 function Base(args) { //创建一个数组,来保存获取 ...

  2. 【转】Android Intent Action 大全

    String ADD_SHORTCUT_ACTION 动作:在系统中添加一个快捷方式.. “android.intent.action.ADD_SHORTCUT” String ALL_APPS_AC ...

  3. 分析fork后多进程对文件的共享

    fork函数是创建一个新的进程作为原进程的子进程,创建的子进程和父进程存在很多的相似性,首先父子进程的虚拟存储空间的用户空间是相同的,是将父进程的拷贝给子进程.同时父子进程对文件的操作是共享方式.因为 ...

  4. gem 安装&卸载pod

    安装: gem 应该是ruby自带的ruby包管理器 sudo gem install cocoapods 卸载: sudo gem uninstall cocoapods

  5. cocos中添加显示文字的三种方式(CCLabelTTF 、CCLabelBMFont 和CCLabelAtlas)

    CCLabelTTF CCLabelTTF 每次调用 setString (即改变文字)的时候,一个新的OPENGL 纹理将会被创建..这意味着setString 和创建一个新的标签一样慢. 这个类使 ...

  6. dom 关键字提示

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  7. php 的简单易用的调式方法,打印方法

    简单的调试方法:echo, print_r, var_dump, exit, debug_backtrace(), debug_print_backtrace(), gettype(), get_cl ...

  8. datagrid url json

    <div class="easyui-accordion" style="width:500px;height:300px;"> <div t ...

  9. 第二百二十四天 how can I 坚持

    实物商品兑换,有点小难搞,其实也没什么难的,也就那些东西,不过好像这就是我设计实现的,干起来挺来劲的. 供暖了,挺暖和的,哈哈. 小米耳机(炫彩版)到了.感觉挺好的. 还在纠结到底要买哪种颜色的羽绒服 ...

  10. Java并发编程:Timer和TimerTask

    Java并发编程:Timer和TimerTask 下面内容转载自: http://blog.csdn.net/xieyuooo/article/details/8607220 其实就Timer来讲就是 ...