关于索引删除的策略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;
          }
        }
      }
  }

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

关于索引删除的策略IndexDeletionPolicy的更多相关文章

  1. ELK日志保留7天-索引生命周期策略

    一.简介 ELK日志我们一般都是按天存储,例如索引名为"kafkalog-2022-04-05",因为日志量所占的存储是非常大的,我们不能一直保存,而是要定期清理旧的,这里就以保留 ...

  2. MySQL索引与优化策略

    1. MySQL索引实现 在MySQL中,索引属于存储引擎级别的概念,不同存储引擎对索引的实现方式是不同的,下面主要讨论MyISAM和InnoDB两个存储引擎的索引实现方式. MyISAM索引实现 M ...

  3. paip.提升性能--- mysql 建立索引 删除索引 很慢的解决.

    paip.提升性能--- mysql 建立索引 删除索引 很慢的解决. 作者Attilax ,  EMAIL:1466519819@qq.com 来源:attilax的专栏 地址:http://blo ...

  4. python 数组中如何根据值,获取索引,如何根据索引删除值 , 以及如何根据值删除值

    假设有一数组 s = [1,2,3,4,5,6,7,8,9] (1)如何根据值获取索引 ,如果值为5 , 那对应的索引为? (2)如何根据索引删除值 , 删除数组中索引5对应的值: (3)根据数组中的 ...

  5. lucene 索引删除

    1.IndexWriter和IndexReader都有删除索引的方法:deleteDocuments(); 不建议使用IndexReader删除索引:使用IndexReader进行删除时,必须关闭所有 ...

  6. mysql中如何删除表上的索引?删除索引?

    需求描述: 今天在做SQL的优化的时候,想要把mysql中某个表上的索引删除掉,突然忘记语法了,找到帮助,在此记录下 操作过程: 1.查看表上的索引 show index from ti_o_sms; ...

  7. elasticserach 索引删除 源码分析

    索引的构成 在看IndicesService服务中移除索引的前提,先了解一个Index类的构成,也就是索引的一些基本信息,代码贴图如下:   主要的信息就两个:一个是name,表示索引名称,一个是uu ...

  8. MySQL外键及级联删除 && 表的存储引擎与创建索引 && 删除数据库和表

    Messages表: mysql>create table Messages( ->message_id int auto_increment primary key, ->user ...

  9. mysql创建索引/删除索引操作

    -- 1.ALTER 创建索引 -- table_name表名,column_list列名,index_name索引名 -- 创建index索引 ALTER TABLE table_name ADD ...

随机推荐

  1. K&amp;R练习题6-1统计关键词出现的次数

    这道练习题训练了: 1.结构体数组 2.二分查找 3.指针操作 ---- 都不难.但非常基础,我认为非常好,做完了记到博客上来,题目见k&R,实现例如以下: /* * Practice of ...

  2. CIconListBox带图标的列表框类

    有时候,我们需要在列表框ListBox中插入带图标的文字项,这就需要自己派生一个类出来了,网上的一个CIconListBox类还不错,网站http://www.codeguru.com/Cpp/con ...

  3. 《Java虚拟机原理图解》1.3、class文件里的訪问标志、类索引、父类索引、接口索引集合

    讲完了class文件里的常量池,我们就相当于克服了class文件里最麻烦的模块了.如今,我们来看一下class文件里紧接着常量池后面的几个东西:訪问标志.类索引.父类索引.接口索引集合. 1. 訪问标 ...

  4. IE Jquery中拒绝訪问的处理方法

    多人合作开发一个站点过程中,为便于开发,将一些公共文件如js,css,images放在外网上,各自链接这类文件以供使用.本地測试时网页的一些JS代码在IE8,IE6中会停止运行,并报某个js文件拒绝訪 ...

  5. C#、ASP.NET、WinForm - 实现邮件发送的功能

    转载自:http://www.cnblogs.com/mingmingruyuedlut/archive/2011/10/14/2212255.html 发送邮件所用的核心知识点 微软封装好的Mail ...

  6. pthread_setschedprio()函数详解!!!

    pthread_setschedprio() Set a thread's priority 用于设置现成的优先级 包含在头文件 #include <pthread.h> 用法:int p ...

  7. Qt之多线程

    源地址:http://blog.csdn.net/liuhongwei123888/article/details/6072320 Qt 是一种基于 C++ 的跨平台 GUI 系统,能够提供给用户构造 ...

  8. 学习老外用webstorm开发nodejs的技巧--代码提示DefinitelyTyped

    最近入了nodejs的坑,作为老码农,js对我来说还是很容易的.webstorm虽说用得不多,但是pycharms我是老手了,idea的东西一脉相承,想想也就那样了. 但是自从看了某个视频后,觉得毕竟 ...

  9. EasyUI - 操作 Tree 控件

    效果: HTML代码: 使用了模板页 <asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHo ...

  10. asp.net 检查文件夹和文件是否存在

    原文  asp.net 检查文件夹和文件是否存在 允许 path 参数指定相对或绝对路径信息. 相对路径信息被解释为相对于当前工作目录. 检查该目录是否存在之前,从 path 参数的末尾移除尾随空格. ...