注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

anqiang专栏

不要问细节是怎么搞的,源码说明一切

 
 
 

日志

 
 

FieldInfos源码解析  

2009-12-05 13:25:02|  分类: Lucene |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

FieldInfos类负责对当前segment中所有的field信息进行管理,它相当于一个公用的fieldInfo池,在每一个其它的index文件中都会用到它。在读取index信息前,FieldInfos往往是最先被载入内存的(这个文件长度比较小),用于其它index文件获得field信息。

Lucene中,我们知道每个Document是由多个field组成的,因此field才是文本内容的基本组成部分。而Term又是组成这个基本部分的基本单元。对于一个field它会有很多方面的信息,例如:是否切割(tokenized,是否存储(stored,是否保持vector等等,这些信息对于索引来说应该是固定的(当然也可以改变,但是fieldInfo的属性具有后向性,即如果后面fieldInfo信息改变,那么以后所有的保存方式按照最新的这个fieldInfo来进行)。那么,在一个segment中,fieldInfos这些信息需要一个公共的地方来保存它们,这就是fieldInfos类所起到的作用。

源码解析:

/**

   * Construct a FieldInfos object using the directory and the name of the file

   * IndexInput

   * 我们可以注意到FieldInfos信息时一次性全部放入内存中的,这与其它的index文件时不一样的,

   * 因为这个fieldInfos信息要在其它的所有index文件中被用到,它相当于一个公用的池,因此必须要全部

   * 读入内存中去,同时fieldInfos文件比较小,不会占用过多的内存

   * @param d The directory to open the IndexInput from

   * @param name The name of the file to open the IndexInput from in the Directory

   * @throws IOException

   */

  FieldInfos(Directory d, String name) throws IOException {

    IndexInput input = d.openInput(name);

    try {

      try {

        read(input, name);

      } catch (IOException ioe) {

        if (format == FORMAT_PRE) {

          // LUCENE-1623: FORMAT_PRE (before there was a

          // format) may be 2.3.2 (pre-utf8) or 2.4.x (utf8)

          // encoding; retry with input set to pre-utf8

          input.seek(0);

          input.setModifiedUTF8StringsMode();

          byNumber.clear();

          byName.clear();

          try {

            read(input, name);

          } catch (Throwable t) {

            // Ignore any new exception & throw original IOE

            throw ioe;

          }

        } else {

          // The IOException cannot be caused by

          // LUCENE-1623, so re-throw it

          throw ioe;

        }

      }

    } finally {

      input.close();

    }

  }

/**

   * Returns a deep clone of this FieldInfos instance.

   * 一个对于FieldInfos的深度克隆

   */

  synchronized public Object clone() {

    FieldInfos fis = new FieldInfos();

    final int numField = byNumber.size();

    for(int i=0;i<numField;i++) {

      FieldInfo fi = (FieldInfo) ((FieldInfo) byNumber.get(i)).clone();

      fis.byNumber.add(fi);

      fis.byName.put(fi.name, fi);

    }

    return fis;

  }

 /** Adds field info for a Document. */

  /**

   * 为一个文档添加它所有的fieldInfo

   */

  synchronized public void add(Document doc) {

    List fields = doc.getFields();

    Iterator fieldIterator = fields.iterator();

    while (fieldIterator.hasNext()) {

      Fieldable field = (Fieldable) fieldIterator.next();

      add(field.name(), field.isIndexed(), field.isTermVectorStored(), field.isStorePositionWithTermVector(),

              field.isStoreOffsetWithTermVector(), field.getOmitNorms(), falsefield.getOmitTf());

}

/** If the field is not yet known, adds it. If it is known, checks to make

   *  sure that the isIndexed flag is the same as was given previously for this

   *  field. If not - marks it as being indexed.  Same goes for the TermVector

   * parameters.

   *

   * @param name The name of the field

   * @param isIndexed true if the field is indexed

   * @param storeTermVector true if the term vector should be stored

   * @param storePositionWithTermVector true if the term vector with positions should be stored

   * @param storeOffsetWithTermVector true if the term vector with offsets should be stored

   * @param omitNorms true if the norms for the indexed field should be omitted

   * @param storePayloads true if payloads should be stored for this field

   * @param omitTermFreqAndPositions true if term freqs should be omitted for this field

   * 对于field的信息,有后向性

   * 根据后加入的同名field的信息来决定

   * 流程如下:

   * 1.判断当前field在fieldInfos中是否存在

   * 2.如果不存在,则创建一个

   * 3.如果存在,则更新当前找到的fieldInfo

   */

  synchronized public FieldInfo add(String name, boolean isIndexed, boolean storeTermVector,

                       boolean storePositionWithTermVector, boolean storeOffsetWithTermVector,

                       boolean omitNorms, boolean storePayloads, boolean omitTermFreqAndPositions) {

    FieldInfo fi = fieldInfo(name);

    

    if (fi == null) {

      return addInternal(name, isIndexed, storeTermVector, storePositionWithTermVector, storeOffsetWithTermVector, omitNorms, storePayloads, omitTermFreqAndPositions);

    } else {

      fi.update(isIndexed, storeTermVector, storePositionWithTermVector, storeOffsetWithTermVector, omitNorms, storePayloads, omitTermFreqAndPositions);

    }

    return fi;

  }

private FieldInfo addInternal(String name, boolean isIndexed,

                                boolean storeTermVector, boolean storePositionWithTermVector, 

                                boolean storeOffsetWithTermVector, boolean omitNorms, boolean storePayloads, boolean omitTermFreqAndPositions) {

    /**

     * 这样使用intern可以是name这个对象是对象池中的string,

     * 而如果最前面的name不在对象池里面,那么它有可能在以后被gc所回收

     */

name = StringHelper.intern(name);

    FieldInfo fi = new FieldInfo(name, isIndexed, byNumber.size(), storeTermVector, storePositionWithTermVector,

                                 storeOffsetWithTermVector, omitNorms, storePayloads, omitTermFreqAndPositions);

    //在field池中放入fieldInfo

    byNumber.add(fi);

    byName.put(name, fi);

    return fi;

  }

 /**

   * 将fields的信息写入到fnm文件中

   * 格式如下:

   * 索引格式

   * 保存的field的数量

   * for(all fields){

   *     field name

   *     field index style bits

   * 

   * }

   * @param output

   * @throws IOException

   */

  public void write(IndexOutput output) throws IOException {

    output.writeVInt(CURRENT_FORMAT);

    output.writeVInt(size());

    for (int i = 0; i < size(); i++) {

      FieldInfo fi = fieldInfo(i);

      byte bits = 0x0;

      if (fi.isIndexed) bits |= IS_INDEXED;

      if (fi.storeTermVector) bits |= STORE_TERMVECTOR;

      if (fi.storePositionWithTermVector) bits |= STORE_POSITIONS_WITH_TERMVECTOR;

      if (fi.storeOffsetWithTermVector) bits |= STORE_OFFSET_WITH_TERMVECTOR;

      if (fi.omitNorms) bits |= OMIT_NORMS;

      if (fi.storePayloads) bits |= STORE_PAYLOADS;

      if (fi.omitTermFreqAndPositions) bits |= OMIT_TERM_FREQ_AND_POSITIONS;

      

      output.writeString(fi.name);

      output.writeByte(bits);

    }

  }

  评论这张
 
阅读(236)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017