实时搜索设计开发中,IndexReader在饮用计数变为0时调用doClose,而SegmentReader则有一个addCoreClosedListener方法控制在SegmentCoreReaders关闭时的操作,搜索Lucene的代码只有在FieldCacheImpl中看到调用,其中的回调>是让SegmentCoreReaders关闭之后从field cache中删除field cache。
查看Lucene core 4.0的代码,使用的FieldCache只有Field Comparator,FieldCacheRangeFilter,FieldValueFilter等,看起来如果完全基于docvalues做排序和filter,不需要考虑。
另外如果考虑的话,filed cache基于docId,所以内存索引快照并不需要每个都对应一个field cache,只要映射到最新的field cache即可,只要读取时不逾越max doc id即可。因此RamIndexReader.getCoreCacheKey返回对应RamIndexWriter即可。
另外,SegmentCoreReaders的关闭文件句柄操作时IOUtils.close(termVectorsLocal, fieldsReaderLocal,...)。
实时搜索时每个IndexSearcher都需要关闭其Reader的,这样在重复打开时不会有遗漏的文件句柄。
要真正释放资源,应该在new新的实时搜索searcher时不操作(new时自动有一个引用计数了),在searcher替换时调用旧Reader的decRef方法。
搜索前调用一次incRef,搜索完成调用一次decRef。
具体到内存索引Reader,其doClose可以什么都不做。
RealTimeIndexWriter的close,分别调用RamIndexWriter的close方法,SegmentReaderAndLiveDocs的close方法。SegmentReaderAndLiveDocs内部有一个实时的SegmentReader,它也要Close。每次快照生成的SegmentReader共用一个core。ConcreateCompositeReader incRef和decRef时应该对下面的所有AtomicReader操作。
这种手动的incRef,decRef方法比较笨,而且容易出错,如果用Java7可以直接使用AutoClosable.
IndexReader关闭的问题