package org.apache.cassandra.stress.util;
/*
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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.
 * 
 */


import java.util.Arrays;
import java.util.List;
import java.util.Random;

// represents a sample of long (latencies) together with the probability of selection of each sample (i.e. the ratio of
// samples to total number of events). This is used to ensure that, when merging, the result has samples from each
// with equal probability
public final class SampleOfLongs
{

    // nanos
    final long[] sample;

    // probability with which each sample was selected
    final double p;

    SampleOfLongs(long[] sample, int p)
    {
        this.sample = sample;
        this.p = 1 / (float) p;
    }

    SampleOfLongs(long[] sample, double p)
    {
        this.sample = sample;
        this.p = p;
    }

    static SampleOfLongs merge(Random rnd, List<SampleOfLongs> merge, int maxSamples)
    {
        // grab the lowest probability of selection, and normalise all samples to that
        double targetp = 1;
        for (SampleOfLongs sampleOfLongs : merge)
            targetp = Math.min(targetp, sampleOfLongs.p);

        // calculate how many samples we should encounter
        int maxLength = 0;
        for (SampleOfLongs sampleOfLongs : merge)
            maxLength += sampleOfLongs.sample.length * (targetp / sampleOfLongs.p);

        if (maxLength > maxSamples)
        {
            targetp *= maxSamples / (double) maxLength;
            maxLength = maxSamples;
        }

        long[] sample = new long[maxLength];
        int count = 0;
        out: for (SampleOfLongs latencies : merge)
        {
            long[] in = latencies.sample;
            double p = targetp / latencies.p;
            for (int i = 0 ; i < in.length ; i++)
            {
                if (rnd.nextDouble() < p)
                {
                    sample[count++] = in[i];
                    if (count == maxLength)
                        break out;
                }
            }
        }
        if (count != maxLength)
            sample = Arrays.copyOf(sample, count);
        Arrays.sort(sample);
        return new SampleOfLongs(sample, targetp);
    }

    public double medianLatency()
    {
        if (sample.length == 0)
            return 0;
        return sample[sample.length >> 1] * 0.000001d;
    }

    // 0 < rank < 1
    public double rankLatency(float rank)
    {
        if (sample.length == 0)
            return 0;
        int index = (int)(rank * sample.length);
        if (index >= sample.length)
            index = sample.length - 1;
        return sample[index] * 0.000001d;
    }

}

