/***********************************************************************************************************************
* Copyright (C) 2010-2013 by the Stratosphere project (http://stratosphere.eu)
*
* 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 eu.stratosphere.api.common.accumulators;
import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;
import java.util.Map;
import com.google.common.collect.Maps;
/**
* Histogram for discrete-data. Let's you populate a histogram distributedly.
* Implemented as a Integer->Integer HashMap
*
* Could be extended to continuous values later, but then we need to dynamically
* decide about the bin size in an online algorithm (or ask the user)
*/
public class Histogram implements Accumulator<Integer, Map<Integer, Integer>> {
private static final long serialVersionUID = 1L;
private Map<Integer, Integer> hashMap = Maps.newHashMap();
@Override
public void add(Integer value) {
Integer current = hashMap.get(value);
Integer newValue = value;
if (current != null) {
newValue = current + newValue;
}
this.hashMap.put(value, newValue);
}
@Override
public Map<Integer, Integer> getLocalValue() {
return this.hashMap;
}
@Override
public void merge(Accumulator<Integer, Map<Integer, Integer>> other) {
// Merge the values into this map
for (Map.Entry<Integer, Integer> entryFromOther : ((Histogram) other).getLocalValue()
.entrySet()) {
Integer ownValue = this.hashMap.get(entryFromOther.getKey());
if (ownValue == null) {
this.hashMap.put(entryFromOther.getKey(), entryFromOther.getValue());
} else {
this.hashMap.put(entryFromOther.getKey(), entryFromOther.getValue() + ownValue);
}
}
}
@Override
public void resetLocal() {
this.hashMap.clear();
}
@Override
public String toString() {
return this.hashMap.toString();
}
@Override
public void write(DataOutput out) throws IOException {
out.writeInt(hashMap.size());
for (Map.Entry<Integer, Integer> entry : hashMap.entrySet()) {
out.writeInt(entry.getKey());
out.writeInt(entry.getValue());
}
}
@Override
public void read(DataInput in) throws IOException {
int size = in.readInt();
for (int i = 0; i < size; ++i) {
hashMap.put(in.readInt(), in.readInt());
}
}
}