All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.jaeksoft.searchlib.index.IndexSingle Maven / Gradle / Ivy

Go to download

OpenSearchServer is a powerful, enterprise-class, search engine program. Using the web user interface, the crawlers (web, file, database, ...) and the REST/RESTFul API you will be able to integrate quickly and easily advanced full-text search capabilities in your application. OpenSearchServer runs on Windows and Linux/Unix/BSD.

There is a newer version: 1.5.14
Show newest version
/**   
 * License Agreement for OpenSearchServer
 *
 * Copyright (C) 2008-2014 Emmanuel Keller / Jaeksoft
 * 
 * http://www.open-search-server.com
 * 
 * This file is part of OpenSearchServer.
 *
 * OpenSearchServer is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 * OpenSearchServer is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with OpenSearchServer. 
 *  If not, see .
 **/

package com.jaeksoft.searchlib.index;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Collection;
import java.util.Map;
import java.util.Set;

import org.apache.commons.io.filefilter.DirectoryFileFilter;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermDocs;
import org.apache.lucene.index.TermEnum;
import org.apache.lucene.index.TermFreqVector;
import org.apache.lucene.index.TermPositions;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.similar.MoreLikeThis;
import org.json.JSONException;
import org.xml.sax.SAXException;

import com.jaeksoft.searchlib.SearchLibException;
import com.jaeksoft.searchlib.analysis.PerFieldAnalyzer;
import com.jaeksoft.searchlib.filter.FilterAbstract;
import com.jaeksoft.searchlib.filter.FilterHits;
import com.jaeksoft.searchlib.function.expression.SyntaxError;
import com.jaeksoft.searchlib.query.ParseException;
import com.jaeksoft.searchlib.request.AbstractRequest;
import com.jaeksoft.searchlib.request.AbstractSearchRequest;
import com.jaeksoft.searchlib.result.AbstractResult;
import com.jaeksoft.searchlib.schema.FieldValue;
import com.jaeksoft.searchlib.schema.Schema;
import com.jaeksoft.searchlib.schema.SchemaField;
import com.jaeksoft.searchlib.util.ReadWriteLock;
import com.jaeksoft.searchlib.util.Timer;
import com.jaeksoft.searchlib.util.XmlWriter;
import com.jaeksoft.searchlib.webservice.query.document.IndexDocumentResult;

public class IndexSingle extends IndexAbstract {

	final private ReadWriteLock rwl = new ReadWriteLock();

	final private IndexDirectory indexDirectory;

	private final ReaderLocal reader;
	private final WriterInterface writer;

	private volatile boolean online;

	public IndexSingle(File configDir, IndexConfig indexConfig,
			boolean createIfNotExists) throws IOException, URISyntaxException,
			SearchLibException, JSONException {
		super(indexConfig);
		this.online = true;

		boolean bCreate = false;
		File indexDir = new File(configDir, "index");
		if (!indexDir.exists()) {
			if (!createIfNotExists) {
				indexDirectory = null;
				reader = null;
				writer = null;
				return;
			}
			indexDir.mkdir();
			bCreate = true;
		} else
			indexDir = findIndexDirOrSub(indexDir);
		URI remoteURI = indexConfig.getRemoteURI();
		indexDirectory = remoteURI == null ? new IndexDirectory(indexDir)
				: new IndexDirectory(remoteURI);
		bCreate = bCreate || indexDirectory.isEmpty();
		writer = new WriterLocal(indexConfig, this, indexDirectory);
		if (bCreate)
			((WriterLocal) writer).create();
		reader = new ReaderLocal(indexConfig, indexDirectory, true);
	}

	/**
	 * Check if there is old style index sub directory
	 * 
	 * @param indexDir
	 * @return
	 */
	private File findIndexDirOrSub(File indexDir) {
		File[] dirs = indexDir
				.listFiles((FileFilter) DirectoryFileFilter.INSTANCE);
		if (dirs == null)
			return indexDir;
		if (dirs.length == 0)
			return indexDir;
		return dirs[dirs.length - 1];
	}

	@Override
	public void close() {
		rwl.w.lock();
		try {
			if (reader != null)
				reader.close();
			indexDirectory.close();
		} finally {
			rwl.w.unlock();
		}
	}

	private void checkOnline(boolean online) throws SearchLibException {
		if (this.online != online)
			throw new SearchLibException("Index is offline");
	}

	@Override
	public void optimize() throws SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (writer == null)
				return;
			writer.optimize();
			if (reader != null)
				reader.reload();
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	public boolean isOptimizing() {
		rwl.r.lock();
		try {
			return writer != null ? writer.isOptimizing() : false;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	public void deleteAll() throws SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (writer != null)
				writer.deleteAll();
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	public int deleteDocuments(AbstractRequest request)
			throws SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			return writer.deleteDocuments(request);
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	public void addUpdateInterface(UpdateInterfaces updateInterface)
			throws SearchLibException {
		rwl.r.lock();
		try {
			if (writer != null)
				writer.addUpdateInterface(updateInterface);
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	public boolean updateDocument(Schema schema, IndexDocument document)
			throws SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (writer != null)
				return writer.updateDocument(schema, document);
			else
				return false;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	public int updateDocuments(Schema schema,
			Collection documents) throws SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (writer != null)
				return writer.updateDocuments(schema, documents);
			else
				return 0;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	public int updateIndexDocuments(Schema schema,
			Collection documents)
			throws SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (writer != null)
				return writer.updateIndexDocuments(schema, documents);
			else
				return 0;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	public void reload() throws SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			reader.reload();
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	public AbstractResult request(AbstractRequest request)
			throws SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (reader != null)
				return reader.request(request);
			return null;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	public String explain(AbstractRequest request, int docId, boolean bHtml)
			throws SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (reader != null)
				return reader.explain(request, docId, bHtml);
			return null;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	public boolean sameIndex(ReaderInterface reader) {
		rwl.r.lock();
		try {
			if (reader == this)
				return true;
			if (reader == this.reader)
				return true;
			return false;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	public IndexStatistics getStatistics() throws IOException,
			SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (reader != null)
				return reader.getStatistics();
			return null;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	public IndexSingle get(String name) {
		return this;
	}

	@Override
	final public int getDocFreq(final Term term) throws SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (reader != null)
				return reader.getDocFreq(term);
			return 0;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	final public TermEnum getTermEnum() throws SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (reader != null)
				return reader.getTermEnum();
			return null;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	final public TermEnum getTermEnum(final Term term)
			throws SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (reader != null)
				return reader.getTermEnum(term);
			return null;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	final public TermDocs getTermDocs(final Term term)
			throws SearchLibException, IOException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (reader != null)
				return reader.getTermDocs(term);
			return null;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	final public TermPositions getTermPositions() throws IOException,
			SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (reader != null)
				return reader.getTermPositions();
			return null;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	final public TermFreqVector getTermFreqVector(final int docId,
			final String field) throws IOException, SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (reader != null)
				return reader.getTermFreqVector(docId, field);
			return null;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	final public void putTermVectors(final int[] docIds, final String field,
			final Collection termVectors) throws IOException,
			SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (reader != null)
				reader.putTermVectors(docIds, field, termVectors);
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	final public FieldCacheIndex getStringIndex(final String fieldName)
			throws IOException, SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (reader != null)
				return reader.getStringIndex(fieldName);
			return null;
		} finally {
			rwl.r.unlock();
		}

	}

	@Override
	public FilterHits getFilterHits(SchemaField defaultField,
			PerFieldAnalyzer analyzer, AbstractSearchRequest request,
			FilterAbstract filter, Timer timer) throws ParseException,
			IOException, SearchLibException, SyntaxError {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (reader != null)
				return reader.getFilterHits(defaultField, analyzer, request,
						filter, timer);
			return null;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	public DocSetHits searchDocSet(AbstractSearchRequest searchRequest,
			Timer timer) throws IOException, ParseException, SyntaxError,
			SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (reader != null)
				return reader.searchDocSet(searchRequest, timer);
			return null;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	final public boolean isOnline() {
		rwl.r.lock();
		try {
			return online;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	public void setOnline(boolean v) throws SearchLibException {
		rwl.r.lock();
		try {
			if (v == online)
				return;
		} finally {
			rwl.r.unlock();
		}
		rwl.w.lock();
		try {
			if (v == online)
				return;
			online = v;
			if (v)
				reader.reload();
			else
				reader.close();
		} finally {
			rwl.w.unlock();
		}
	}

	@Override
	public long getVersion() throws SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (reader == null)
				return 0;
			return reader.getVersion();
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	public String[] getDocTerms(String field) throws SearchLibException,
			IOException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (reader != null)
				return reader.getDocTerms(field);
			return null;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	protected void writeXmlConfigIndex(XmlWriter xmlWriter) throws SAXException {
		indexConfig.writeXmlConfig(xmlWriter);
	}

	@Override
	public Collection getFieldNames() throws SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (reader != null)
				return reader.getFieldNames();
			return null;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	final public Map getDocumentFields(final int docId,
			final Set fieldNameSet, final Timer timer)
			throws IOException, ParseException, SyntaxError, SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (reader != null)
				return reader.getDocumentFields(docId, fieldNameSet, timer);
			return null;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	public Map getDocumentStoredField(final int docId)
			throws IOException, SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (reader != null)
				return reader.getDocumentStoredField(docId);
			return null;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	public Query rewrite(Query query) throws SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (reader != null)
				return reader.rewrite(query);
			return null;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	public MoreLikeThis getMoreLikeThis() throws SearchLibException {
		rwl.r.lock();
		try {
			checkOnline(true);
			if (reader != null)
				return reader.getMoreLikeThis();
			return null;
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	public void mergeData(WriterInterface source) throws SearchLibException {
		if (!(source instanceof IndexSingle))
			throw new SearchLibException("Unsupported operation");
		IndexSingle sourceIndex = (IndexSingle) source;
		rwl.r.lock();
		try {
			if (writer == null)
				return;
			sourceIndex.rwl.r.lock();
			try {
				writer.mergeData(sourceIndex.writer);
				if (reader != null)
					reader.reload();
			} finally {
				sourceIndex.rwl.r.unlock();
			}
		} finally {
			rwl.r.unlock();
		}
	}

	@Override
	public boolean isMerging() {
		rwl.r.lock();
		try {
			return writer != null ? writer.isMerging() : false;
		} finally {
			rwl.r.unlock();
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy