1 | package de.uka.ipd.sdq.measurement.strategies.activeresource; |
2 | |
3 | import java.io.File; |
4 | import java.io.FileInputStream; |
5 | import java.io.FileOutputStream; |
6 | import java.io.IOException; |
7 | import java.io.InputStream; |
8 | import java.io.ObjectInputStream; |
9 | import java.io.ObjectOutputStream; |
10 | import java.io.OutputStream; |
11 | import java.io.Serializable; |
12 | |
13 | import javax.measure.quantity.Duration; |
14 | |
15 | import org.apache.log4j.Logger; |
16 | import org.jscience.physics.amount.Amount; |
17 | |
18 | |
19 | /** |
20 | * Struct to represent a single entry in the calibration table of |
21 | * the load generators. It is a tuple <TargetTime, Parameter> |
22 | * @author Steffen Becker, Thomas Zolynski |
23 | * |
24 | */ |
25 | class CalibrationEntry implements Serializable { |
26 | private static final long serialVersionUID = -1969713798721640687L; |
27 | |
28 | final private Amount<Duration> targetTime; |
29 | final private long parameter; |
30 | |
31 | /** |
32 | * Constructor |
33 | * @param targetTime The time (in ms) which the workload generator should run and generate load for the given parameter |
34 | * @param parameter The load generator's parameter for which the algorithm runs targetTime milliseconds |
35 | */ |
36 | public CalibrationEntry(Amount<Duration> targetTime, long parameter) { |
37 | super(); |
38 | this.targetTime = targetTime; |
39 | this.parameter = parameter; |
40 | } |
41 | |
42 | /** |
43 | * @return Target time in ms |
44 | */ |
45 | public Amount<Duration> getTargetTime() { |
46 | return targetTime; |
47 | } |
48 | |
49 | /** |
50 | * @return Algorithm's parameter for which the algorithm runs target time milliseconds |
51 | */ |
52 | public long getParameter() { |
53 | return parameter; |
54 | } |
55 | |
56 | public String toString() { |
57 | return AbstractDemandStrategy.formatDuration(targetTime) + "\t | \t" + parameter; |
58 | } |
59 | } |
60 | |
61 | /** |
62 | * Class representing the calibration table. Stores a collection of calibration entries. |
63 | * |
64 | * @author Tobias Denker, Anne Koziolek, Steffen Becker, Thomas Zolynski |
65 | */ |
66 | public class CalibrationTable { |
67 | |
68 | /** Default number of tuples <targetTime, parameter> to store in the calibration table */ |
69 | public static final int DEFAULT_CALIBRATION_TABLE_SIZE = 11; |
70 | |
71 | protected CalibrationEntry[] table; |
72 | |
73 | private static Logger logger = Logger.getLogger(AbstractDemandStrategy.class.getName()); |
74 | |
75 | /** |
76 | * Private constructor. Used when created by loading an existing calibration table. |
77 | */ |
78 | public CalibrationTable() { |
79 | table = new CalibrationEntry[DEFAULT_CALIBRATION_TABLE_SIZE]; |
80 | } |
81 | |
82 | /** |
83 | * Constructor. New calibration table with given size. |
84 | * |
85 | * @param tableSize size of the calibration table |
86 | */ |
87 | public CalibrationTable(int tableSize) { |
88 | table = new CalibrationEntry[tableSize]; |
89 | } |
90 | |
91 | /** |
92 | * Loads calibration from config file |
93 | * @return The loaded calibration file or null if the file could not be loaded |
94 | */ |
95 | public static CalibrationTable load(File configFile) { |
96 | CalibrationTable calibrationTable = null; |
97 | |
98 | // tests whether the calibration file exists and can be loaded |
99 | if (configFile.exists()) { |
100 | logger.debug("Loaded calibration from '" + configFile + "'"); |
101 | |
102 | calibrationTable = new CalibrationTable(); |
103 | |
104 | InputStream fis = null; |
105 | try { |
106 | fis = new FileInputStream(configFile); |
107 | ObjectInputStream o = new ObjectInputStream(fis); |
108 | calibrationTable.setTable((CalibrationEntry[]) o.readObject()); |
109 | } catch (IOException e) { |
110 | logger.error("Error while loading " + configFile, e); |
111 | |
112 | } catch (ClassNotFoundException e) { |
113 | logger.error("Error while reading " + configFile, e); |
114 | |
115 | } catch (Exception e) { |
116 | logger.error("Error while reading " + configFile, e); |
117 | |
118 | } finally { |
119 | try { |
120 | fis.close(); |
121 | } catch (Exception e) { |
122 | } |
123 | } |
124 | |
125 | } else { |
126 | logger.debug(configFile + " not existing yet"); |
127 | } |
128 | |
129 | return calibrationTable; |
130 | } |
131 | |
132 | /** |
133 | * Saves calibration to config file. Config file uses a Java object stream to serialise the |
134 | * calibration table. |
135 | */ |
136 | public void save(File configFile) { |
137 | logger.info("Saving calibration to '" + configFile + "'"); |
138 | OutputStream fos = null; |
139 | try { |
140 | fos = new FileOutputStream(configFile); |
141 | |
142 | ObjectOutputStream o = new ObjectOutputStream(fos); |
143 | o.writeObject(table); |
144 | |
145 | } catch (IOException e) { |
146 | logger.error("Error while writing calibration data", e); |
147 | } finally { |
148 | try { |
149 | fos.close(); |
150 | } catch (Exception e) { |
151 | } |
152 | } |
153 | } |
154 | |
155 | private void setTable(CalibrationEntry[] table) { |
156 | this.table = table; |
157 | } |
158 | |
159 | /** |
160 | * Returns the calibration entry for given number. |
161 | * |
162 | * @param entryNumber |
163 | * @return |
164 | */ |
165 | public CalibrationEntry getEntry(int entryNumber) { |
166 | return table[entryNumber]; |
167 | } |
168 | |
169 | /** |
170 | * Creates a new calibration entry. |
171 | * |
172 | * @param entryNumber entry number (position in table) |
173 | * @param targetTime |
174 | * @param parameter |
175 | */ |
176 | public void addEntry(int entryNumber, Amount<Duration> targetTime, long parameter) { |
177 | table[entryNumber] = new CalibrationEntry(targetTime, parameter); |
178 | } |
179 | |
180 | /** |
181 | * Returns the size of the calibration table. |
182 | * |
183 | * @return |
184 | */ |
185 | public int size() { |
186 | return table.length; |
187 | } |
188 | |
189 | } |