zoukankan      html  css  js  c++  java
  • 关于索引删除的策略IndexDeletionPolicy

    关于索引删除的策略IndexDeletionPolicy 。

    public IndexWriter(Directory d, Analyzer a, boolean create)
             throws CorruptIndexException, LockObtainFailedException, IOException {
          init(d, a, create, false, null, true);
    }

    构造一个IndexWriter需要调用init()方法进行初始化,init()方法的声明如下所示:

    /**
    * 该方法中的参数列表中。各个参数的含义如下:
    * d :指定的存放建立索引文件的索引目录
    * a :一个传递进来分析器
    * create :是否要重新写入索引文件,如果为true,则重写索引文件;如果为false,则追加写入索引文件
    * closeDir :一个boolean型变量,表示是否关闭索引目录Directory d,它是IndexWriter的一个成员变量
    * deletionPolicy :指定删除索引文件使用的策略
    * autoCommit :建立索引文件后,不对已经存在的索引进行Clone,自动提交。
    */

    private void init(Directory d, Analyzer a, final boolean create, boolean closeDir, IndexDeletionPolicy deletionPolicy, boolean autoCommit)
          throws CorruptIndexException, LockObtainFailedException, IOException

    IndexDeletionPolicy是一个接口,是有关在建立索引的过程中,对索引文件进行灵活地(删除)操作的一种自定义接口。可以在合适的时机进行删除操作,可以指定删除的时刻,完全可以根据自己的需要进行定制,但是,这可能会造成存储开销,但是相对于删除操作策略的灵活便利性,这也是比较值得的。

    IndexDeletionPolicy接口的定义非常简单,而且为我们做了启发式的指引:

    package org.apache.lucene.index;

    import java.util.List;
    import java.io.IOException;

    // 该接口示例了两种删除索引文件的时机,即所谓的Points

    public interface IndexDeletionPolicy {

    // 一个IndexWriter索引器初始化的时候,可以删除一些时刻(提交点)提交的索引文件,这些提交点存放在一个List中,包括最早提交点和最近的提点之间的所有提交点,当然,删除他们是可选的,而且应当慎重,因为一旦删除便不可回滚。
    public void onInit(List commits) throws IOException;

    // 当新建的索引写入目录,并已经提交的时候,我们仍然可以删除指定List中一些时刻(提交点)提交的索引文件,当然,删除他们是可选的,而且应当慎重
    public void onCommit(List commits) throws IOException;
    }

    IndexDeletionPolicy接口的实现类如图所示:

    通过对IndexDeletionPolicy接口的实现类进行学习,把握最基本的索引删除的动机和行为。通过IndexDeletionPolicy接口的实现类的类名就可以大概了解到它的索引删除策略:

    1、KeepOnlyLastCommitDeletionPolicy策略

    KeepOnlyLastCommitDeletionPolicy类在初始化一个IndexWriter的时候,在init方法中如果指定IndexDeletionPolicy deletionPolicy为null,则默认的索引删除策略为KeepOnlyLastCommitDeletionPolicy。

    KeepOnlyLastCommitDeletionPolicy类的源代码非常容易理解,如下所示:

    package org.apache.lucene.index;

    import java.util.List;

    public final class KeepOnlyLastCommitDeletionPolicy implements IndexDeletionPolicy {

    //     初始化IndexWriter的时候,除了保留最近的一个提交点以外,删除所有提交点提交的索引文件
    public void onInit(List commits) {
          // Note that commits.size() should normally be 1:
          onCommit(commits);
    }

    //  除了最近时刻的提交点保留以外,其余的全部删除
    public void onCommit(List commits) {
          // Note that commits.size() should normally be 2 (if not
          // called by onInit above):
          int size = commits.size();
          for(int i=0;i<size-1;i++) {      //  IndexCommitPoint也很重要,因为它涉及到了索引段,比较复杂,在后面系统学习
            ((IndexCommitPoint) commits.get(i)).delete();
          }
    }
    }

    2、KeepNoneOnInitDeletionPolicy策略

    初始化时删除所有提交点的索引段,最后提交的时候,保留最近提交点的索引段。

    class KeepNoneOnInitDeletionPolicy implements IndexDeletionPolicy {
          int numOnInit;
          int numOnCommit;
          public void onInit(List commits) {
            verifyCommitOrder(commits);
            numOnInit++;
            //  初始化的时候,就删除所有的提交点
            Iterator it = commits.iterator();
            while(it.hasNext()) {
              ((IndexCommitPoint) it.next()).delete();
            }
          }
          public void onCommit(List commits) {

          //     验证每个提交点提交的索引文件(索引段)名称的正确性
            verifyCommitOrder(commits);
            int size = commits.size();
         //  除了最近时刻的提交点保留以外,其余的全部删除
            for(int i=0;i<size-1;i++) {
              ((IndexCommitPoint) commits.get(i)).delete();
            }
            numOnCommit++;
          }
      }

    3、KeepAllDeletionPolicy策略

    保留所有提交点,不删除任何提交点的索引段。

    class KeepAllDeletionPolicy implements IndexDeletionPolicy {
          int numOnInit;
          int numOnCommit;
          public void onInit(List commits) {
            verifyCommitOrder(commits);
            numOnInit++;
          }
          public void onCommit(List commits) {
            verifyCommitOrder(commits);
            numOnCommit++;
          }
      }

    4、KeepLastNDeletionPolicy策略

    初始化时,不删除任何提交点;最后提交时,保留指定的最近的N个提交点。

    class KeepLastNDeletionPolicy implements IndexDeletionPolicy {
          int numOnInit;
          int numOnCommit;
          int numToKeep;
          int numDelete;
          Set seen = new HashSet();      //     Set seen用于保证不重复删除某个提交点

          public KeepLastNDeletionPolicy(int numToKeep) {    //    初始化显式指定最近提交点的个数
            this.numToKeep = numToKeep;
          }

          public void onInit(List commits) {
            verifyCommitOrder(commits);
            numOnInit++;
            // false指定了不做任何删除
            doDeletes(commits, false);
          }

          public void onCommit(List commits) {
            verifyCommitOrder(commits);
            doDeletes(commits, true);      //  根据初始化的numToKeep,保留最近numToKeep个提交点
          }
         
          private void doDeletes(List commits, boolean isCommit) {
            if (isCommit) {
              String fileName = ((IndexCommitPoint) commits.get(commits.size()-1)).getSegmentsFileName();
              if (seen.contains(fileName)) {
                throw new RuntimeException("onCommit was called twice on the same commit point: " + fileName);
              }
              seen.add(fileName);      //     seen中加入的是已经删除的提交点
              numOnCommit++;
            }
            int size = commits.size();
            for(int i=0;i<size-numToKeep;i++) {    //  删除前size-numToKeep个提交点
              ((IndexCommitPoint) commits.get(i)).delete();
              numDelete++;
            }
          }
      }

    5、ExpirationTimeDeletionPolicy策略

    如果某个提交的响应已经超过指定时间,则删除掉这个提交点。

    class ExpirationTimeDeletionPolicy implements IndexDeletionPolicy {

          Directory dir;
          double expirationTimeSeconds;      //  指定提交超时时间
          int numDelete;

          public ExpirationTimeDeletionPolicy(Directory dir, double seconds) {
            this.dir = dir;
            this.expirationTimeSeconds = seconds;
          }

          public void onInit(List commits) throws IOException {
            verifyCommitOrder(commits);
            onCommit(commits);
          }

          public void onCommit(List commits) throws IOException {
            verifyCommitOrder(commits);

            IndexCommitPoint lastCommit = (IndexCommitPoint) commits.get(commits.size()-1);

            // 根据索引文件的最后提交时间
            double expireTime = dir.fileModified(lastCommit.getSegmentsFileName())/1000.0 - expirationTimeSeconds;

            Iterator it = commits.iterator();

            while(it.hasNext()) {
              IndexCommitPoint commit = (IndexCommitPoint) it.next();
              double modTime = dir.fileModified(commit.getSegmentsFileName())/1000.0;
              if (commit != lastCommit && modTime < expireTime) {
                commit.delete();
                numDelete += 1;
              }
            }
          }
      }

    上面五种删除策略,主要地,无非是在索引器初始化的时刻和建立索引提交的时刻,来选择是否删除提交点。

  • 相关阅读:
    Word中如何删除目录页的页码
    在java程序代码中打开文件
    Web程序报错:Error instantiating servlet
    将日期类型数据写入到数据库中
    《将博客搬至CSDN》
    软件测试工程师常见的面试题
    我对需求文档的理解
    简单的学生管理系统,实现增删改查
    如何求两个数的最大公约数
    【转载】LoadRunner监控window系统各项指标详解
  • 原文地址:https://www.cnblogs.com/pangblog/p/3303994.html
Copyright © 2011-2022 走看看