View Javadoc
1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
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   * @author Ceki Gülcü
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 }