class CountMinHeavyHitter implements HeavyHitter, Serializable {

	public void merge(HeavyHitter toMerge) throws CMHeavyHitterMergeException {

		try {
			CountMinHeavyHitter cmToMerge = (CountMinHeavyHitter)toMerge;
			if (this.fraction != cmToMerge.fraction) {
				throw new CMHeavyHitterMergeException("The fraction for both heavy hitters must be the same");
			}

			this.countMinSketch = CountMinSketch.merge(this.countMinSketch, cmToMerge.countMinSketch);

			HashMap<Object,Long> mergedHeavyHitters = new HashMap<Object, Long>();

			for (Map.Entry<Object, Long> entry : this.heavyHitters.entrySet()) {
				mergedHeavyHitters.put(entry.getKey(), estimateCount(entry.getKey()));
			}

			for (Map.Entry<Object, Long> entry : cmToMerge.heavyHitters.entrySet()) {
				if (!mergedHeavyHitters.containsKey(entry.getKey())) {
					mergedHeavyHitters.put(entry.getKey(), estimateCount(entry.getKey()));
				}
			}
			this.heavyHitters = mergedHeavyHitters;
			cardinality+=cmToMerge.cardinality;

		}catch (ClassCastException ex){
			throw new CMHeavyHitterMergeException("Both heavy hitter objects must belong to the same class");
		}catch (Exception ex){
			throw new CMHeavyHitterMergeException("Cannot merge count min sketches: "+ex.getMessage());
		}
	}

	public  CountMinHeavyHitter(double fraction, double error, double confidence, int seed);
	public  CountMinHeavyHitter(CountMinSketch countMinSketch, double fraction);

}