/** * Replication Benchmarker * https://github.com/score-team/replication-benchmarker/ Copyright (C) 2013 * LORIA / Inria / SCORE Team * * This program is free software: you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program. If not, see <http://www.gnu.org/licenses/>. */ package crdt.simulator.random; import crdt.simulator.Trace; import crdt.simulator.TraceOperation; import collect.VectorClock; import crdt.simulator.random.NTrace.RandomParameters; import java.util.Enumeration; import java.util.Map; import java.util.Random; /** * An enumeration to generate caussally consistent trace of operation. Each * operation produced is a Random operation (TraceOperation.OpType.rdm) and * should be instanciate by the targeted simulator. * * @author urso */ public class RandomTrace implements Trace { private final long duration, delay; private final double probability, sdv; private final int replicas; private final Map<Long, VectorClock>[] delivery; private final VectorClock[] states; private final ReplicaProfile rp; private final RandomGauss r; private final OperationProfile op; public OperationProfile getOperationProfile() { return op; } static public interface ReplicaProfile { boolean willGenerate(int replica, long time, long duration, double probability); } /** * FLAT Profile : allways same probaility. */ static public final ReplicaProfile FLAT = new ReplicaProfile() { Random r = new Random(); @Override public boolean willGenerate(int replica, long time, long duration, double probability) { return r.nextDouble() < probability; } @Override public String toString() { return "Flat"; } }; /** * Constructor of a random trace. * * @param duration duration for generation * @param profile profile of replicas (FLAT, ...) * @param probability base probability for operation generation * @param delay average delay for operation reception (gaussian) * @param sdv standard deviation of delay for operation reception (gaussian) * @param replicas number of replicas */ public RandomTrace(final long duration, final ReplicaProfile rp, final OperationProfile op, final double probability, final long delay, final double sdv, final int replicas) { this.duration = duration; this.rp = rp; this.delay = delay; this.sdv = sdv; this.probability = probability; this.replicas = replicas; delivery = new Map[replicas]; for (int i = 0; i < replicas; i++) { delivery[i] = new java.util.HashMap<Long, VectorClock>(); } states = new VectorClock[replicas]; for (int i = 0; i < replicas; i++) { states[i] = new VectorClock(); } this.r = new RandomGauss(); this.op = op; } public RandomTrace(RandomTrace old, RandomParameters n) { this.duration = n.duration; this.rp = n.rp; this.delay = n.delay; this.sdv = n.sdv; this.op = n.op; this.probability = n.probability; this.replicas = n.replicas; if (old != null) { this.delivery = new Map[Math.max(old.delivery.length, n.replicas)]; System.arraycopy(old.delivery, 0, delivery, 0, old.replicas); for (int i = old.replicas; i < delivery.length; i++) { delivery[i] = new java.util.HashMap<Long, VectorClock>(); } states = new VectorClock[delivery.length]; System.arraycopy(old.states, 0, states, 0, old.states.length); for (int i = old.states.length; i < states.length; i++) { states[i] = new VectorClock(); } this.r = old.r; }else{ this.delivery = new Map[n.replicas]; for (int i = 0; i < delivery.length; i++) { delivery[i] = new java.util.HashMap<Long, VectorClock>(); } states = new VectorClock[delivery.length]; for (int i = 0; i < states.length; i++) { states[i] = new VectorClock(); } this.r = new RandomGauss(); } } @Override public Enumeration<TraceOperation> enumeration() { Enumeration<TraceOperation> it = new Enumeration<TraceOperation>() { private TraceOperation next; private int rindex; private long nbop; @Override public boolean hasMoreElements() { return next != null; } @Override public TraceOperation nextElement() { // System.out.println(time); TraceOperation o = next; next = null; while (next == null && nbop < duration) { VectorClock vc = states[rindex], d = delivery[rindex].get(nbop); if (d != null) { vc.upTo(d); } if (rp.willGenerate(rindex, nbop, duration, probability)) { vc.inc(rindex); VectorClock opc = (VectorClock) vc.clone(); next = new RandomOperation(op, rindex, opc); for (int i = 0; i < replicas; i++) { long rt = nbop + r.nextLongGaussian(delay, sdv); VectorClock x = delivery[i].get(rt); if (x == null) { delivery[i].put(rt, opc); } else { x = (VectorClock) x.clone(); x.upTo(opc); delivery[i].put(rt, x); } } nbop++; } rindex = (rindex + 1) % replicas; } return o; } }; it.nextElement(); return it; } }