RAMDirectory类是与内存目录相关的,它和FSDirectory有很大地不同,这主要从它的构造函数来看:
public RAMDirectory() {
setLockFactory(new SingleInstanceLockFactory());
}
初始化的时候,指定的是LockFactory抽象类的一个具体实现类SingleInstanceLockFactory。 SingleInstanceLockFactory类的特点是,所有的加锁操作必须通过该SingleInstanceLockFactory的一个实例而发生,也就是说,在进行加锁操作的时候,必须获取到这个SingleInstanceLockFactory的实例。
实际上,在获取到一个SingleInstanceLockFactory的实例后,那么对该目录Directory进行的所有的锁都已经获取到,这些锁都被存放到SingleInstanceLockFactory类定义的locks中。
因此,多个线程要进行加锁操作的时候,需要考虑同步问题。这主要是在获取SingleInstanceLockFactory中的 SingleInstanceLock的时候,同步多个线程,包括请求加锁、释放锁,以及与此相关的共享变量。而 SingleInstanceLockFactory类的定义也充分体现了这一点:
package org.apache.lucene.store;
import java.io.IOException;
import java.util.HashSet;
import java.util.Enumeration;
public class SingleInstanceLockFactory extends LockFactory {
private HashSet locks = new HashSet();
public Lock makeLock(String lockName) {
//从锁工厂中, 根据指定的锁lockName返回一个SingleInstanceLock实例
return new SingleInstanceLock(locks, lockName);
}
public void clearLock(String lockName) throws IOException {
synchronized (locks) { // 从SingleInstanceLockFactory中清除某个锁的时候,需要同步
if (locks.contains(lockName)) {
locks.remove(lockName);
}
}
}
};
class SingleInstanceLock extends Lock {
String lockName;
private HashSet locks;
public SingleInstanceLock(HashSet locks, String lockName) {
this.locks = locks;
this.lockName = lockName;
}
public boolean obtain() throws IOException {
synchronized (locks) { // 获取锁时需要同步
return locks.add(lockName);
}
}
public void release() {
synchronized (locks) { // 释放锁时需要同步
locks.remove(lockName);
}
}
public boolean isLocked() {
synchronized (locks) {
return locks.contains(lockName);
}
}
public String toString() {
return "SingleInstanceLock: " + lockName;
}
}
因为RAMDirectory是与内存相关的目录,所以它不是永久存在的,不像FSDirectory,所以实例化一个RAMDirectory可以从一个FSDirectory的实例来完成。如下:
public RAMDirectory(File dir) throws IOException {
this(FSDirectory.getDirectory(dir), true);
}
public RAMDirectory(String dir) throws IOException {
this(FSDirectory.getDirectory(dir), true);
}
RAMDirectory的这两个构造方法,就是根据一个FSDirectory进行初始化的,即在打开一个FSDirectory的时候,同时就有一个RAMDirectory被创建了。
为什么不直接操作FSDirectory呢?可以想到,执行I/O操作速度很慢的,而在内存中的RAMDirectory处理的效率会有很大的提高。
RAMDirectory的特点决定了,对目录Directory进行复杂的操作时,都要把这些操作转移到内存中来处理。通过拷贝目录的方式也可以实例化一个RAMdirectory,如下所示:
public RAMDirectory(Directory dir) throws IOException {
this(dir, false);
}
private RAMDirectory(Directory dir, boolean closeDir) throws IOException {
this();
Directory.copy(dir, this, closeDir);
}
将指定的dir目录拷贝到当前的内存中,即实例化一个RAMDirectory。这里,closeDir是一个很重要的状态变量,指定了拷贝完成后,源目录dir是否关闭。如果实例化一个RAMDirectory完成后就关闭源目录dir,可能会因为处理的时间非常短,而需要再次打开源目录 dir,持久化到文件系统目录,开销可能会比直接操作源目录dir要大,这点要权衡。
另外,RAMDirectory类定义的成员中,有一个HashMap成员:
HashMap fileMap = new HashMap();
fileMap中存放了从源目录中取得的File,所以在RAMDirectory维护目录中文件的时候,都需要用到fileMap。
而且,管理RAMDirectory的时候,都需要synchronized。
分享到:
相关推荐
1> lucene学习笔记 2> 全文检索的实现机制 【1】lucene学习笔记的目录如下 1. 概述 3 2. lucene 的包结构 3 3. 索引文件格式 3 4. lucene中主要的类 4 4.1. Document文档类 4 4.1.1. 常用方法 4 4.1.2. 示例 4 4.2...
《Lucene搜索引擎开发权威经典11-14》是一本深度剖析Lucene搜索引擎技术的专业书籍,专注于讲解如何利用Lucene进行高效、精准的全文检索。该书以Lucene的2.1版本为背景,深入浅出地介绍了从基础概念到实际开发应用的...
实际应用中,可以结合代码实战如`FuzzyQueryParserDemo.java`, `SpanNearQueryParserDemo.java`, 和 `RangeQueryParserDemo.java`进行学习和实践,以掌握这些高级搜索技巧。理解并熟练运用这些方法,将有助于构建出...
6. **第14章:Web搜索引擎开发实例** - 最后,作者引导读者探索如何使用Lucene构建一个简单的Web搜索引擎,包括网页抓取、HTML解析以及如何处理网页链接结构。 通过阅读和实践这些章节,读者不仅能够掌握Lucene的...
通过学习《搜索引擎Lucene+Heritrix(第二版)4》这本书,读者不仅可以了解搜索引擎的基本原理,还能掌握如何利用Lucene构建自己的全文搜索引擎,以及如何用Heritrix进行大规模的网络数据抓取。书中的ch14-ch16章节...
【学习阶段11-14】物流BOS系统、MyBatis、SpringMVC、SSM综合练习(58-76天): 这些阶段涉及具体项目的实践,MyBatis是轻量级的ORM框架,SpringMVC是Spring的Web MVC组件,SSM是Spring、SpringMVC和MyBatis的集成。...
了解并掌握常用的外部API和框架,如Log4J(日志)、Quartz(调度)、JGroups(网络组通信)、JCache(分布式缓存)、Lucene(全文检索)等。 ### 19. 跨平台与本地接口 学习跨平台开发技巧,掌握JNI(Java Native ...
#### 14. Web服务技术 学习SOAP、REST等Web服务技术,包括JAX-RPC、SAAJ、JAX-WS等API的使用,实现跨平台的数据交换和服务集成。 #### 15. IoC/DI容器与框架 熟悉Spring、PicoContainer等依赖注入(DI)和面向切面...
#### 目标14:学习Web服务API - **技术要点**:JAX-RPC、SAAJ、JAXB、JAXM、JAXR、JWSDP等。 - **应用场景**:构建SOAP、RESTful风格的服务端点。 #### 目标15:学习依赖注入(DI)和控制反转(IoC)容器 - **...
- **Lucene**:学习全文检索技术的基础知识。 ### 21. 本地接口与连接器 - **JNI、JCA**:掌握Java Native Interface、Java Connector Architecture等技术,实现Java与其他语言或平台的交互。 通过以上知识点的...
#### 14. 日志记录与调度 了解不同日志框架如Log4J,以及任务调度工具如Quartz,可以提升应用的运维能力和自动化水平。 #### 15. 分布式缓存与全文搜索 掌握分布式缓存如JCache,以及全文搜索引擎如Lucene,是...
### 全文检索技术及其应用 #### 知识点一:全文检索与倒排索引的概念 ...通过上述知识点的学习和理解,我们可以更好地掌握全文检索技术的核心原理和应用场景,特别是在电子商务、搜索引擎等领域中的实际应用案例。
#### 14. **Web开发** - Servlets、JSP、JSTL等技术用于构建动态网页,以及MVC/MODEL2设计模式。 #### 15. **Web服务器** - Tomcat、Resin、JRun等服务器的配置和管理。 #### 16. **远程方法调用(RMI)** - RMI/...
6. 由于Elasticsearch基于Lucene构建,理解Lucene的原理和操作对于深入学习Elasticsearch是非常有帮助的。 7. 书中提供的案例和解决方案可能涵盖如何优化搜索速度、如何处理大规模数据集、如何提高搜索结果的相关性...
Lucene、Solr(搜索) httpclient(调用系统服务) Mysql MyCat mysql分布式集群解决方案 LVS+Nginx(web服务器) Quartz(定时任务) ActiveMQ(消息队列) Alibaba Dubbo服务接口集群 Fastdfs 分布式文件...
News.zip 是上图中批量插入时要输入的XML文件,它包含3万条从新浪和中华网抓下来的过时的新闻,大约2000万字左右,可供各位朋友学习使用。 注意:如果要导入news.xml,这个文件必须要和Demo.KTDictSegAnalyzer.exe...
11. **中文分词**:在Lucene和Lietu等工具中,中文分词是文本预处理的关键步骤,正向最大匹配是常见的分词算法。 12. **查找词典算法**:Trie树是构建词典和进行快速查找的高效数据结构,包括数字搜索树和Tire树,...
14. 搜索的未来发展:搜索的未来发展方向是人工智能、自然语言处理、机器学习等领域。 通过本文,我们可以了解到 ElasticSearch 的基础知识点,包括搜索的概念、倒排索引、ElasticSearch 介绍等。 ElasticSearch 是...
- **Lucene到JBPM**:掌握全文检索引擎Lucene,以及工作流引擎JBPM,用于提升系统的搜索功能和业务流程自动化。 9. **XML**: - **语法和解析**:学习XML的语法规范和解析技术,用于数据交换和配置文件处理。 10...
你需要学习Lucene的基本操作,包括创建索引、分析文本、查询执行和结果排序。理解分词器(Analyzer)的选择和定制,以及如何使用Document、Field和IndexWriter等核心类是关键。此外,熟悉ScoreDoc、TopDocs等概念,...