1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.diyefi.openlogviewer.genericlog;
24
25 import java.beans.PropertyChangeEvent;
26 import java.beans.PropertyChangeListener;
27 import java.beans.PropertyChangeSupport;
28 import java.util.LinkedHashMap;
29 import java.util.Iterator;
30 import java.util.Arrays;
31 import java.util.ResourceBundle;
32
33 import org.diyefi.openlogviewer.Keys;
34 import org.diyefi.openlogviewer.OpenLogViewer;
35 import org.diyefi.openlogviewer.Text;
36 import org.diyefi.openlogviewer.coloring.InitialLineColoring;
37
38 public class GenericLog extends LinkedHashMap<String, GenericDataElement> {
39 public static final String RECORD_COUNT_KEY = "OLV Record Count";
40 public static final String tempResetKey = "OLV Temp Resets";
41 public static final String elapsedTimeKey = "OLV Elapsed Time";
42
43
44
45 public static enum LogState { LOG_NOT_LOADED, LOG_LOADING, LOG_LOADED }
46
47 private static final long serialVersionUID = 1L;
48
49
50 private static final int NUMBER_OF_BUILTIN_FIELDS = 3;
51 private static final int RECORD_COUNT_OFFSET = 0;
52 private static final int TEMP_RESET_OFFSET = 1;
53 private static final int ELAPSED_TIME_OFFSET = 2;
54 private static final int SIZE_OF_DOUBLE = 8;
55 private static final int NUMBER_OF_BYTES_IN_A_MEG = 1000000;
56
57 private final ResourceBundle labels;
58 private final GenericDataElement recordCountElement;
59 private final PropertyChangeSupport pcs;
60 private final int ourLoadFactor;
61 private final int numberOfInternalHeaders;
62
63 private LogState logStatus;
64 private String logStatusMessage;
65
66
67 private int currentCapacity;
68 private int currentPosition = -1;
69
70
71 private final PropertyChangeListener autoLoad = new PropertyChangeListener() {
72 public void propertyChange(final PropertyChangeEvent propertyChangeEvent) {
73 if ((LogState) propertyChangeEvent.getNewValue() == LogState.LOG_LOADING) {
74 final GenericLog genLog = (GenericLog) propertyChangeEvent.getSource();
75 genLog.setLogStatus(LogState.LOG_LOADING);
76 OpenLogViewer.getInstance().setLog(genLog);
77 } else if ((LogState) propertyChangeEvent.getNewValue() == LogState.LOG_LOADED) {
78 final GenericLog genLog = (GenericLog) propertyChangeEvent.getSource();
79 genLog.setLogStatus(LogState.LOG_LOADED);
80 OpenLogViewer.getInstance().setLog(genLog);
81 OpenLogViewer.getInstance().getOptionFrame().updateFromLog(genLog);
82 InitialLineColoring.INSTANCE.giveBackAllColors();
83 }
84 }
85 };
86
87
88
89
90
91
92 public GenericLog(final String[] headers, final int initialCapacity, final int ourLoadFactor, final ResourceBundle labels) {
93 super(1 + (headers.length + NUMBER_OF_BUILTIN_FIELDS), 1.0f);
94
95 this.labels = labels;
96
97 GenericDataElement.resetPosition();
98 logStatus = LogState.LOG_NOT_LOADED;
99 pcs = new PropertyChangeSupport(this);
100 addPropertyChangeListener(Keys.LOG_LOADED, autoLoad);
101
102 this.ourLoadFactor = ourLoadFactor;
103 currentCapacity = initialCapacity;
104
105
106 numberOfInternalHeaders = headers.length + NUMBER_OF_BUILTIN_FIELDS;
107 final String[] internalHeaders = Arrays.copyOf(headers, numberOfInternalHeaders);
108
109
110 internalHeaders[headers.length + RECORD_COUNT_OFFSET] = RECORD_COUNT_KEY;
111 internalHeaders[headers.length + TEMP_RESET_OFFSET] = tempResetKey;
112 internalHeaders[headers.length + ELAPSED_TIME_OFFSET] = elapsedTimeKey;
113
114 for (int x = 0; x < internalHeaders.length; x++) {
115 final GenericDataElement gde = new GenericDataElement(initialCapacity);
116 gde.setName(internalHeaders[x]);
117 this.put(internalHeaders[x], gde);
118 }
119
120 recordCountElement = this.get(RECORD_COUNT_KEY);
121 }
122
123
124
125
126
127
128 public final void addValue(final String key, final double value) {
129 get(key).add(value);
130 }
131
132 public final void incrementPosition() {
133 currentPosition++;
134 GenericDataElement.incrementPosition();
135 if (currentPosition >= currentCapacity) {
136 System.out.println(OpenLogViewer.NEWLINE + labels.getString(Text.MEMORY_RESIZE_WARNING));
137 final long startResizes = System.currentTimeMillis();
138 System.out.println(labels.getString(Text.MEMORY_OLD_CAPACITY) + currentCapacity);
139 final Runtime ourRuntime = Runtime.getRuntime();
140
141 System.out.println(labels.getString(Text.MEMORY_BEFORE)
142 + labels.getString(Text.MEMORY_MAX) + ourRuntime.maxMemory()
143 + labels.getString(Text.MEMORY_FREE) + ourRuntime.freeMemory()
144 + labels.getString(Text.MEMORY_TOTAL) + ourRuntime.totalMemory());
145
146 int numberResized = 0;
147 final Iterator<GenericDataElement> genLogIterator = this.values().iterator();
148 while (genLogIterator.hasNext()) {
149
150 final long overheadInMemory = currentCapacity * SIZE_OF_DOUBLE;
151 final long increaseInMemory = overheadInMemory * ourLoadFactor;
152
153
154
155 final long requiredMemory = 2 * (increaseInMemory + overheadInMemory);
156 final long availableMemory = ourRuntime.freeMemory();
157
158 if (availableMemory < requiredMemory) {
159 currentPosition--;
160 System.out.println(labels.getString(Text.DETECTED_OOME_MEMORY_DOOM));
161 System.out.println(labels.getString(Text.MEMORY_TOTAL_AVAILABLE) + availableMemory
162 + labels.getString(Text.MEMORY_TOTAL_REQUIRED) + requiredMemory
163 + labels.getString(Text.MEMORY_TOTAL_INCREASE) + increaseInMemory
164 + labels.getString(Text.MEMORY_TOTAL_OVERHEAD) + overheadInMemory);
165 System.out.println(labels.getString(Text.JVM_HELP_MESSAGE));
166 final long allocatedMemory = (ourRuntime.maxMemory() / NUMBER_OF_BYTES_IN_A_MEG);
167 throw new RuntimeException(allocatedMemory + labels.getString(Text.MEG_INSUFFICIENT_MEMORY_FOR_INCREASE)
168 + labels.getString(Text.JVM_HELP_MESSAGE) + OpenLogViewer.NEWLINE
169 + labels.getString(Text.RESIZE_COMPLETED_PART1) + numberResized
170 + labels.getString(Text.RESIZE_COMPLETED_PART2) + numberOfInternalHeaders
171 + labels.getString(Text.RESIZE_COMPLETED_PART3) + currentCapacity
172 + labels.getString(Text.RESIZE_COMPLETED_PART4) + (currentCapacity * ourLoadFactor)
173 + labels.getString(Text.RESIZE_COMPLETED_PART5));
174 }
175
176 final GenericDataElement dataElement = genLogIterator.next();
177 dataElement.increaseCapacity(ourLoadFactor);
178 numberResized++;
179 }
180 currentCapacity *= ourLoadFactor;
181
182 System.out.println(labels.getString(Text.MEMORY_AFTER)
183 + labels.getString(Text.MEMORY_MAX) + ourRuntime.maxMemory()
184 + labels.getString(Text.MEMORY_FREE) + ourRuntime.freeMemory()
185 + labels.getString(Text.MEMORY_TOTAL) + ourRuntime.totalMemory());
186
187 final long finishResizes = System.currentTimeMillis();
188 System.out.println(labels.getString(Text.MEMORY_NEW_CAPACITY) + currentCapacity);
189 System.out.println(labels.getString(Text.MEMORY_RESIZES_TOOK)
190 + (finishResizes - startResizes)
191 + labels.getString(Text.MEMORY_RESIZES_UNIT));
192 }
193
194 recordCountElement.add((double) currentPosition);
195 }
196
197
198
199
200
201 public final void setLogStatus(final LogState newLogStatus) {
202 final LogState oldLogStatus = this.logStatus;
203 this.logStatus = newLogStatus;
204 pcs.firePropertyChange(Keys.LOG_LOADED, oldLogStatus, newLogStatus);
205 }
206
207
208
209
210
211 public final LogState getLogStatus() {
212 return this.logStatus;
213 }
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228 public final void addPropertyChangeListener(final String name, final PropertyChangeListener listener) {
229 pcs.addPropertyChangeListener(name, listener);
230 }
231
232
233
234
235
236
237 public final void removePropertyChangeListener(final String propertyName, final PropertyChangeListener listener) {
238 pcs.removePropertyChangeListener(propertyName, listener);
239 }
240
241 public final String getLogStatusMessage() {
242 return logStatusMessage;
243 }
244
245 public final void setLogStatusMessage(final String message) {
246 this.logStatusMessage = message;
247 }
248
249 public final int getRecordCount() {
250 return currentPosition;
251 }
252
253 public final void clearOut() {
254 final Iterator<GenericDataElement> lastRound = this.values().iterator();
255 while (lastRound.hasNext()) {
256 lastRound.next().clearOut();
257 }
258 this.clear();
259 }
260 }