package mil.nga.giat.geowave.core.store.adapter.statistics.histogram;

import java.nio.ByteBuffer;

import com.tdunning.math.stats.MergingDigest;
import com.tdunning.math.stats.TDigest;

import mil.nga.giat.geowave.core.index.ByteArrayUtils;

public class TDigestNumericHistogram implements
		NumericHistogram
{
	private static final double DEFAULT_COMPRESSION = 100;
	private TDigest tdigest;
	private long count = 0;

	public TDigestNumericHistogram() {
		super();
		tdigest = TDigest.createMergingDigest(DEFAULT_COMPRESSION);
	}

	@Override
	public void merge(
			final NumericHistogram other ) {
		if (other instanceof TDigestNumericHistogram) {
			tdigest.add(((TDigestNumericHistogram) other).tdigest);
			count += ((TDigestNumericHistogram) other).count;
		}
	}

	@Override
	public void add(
			final double v ) {
		tdigest.add(v);
		count++;
	}

	@Override
	public double quantile(
			final double q ) {
		return tdigest.quantile(q);
	}

	@Override
	public double cdf(
			final double val ) {
		return tdigest.cdf(val);
	}

	@Override
	public int bufferSize() {
		return tdigest.smallByteSize() + ByteArrayUtils.variableLengthEncode(count).length;
	}

	@Override
	public void toBinary(
			final ByteBuffer buffer ) {
		tdigest.asSmallBytes(buffer);
		final byte[] remaining = new byte[buffer.remaining()];
		buffer.get(remaining);
		count = ByteArrayUtils.variableLengthDecode(remaining);
	}

	@Override
	public void fromBinary(
			final ByteBuffer buffer ) {
		tdigest = MergingDigest.fromBytes(buffer);
		buffer.put(ByteArrayUtils.variableLengthEncode(count));
	}

	@Override
	public double getMaxValue() {
		return tdigest.getMax();
	}

	@Override
	public double getMinValue() {
		return tdigest.getMin();
	}

	@Override
	public long getTotalCount() {
		return count;
	}

	@Override
	public double sum(
			final double val,
			final boolean inclusive ) {
		final double sum = tdigest.cdf(val) * count;
		if (inclusive && (sum < 1)) {
			return 1.0;
		}
		return sum;
	}

}

@@ -1256,98 +1256,19 @@
 ;%0A%09%09
-final byte%5B%5D remaining = new byte%5Bbuffer.remaining()%5D;%0A%09%09buffer.get(remaining);%0A%09%09count = 
+buffer.put(
 Byte
@@ -1296,24 +1296,21 @@
 ngth
-De
+En
 code(
-remaining
+count)
 );%0A%09
@@ -1422,35 +1422,114 @@
 (buffer);%0A%09%09
-buffer.put(
+final byte%5B%5D remaining = new byte%5Bbuffer.remaining()%5D;%0A%09%09buffer.get(remaining);%0A%09%09count = 
 ByteArrayUti
@@ -1541,37 +1541,40 @@
 riableLength
-En
+De
 code(
-count)
+remaining
 );%0A%09%7D%0A%0A%09@Ove

fix to tdigest count serialization (#1354)