DocFieldProcessor类

DocFieldProcessor类的任务1 按顺序存储所有的field和对应的fieldinfo2 为当前这篇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);
    }
  }
  
时间: 2024-12-14 03:33:24

DocFieldProcessor类的相关文章

jvm系列(一):java类的加载机制

java类的加载机制 原文:http://www.cnblogs.com/ityouknow/p/5603287.html 1.什么是类的加载 类的加载指的是将类的.class文件中的二进制数据读入到内存中,将其放在运行时数据区的方法区内,然后在堆区创建一个java.lang.Class对象,用来封装类在方法区内的数据结构.类的加载的最终产品是位于堆区中的Class对象,Class对象封装了类在方法区内的数据结构,并且向Java程序员提供了访问方法区内的数据结构的接口. 类加载器并不需要等到某个

iOS -- SKSpriteNode类

SKSpriteNode类 继承自 SKNode:UIResponder:NSObject 符合 NSCoding(SKNode)NSCopying(SKNode)NSObject(NSObject) 框架  /System/Library/Frameworks/SpriteKit.framework 可用性 可用于iOS 7.0或者更晚的版本 声明于 SKSpriteNode.h 参考指南 Sprite Kit Progamming Guide 概览 重要提示:这是一个初步的API或者开发技术

iOS -- SKScene类

SKScene类 继承自 SKEffectNode:SKNode:UIResponder:NSObject 符合 NSCoding(SKNode)NSCopying(SKNode)NSObject(NSObject) 框架  /System/Library/Frameworks/SpriteKit.framework 可用性 可用于iOS 7.0或者更晚的版本 声明于 SKScene.h 参考指南 Sprite Kit Progamming Guide 概览 重要提示:这是一个初步的API或者开

iOS -- SKPhysicsWorld类

SKPhysicsWorld类 继承自 NSObject 符合 NSCodingNSObject(NSObject) 框架  /System/Library/Frameworks/SpriteKit.framework 可用性 可用于iOS 7.0或者更晚的版本 声明于 SKPhysicsWorld.h 参考指南 Sprite Kit Progamming Guide 概览 重要提示:这是一个初步的API或者开发技术文档.虽然已经审阅了本文档的技术准确性,但是它不是最终的版本.本机密信息仅适用于

C#嵌套类

嵌套类顾名思义就是类或者结构中定义的类 class Container { class Nested { Nested() { } } } <1>嵌套类的默认访问权限是private ,可以指定为public,protected,private,internal,protected internal.<2>嵌套类型可以访问外部类(包裹嵌套类的类),如果要访问外部类型,要把外部类通过构造函数传进一个实例<3>嵌套类中只能访问外部类中的静态成员,不能直接访问外部类的非静态成

一个实用的C#网页抓取类代码分享

一个实用的C# 网页抓取类 模拟蜘蛛,类中定义了超多的C#采集文章.网页抓取文章的基础技巧,下面分享代码: using System; using System.Data; using System.Configuration; using System.Net; using System.IO; using System.Text; using System.Collections.Generic; using System.Text.RegularExpressions; using Sys

类图(Rose) - Windows XP经典软件系列

最近开始了自己高级数据结构之旅,在这次旅行中,我将持续把一些高级的数据结构从理论到编码都过一遍,同时通过博客形式分享出来,希望大家指出不足之处! 二叉排序树是一种动态排序的数据结构,支持插入.删除.查找等操作,且平均时间复杂度为O(log(N)),但是普通二叉排序树不能保证树退化为一颗分支的情况,此时最坏情况下的时间复杂度为O(N).此时,平衡二叉树的产生了.平衡二叉树是一种动态调整平衡的数据结构,但理想的平衡二叉树很难,于是人们使用AVL.红黑树.Treap.伸展树等来替代平衡二叉树,这些数据

java 类对象使用

在学习反射机制时,总结一下获得类对象方式: 第一种方式:通过类本身来获得对象 Class<?> classname = this.getClass(); 或者this.class 第二种方式:通过子类的实例获取父类对象 ClassName cn = new ClassName(); UserClass = cn.getClass(); Class<?> SubUserClass = UserClass.getSuperclass(); 第三种方式:通过类名加.class获取对象 C

Python-class类的相关总结

在Python中,所有的数据类型都可以视为对象,自定义的对象数据类型就是面向对象中的类(class)的概念. 面向对象编程:object oriented programming简称OOP. 1 ###简单举例,以登记学生的姓名和成绩举例 2 #!/usr/bin/python 3 #-*- coding:utf-8 -*- 4 class Student(object): ##定义student类 5 def __init__(self, name, score): ##__init__可以绑