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

com.jaeksoft.searchlib.collapse.CollapseAbstract Maven / Gradle / Ivy

/**   
 * License Agreement for OpenSearchServer
 *
 * Copyright (C) 2008-2013 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.collapse;

import java.io.IOException;
import java.util.Collection;

import com.jaeksoft.searchlib.function.expression.SyntaxError;
import com.jaeksoft.searchlib.index.FieldCacheIndex;
import com.jaeksoft.searchlib.index.ReaderAbstract;
import com.jaeksoft.searchlib.query.ParseException;
import com.jaeksoft.searchlib.request.AbstractSearchRequest;
import com.jaeksoft.searchlib.result.collector.CollapseDocInterface;
import com.jaeksoft.searchlib.result.collector.DistanceInterface;
import com.jaeksoft.searchlib.result.collector.DocIdInterface;
import com.jaeksoft.searchlib.result.collector.JoinDocInterface;
import com.jaeksoft.searchlib.result.collector.ScoreInterface;
import com.jaeksoft.searchlib.result.collector.collapsing.CollapseBaseCollector;
import com.jaeksoft.searchlib.result.collector.collapsing.CollapseCollectorInterface;
import com.jaeksoft.searchlib.result.collector.collapsing.CollapseDistanceCollector;
import com.jaeksoft.searchlib.result.collector.collapsing.CollapseJoinDocCollector;
import com.jaeksoft.searchlib.result.collector.collapsing.CollapseScoreDocCollector;
import com.jaeksoft.searchlib.util.Timer;

public abstract class CollapseAbstract {

	private transient final int collapseMax;
	private transient final String collapseField;
	private transient final CollapseParameters.Mode collapseMode;
	private transient final CollapseParameters.Type collapseType;
	private transient final Collection collapseFunctionFields;
	protected transient final AbstractSearchRequest searchRequest;
	private transient CollapseDocInterface collapsedDocs;

	protected CollapseAbstract(AbstractSearchRequest searchRequest) {
		this.searchRequest = searchRequest;
		this.collapseField = searchRequest.getCollapseField();
		this.collapseMax = searchRequest.getCollapseMax();
		this.collapseMode = searchRequest.getCollapseMode();
		this.collapseType = searchRequest.getCollapseType();
		this.collapseFunctionFields = searchRequest.getCollapseFunctionFields();
		this.collapsedDocs = null;
	}

	protected abstract CollapseCollectorInterface collapse(
			DocIdInterface collector, int fetchLength,
			FieldCacheIndex collapseStringIndex, Timer timer);

	public CollapseDocInterface run(DocIdInterface collector, int fetchLength,
			FieldCacheIndex collapseStringIndex, Timer timer)
			throws IOException {

		collapsedDocs = null;

		if (collector == null)
			return null;

		int numFound = collector.getSize();
		if (fetchLength > numFound)
			fetchLength = numFound;

		CollapseCollectorInterface collapseCollectorInterface = collapse(
				collector, fetchLength, collapseStringIndex, timer);

		collapsedDocs = collapseCollectorInterface
				.getCollector(CollapseDocInterface.class);
		return collapsedDocs;
	}

	protected String getCollapseField() {
		return collapseField;
	}

	public DocIdInterface getCollapsedDoc() {
		return collapsedDocs;
	}

	public CollapseParameters.Mode getCollapseMode() {
		return collapseMode;
	}

	public CollapseParameters.Type getCollapseType() {
		return collapseType;
	}

	protected int getCollapsedDocsLength() {
		if (collapsedDocs == null)
			return 0;
		return collapsedDocs.getSize();
	}

	/**
	 * @return the collapseMax
	 */
	public final int getCollapseMax() {
		return collapseMax;
	}

	public boolean getCollectDocArray() {
		if (collapseMax == 0)
			return true;
		if (collapseFunctionFields == null)
			return false;
		return collapseFunctionFields.size() > 0;
	}

	public static CollapseAbstract newInstance(
			AbstractSearchRequest searchRequest) {
		CollapseParameters.Mode mode = searchRequest.getCollapseMode();
		if (mode == CollapseParameters.Mode.ADJACENT)
			return new CollapseAdjacent(searchRequest);
		else if (mode == CollapseParameters.Mode.CLUSTER)
			return new CollapseCluster(searchRequest);
		return null;
	}

	final private static int getNewFetchRows(long rows, long searchRows,
			long collapsedDocCount) {
		long fact = rows / searchRows;
		if (fact == 0)
			fact = 1;
		rows = rows + searchRows + collapsedDocCount * fact;
		if (rows > Integer.MAX_VALUE)
			rows = Integer.MAX_VALUE;
		return (int) rows;
	}

	private CollapseDocInterface collapseFromCollector(
			DocIdInterface collector, int searchRows, int end,
			FieldCacheIndex collapseFieldStringIndex, Timer timer)
			throws IOException {
		int lastRows = 0;
		int rows = end;
		int numFound = collector.getSize();
		int i = 0;
		Timer iterationTimer = new Timer(timer,
				"Optimized collapse iteration from all docs");
		while (getCollapsedDocsLength() < end) {
			i++;
			if (rows > numFound)
				rows = numFound;
			if (lastRows == rows)
				break;
			collapsedDocs = run(collector, rows, collapseFieldStringIndex,
					iterationTimer);
			lastRows = rows;
			rows = getNewFetchRows(rows, searchRows,
					collapsedDocs.getCollapsedCount());
		}
		iterationTimer.end("Optimized collapse iteration from all docs: " + i);
		return collapsedDocs;
	}

	/**
	 * Fetch new documents until collapsed results is complete.
	 * 
	 * @throws IOException
	 * @throws SyntaxError
	 * @throws ParseException
	 */
	private CollapseDocInterface collapseOptimized(ReaderAbstract reader,
			DocIdInterface collector, Timer timer) throws IOException,
			ParseException, SyntaxError {

		int searchRows = searchRequest.getRows();
		int end = searchRequest.getEnd();
		FieldCacheIndex collapseFieldStringIndex = reader
				.getStringIndex(searchRequest.getCollapseField());
		return collapseFromCollector(collector, searchRows, end,
				collapseFieldStringIndex, timer);
	}

	private CollapseDocInterface collapseFull(ReaderAbstract reader,
			DocIdInterface collector, Timer timer) throws IOException,
			ParseException, SyntaxError {
		FieldCacheIndex collapseFieldStringIndex = reader
				.getStringIndex(searchRequest.getCollapseField());
		collapsedDocs = run(collector, collector.getSize(),
				collapseFieldStringIndex, timer);
		return collapsedDocs;
	}

	final public CollapseDocInterface collapse(ReaderAbstract reader,
			DocIdInterface collector, Timer timer) throws IOException,
			ParseException, SyntaxError {
		Timer collapseTimer = new Timer(timer, "collapse "
				+ collapseMode.getLabel() + " " + collapseType.getLabel());
		try {
			if (collapseType == CollapseParameters.Type.OPTIMIZED)
				return collapseOptimized(reader, collector, timer);
			if (collapseType == CollapseParameters.Type.FULL)
				return collapseFull(reader, collector, timer);
			return null;
		} finally {
			collapseTimer.getDuration();
		}
	}

	final protected static CollapseCollectorInterface getNewCollapseInterfaceInstance(
			final DocIdInterface collector, final int capacity,
			final boolean collectDocArray) {
		CollapseBaseCollector base = new CollapseBaseCollector(collector,
				capacity, collectDocArray);
		CollapseCollectorInterface last = base;
		ScoreInterface scoreInterface = collector
				.getCollector(ScoreInterface.class);
		if (scoreInterface != null)
			last = new CollapseScoreDocCollector(base, scoreInterface);
		DistanceInterface distanceInterface = collector
				.getCollector(DistanceInterface.class);
		if (distanceInterface != null)
			last = new CollapseDistanceCollector(base, distanceInterface);
		JoinDocInterface joinDocInterface = collector
				.getCollector(JoinDocInterface.class);
		if (joinDocInterface != null)
			last = new CollapseJoinDocCollector(base, joinDocInterface);
		return last;
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy