zoukankan      html  css  js  c++  java
  • Lucene的DocFieldProcessor类

    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);
        }
      }
      
  • 相关阅读:
    (一)Python入门-3序列:04列表-元素删除的3种方式-删除本质是数组元素拷贝
    (一)Python入门-3序列:05列表-元素的访问-元素出现次数统计-成员资格判断
    Java学习笔记_180704_final和static关键字
    Java学习笔记_180702_基本类型和引用类型作为参数传递特性
    Java学习笔记_180702_面向对象编程
    如何手动实现整型数值60的二进制到十六进制的转换
    Java学习笔记_180627_循环控制语句
    兔子生兔子问题(斐波那契数列)
    Java学习笔记_180625_基础语法
    ubuntu和win10双系统,用ubuntu引导win10启动
  • 原文地址:https://www.cnblogs.com/hdflzh/p/3792356.html
Copyright © 2011-2022 走看看