Commit b2154ccd authored by Honza Brázdil's avatar Honza Brázdil
Browse files

Abstract BatchRankingQueryOperation from BatchKNNQueryOperation

parent 97098ac2
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.logging.Level;
import java.util.logging.Logger;

import messif.algorithms.Algorithm;
import messif.objects.LocalAbstractObject;
import messif.objects.util.AbstractObjectIterator;
@@ -35,6 +36,7 @@ import messif.operations.QueryOperation;
import messif.operations.query.GetAlgorithmInfoOperation;
import messif.operations.RankingSingleQueryOperation;
import messif.operations.query.BatchKNNQueryOperation;
import messif.operations.query.BatchRankingQueryOperation;
import messif.utility.Convert;

/**
@@ -107,13 +109,13 @@ public class FileSequentialScan extends Algorithm {
    }

    /**
     * Processes the batch k-NN operation; the batch is split into sub-batches which are processed 
     * Processes the batch ranking operation; the batch is split into sub-batches which are processed 
     *  in parallel. A separate thread reads the data from the data file.
     * @param operation batch operation to be processed
     * @throws IOException if the data file cannot be read
     * @throws ClassNotFoundException if the specified data class is not valid
     */
    public void batchQuerySearch(BatchKNNQueryOperation operation) throws IOException, ClassNotFoundException {
    public void batchQuerySearch(BatchRankingQueryOperation operation) throws IOException, ClassNotFoundException {
        List<Future> futures = new ArrayList<>();

        // list of all data queues used by individual query batches
@@ -130,7 +132,7 @@ public class FileSequentialScan extends Algorithm {
                operationBatch.add(operation.getOperation(queryCounter));
            } while ((++ queryCounter % queryBatchSize) != 0 && queryCounter < operation.getNOperations());
            
            // start thread that will process a sub-batch of KNN operations
            // start thread that will process a sub-batch of ranking operations
            futures.add(getOperationsThreadPool().submit(new EvaluationThread(operationBatch, dataBatch)));
        }
        
+10 −123
Original line number Diff line number Diff line
@@ -17,15 +17,12 @@
package messif.operations.query;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import messif.objects.LocalAbstractObject;
import messif.objects.util.AbstractObjectIterator;
import messif.operations.AbstractOperation;
import messif.operations.AnswerType;
import messif.operations.OperationErrorCode;
import messif.operations.QueryOperation;

/**
 * A batch of several K-nearest neighbors query operations encapsulated as a single operation.
@@ -33,16 +30,13 @@ import messif.operations.QueryOperation;
 * @author Michal Batko, Masaryk University, Brno, Czech Republic, batko@fi.muni.cz
 * @author Vlastislav Dohnal, Masaryk University, Brno, Czech Republic, dohnal@fi.muni.cz
 * @author David Novak, Masaryk University, Brno, Czech Republic, david.novak@fi.muni.cz
 * @author Honza Brázdil, janinko.g@gmail.com
 */
@AbstractOperation.OperationName("k-nearest neighbors query")
public class BatchKNNQueryOperation extends QueryOperation {
public class BatchKNNQueryOperation extends BatchRankingQueryOperation<KNNQueryOperation> {

    /** Class serial id for serialization */
    private static final long serialVersionUID = 1L;

    //****************** Attributes ******************//

    private final List<KNNQueryOperation> knnOperations ;
    private static final long serialVersionUID = 2L;

    //****************** Constructors ******************//

@@ -68,7 +62,7 @@ public class BatchKNNQueryOperation extends QueryOperation {
    }

    /**
     * Creates a list of {@link KNNQueryOperation} for all specified query objects.
     * Creates a list of {@link KNNQueryOperation} for part of specified query objects.
     * @param queryObjects iterator over the query objects
     * @param maxNQueries maximal number of query objects read from the iterator (can be {@code Integer.MAX_VALUE}
     * @param k the number of nearest neighbors to retrieve for each operation
@@ -76,123 +70,16 @@ public class BatchKNNQueryOperation extends QueryOperation {
     */
    @AbstractOperation.OperationConstructor({"Query object", "Number of nearest objects", "Store the meta-object subdistances?", "Answer type"})
    public BatchKNNQueryOperation(Iterator<? extends LocalAbstractObject> queryObjects, int maxNQueries, int k, AnswerType answerType) {
        super(answerType);
        super(constructKNNQueryies(queryObjects, maxNQueries, k, answerType), answerType);
    }
    
    private static List<KNNQueryOperation> constructKNNQueryies(Iterator<? extends LocalAbstractObject> queryObjects, int maxNQueries, int k, AnswerType answerType){
        List<KNNQueryOperation> operations = new ArrayList<>();
        int i = 0;
        while (queryObjects.hasNext() && i ++ < maxNQueries) {
            operations.add(new KNNQueryOperation(queryObjects.next(), k, answerType));
        }
        this.knnOperations = Collections.unmodifiableList(operations);
    }

    //****************** Attribute access ******************//

    public int getNOperations() {
        return knnOperations.size();
    }
    
    public KNNQueryOperation getOperation(int index) {
        return knnOperations.get(index);
    }

    public List<KNNQueryOperation> getKnnOperations() {
        return knnOperations;
    }
    

    /**
     * Returns argument that was passed while constructing instance.
     * If the argument is not stored within operation, <tt>null</tt> is returned.
     * @param index index of an argument passed to constructor
     * @return argument that was passed while constructing instance
     * @throws IndexOutOfBoundsException if index parameter is out of range
     */
    @Override
    public Object getArgument(int index) throws IndexOutOfBoundsException {
        switch (index) {
        default:
            throw new IndexOutOfBoundsException("kNNQueryOperation has only two arguments");
        }
        return operations;
    }

    /**
     * Returns number of arguments that were passed while constructing this instance.
     * @return number of arguments that were passed while constructing this instance
     */
    @Override
    public int getArgumentCount() {
        return 0;
    }

    @Override
    public boolean wasSuccessful() {
        return getErrorCode() == OperationErrorCode.RESPONSE_RETURNED;
    }

    @Override
    public void endOperation() {
        endOperation(OperationErrorCode.RESPONSE_RETURNED);
    }

    @Override
    public int evaluate(AbstractObjectIterator objects) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public Class getAnswerClass() {
        if (knnOperations.isEmpty()) {
            return null;
        }
        return (knnOperations.get(0).getAnswerClass());
    }

    @Override
    public int getAnswerCount() {
        return 0;
    }

    @Override
    public Iterator getAnswer() {
        return Collections.emptyIterator();
    }

    @Override
    public Iterator getAnswer(int skip, int count) {
        return Collections.emptyIterator();        
    }

    @Override
    public Iterator getAnswerObjects() {
        return Collections.emptyIterator();
    }

    @Override
    public void resetAnswer() {
    }

    @Override
    public int getSubAnswerCount() {
        return knnOperations.size();
    }

    @Override
    public Iterator getSubAnswer(int index) throws IndexOutOfBoundsException {
        return knnOperations.get(index).getAnswer();
    }

    @Override
    public Iterator getSubAnswer(Object key) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    protected boolean dataEqualsImpl(QueryOperation operation) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public int dataHashCode() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}
+186 −0
Original line number Diff line number Diff line
/*
 *  This file is part of MESSIF library.
 *
 *  MESSIF library 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.
 *
 *  MESSIF library 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 MESSIF library.  If not, see <http://www.gnu.org/licenses/>.
 */
package messif.operations.query;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import messif.objects.util.AbstractObjectIterator;
import messif.operations.AbstractOperation;
import messif.operations.AnswerType;
import messif.operations.OperationErrorCode;
import messif.operations.QueryOperation;
import messif.operations.RankingSingleQueryOperation;

/**
 * A batch of several ranking query operations encapsulated as a single operation.
 * 
 * @author Michal Batko, Masaryk University, Brno, Czech Republic, batko@fi.muni.cz
 * @author Vlastislav Dohnal, Masaryk University, Brno, Czech Republic, dohnal@fi.muni.cz
 * @author David Novak, Masaryk University, Brno, Czech Republic, david.novak@fi.muni.cz
 * @author Honza Brázdil, janinko.g@gmail.com
 * @param <T> Type of the ranking query operation.
 */
@AbstractOperation.OperationName("k-nearest neighbors query")
public class BatchRankingQueryOperation<T extends RankingSingleQueryOperation> extends QueryOperation {

    /** Class serial id for serialization */
    private static final long serialVersionUID = 1L;

    //****************** Attributes ******************//

    private final List<T> operations ;

    //****************** Constructors ******************//

    /**
     * Creates a list of {@link RankingSingleQueryOperation} for all specified query operation.
     * @param operations Collection of ranking operations.
     */
    @AbstractOperation.OperationConstructor({"Query object", "Number of nearest objects"})
    public BatchRankingQueryOperation(Collection<T> operations) {
        this(operations, AnswerType.NODATA_OBJECTS);
    }

    /**
     * Creates a list of {@link RankingSingleQueryOperation} for all specified query operation.
     * @param operations Collection of ranking operations.
     * @param answerType the type of objects this operation stores in its answer
     */
    @AbstractOperation.OperationConstructor({"Query object", "Number of nearest objects", "Answer type"})
    public BatchRankingQueryOperation(Collection<T> operations, AnswerType answerType) {
        super(answerType);
        this.operations = Collections.unmodifiableList(new ArrayList<>(operations));
        for(T operation : operations){
            operation.setAnswerType(answerType);
        }
    }

    //****************** Attribute access ******************//

    public int getNOperations() {
        return operations.size();
    }
    
    public T getOperation(int index) {
        return operations.get(index);
    }

    public List<T> getKnnOperations() {
        return operations;
    }
    

    /**
     * Returns argument that was passed while constructing instance.
     * If the argument is not stored within operation, <tt>null</tt> is returned.
     * @param index index of an argument passed to constructor
     * @return argument that was passed while constructing instance
     * @throws IndexOutOfBoundsException if index parameter is out of range
     */
    @Override
    public Object getArgument(int index) throws IndexOutOfBoundsException {
        switch (index) {
        default:
            throw new IndexOutOfBoundsException("kNNQueryOperation has only two arguments");
        }
    }

    /**
     * Returns number of arguments that were passed while constructing this instance.
     * @return number of arguments that were passed while constructing this instance
     */
    @Override
    public int getArgumentCount() {
        return 0;
    }

    @Override
    public boolean wasSuccessful() {
        return getErrorCode() == OperationErrorCode.RESPONSE_RETURNED;
    }

    @Override
    public void endOperation() {
        endOperation(OperationErrorCode.RESPONSE_RETURNED);
    }

    @Override
    public int evaluate(AbstractObjectIterator objects) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public Class getAnswerClass() {
        if (operations.isEmpty()) {
            return null;
        }
        return (operations.get(0).getAnswerClass());
    }

    @Override
    public int getAnswerCount() {
        return 0;
    }

    @Override
    public Iterator getAnswer() {
        return Collections.emptyIterator();
    }

    @Override
    public Iterator getAnswer(int skip, int count) {
        return Collections.emptyIterator();        
    }

    @Override
    public Iterator getAnswerObjects() {
        return Collections.emptyIterator();
    }

    @Override
    public void resetAnswer() {
    }

    @Override
    public int getSubAnswerCount() {
        return operations.size();
    }

    @Override
    public Iterator getSubAnswer(int index) throws IndexOutOfBoundsException {
        return operations.get(index).getAnswer();
    }

    @Override
    public Iterator getSubAnswer(Object key) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    protected boolean dataEqualsImpl(QueryOperation operation) {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    @Override
    public int dataHashCode() {
        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }
}