package com.tinkerpop.pipes.sideeffect;
import com.tinkerpop.pipes.AbstractPipe;
import com.tinkerpop.pipes.Pipe;
import com.tinkerpop.pipes.PipeFunction;
import com.tinkerpop.pipes.util.PipeHelper;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author Marko A. Rodriguez (http://markorodriguez.com)
*/
public class GroupByPipe<S, K, V> extends AbstractPipe<S, S> implements SideEffectPipe.GreedySideEffectPipe<S, Map<K, List<V>>> {
protected Map<K, Collection<V>> byMap;
protected final PipeFunction<S, K> keyFunction;
protected final PipeFunction<S, V> valueFunction;
public GroupByPipe(final Map<K, Collection<V>> byMap, final PipeFunction<S, K> keyFunction, final PipeFunction<S, V> valueFunction) {
this.byMap = byMap;
this.keyFunction = keyFunction;
this.valueFunction = valueFunction;
}
public GroupByPipe(final PipeFunction<S, K> keyFunction, final PipeFunction<S, V> valueFunction) {
this(new HashMap<K, Collection<V>>(), keyFunction, valueFunction);
}
protected S processNextStart() {
final S s = this.starts.next();
final K key = this.getKey(s);
final V value = this.getValue(s);
Collection<V> list = this.byMap.get(key);
if (null == list) {
list = new ArrayList<V>();
this.byMap.put(key, list);
}
this.addValue(value, list);
return s;
}
public Map getSideEffect() {
return this.byMap;
}
public void addValue(final V value, final Collection values) {
if (value instanceof Pipe) {
PipeHelper.fillCollection((Pipe) value, values);
} else {
values.add(value);
}
}
protected K getKey(final S start) {
return (null == this.keyFunction) ? (K) start : this.keyFunction.compute(start);
}
protected V getValue(final S start) {
return (null == this.valueFunction) ? (V) start : this.valueFunction.compute(start);
}
public void reset() {
this.byMap = new HashMap<K, Collection<V>>();
super.reset();
}
}