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

小葫芦君(汉斯的博客)

博客迁移到新博客:https://blog.ssxingshou.com

 
 
 

日志

 
 
关于我

小小葫芦商城,为您提供高品质的商品,一流的产品,一流的包装服务,一流的物流服务,放心购买

网易考拉推荐

Lucene-2.3.1 源代码阅读学习(15)  

2008-04-28 15:54:48|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

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

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

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

历史上的今天

在LOFTER的更多文章

评论

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

页脚

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