Example usage for com.google.common.collect MinMaxPriorityQueue pollFirst

List of usage examples for com.google.common.collect MinMaxPriorityQueue pollFirst

Introduction

In this page you can find the example usage for com.google.common.collect MinMaxPriorityQueue pollFirst.

Prototype

public E pollFirst() 

Source Link

Document

Removes and returns the least element of this queue, or returns null if the queue is empty.

Usage

From source file:kungfu.algdesign.ds.MovingMedian.java

public static void calculate(Queue<Integer> data, Queue<Integer> medians) {
    MinMaxPriorityQueue<Integer> minHeap = MinMaxPriorityQueue.create();
    MinMaxPriorityQueue<Integer> maxHeap = MinMaxPriorityQueue.create();

    minHeap.add(Integer.MIN_VALUE);
    maxHeap.add(Integer.MAX_VALUE);

    Integer item = null;/*from www.  j  av  a2  s .  co  m*/
    Integer median = null;

    while ((item = data.poll()) != null) {
        if (median == null) {
            maxHeap.add(item);
        } else if (item >= median) {
            maxHeap.add(item);
        } else {
            minHeap.add(item);
        }

        if (maxHeap.size() - minHeap.size() == 2) {
            minHeap.add(maxHeap.pollFirst());
        } else if (minHeap.size() - maxHeap.size() == 2) {
            maxHeap.add(minHeap.pollLast());
        }

        if (minHeap.size() == maxHeap.size() || minHeap.size() > maxHeap.size()) {
            median = minHeap.peekLast();
        } else {
            median = maxHeap.peekFirst();
        }

        medians.add(median);
    }
}

From source file:com.linkedin.pinot.core.query.aggregation.groupby.AggregationGroupByOperatorService.java

/**
 * Given a map from group by keys to results for multiple aggregation functions, trim the results to desired size and
 * put them into a list of group by results.
 *
 * @param aggrFuncList List of aggregation functions.
 * @param aggrGroupByResults Map from group by keys to result arrays.
 * @param trimmedGroupByResultList List of maps containing group by results returned.
 * @param numAggrFunctions Number of aggregation functions.
 * @param trimSize Desired trim size./*from  ww  w .  ja v  a  2  s . c o m*/
 */
@SuppressWarnings("unchecked")
private static void trimToSize(List<AggregationFunction> aggrFuncList,
        Map<String, Serializable[]> aggrGroupByResults,
        List<Map<String, Serializable>> trimmedGroupByResultList, int numAggrFunctions, int trimSize) {
    MinMaxPriorityQueue<ImmutablePair<Serializable, String>>[] heaps = new MinMaxPriorityQueue[numAggrFunctions];
    for (int i = 0; i < numAggrFunctions; i++) {
        boolean reverseOrder = aggrFuncList.get(i).getFunctionName().startsWith(MIN_PREFIX);
        heaps[i] = getMinMaxPriorityQueue(aggrGroupByResults.values().iterator().next()[i], trimSize,
                reverseOrder);
    }

    for (String key : aggrGroupByResults.keySet()) {
        Serializable[] results = aggrGroupByResults.get(key);
        for (int i = 0; i < numAggrFunctions; i++) {
            Serializable result = results[i];
            MinMaxPriorityQueue<ImmutablePair<Serializable, String>> heap = heaps[i];
            if (heap == null) {
                trimmedGroupByResultList.get(i).put(key, result);
            } else {
                heap.add(new ImmutablePair(result, key));
            }
        }
    }

    for (int i = 0; i < numAggrFunctions; i++) {
        MinMaxPriorityQueue<ImmutablePair<Serializable, String>> heap = heaps[i];
        ImmutablePair<Serializable, String> pair;
        if (heap != null) {
            while ((pair = heap.pollFirst()) != null) {
                trimmedGroupByResultList.get(i).put(pair.getRight(), pair.getLeft());
            }
        }
    }
}

From source file:com.metamx.druid.master.BalancerCostAnalyzer.java

/**
 * For assignment, we want to move to the lowest cost server that isn't already serving the segment.
 *
 * @param proposalSegment A DataSegment that we are proposing to move.
 * @param serverHolders   An iterable of ServerHolders for a particular tier.
 *
 * @return A ServerHolder with the new home for a segment.
 *//* www  .ja v  a 2 s.  c om*/
public ServerHolder findNewSegmentHomeAssign(final DataSegment proposalSegment,
        final Iterable<ServerHolder> serverHolders) {
    MinMaxPriorityQueue<Pair<Double, ServerHolder>> costsAndServers = computeCosts(proposalSegment,
            serverHolders);
    while (!costsAndServers.isEmpty()) {
        ServerHolder toServer = costsAndServers.pollFirst().rhs;
        if (!toServer.isServingSegment(proposalSegment)) {
            return toServer;
        }
    }

    return null;
}

From source file:com.metamx.druid.master.BalancerCostAnalyzer.java

/**
 * For balancing, we want to only make a move if the minimum cost server is not already serving the segment.
 *
 * @param proposalSegment A DataSegment that we are proposing to move.
 * @param serverHolders   An iterable of ServerHolders for a particular tier.
 *
 * @return A ServerHolder with the new home for a segment.
 *///from   ww w . j  a  va 2 s  . co  m
public ServerHolder findNewSegmentHomeBalance(final DataSegment proposalSegment,
        final Iterable<ServerHolder> serverHolders) {
    MinMaxPriorityQueue<Pair<Double, ServerHolder>> costsAndServers = computeCosts(proposalSegment,
            serverHolders);
    if (costsAndServers.isEmpty()) {
        return null;
    }

    ServerHolder toServer = costsAndServers.pollFirst().rhs;
    if (!toServer.isServingSegment(proposalSegment)) {
        return toServer;
    }

    return null;
}

From source file:com.linkedin.pinot.core.query.aggregation.groupby.AggregationGroupByOperatorService.java

/**
 * Translate the reducedGroupByResults (output of broker's reduce) to AggregationResult object
 * to be used to build the BrokerResponse.
 *
 * @param reducedGroupByResults//from   w ww  .j a v a  2  s .  c o  m
 * @return
 */
public List<AggregationResult> renderAggregationGroupByResult(
        List<Map<String, Serializable>> reducedGroupByResults) {
    if (reducedGroupByResults == null || reducedGroupByResults.size() != _aggregationFunctionList.size()) {
        return null;
    }

    List<AggregationResult> aggregationResults = new ArrayList<AggregationResult>();
    for (int i = 0; i < _aggregationFunctionList.size(); ++i) {
        int groupSize = _groupByColumns.size();

        Map<String, Serializable> reducedGroupByResult = reducedGroupByResults.get(i);
        AggregationFunction aggregationFunction = _aggregationFunctionList.get(i);

        String functionName = aggregationFunction.getFunctionName();
        List<GroupByResult> groupByResults = new ArrayList<GroupByResult>();

        if (!reducedGroupByResult.isEmpty()) {
            /* Reverse sort order for min functions. */
            boolean reverseOrder = aggregationFunction.getFunctionName().startsWith(MIN_PREFIX);

            // The MinMaxPriorityQueue will only add TOP N
            MinMaxPriorityQueue<ImmutablePair<Serializable, String>> minMaxPriorityQueue = getMinMaxPriorityQueue(
                    reducedGroupByResult.values().iterator().next(), _groupByTopN, reverseOrder);

            if (minMaxPriorityQueue != null) {
                for (String groupedKey : reducedGroupByResult.keySet()) {
                    minMaxPriorityQueue
                            .add(new ImmutablePair(reducedGroupByResult.get(groupedKey), groupedKey));
                }

                ImmutablePair res;
                while ((res = (ImmutablePair) minMaxPriorityQueue.pollFirst()) != null) {
                    String groupByColumnsString = (String) res.getRight();
                    List<String> groupByColumns = Arrays.asList(groupByColumnsString.split(
                            GroupByConstants.GroupByDelimiter.groupByMultiDelimeter.toString(), groupSize));

                    Serializable value = (Serializable) res.getLeft();
                    GroupByResult groupValue = new GroupByResult();

                    groupValue.setGroup(groupByColumns);
                    groupValue.setValue(formatValue(value));
                    groupByResults.add(groupValue);
                }
            }
        }

        AggregationResult aggregationResult = new AggregationResult(groupByResults, _groupByColumns,
                functionName);
        aggregationResults.add(aggregationResult);
    }

    return aggregationResults;
}

From source file:com.linkedin.pinot.core.query.aggregation.groupby.AggregationGroupByOperatorService.java

/**
 * Given a group by result, return a group by result trimmed to provided size.
 * Sorting ordering is determined based on aggregation function.
 *
 * @param aggregationFunction/*from www  . j av a2s .  c  om*/
 * @param aggregationGroupByResult
 * @param trimSize
 * @return
 */
private Map<String, Serializable> trimToSize(AggregationFunction aggregationFunction,
        Map<String, Serializable> aggregationGroupByResult, int trimSize) {

    boolean reverseOrder = aggregationFunction.getFunctionName().startsWith(MIN_PREFIX);
    MinMaxPriorityQueue<ImmutablePair<Serializable, String>> minMaxPriorityQueue = getMinMaxPriorityQueue(
            aggregationGroupByResult.values().iterator().next(), trimSize, reverseOrder);

    if (minMaxPriorityQueue == null) {
        return aggregationGroupByResult;
    }

    // The MinMaxPriorityQueue will add only the TOP N elements.
    for (String groupedKey : aggregationGroupByResult.keySet()) {
        minMaxPriorityQueue.add(new ImmutablePair(aggregationGroupByResult.get(groupedKey), groupedKey));
    }

    Map<String, Serializable> trimmedResult = new HashMap<>();
    ImmutablePair<Serializable, String> pair;
    while ((pair = (ImmutablePair) minMaxPriorityQueue.pollFirst()) != null) {
        trimmedResult.put(pair.getRight(), pair.getLeft());
    }
    return trimmedResult;
}

From source file:com.linkedin.pinot.core.query.aggregation.groupby.AggregationGroupByOperatorService.java

public List<JSONObject> renderGroupByOperators(List<Map<String, Serializable>> finalAggregationResult) {
    try {//from  w  w w  .j  a  v  a 2s  . c o m
        if (finalAggregationResult == null
                || finalAggregationResult.size() != _aggregationFunctionList.size()) {
            return null;
        }
        List<JSONObject> retJsonResultList = new ArrayList<JSONObject>();
        for (int i = 0; i < _aggregationFunctionList.size(); ++i) {
            JSONArray groupByResultsArray = new JSONArray();

            int groupSize = _groupByColumns.size();
            Map<String, Serializable> reducedGroupByResult = finalAggregationResult.get(i);
            AggregationFunction aggregationFunction = _aggregationFunctionList.get(i);

            if (!reducedGroupByResult.isEmpty()) {
                boolean reverseOrder = aggregationFunction.getFunctionName().startsWith(MIN_PREFIX);

                MinMaxPriorityQueue<ImmutablePair<Serializable, String>> minMaxPriorityQueue = getMinMaxPriorityQueue(
                        reducedGroupByResult.values().iterator().next(), _groupByTopN, reverseOrder);

                if (minMaxPriorityQueue != null) {
                    // The MinMaxPriorityQueue will only add TOP N
                    for (String groupedKey : reducedGroupByResult.keySet()) {
                        minMaxPriorityQueue
                                .add(new ImmutablePair(reducedGroupByResult.get(groupedKey), groupedKey));
                    }

                    ImmutablePair res;
                    while ((res = (ImmutablePair) minMaxPriorityQueue.pollFirst()) != null) {
                        JSONObject groupByResultObject = new JSONObject();
                        groupByResultObject.put("group",
                                new JSONArray(((String) res.getRight()).split(
                                        GroupByConstants.GroupByDelimiter.groupByMultiDelimeter.toString(),
                                        groupSize)));
                        //          if (res.getFirst() instanceof Number) {
                        //            groupByResultObject.put("value", df.format(res.getFirst()));
                        //          } else {
                        //            groupByResultObject.put("value", res.getFirst());
                        //          }
                        //          groupByResultsArray.put(realGroupSize - 1 - j, groupByResultObject);
                        groupByResultObject.put("value",
                                aggregationFunction.render((Serializable) res.getLeft()).get("value"));
                        groupByResultsArray.put(groupByResultObject);
                    }
                }
            }

            JSONObject result = new JSONObject();
            result.put("function", aggregationFunction.getFunctionName());
            result.put("groupByResult", groupByResultsArray);
            result.put("groupByColumns", new JSONArray(_groupByColumns));
            retJsonResultList.add(result);
        }
        return retJsonResultList;
    } catch (JSONException e) {
        LOGGER.error("Caught exception while processing group by aggregation", e);
        Utils.rethrowException(e);
        throw new AssertionError("Should not reach this");
    }
}

From source file:com.linkedin.pinot.controller.helix.core.relocation.RealtimeSegmentRelocator.java

/**
 * Given the instanceStateMap and a list of consuming and completed servers for a realtime resource,
 * creates a new instanceStateMap, where one replica's instance is replaced from a consuming server to a completed server
 * @param instanceStateMap/*from  w w  w .j  ava 2s. co m*/
 * @param consumingServers
 * @param completedServersQueue
 * @return
 */
private Map<String, String> createNewInstanceStateMap(Map<String, String> instanceStateMap,
        List<String> consumingServers, MinMaxPriorityQueue<Map.Entry<String, Integer>> completedServersQueue) {

    Map<String, String> newInstanceStateMap = null;

    // proceed only if all segments are ONLINE, and at least 1 server is from consuming list
    for (String state : instanceStateMap.values()) {
        if (!state.equals(PinotHelixSegmentOnlineOfflineStateModelGenerator.ONLINE_STATE)) {
            return newInstanceStateMap;
        }
    }

    for (String instance : instanceStateMap.keySet()) {
        if (consumingServers.contains(instance)) {
            // Decide best strategy to pick completed server.
            // 1. pick random from list of completed servers
            // 2. pick completed server with minimum segments, based on ideal state of this resource
            // 3. pick completed server with minimum segment, based on ideal state of all resources in this tenant
            // 4. use SegmentAssignmentStrategy

            // TODO: Using 2 for now. We should use 4. However the current interface and implementations cannot be used as is.
            // We should refactor the SegmentAssignmentStrategy interface suitably and reuse it here

            Map.Entry<String, Integer> chosenServer = null;
            List<Map.Entry<String, Integer>> polledServers = new ArrayList<>(1);
            while (!completedServersQueue.isEmpty()) {
                Map.Entry<String, Integer> server = completedServersQueue.pollFirst();
                if (instanceStateMap.keySet().contains(server.getKey())) {
                    polledServers.add(server);
                } else {
                    chosenServer = server;
                    break;
                }
            }
            completedServersQueue.addAll(polledServers);
            if (chosenServer == null) {
                throw new IllegalStateException("Could not find server to relocate segment");
            }

            newInstanceStateMap = new HashMap<>(instanceStateMap.size());
            newInstanceStateMap.putAll(instanceStateMap);
            newInstanceStateMap.remove(instance);
            newInstanceStateMap.put(chosenServer.getKey(),
                    PinotHelixSegmentOnlineOfflineStateModelGenerator.ONLINE_STATE);

            chosenServer.setValue(chosenServer.getValue() + 1);
            completedServersQueue.add(chosenServer);
            break;
        }
    }
    return newInstanceStateMap;
}