package proj.zoie.impl.indexing.internal; /** * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import it.unimi.dsi.fastutil.longs.LongSet; import java.io.IOException; import org.apache.log4j.Logger; import org.apache.lucene.analysis.Analyzer; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; import org.apache.lucene.index.SerialMergeScheduler; import org.apache.lucene.index.IndexWriter.MaxFieldLength; import org.apache.lucene.search.Similarity; import org.apache.lucene.store.RAMDirectory; import proj.zoie.api.ZoieIndexReader; import proj.zoie.api.indexing.IndexReaderDecorator; public class RAMSearchIndex<R extends IndexReader> extends BaseSearchIndex<R> { private long _version; private final RAMDirectory _directory; private final IndexReaderDecorator<R> _decorator; // a consistent pair of reader and deleted set private volatile ZoieIndexReader<R> _currentReader; public static final Logger log = Logger.getLogger(RAMSearchIndex.class); RAMSearchIndex(long version, IndexReaderDecorator<R> decorator) { _directory = new RAMDirectory(); _version = version; _decorator = decorator; _currentReader = null; // ConcurrentMergeScheduler cms = new ConcurrentMergeScheduler(); // cms.setMaxThreadCount(1); _mergeScheduler = new SerialMergeScheduler(); } public void close() { super.close(); if (_directory!=null) { _directory.close(); } } public long getVersion() { return _version; } public void setVersion(long version) throws IOException { _version = version; } public int getNumdocs() { ZoieIndexReader<R> reader=null; try { reader=openIndexReader(); } catch (IOException e) { log.error(e.getMessage(),e); } if (reader!=null) { return reader.numDocs(); } else { return 0; } } @Override public ZoieIndexReader<R> openIndexReader() throws IOException { return _currentReader; } @Override protected IndexReader openIndexReaderForDelete() throws IOException { if (IndexReader.indexExists(_directory)){ return IndexReader.open(_directory,false); } else{ return null; } } private ZoieIndexReader<R> openIndexReaderInternal() throws IOException { if (IndexReader.indexExists(_directory)) { IndexReader srcReader=null; ZoieIndexReader<R> finalReader=null; try { // for RAM indexes, just get a new index reader srcReader=IndexReader.open(_directory,true); finalReader=ZoieIndexReader.open(srcReader, _decorator); return finalReader; } catch(IOException ioe) { // if reader decoration fails, still need to close the source reader if (srcReader!=null) { srcReader.close(); } throw ioe; } } else{ return null; // null indicates no index exist, following the contract } } public IndexWriter openIndexWriter(Analyzer analyzer,Similarity similarity) throws IOException { if(_indexWriter != null) return _indexWriter; // if index does not exist, create empty index boolean create = !IndexReader.indexExists(_directory); IndexWriter idxWriter = new IndexWriter(_directory, analyzer, create, MaxFieldLength.UNLIMITED); // TODO disable compound file for RAMDirecory when lucene bug is fixed idxWriter.setUseCompoundFile(true); idxWriter.setMergeScheduler(_mergeScheduler); idxWriter.setRAMBufferSizeMB(3); if (similarity != null) { idxWriter.setSimilarity(similarity); } _indexWriter = idxWriter; return idxWriter; } @Override public void refresh() throws IOException { synchronized(this) { ZoieIndexReader<R> reader = null; if (_currentReader==null) { reader = openIndexReaderInternal(); } else { reader = (ZoieIndexReader<R>)_currentReader.reopen(true); } _currentReader = reader; LongSet delDocs = _delDocs; clearDeletes(); markDeletes(delDocs); // re-mark deletes } } }