private void distributedProcessMissingTop(ResponseBuilder rb,
      ComponentFields mtasFields) throws IOException {
    // initialise
    Map<String, SortedMap<String, MtasDataItemNumberComparator>> mergedComparatorLists = new HashMap<>();
    Map<String, MtasDataItemNumberComparator> mergedComparatorBoundaryList = new HashMap<>();
    Map<String, MtasDataItemNumberComparator> summedComparatorBoundaryList = new HashMap<>();
    Map<String, Map<String, MtasDataItemNumberComparator>> comparatorBoundariesList = new HashMap<>();
    // check all termvectors, and initialize
    for (String field : mtasFields.list.keySet()) {
      List<ComponentTermVector> tvList = mtasFields.list
          .get(field).termVectorList;
      if (tvList != null) {
        for (ComponentTermVector tv : tvList) {
          if (!tv.subComponentFunction.sortType.equals(CodecUtil.SORT_TERM)) {
            mergedComparatorLists.put(tv.key,
                new TreeMap<String, MtasDataItemNumberComparator>());
          }
        }
      }
    }
    // compute for each termvector the mergedComparatorList and the
    // summedBoundary
    for (ShardRequest sreq : rb.finished) {
      if (sreq.params.getBool(MtasSolrSearchComponent.PARAM_MTAS, false)
          && sreq.params.getBool(PARAM_MTAS_TERMVECTOR, false)) {
        for (ShardResponse shardResponse : sreq.responses) {
          SortedMap<String, MtasDataItemNumberComparator> mergedComparatorList;
          NamedList<Object> response = shardResponse.getSolrResponse()
              .getResponse();
          String key;
          MtasSolrMtasResult list;
          MtasDataItemNumberComparator comparatorLast;
          Map<String, MtasDataItemNumberComparator> comparatorList;
          try {
            List<NamedList<Object>> data = (List<NamedList<Object>>) response
                .findRecursive("mtas", NAME);
            if (data != null) {
              for (int i = 0; i < data.size(); i++) {
                NamedList<Object> dataItem = data.get(i);
                try {
                  key = (String) dataItem.get("key");
                  list = (MtasSolrMtasResult) dataItem.get("list");
                  if (list != null) {
                    comparatorLast = list.getResult().getLastSortValue();
                    comparatorList = list.getResult().getComparatorList();
                    if (key == null) {
                      dataItem.clear();
                    } else if (comparatorLast == null || comparatorList == null
                        || !mergedComparatorLists.containsKey(key)) {
                      // do nothing
                    } else {
                      mergedComparatorList = mergedComparatorLists.get(key);
                      for (Entry<String, MtasDataItemNumberComparator> entry : comparatorList
                          .entrySet()) {
                        if (mergedComparatorList.containsKey(entry.getKey())) {
                          mergedComparatorList.get(entry.getKey())
                              .add(entry.getValue().getValue());
                        } else {
                          mergedComparatorList.put(entry.getKey(),
                              entry.getValue().clone());
                        }
                      }
                      if (!comparatorBoundariesList.containsKey(key)) {
                        comparatorBoundariesList.put(key,
                            new HashMap<String, MtasDataItemNumberComparator>());
                      }
                      comparatorBoundariesList.get(key)
                          .put(shardResponse.getShardAddress(), comparatorLast);
                      if (summedComparatorBoundaryList.containsKey(key)) {
                        summedComparatorBoundaryList.get(key)
                            .add(comparatorLast.getValue());
                      } else {
                        summedComparatorBoundaryList.put(key,
                            comparatorLast.clone());
                      }
                    }
                  } else {
                    throw new IOException("no data returned");
                  }
                } catch (ClassCastException e) {
                  log.debug(e);
                  dataItem.clear();
                }
              }
            }
          } catch (ClassCastException e) {
            log.debug(e);
            // shouldnt happen
          }
          shardResponse.getSolrResponse().setResponse(response);
        }
      }
    }
    // compute for each relevant termvector the mergedComparatorBoundary
    HashMap<String, HashMap<String, HashMap<String, MtasDataItemNumberComparator>>> recomputeFieldList = new HashMap<>();
    for (String field : mtasFields.list.keySet()) {
      List<ComponentTermVector> tvList = mtasFields.list
          .get(field).termVectorList;
      if (tvList != null) {
        for (ComponentTermVector tv : tvList) {
          SortedMap<String, MtasDataItemNumberComparator> mergedComparatorList;
          if (mergedComparatorLists.containsKey(tv.key)) {
            mergedComparatorList = mergedComparatorLists.get(tv.key);
            if (mergedComparatorList.size() < tv.number || tv.number <= 0) {
              // do nothing
            } else {
              final int sortDirection = tv.subComponentFunction.sortDirection
                  .equals(CodecUtil.SORT_DESC) ? -1 : 1;
              SortedSet<Map.Entry<String, MtasDataItemNumberComparator>> sortedSet = new TreeSet<>(
                  (Map.Entry<String, MtasDataItemNumberComparator> e1,
                      Map.Entry<String, MtasDataItemNumberComparator> e2) -> (e1
                          .getValue().compareTo(e2.getValue().getValue()) == 0)
                              ? e1.getKey().compareTo(e2.getKey())
                              : e1.getValue().compareTo(
                                  e2.getValue().getValue()) * sortDirection);
              sortedSet.addAll(mergedComparatorLists.get(tv.key).entrySet());
              Optional<Map.Entry<String, MtasDataItemNumberComparator>> optionalItem = sortedSet
                  .stream().skip(tv.number - 1L).findFirst();
              if (optionalItem.isPresent()) {
                mergedComparatorBoundaryList.put(tv.key,
                    optionalItem.get().getValue());
              }
            }
          }
        }
      }
      HashMap<String, HashMap<String, MtasDataItemNumberComparator>> recomputeList = new HashMap<>();
      if (tvList != null) {
        for (ComponentTermVector tv : tvList) {
          String key = tv.key;
          if (mergedComparatorBoundaryList.containsKey(key)
              && summedComparatorBoundaryList.containsKey(key)) {
            // set termvector to recompute
            recomputeList.put(key,
                new HashMap<String, MtasDataItemNumberComparator>());
            // sort
            List<Entry<String, MtasDataItemNumberComparator>> list = new LinkedList<>(
                comparatorBoundariesList.get(key).entrySet());
            Collections.sort(list,
                (Entry<String, MtasDataItemNumberComparator> e1,
                    Entry<String, MtasDataItemNumberComparator> e2) -> e1
                        .getValue().compareTo(e2.getValue().getValue()));
            HashMap<String, MtasDataItemNumberComparator> sortedHashMap = new LinkedHashMap<>();
            for (Iterator<Map.Entry<String, MtasDataItemNumberComparator>> it = list
                .iterator(); it.hasNext();) {
              Map.Entry<String, MtasDataItemNumberComparator> entry = it.next();
              sortedHashMap.put(entry.getKey(), entry.getValue());
            }

            MtasDataItemNumberComparator mainNewBoundary = mergedComparatorBoundaryList
                .get(key).recomputeBoundary(sortedHashMap.size());
            // System.out.println(
            // "MAIN NEW BOUNDARY for '" + key + "' : " + mainNewBoundary);

            MtasDataItemNumberComparator sum = null;
            int number = 0;
            for (Entry<String, MtasDataItemNumberComparator> entry : sortedHashMap
                .entrySet()) {
              MtasDataItemNumberComparator newBoundary = mainNewBoundary
                  .clone();
              MtasDataItemNumberComparator currentBoundary = entry.getValue();
              int compare = currentBoundary.compareTo(newBoundary.getValue());
              if (tv.subComponentFunction.sortDirection
                  .equals(CodecUtil.SORT_DESC)) {
                compare *= -1;
              }
              if (compare < 0) {
                HashMap<String, MtasDataItemNumberComparator> recomputeSubList = new HashMap<>();
                // sum not null if number>0, but do check
                if (number > 0 && sum != null
                    && tv.subComponentFunction.sortDirection
                        .equals(CodecUtil.SORT_DESC)) {
                  MtasDataItemNumberComparator tmpSumBoundary = mergedComparatorBoundaryList
                      .get(key);
                  tmpSumBoundary.subtract(sum.getValue());
                  MtasDataItemNumberComparator alternativeNewBoundary = tmpSumBoundary
                      .recomputeBoundary(sortedHashMap.size() - number);
                  compare = newBoundary
                      .compareTo(alternativeNewBoundary.getValue());
                  if (compare < 0) {
                    newBoundary = alternativeNewBoundary;
                    compare = currentBoundary.compareTo(newBoundary.getValue());
                    if (tv.subComponentFunction.sortDirection
                        .equals(CodecUtil.SORT_DESC)) {
                      compare *= -1;
                    }
                    if (compare < 0) {
                      recomputeSubList.put(entry.getKey(), newBoundary);
                    }
                  } else {
                    recomputeSubList.put(entry.getKey(), newBoundary);
                  }
                } else {
                  recomputeSubList.put(entry.getKey(), newBoundary);
                }
                if (!recomputeSubList.isEmpty()) {
                  if (!recomputeList.containsKey(key)) {
                    recomputeList.put(key, recomputeSubList);
                  } else {
                    recomputeList.get(key).putAll(recomputeSubList);
                  }
                }
              } else {
                newBoundary = currentBoundary.clone();
              }
              if (sum == null) {
                sum = newBoundary.clone();
              } else {
                sum.add(newBoundary.getValue());
              }
              number++;
            }
          }
        }
      }
      if (!recomputeList.isEmpty()) {
        recomputeFieldList.put(field, recomputeList);
      }
    }

    // finally, recompute
    if (recomputeFieldList.size() > 0) {

      // remove output for termvectors in recompute list and get list of shards
      HashSet<String> shards = new HashSet<>();
      for (ShardRequest sreq : rb.finished) {
        if (sreq.params.getBool(MtasSolrSearchComponent.PARAM_MTAS, false)
            && sreq.params.getBool(PARAM_MTAS_TERMVECTOR, false)) {
          for (ShardResponse shardResponse : sreq.responses) {
            NamedList<Object> response = shardResponse.getSolrResponse()
                .getResponse();
            String key;
            String field;
            String shardAddress = shardResponse.getShardAddress();
            try {
              ArrayList<NamedList<Object>> data = (ArrayList<NamedList<Object>>) response
                  .findRecursive("mtas", NAME);
              shards.add(shardAddress);
              if (data != null) {
                for (int i = 0; i < data.size(); i++) {
                  NamedList<Object> dataItem = data.get(i);
                  try {
                    key = (String) dataItem.get("key");
                    field = (String) dataItem.get("field");
                    boolean doClear;
                    doClear = field != null && key != null;
                    doClear = doClear ? recomputeFieldList.get(field) != null
                        : false;
                    doClear = doClear
                        ? recomputeFieldList.get(field).containsKey(key)
                        : false;
                    doClear = doClear ? recomputeFieldList.get(field).get(key)
                        .containsKey(shardAddress) : false;
                    if (doClear) {
                      dataItem.clear();
                      dataItem.add("key", key);
                    }
                  } catch (ClassCastException e) {
                    log.debug(e);
                    dataItem.clear();
                  }
                }
              }
            } catch (ClassCastException e) {
              log.debug(e);
              // shouldnt happen
            }
            shardResponse.getSolrResponse().setResponse(response);
          }
        }
      }

      // parameter
      HashMap<String, ModifiableSolrParams> requestParamList = new HashMap<>();
      for (String shardAddress : shards) {
        ModifiableSolrParams paramsNewRequest = new ModifiableSolrParams();
        int termvectorCounter = 0;
        for (String field : mtasFields.list.keySet()) {
          List<ComponentTermVector> tvList = mtasFields.list
              .get(field).termVectorList;
          if (recomputeFieldList.containsKey(field)) {
            HashMap<String, HashMap<String, MtasDataItemNumberComparator>> recomputeList = recomputeFieldList
                .get(field);
            if (tvList != null) {
              for (ComponentTermVector tv : tvList) {
                if (recomputeList.containsKey(tv.key)
                    && recomputeList.get(tv.key).containsKey(shardAddress)) {
                  paramsNewRequest.add(
                      PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "."
                          + NAME_MTAS_TERMVECTOR_BOUNDARY,
                      String.valueOf(recomputeList.get(tv.key).get(shardAddress)
                          .getValue()));
                  paramsNewRequest.add(PARAM_MTAS_TERMVECTOR + "."
                      + termvectorCounter + "." + NAME_MTAS_TERMVECTOR_FIELD,
                      field);
                  paramsNewRequest.add(PARAM_MTAS_TERMVECTOR + "."
                      + termvectorCounter + "." + NAME_MTAS_TERMVECTOR_PREFIX,
                      tv.prefix);
                  paramsNewRequest.add(PARAM_MTAS_TERMVECTOR + "."
                      + termvectorCounter + "." + NAME_MTAS_TERMVECTOR_KEY,
                      tv.key);
                  paramsNewRequest.add(
                      PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "."
                          + NAME_MTAS_TERMVECTOR_NUMBER,
                      String.valueOf(tv.number));
                  if (tv.subComponentFunction.sortType != null) {
                    paramsNewRequest.add(
                        PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "."
                            + NAME_MTAS_TERMVECTOR_SORT_TYPE,
                        tv.subComponentFunction.sortType);
                  }
                  if (tv.subComponentFunction.sortDirection != null) {
                    paramsNewRequest.add(
                        PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "."
                            + NAME_MTAS_TERMVECTOR_SORT_DIRECTION,
                        tv.subComponentFunction.sortDirection);
                  }
                  if (tv.subComponentFunction.type != null) {
                    paramsNewRequest.add(
                        PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "."
                            + NAME_MTAS_TERMVECTOR_TYPE,
                        tv.subComponentFunction.type);
                  }
                  if (tv.distances != null) {
                    int distanceCounter = 0;
                    for (SubComponentDistance distance : tv.distances) {
                      paramsNewRequest.add(
                          PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "."
                              + NAME_MTAS_TERMVECTOR_DISTANCE + "."
                              + distanceCounter + "."
                              + NAME_MTAS_TERMVECTOR_DISTANCE_TYPE,
                          distance.type);
                      paramsNewRequest.add(
                          PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "."
                              + NAME_MTAS_TERMVECTOR_DISTANCE + "."
                              + distanceCounter + "."
                              + NAME_MTAS_TERMVECTOR_DISTANCE_BASE,
                          distance.base);
                      if (distance.key != null) {
                        paramsNewRequest.add(
                            PARAM_MTAS_TERMVECTOR + "." + termvectorCounter
                                + "." + NAME_MTAS_TERMVECTOR_DISTANCE + "."
                                + distanceCounter + "."
                                + NAME_MTAS_TERMVECTOR_DISTANCE_KEY,
                            distance.key);
                      }
                      if (distance.minimum != null) {
                        paramsNewRequest.add(
                            PARAM_MTAS_TERMVECTOR + "." + termvectorCounter
                                + "." + NAME_MTAS_TERMVECTOR_DISTANCE + "."
                                + distanceCounter + "."
                                + NAME_MTAS_TERMVECTOR_DISTANCE_MINIMUM,
                            String.valueOf(distance.minimum));
                      }
                      if (distance.maximum != null) {
                        paramsNewRequest.add(
                            PARAM_MTAS_TERMVECTOR + "." + termvectorCounter
                                + "." + NAME_MTAS_TERMVECTOR_DISTANCE + "."
                                + distanceCounter + "."
                                + NAME_MTAS_TERMVECTOR_DISTANCE_MAXIMUM,
                            String.valueOf(distance.maximum));
                      }
                      if (distance.parameters != null) {
                        for (Entry<String, String> parameter : distance.parameters
                            .entrySet()) {
                          paramsNewRequest.add(
                              PARAM_MTAS_TERMVECTOR + "." + termvectorCounter
                                  + "." + NAME_MTAS_TERMVECTOR_DISTANCE + "."
                                  + distanceCounter + "."
                                  + NAME_MTAS_TERMVECTOR_DISTANCE_PARAMETER
                                  + "." + parameter.getKey(),
                              parameter.getValue());
                        }
                      }
                      distanceCounter++;
                    }
                  }
                  if (tv.functions != null) {
                    int functionCounter = 0;
                    for (SubComponentFunction function : tv.functions) {
                      paramsNewRequest.add(
                          PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "."
                              + NAME_MTAS_TERMVECTOR_FUNCTION + "."
                              + functionCounter + "."
                              + NAME_MTAS_TERMVECTOR_FUNCTION_EXPRESSION,
                          function.expression);
                      paramsNewRequest.add(
                          PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "."
                              + NAME_MTAS_TERMVECTOR_FUNCTION + "."
                              + functionCounter + "."
                              + NAME_MTAS_TERMVECTOR_FUNCTION_KEY,
                          function.key);
                      if (function.type != null) {
                        paramsNewRequest.add(
                            PARAM_MTAS_TERMVECTOR + "." + termvectorCounter
                                + "." + NAME_MTAS_TERMVECTOR_FUNCTION + "."
                                + functionCounter + "."
                                + NAME_MTAS_TERMVECTOR_FUNCTION_TYPE,
                            function.type);
                      }
                      functionCounter++;
                    }
                  }
                  if (tv.regexp != null) {
                    paramsNewRequest.add(PARAM_MTAS_TERMVECTOR + "."
                        + termvectorCounter + "." + NAME_MTAS_TERMVECTOR_REGEXP,
                        tv.regexp);
                  }
                  termvectorCounter++;
                }
              }
            }
          }
        }
        if (!paramsNewRequest.getParameterNames().isEmpty()) {
          requestParamList.put(shardAddress, paramsNewRequest);
        }
      }

      // new requests
      for (Entry<String, ModifiableSolrParams> entry : requestParamList
          .entrySet()) {
        ShardRequest sreq = new ShardRequest();
        sreq.shards = new String[] { entry.getKey() };
        sreq.purpose = ShardRequest.PURPOSE_PRIVATE;
        sreq.params = entry.getValue();
        sreq.params.add(CommonParams.FQ,
            rb.req.getParams().getParams(CommonParams.FQ));
        sreq.params.add(CommonParams.Q,
            rb.req.getParams().getParams(CommonParams.Q));
        sreq.params.add(CommonParams.CACHE,
            rb.req.getParams().getParams(CommonParams.CACHE));
        sreq.params.add(CommonParams.ROWS, "0");
        sreq.params.add(MtasSolrSearchComponent.PARAM_MTAS, rb.req
            .getOriginalParams().getParams(MtasSolrSearchComponent.PARAM_MTAS));
        sreq.params.add(PARAM_MTAS_TERMVECTOR,
            rb.req.getOriginalParams().getParams(PARAM_MTAS_TERMVECTOR));
        rb.addRequest(searchComponent, sreq);
      }
    }

  }
private void distributedProcessMissingTop ( ResponseBuilder rb , ComponentFields mtasFields ) throws IOException { Map < String , SortedMap < String , MtasDataItemNumberComparator > > mergedComparatorLists = new HashMap < > ( ) ; Map < String , MtasDataItemNumberComparator > mergedComparatorBoundaryList = new HashMap < > ( ) ; Map < String , MtasDataItemNumberComparator > summedComparatorBoundaryList = new HashMap < > ( ) ; Map < String , Map < String , MtasDataItemNumberComparator > > comparatorBoundariesList = new HashMap < > ( ) ; for ( String field : mtasFields . list . keySet ( ) ) { List < ComponentTermVector > tvList = mtasFields . list . get ( field ) . termVectorList ; if ( tvList != null ) { for ( ComponentTermVector tv : tvList ) { if ( ! tv . subComponentFunction . sortType . equals ( CodecUtil . SORT_TERM ) ) { mergedComparatorLists . put ( tv . key , new TreeMap < String , MtasDataItemNumberComparator > ( ) ) ; } } } } for ( ShardRequest sreq : rb . finished ) { if ( sreq . params . getBool ( MtasSolrSearchComponent . PARAM_MTAS , false ) && sreq . params . getBool ( PARAM_MTAS_TERMVECTOR , false ) ) { for ( ShardResponse shardResponse : sreq . responses ) { SortedMap < String , MtasDataItemNumberComparator > mergedComparatorList ; NamedList < Object > response = shardResponse . getSolrResponse ( ) . getResponse ( ) ; String key ; MtasSolrMtasResult list ; MtasDataItemNumberComparator comparatorLast ; Map < String , MtasDataItemNumberComparator > comparatorList ; try { List < NamedList < Object > > data = ( List < NamedList < Object > > ) response . findRecursive ( "mtas" , NAME ) ; if ( data != null ) { for ( int i = 0 ; i < data . size ( ) ; i ++ ) { NamedList < Object > dataItem = data . get ( i ) ; try { key = ( String ) dataItem . get ( "key" ) ; list = ( MtasSolrMtasResult ) dataItem . get ( "list" ) ; if ( list != null ) { comparatorLast = list . getResult ( ) . getLastSortValue ( ) ; comparatorList = list . getResult ( ) . getComparatorList ( ) ; if ( key == null ) { dataItem . clear ( ) ; } else if ( comparatorLast == null || comparatorList == null || ! mergedComparatorLists . containsKey ( key ) ) { } else { mergedComparatorList = mergedComparatorLists . get ( key ) ; for ( Entry < String , MtasDataItemNumberComparator > entry : comparatorList . entrySet ( ) ) { if ( mergedComparatorList . containsKey ( entry . getKey ( ) ) ) { mergedComparatorList . get ( entry . getKey ( ) ) . add ( entry . getValue ( ) . getValue ( ) ) ; } else { mergedComparatorList . put ( entry . getKey ( ) , entry . getValue ( ) . clone ( ) ) ; } } if ( ! comparatorBoundariesList . containsKey ( key ) ) { comparatorBoundariesList . put ( key , new HashMap < String , MtasDataItemNumberComparator > ( ) ) ; } comparatorBoundariesList . get ( key ) . put ( shardResponse . getShardAddress ( ) , comparatorLast ) ; if ( summedComparatorBoundaryList . containsKey ( key ) ) { summedComparatorBoundaryList . get ( key ) . add ( comparatorLast . getValue ( ) ) ; } else { summedComparatorBoundaryList . put ( key , comparatorLast . clone ( ) ) ; } } } else { throw new IOException ( "no data returned" ) ; } } catch ( ClassCastException e ) { log . debug ( e ) ; dataItem . clear ( ) ; } } } } catch ( ClassCastException e ) { log . debug ( e ) ; } shardResponse . getSolrResponse ( ) . setResponse ( response ) ; } } } HashMap < String , HashMap < String , HashMap < String , MtasDataItemNumberComparator > > > recomputeFieldList = new HashMap < > ( ) ; for ( String field : mtasFields . list . keySet ( ) ) { List < ComponentTermVector > tvList = mtasFields . list . get ( field ) . termVectorList ; if ( tvList != null ) { for ( ComponentTermVector tv : tvList ) { SortedMap < String , MtasDataItemNumberComparator > mergedComparatorList ; if ( mergedComparatorLists . containsKey ( tv . key ) ) { mergedComparatorList = mergedComparatorLists . get ( tv . key ) ; if ( mergedComparatorList . size ( ) < tv . number || tv . number <= 0 ) { } else { final int sortDirection = tv . subComponentFunction . sortDirection . equals ( CodecUtil . SORT_DESC ) ? - 1 : 1 ; SortedSet < Map . Entry < String , MtasDataItemNumberComparator > > sortedSet = new TreeSet < > ( ( Map . Entry < String , MtasDataItemNumberComparator > e1 , Map . Entry < String , MtasDataItemNumberComparator > e2 ) -> ( e1 . getValue ( ) . compareTo ( e2 . getValue ( ) . getValue ( ) ) == 0 ) ? e1 . getKey ( ) . compareTo ( e2 . getKey ( ) ) : e1 . getValue ( ) . compareTo ( e2 . getValue ( ) . getValue ( ) ) * sortDirection ) ; sortedSet . addAll ( mergedComparatorLists . get ( tv . key ) . entrySet ( ) ) ; Optional < Map . Entry < String , MtasDataItemNumberComparator > > optionalItem = sortedSet . stream ( ) . skip ( tv . number - 1L ) . findFirst ( ) ; if ( optionalItem . isPresent ( ) ) { mergedComparatorBoundaryList . put ( tv . key , optionalItem . get ( ) . getValue ( ) ) ; } } } } } HashMap < String , HashMap < String , MtasDataItemNumberComparator > > recomputeList = new HashMap < > ( ) ; if ( tvList != null ) { for ( ComponentTermVector tv : tvList ) { String key = tv . key ; if ( mergedComparatorBoundaryList . containsKey ( key ) && summedComparatorBoundaryList . containsKey ( key ) ) { recomputeList . put ( key , new HashMap < String , MtasDataItemNumberComparator > ( ) ) ; List < Entry < String , MtasDataItemNumberComparator > > list = new LinkedList < > ( comparatorBoundariesList . get ( key ) . entrySet ( ) ) ; Collections . sort ( list , ( Entry < String , MtasDataItemNumberComparator > e1 , Entry < String , MtasDataItemNumberComparator > e2 ) -> e1 . getValue ( ) . compareTo ( e2 . getValue ( ) . getValue ( ) ) ) ; HashMap < String , MtasDataItemNumberComparator > sortedHashMap = new LinkedHashMap < > ( ) ; for ( Iterator < Map . Entry < String , MtasDataItemNumberComparator > > it = list . iterator ( ) ; it . hasNext ( ) ; ) { Map . Entry < String , MtasDataItemNumberComparator > entry = it . next ( ) ; sortedHashMap . put ( entry . getKey ( ) , entry . getValue ( ) ) ; } MtasDataItemNumberComparator mainNewBoundary = mergedComparatorBoundaryList . get ( key ) . recomputeBoundary ( sortedHashMap . size ( ) ) ; MtasDataItemNumberComparator sum = null ; int number = 0 ; for ( Entry < String , MtasDataItemNumberComparator > entry : sortedHashMap . entrySet ( ) ) { MtasDataItemNumberComparator newBoundary = mainNewBoundary . clone ( ) ; MtasDataItemNumberComparator currentBoundary = entry . getValue ( ) ; int compare = currentBoundary . compareTo ( newBoundary . getValue ( ) ) ; if ( tv . subComponentFunction . sortDirection . equals ( CodecUtil . SORT_DESC ) ) { compare *= - 1 ; } if ( compare < 0 ) { HashMap < String , MtasDataItemNumberComparator > recomputeSubList = new HashMap < > ( ) ; if ( number > 0 && sum != null && tv . subComponentFunction . sortDirection . equals ( CodecUtil . SORT_DESC ) ) { MtasDataItemNumberComparator tmpSumBoundary = mergedComparatorBoundaryList . get ( key ) ; tmpSumBoundary . subtract ( sum . getValue ( ) ) ; MtasDataItemNumberComparator alternativeNewBoundary = tmpSumBoundary . recomputeBoundary ( sortedHashMap . size ( ) - number ) ; compare = newBoundary . compareTo ( alternativeNewBoundary . getValue ( ) ) ; if ( compare < 0 ) { newBoundary = alternativeNewBoundary ; compare = currentBoundary . compareTo ( newBoundary . getValue ( ) ) ; if ( tv . subComponentFunction . sortDirection . equals ( CodecUtil . SORT_DESC ) ) { compare *= - 1 ; } if ( compare < 0 ) { recomputeSubList . put ( entry . getKey ( ) , newBoundary ) ; } } else { recomputeSubList . put ( entry . getKey ( ) , newBoundary ) ; } } else { recomputeSubList . put ( entry . getKey ( ) , newBoundary ) ; } if ( ! recomputeSubList . isEmpty ( ) ) { if ( ! recomputeList . containsKey ( key ) ) { recomputeList . put ( key , recomputeSubList ) ; } else { recomputeList . get ( key ) . putAll ( recomputeSubList ) ; } } } else { newBoundary = currentBoundary . clone ( ) ; } if ( sum == null ) { sum = newBoundary . clone ( ) ; } else { sum . add ( newBoundary . getValue ( ) ) ; } number ++ ; } } } } if ( ! recomputeList . isEmpty ( ) ) { recomputeFieldList . put ( field , recomputeList ) ; } } if ( recomputeFieldList . size ( ) > 0 ) { HashSet < String > shards = new HashSet < > ( ) ; for ( ShardRequest sreq : rb . finished ) { if ( sreq . params . getBool ( MtasSolrSearchComponent . PARAM_MTAS , false ) && sreq . params . getBool ( PARAM_MTAS_TERMVECTOR , false ) ) { for ( ShardResponse shardResponse : sreq . responses ) { NamedList < Object > response = shardResponse . getSolrResponse ( ) . getResponse ( ) ; String key ; String field ; String shardAddress = shardResponse . getShardAddress ( ) ; try { ArrayList < NamedList < Object > > data = ( ArrayList < NamedList < Object > > ) response . findRecursive ( "mtas" , NAME ) ; shards . add ( shardAddress ) ; if ( data != null ) { for ( int i = 0 ; i < data . size ( ) ; i ++ ) { NamedList < Object > dataItem = data . get ( i ) ; try { key = ( String ) dataItem . get ( "key" ) ; field = ( String ) dataItem . get ( "field" ) ; boolean doClear ; doClear = field != null && key != null ; doClear = doClear ? recomputeFieldList . get ( field ) != null : false ; doClear = doClear ? recomputeFieldList . get ( field ) . containsKey ( key ) : false ; doClear = doClear ? recomputeFieldList . get ( field ) . get ( key ) . containsKey ( shardAddress ) : false ; if ( doClear ) { dataItem . clear ( ) ; dataItem . add ( "key" , key ) ; } } catch ( ClassCastException e ) { log . debug ( e ) ; dataItem . clear ( ) ; } } } } catch ( ClassCastException e ) { log . debug ( e ) ; } shardResponse . getSolrResponse ( ) . setResponse ( response ) ; } } } HashMap < String , ModifiableSolrParams > requestParamList = new HashMap < > ( ) ; for ( String shardAddress : shards ) { ModifiableSolrParams paramsNewRequest = new ModifiableSolrParams ( ) ; int termvectorCounter = 0 ; for ( String field : mtasFields . list . keySet ( ) ) { List < ComponentTermVector > tvList = mtasFields . list . get ( field ) . termVectorList ; if ( recomputeFieldList . containsKey ( field ) ) { HashMap < String , HashMap < String , MtasDataItemNumberComparator > > recomputeList = recomputeFieldList . get ( field ) ; if ( tvList != null ) { for ( ComponentTermVector tv : tvList ) { if ( recomputeList . containsKey ( tv . key ) && recomputeList . get ( tv . key ) . containsKey ( shardAddress ) ) { paramsNewRequest . add ( PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "." + NAME_MTAS_TERMVECTOR_BOUNDARY , String . valueOf ( recomputeList . get ( tv . key ) . get ( shardAddress ) . getValue ( ) ) ) ; paramsNewRequest . add ( PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "." + NAME_MTAS_TERMVECTOR_FIELD , field ) ; paramsNewRequest . add ( PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "." + NAME_MTAS_TERMVECTOR_PREFIX , tv . prefix ) ; paramsNewRequest . add ( PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "." + NAME_MTAS_TERMVECTOR_KEY , tv . key ) ; paramsNewRequest . add ( PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "." + NAME_MTAS_TERMVECTOR_NUMBER , String . valueOf ( tv . number ) ) ; if ( tv . subComponentFunction . sortType != null ) { paramsNewRequest . add ( PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "." + NAME_MTAS_TERMVECTOR_SORT_TYPE , tv . subComponentFunction . sortType ) ; } if ( tv . subComponentFunction . sortDirection != null ) { paramsNewRequest . add ( PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "." + NAME_MTAS_TERMVECTOR_SORT_DIRECTION , tv . subComponentFunction . sortDirection ) ; } if ( tv . subComponentFunction . type != null ) { paramsNewRequest . add ( PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "." + NAME_MTAS_TERMVECTOR_TYPE , tv . subComponentFunction . type ) ; } if ( tv . distances != null ) { int distanceCounter = 0 ; for ( SubComponentDistance distance : tv . distances ) { paramsNewRequest . add ( PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "." + NAME_MTAS_TERMVECTOR_DISTANCE + "." + distanceCounter + "." + NAME_MTAS_TERMVECTOR_DISTANCE_TYPE , distance . type ) ; paramsNewRequest . add ( PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "." + NAME_MTAS_TERMVECTOR_DISTANCE + "." + distanceCounter + "." + NAME_MTAS_TERMVECTOR_DISTANCE_BASE , distance . base ) ; if ( distance . key != null ) { paramsNewRequest . add ( PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "." + NAME_MTAS_TERMVECTOR_DISTANCE + "." + distanceCounter + "." + NAME_MTAS_TERMVECTOR_DISTANCE_KEY , distance . key ) ; } if ( distance . minimum != null ) { paramsNewRequest . add ( PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "." + NAME_MTAS_TERMVECTOR_DISTANCE + "." + distanceCounter + "." + NAME_MTAS_TERMVECTOR_DISTANCE_MINIMUM , String . valueOf ( distance . minimum ) ) ; } if ( distance . maximum != null ) { paramsNewRequest . add ( PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "." + NAME_MTAS_TERMVECTOR_DISTANCE + "." + distanceCounter + "." + NAME_MTAS_TERMVECTOR_DISTANCE_MAXIMUM , String . valueOf ( distance . maximum ) ) ; } if ( distance . parameters != null ) { for ( Entry < String , String > parameter : distance . parameters . entrySet ( ) ) { paramsNewRequest . add ( PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "." + NAME_MTAS_TERMVECTOR_DISTANCE + "." + distanceCounter + "." + NAME_MTAS_TERMVECTOR_DISTANCE_PARAMETER + "." + parameter . getKey ( ) , parameter . getValue ( ) ) ; } } distanceCounter ++ ; } } if ( tv . functions != null ) { int functionCounter = 0 ; for ( SubComponentFunction function : tv . functions ) { paramsNewRequest . add ( PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "." + NAME_MTAS_TERMVECTOR_FUNCTION + "." + functionCounter + "." + NAME_MTAS_TERMVECTOR_FUNCTION_EXPRESSION , function . expression ) ; paramsNewRequest . add ( PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "." + NAME_MTAS_TERMVECTOR_FUNCTION + "." + functionCounter + "." + NAME_MTAS_TERMVECTOR_FUNCTION_KEY , function . key ) ; if ( function . type != null ) { paramsNewRequest . add ( PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "." + NAME_MTAS_TERMVECTOR_FUNCTION + "." + functionCounter + "." + NAME_MTAS_TERMVECTOR_FUNCTION_TYPE , function . type ) ; } functionCounter ++ ; } } if ( tv . regexp != null ) { paramsNewRequest . add ( PARAM_MTAS_TERMVECTOR + "." + termvectorCounter + "." + NAME_MTAS_TERMVECTOR_REGEXP , tv . regexp ) ; } termvectorCounter ++ ; } } } } } if ( ! paramsNewRequest . getParameterNames ( ) . isEmpty ( ) ) { requestParamList . put ( shardAddress , paramsNewRequest ) ; } } for ( Entry < String , ModifiableSolrParams > entry : requestParamList . entrySet ( ) ) { ShardRequest sreq = new ShardRequest ( ) ; sreq . shards = new String [ ] { entry . getKey ( ) } ; sreq . purpose = ShardRequest . PURPOSE_PRIVATE ; sreq . params = entry . getValue ( ) ; sreq . params . add ( CommonParams . FQ , rb . req . getParams ( ) . getParams ( CommonParams . FQ ) ) ; sreq . params . add ( CommonParams . Q , rb . req . getParams ( ) . getParams ( CommonParams . Q ) ) ; sreq . params . add ( CommonParams . CACHE , rb . req . getParams ( ) . getParams ( CommonParams . CACHE ) ) ; sreq . params . add ( CommonParams . ROWS , "0" ) ; sreq . params . add ( MtasSolrSearchComponent . PARAM_MTAS , rb . req . getOriginalParams ( ) . getParams ( MtasSolrSearchComponent . PARAM_MTAS ) ) ; sreq . params . add ( PARAM_MTAS_TERMVECTOR , rb . req . getOriginalParams ( ) . getParams ( PARAM_MTAS_TERMVECTOR ) ) ; rb . addRequest ( searchComponent , sreq ) ; } } }
Distributed process missing top.

@param rb the rb
@param mtasFields the mtas fields
@throws IOException Signals that an I/O exception has occurred.