Package com.flaptor.indextank.rpc

Source Code of com.flaptor.indextank.rpc.SearcherServer$SearcherImpl

/*
* Copyright (c) 2011 LinkedIn, Inc
*
* Licensed 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.
*/

package com.flaptor.indextank.rpc;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.log4j.Logger;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TBinaryProtocol.Factory;
import org.apache.thrift.server.TServer;
import org.apache.thrift.server.TThreadPoolServer;
import org.apache.thrift.transport.TServerSocket;
import org.apache.thrift.transport.TTransportException;

import com.flaptor.indextank.index.scorer.DynamicDataManager;
import com.flaptor.indextank.index.scorer.FunctionRangeFilter;
import com.flaptor.indextank.index.scorer.IntersectionMatchFilter;
import com.flaptor.indextank.index.scorer.MatchFilter;
import com.flaptor.indextank.index.scorer.Scorer;
import com.flaptor.indextank.index.scorer.VariablesRangeFilter;
import com.flaptor.indextank.query.IndexEngineParser;
import com.flaptor.indextank.query.MatchAllQuery;
import com.flaptor.indextank.query.NoSuchQueryVariableException;
import com.flaptor.indextank.query.ParseException;
import com.flaptor.indextank.query.Query;
import com.flaptor.indextank.query.QueryVariables;
import com.flaptor.indextank.query.QueryVariablesImpl;
import com.flaptor.indextank.search.DocumentSearcher;
import com.flaptor.indextank.search.SearchResult;
import com.flaptor.indextank.search.SearchResults;
import com.flaptor.util.Execute;
import com.flaptor.util.Pair;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multiset;

public class SearcherServer {
    private static final Logger logger = Logger.getLogger(Execute.whoAmI());
    private DocumentSearcher searcher;
    private int port;
  private final IndexEngineParser parser;
  private final DynamicDataManager dynamicDataManager;
  private final Scorer scorer;


    public SearcherServer(DocumentSearcher searcher, IndexEngineParser parser, DynamicDataManager dynamicDataManager, Scorer scorer, int port){
        this.scorer = scorer;
    this.dynamicDataManager = dynamicDataManager;
    this.searcher = searcher;
    this.parser = parser; 
        this.port = port;
    }

    public void start(){
        Thread t = new Thread() {
       
            public void run() {
                try {
                    TServerSocket serverTransport = new TServerSocket(SearcherServer.this.port);
                    Searcher.Processor processor = new Searcher.Processor(new SearcherImpl(SearcherServer.this.searcher));
                    Factory protFactory = new TBinaryProtocol.Factory(true, true);
                    TServer server = new TThreadPoolServer(processor, serverTransport, protFactory);
                    System.out.println("Starting searcher server on port " + SearcherServer.this.port + " ...");
                    server.serve();
                } catch( TTransportException tte ){
                    tte.printStackTrace();
                }
            }
        };
        t.start();
    }

    /**
     * Converts a ISearchResults to Thrift ResultSet.
     */
    private static ResultSet toResultSet(SearchResults results) {
        ResultSet rs = new ResultSet();
        rs.set_status("OK");
        rs.set_matches(results.getMatches());
        rs.set_facets(toFacetsMap(results.getFacets()));
        rs.set_didyoumean(results.getDidYouMean());

        rs.set_docs(Lists.<Map<String,String>>newArrayList());
        rs.set_scores(Lists.<Double>newArrayList());
        rs.set_variables(Lists.<Map<Integer,Double>>newArrayList());
        rs.set_categories(Lists.<Map<String,String>>newArrayList());

        for (SearchResult sr : results.getResults()) {
            Map<String,String> doc = Maps.newHashMap();
            doc.putAll(sr.getFields());
            doc.put("docid", sr.getDocId());
            rs.add_to_docs(doc);
            rs.add_to_scores(sr.getScore());
            rs.add_to_variables(sr.getVariables());
            rs.add_to_categories(sr.getCategories());
        }
       
        return rs;
    }


    private static Map<String, Map<String, Integer>> toFacetsMap(Map<String, Multiset<String>> facets) {
      Map<String, Map<String, Integer>> results = Maps.newHashMap();
     
      for (Entry<String, Multiset<String>> entry : facets.entrySet()) {
      Map<String, Integer> value = Maps.newHashMap();
     
      for (String catValue : entry.getValue()) {
        value.put(catValue, entry.getValue().count(catValue));
      }
     
      results.put(entry.getKey(), value);
    }
     
      return results;
  }

  private Query generateQuery(String str, int start, int len, QueryVariables vars, Multimap<String, String> facetsFilter, MatchFilter rangeFilters) throws ParseException {
        return new Query(parser.parseQuery(str), str, vars, facetsFilter, rangeFilters);
    }


    private class SearcherImpl implements Searcher.Iface {
        private DocumentSearcher searcher;

        // constructor
        private SearcherImpl(DocumentSearcher searcher){
            this.searcher = searcher ;
        }

        public ResultSet search(String queryStr, int start, int len, int scoringFunctionIndex, Map<Integer, Double> queryVariables, List<CategoryFilter> facetsFilter, List<RangeFilter> variableRangeFilters, List<RangeFilter> functionRangeFilters, Map<String,String> extraParameters) throws IndextankException, InvalidQueryException, MissingQueryVariableException {
            logger.debug("Searching: start: " + start + ", len: " + len +", query: \"" + queryStr + "\"");
            try {
                Query query = generateQuery(queryStr,start,len, QueryVariablesImpl.fromMap(queryVariables), convertToMultimap(facetsFilter), new IntersectionMatchFilter(convertToVariableRangeFilter(variableRangeFilters), convertToFunctionRangeFilter(functionRangeFilters)));
                ResultSet resultSet = toResultSet(this.searcher.search(query, start, len, scoringFunctionIndex, extraParameters));
                logger.info("Search found " + resultSet.get_matches() + " results - start: " + start + ", len: " + len +", query: \"" + queryStr + "\"");
                return resultSet;
            } catch (NoSuchQueryVariableException e) {
                if (logger.isDebugEnabled()) {
                    logger.debug("Some query variables (" + queryVariables + ") are missing for evaluating functions",e);
                }
                MissingQueryVariableException ite = new MissingQueryVariableException();
                ite.set_message("Missing query variable with index '" + e.getMissingVariableIndex() + "'");
                throw ite;
            } catch (ParseException pe) {
                if (logger.isDebugEnabled()){
                    logger.debug("Parsing '" + queryStr + "' failed with " + pe,pe);
                }
                InvalidQueryException ite = new InvalidQueryException();
                ite.set_message("Invalid query");
                throw ite;
            } catch (RuntimeException e) {
                logger.error("RuntimeException while processing search. Will throw an IndexTankException. Original Exception is:", e);
                throw new IndextankException();
            } catch (InterruptedException e) {
                logger.error("Interrupted while searching.");
                IndextankException ite = new IndextankException();
                ite.set_message("Interrupted while searching.");
                throw ite;
            }
        }
       
        private VariablesRangeFilter convertToVariableRangeFilter(List<RangeFilter> rangeFilters) {
          Multimap<Integer, Pair<Float, Float>> filters = HashMultimap.create();
          for (RangeFilter filter : rangeFilters) {
        filters.put(filter.get_key(), new Pair<Float, Float>(filter.is_no_floor() ? null : (float)filter.get_floor(), filter.is_no_ceil() ? null : (float)filter.get_ceil()));
      }
         
      return new VariablesRangeFilter(dynamicDataManager, filters);
        }

        private FunctionRangeFilter convertToFunctionRangeFilter(List<RangeFilter> rangeFilters) {
          Multimap<Integer, Pair<Float, Float>> filters = HashMultimap.create();
          for (RangeFilter filter : rangeFilters) {
        filters.put(filter.get_key(), new Pair<Float, Float>(filter.is_no_floor() ? null : (float)filter.get_floor(), filter.is_no_ceil() ? null : (float)filter.get_ceil()));
          }
         
          return new FunctionRangeFilter(scorer, dynamicDataManager, filters);
        }

    private Multimap<String, String> convertToMultimap(List<CategoryFilter> facetsFilter) {
          Multimap<String, String> result = HashMultimap.create();
          for (CategoryFilter facetFilter : facetsFilter) {
        result.put(facetFilter.get_category(), facetFilter.get_value());
      }
         
          return result;
    }

    @Override
        public int count(String queryStr) throws IndextankException {
            logger.debug("Counting: query: \"" + queryStr + "\"");
            try {
                Query query = generateQuery(queryStr,0,1,null, ImmutableMultimap.<String, String>of(), VariablesRangeFilter.NO_FILTER);
                int count = this.searcher.countMatches(query);
                logger.info("Counted " + count + " for query: \"" + queryStr + "\"");
                return count;
            } catch (ParseException pe) {
                if (logger.isDebugEnabled()){
                    logger.debug("Parsing '" + queryStr + "' failed with " + pe,pe);
                }
               
                IndextankException ite = new IndextankException();
                ite.set_message("Invalid query");
                throw ite;
            } catch (RuntimeException e) {
                logger.error("RuntimeException while processing count. Will throw an IndexTankException. Original Exception is:", e);
                throw new IndextankException();
            } catch (InterruptedException e) {
                logger.error("Interrupted while searching.");
                IndextankException ite = new IndextankException();
                ite.set_message("Interrupted while searching.");
                throw ite;
            }
        }
       
        @Override
        public int size() throws IndextankException {
            try {
                logger.debug("Fetching size");
                Query query = new Query(new MatchAllQuery(),null,null);
                int size = this.searcher.countMatches(query);
                logger.info("Fetched size: " + size);
                return size;
            } catch (RuntimeException e) {
                logger.error("RuntimeException while processing size. Will throw an IndexTankException. Original Exception is:", e);
                throw new IndextankException();
            } catch (InterruptedException e) {
                logger.error("Interrupted while searching.");
                IndextankException ite = new IndextankException();
                ite.set_message("Interrupted while searching.");
                throw ite;
            }
        }

        public SearcherStats stats(){
            return new SearcherStats();
        }

    }

}
TOP

Related Classes of com.flaptor.indextank.rpc.SearcherServer$SearcherImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.