blob: e8531020db7f18a919f55f2dba7301b7e1ef6db3 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 École Polytechnique de Montréal
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.tracecompass.incubator.internal.xaf.core.statemachine.variable.utils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.Random;
import org.eclipse.tracecompass.incubator.internal.xaf.ui.statemachine.StateMachineInstance.InstanceStepInformation;
/**
* Iterator that allows to automatically sample and return the right number of
* instance step information to analyze.
*
* @author Raphaël Beamonte
*/
public class IsiSampleIterator implements Iterator<InstanceStepInformation> {
private final Iterator<InstanceStepInformation> iterator;
private final Collection<InstanceStepInformation> collection;
private final int size;
private int count;
/**
* Whether to use the full population of elements or to sample it
*/
public final boolean useFullPopulation;
/**
* Constructor
* @param collection The full collection of instance step information
*/
public IsiSampleIterator(Collection<InstanceStepInformation> collection) {
this.collection = collection;
double population = collection.size();
double sample = sampleSize(population);
if (sample < population) {
useFullPopulation = false;
size = (int)sample;
count = size;
iterator = new Iterator<InstanceStepInformation>() {
private Random rand = new Random();
private ArrayList<InstanceStepInformation> isiList = new ArrayList<>(collection);
@Override
public boolean hasNext() {
return (count > 0);
}
@Override
public InstanceStepInformation next() {
if (!isiList.isEmpty()) {
int select = Math.abs(rand.nextInt(isiList.size()));
return isiList.remove(select);
}
return null;
}
};
} else {
size = collection.size();
count = size;
iterator = collection.iterator();
useFullPopulation = true;
}
}
private static double sampleSize(Double population) {
double z = 1.96; // z-score for confidence 95%
double p = 0.5; // Distribution = 50%
double e = 0.05; // Error margin = 5%
return StateMachineVariableHelpers.sampleSize(population, z, p, e);
}
@Override
public boolean hasNext() {
return iterator.hasNext();
}
@Override
public InstanceStepInformation next() {
count--;
return iterator.next();
}
/**
* @return The number of elements that will be returned by the iterator
*/
public int size() {
return size;
}
/**
* @return The number of elements that still have to be returned by the iterator
*/
public int count() {
return count;
}
/**
* Ask for one more element from the iterator, if available
*/
public void inc() {
if (collection.size() > count) {
count++;
}
}
}