1
2
3
4
5
6
7
8
9
10
11
12
13
14 package ch.qos.logback.core.spi;
15
16 import ch.qos.logback.core.helpers.CyclicBuffer;
17
18 import java.util.*;
19
20
21
22
23 public class CyclicBufferTrackerSimulator {
24
25 static class Parameters {
26 public int keySpaceLen;
27 public int maxTimestampInc;
28 public int simulationLength;
29 }
30
31 CyclicBufferTracker<Object> realCBTracker = new CyclicBufferTracker<Object>();
32 CyclicBufferTrackerT<Object> t_CBTracker = new CyclicBufferTrackerT<Object>();
33
34 List<SimulationEvent> scenario = new ArrayList<SimulationEvent>();
35 List<String> keySpace = new ArrayList<String>();
36 Random randomKeyGen = new Random(100);
37 Random simulatorRandom = new Random(11234);
38 Parameters params;
39
40 int getToEndOfLifeRatio = 10;
41
42 CyclicBufferTrackerSimulator(Parameters params) {
43 this.params = params;
44 Map<String, String> checkMap = new HashMap<String, String>();
45 for (int i = 0; i < params.keySpaceLen; i++) {
46 String k = getRandomKeyStr();
47 if (checkMap.containsKey(k)) {
48 System.out.println("random key collision occurred");
49 k += "" + i;
50 }
51 keySpace.add(k);
52 checkMap.put(k, k);
53 }
54
55 }
56
57 private String getRandomKeyStr() {
58 int ri = randomKeyGen.nextInt();
59 return String.format("%X", ri);
60 }
61
62 void buildScenario() {
63 long timestamp = 30000;
64 int keySpaceLen = keySpace.size();
65 for (int i = 0; i < params.simulationLength; i++) {
66 int keyIndex = simulatorRandom.nextInt(keySpaceLen);
67 timestamp += simulatorRandom.nextInt(params.maxTimestampInc);
68 String key = keySpace.get(keyIndex);
69 scenario.add(new SimulationEvent(EventType.INSERT, key, timestamp));
70 if (simulatorRandom.nextInt(getToEndOfLifeRatio) == 0) {
71 scenario.add(new SimulationEvent(EventType.END_OF_LIFE, key, timestamp));
72 }
73 scenario.add(new SimulationEvent(EventType.REMOVE_STALE, key, timestamp));
74 }
75 }
76
77 public void dump() {
78 for (SimulationEvent simeEvent : scenario) {
79 System.out.println(simeEvent);
80 }
81 }
82
83 void play(SimulationEvent simulationEvent, ComponentTracker<CyclicBuffer<Object>> tracker) {
84 String key = simulationEvent.key;
85 long timestamp = simulationEvent.timestamp;
86 EventType eventType = simulationEvent.eventType;
87 switch (eventType) {
88 case INSERT:
89 tracker.getOrCreate(key, timestamp);
90 break;
91 case END_OF_LIFE:
92 tracker.endOfLife(key);
93 break;
94 case REMOVE_STALE:
95 tracker.removeStaleComponents(timestamp);
96 break;
97 }
98 }
99
100 public void simulate() {
101 for (SimulationEvent simeEvent : scenario) {
102 play(simeEvent, realCBTracker);
103 play(simeEvent, t_CBTracker);
104 }
105 }
106
107
108 enum EventType {
109 INSERT, END_OF_LIFE, REMOVE_STALE;
110 }
111
112 class SimulationEvent {
113 final public String key;
114 final public long timestamp;
115 final EventType eventType;
116
117 public SimulationEvent(EventType eventType, String key, long timestamp) {
118 this.eventType = eventType;
119 this.key = key;
120 this.timestamp = timestamp;
121 }
122
123 @Override
124 public String toString() {
125 return "SimulationEvent{" + "eventType=" + eventType + ", key='" + key + '\'' + ", timestamp=" + timestamp
126 + '}';
127 }
128 }
129 }