All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.browseengine.bobo.util.ListMerger Maven / Gradle / Ivy
/**
* This software is licensed to you under the Apache License, Version 2.0 (the
* "Apache License").
*
* LinkedIn's contributions are made under the Apache License. If you contribute
* to the Software, the contributions will be deemed to have been made under the
* Apache License, unless you expressly indicate otherwise. Please do not make any
* contributions that would be inconsistent with the Apache License.
*
* You may obtain a copy of the Apache License at http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, this software
* distributed under the Apache License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the Apache
* License for the specific language governing permissions and limitations for the
* software governed under the Apache License.
*
* © 2012 LinkedIn Corp. All Rights Reserved.
*/
package com.browseengine.bobo.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.lucene.util.PriorityQueue;
import com.browseengine.bobo.api.BrowseFacet;
import com.browseengine.bobo.api.BrowseRequest;
import com.browseengine.bobo.api.FacetAccessible;
import com.browseengine.bobo.api.FacetSpec;
import com.browseengine.bobo.api.FacetSpec.FacetSortSpec;
import com.browseengine.bobo.api.MappedFacetAccessible;
import com.browseengine.bobo.facets.impl.FacetHitcountComparatorFactory;
/**
* @author ymatsuda
*
*/
public class ListMerger
{
public static class MergedIterator implements Iterator
{
private class IteratorNode
{
public Iterator _iterator;
public T _curVal;
public IteratorNode(Iterator iterator)
{
_iterator = iterator;
_curVal = null;
}
public boolean fetch()
{
if(_iterator.hasNext())
{
_curVal = _iterator.next();
return true;
}
_curVal = null;
return false;
}
}
private final PriorityQueue _queue;
private MergedIterator(final int length, final Comparator comparator)
{
_queue = new PriorityQueue()
{
{
this.initialize(length);
}
@SuppressWarnings("unchecked")
@Override
protected boolean lessThan(Object o1, Object o2)
{
T v1 = ((IteratorNode)o1)._curVal;
T v2 = ((IteratorNode)o2)._curVal;
return (comparator.compare(v1, v2) < 0);
}
};
}
public MergedIterator(final List> iterators, final Comparator comparator)
{
this(iterators.size(), comparator);
for(Iterator iterator : iterators)
{
IteratorNode ctx = new IteratorNode(iterator);
if(ctx.fetch()) _queue.add(ctx);
}
}
public MergedIterator(final Iterator[] iterators, final Comparator comparator)
{
this(iterators.length, comparator);
for(Iterator iterator : iterators)
{
IteratorNode ctx = new IteratorNode(iterator);
if(ctx.fetch()) _queue.add(ctx);
}
}
public boolean hasNext()
{
return _queue.size() > 0;
}
@SuppressWarnings("unchecked")
public T next()
{
IteratorNode ctx = (IteratorNode)_queue.top();
T val = ctx._curVal;
if (ctx.fetch())
{
_queue.updateTop();
}
else
{
_queue.pop();
}
return val;
}
public void remove()
{
throw new UnsupportedOperationException();
}
}
private ListMerger() { }
public static Iterator mergeLists(final Iterator[] iterators, final Comparator comparator)
{
return new MergedIterator(iterators, comparator);
}
public static Iterator mergeLists(final List> iterators, final Comparator comparator)
{
return new MergedIterator(iterators, comparator);
}
public static ArrayList mergeLists(int offset, int count, Iterator[] iterators, Comparator comparator)
{
return mergeLists(offset, count, new MergedIterator(iterators, comparator));
}
public static ArrayList mergeLists(int offset, int count, List> iterators, Comparator comparator)
{
return mergeLists(offset, count, new MergedIterator(iterators, comparator));
}
private static ArrayList mergeLists(int offset, int count, Iterator mergedIter)
{
if (count == 0) return new ArrayList();
for (int c = 0; c < offset && mergedIter.hasNext(); c++)
{
mergedIter.next();
}
ArrayList mergedList = new ArrayList();
for (int c = 0; c < count && mergedIter.hasNext(); c++)
{
mergedList.add(mergedIter.next());
}
return mergedList;
}
public static final Comparator FACET_VAL_COMPARATOR = new Comparator(){
public int compare(BrowseFacet o1, BrowseFacet o2) {
int ret = o1.getValue().compareTo(o2.getValue());
if (o1.getValue().startsWith("-") && o2.getValue().startsWith("-")) {
ret =-ret;
}
return ret;
}
};
public static Map mergeSimpleFacetContainers(Collection> subMaps,BrowseRequest req)
{
Map> counts = new HashMap>();
for (Map subMap : subMaps)
{
for(Map.Entry entry : subMap.entrySet())
{
Map count = counts.get(entry.getKey());
if(count == null)
{
count = new HashMap();
counts.put(entry.getKey(), count);
}
for(BrowseFacet facet : entry.getValue().getFacets())
{
String val = facet.getValue();
BrowseFacet oldValue = count.get(val);
if(oldValue == null)
{
count.put(val, new BrowseFacet(val, facet.getHitCount()));
}
else
{
oldValue.setHitCount(oldValue.getHitCount() + facet.getHitCount());
}
}
}
}
Map mergedFacetMap = new HashMap();
for(String facet : counts.keySet())
{
FacetSpec fs = req.getFacetSpec(facet);
FacetSpec.FacetSortSpec sortSpec = fs.getOrderBy();
Comparator comparator;
if (FacetSortSpec.OrderValueAsc.equals(sortSpec))
comparator = FACET_VAL_COMPARATOR;
else if (FacetSortSpec.OrderHitsDesc.equals(sortSpec))
comparator = FacetHitcountComparatorFactory.FACET_HITS_COMPARATOR;
else comparator = fs.getCustomComparatorFactory().newComparator();
Map facetValueCounts = counts.get(facet);
BrowseFacet[] facetArray = facetValueCounts.values().toArray(new BrowseFacet[facetValueCounts.size()]);
Arrays.sort(facetArray, comparator);
int numToShow = facetArray.length;
if (req != null)
{
FacetSpec fspec = req.getFacetSpec(facet);
if (fspec != null)
{
int maxCount = fspec.getMaxCount();
if(maxCount>0)
{
numToShow = Math.min(maxCount,numToShow);
}
}
}
BrowseFacet[] facets;
if(numToShow == facetArray.length)
{
facets = facetArray;
}
else
{
facets = new BrowseFacet[numToShow];
System.arraycopy(facetArray, 0, facets, 0, numToShow);
}
MappedFacetAccessible mergedFacetAccessible = new MappedFacetAccessible(facets);
mergedFacetMap.put(facet, mergedFacetAccessible);
}
return mergedFacetMap;
}
}