/*
 * 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.
 */
package org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.partitioners;
import java.util.Arrays;
import java.util.Random;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class DiscreteProbabilitySampleGenerator {
    Random rGen;
    float[] probVec;
    float epsilon = 0.0001f;
        
    private static final Log LOG = LogFactory.getLog(DiscreteProbabilitySampleGenerator.class);
    
    public DiscreteProbabilitySampleGenerator(float[] probVec) {
        rGen = new Random();
        float sum = 0.0f;
        for (float f : probVec) {
            sum += f;
        }
        this.probVec = probVec;
        if (1-epsilon > sum || sum > 1+epsilon) { 
            LOG.info("Sum of probabilities should be near one: " + sum);
        }
    }
    
    public int getNext(){
        double toss = rGen.nextDouble();
        // if the uniformly random number that I generated
        // is in the probability range for a given partition,
        // pick that partition
        // For some sample item which occurs only in partitions
        // 1 and 2
        // say probVec[1] = 0.3
        // and probVec[2] = 0.7
        // if our coin toss generate < 0.3, we pick 1 otherwise we pick 2
        int lastIdx = -1;
        for(int i=0;i<probVec.length;i++){
            if (probVec[i] != 0) lastIdx = i;
            toss -= probVec[i];
            if(toss<=0.0)
                return i;
        }        
        return lastIdx;
    }
    
    public static void main(String[] args) {
        float[] vec = { 0, 0.3f, 0.2f, 0, 0, 0.5f };
        DiscreteProbabilitySampleGenerator gen = new DiscreteProbabilitySampleGenerator(vec);
        CountingMap<Integer> cm = new CountingMap<Integer>();
        for(int i=0;i<100;i++){
            cm.put(gen.getNext(), 1);
        }
        cm.display();
    }

    @Override
    public String toString() {
        return Arrays.toString(probVec);
    }
    
    
}
