1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 package org.jrobin.core;
27
28 import java.io.IOException;
29
30
31
32
33
34
35
36
37
38
39
40
41
42 public class Robin implements RrdUpdater {
43 private Archive parentArc;
44 private RrdInt pointer;
45 private RrdDoubleArray values;
46 private int rows;
47
48 Robin(Archive parentArc, int rows, boolean shouldInitialize) throws IOException {
49 this.parentArc = parentArc;
50 this.pointer = new RrdInt(this);
51 this.values = new RrdDoubleArray(this, rows);
52 this.rows = rows;
53 if (shouldInitialize) {
54 pointer.set(0);
55 values.set(0, Double.NaN, rows);
56 }
57 }
58
59
60
61
62
63
64
65 public double[] getValues() throws IOException {
66 return getValues(0, rows);
67 }
68
69
70 void store(double newValue) throws IOException {
71 int position = pointer.get();
72 values.set(position, newValue);
73 pointer.set((position + 1) % rows);
74 }
75
76
77 void bulkStore(double newValue, int bulkCount) throws IOException {
78 assert bulkCount <= rows: "Invalid number of bulk updates: " + bulkCount +
79 " rows=" + rows;
80 int position = pointer.get();
81
82 int tailUpdateCount = Math.min(rows - position, bulkCount);
83 values.set(position, newValue, tailUpdateCount);
84 pointer.set((position + tailUpdateCount) % rows);
85
86 int headUpdateCount = bulkCount - tailUpdateCount;
87 if (headUpdateCount > 0) {
88 values.set(0, newValue, headUpdateCount);
89 pointer.set(headUpdateCount);
90 }
91 }
92
93 void update(double[] newValues) throws IOException {
94 assert rows == newValues.length: "Invalid number of robin values supplied (" + newValues.length +
95 "), exactly " + rows + " needed";
96 pointer.set(0);
97 values.writeDouble(0, newValues);
98 }
99
100
101
102
103
104
105
106
107
108 public void setValues(double[] newValues) throws IOException, RrdException {
109 if (rows != newValues.length) {
110 throw new RrdException("Invalid number of robin values supplied (" + newValues.length +
111 "), exactly " + rows + " needed");
112 }
113 update(newValues);
114 }
115
116
117
118
119
120
121
122 public void setValues(double newValue) throws IOException {
123 double[] values = new double[rows];
124 for (int i = 0; i < values.length; i++) {
125 values[i] = newValue;
126 }
127 update(values);
128 }
129
130 String dump() throws IOException {
131 StringBuffer buffer = new StringBuffer("Robin " + pointer.get() + "/" + rows + ": ");
132 double[] values = getValues();
133 for (double value : values) {
134 buffer.append(Util.formatDouble(value, true)).append(" ");
135 }
136 buffer.append("\n");
137 return buffer.toString();
138 }
139
140
141
142
143
144
145
146
147 public double getValue(int index) throws IOException {
148 int arrayIndex = (pointer.get() + index) % rows;
149 return values.get(arrayIndex);
150 }
151
152
153
154
155
156
157
158
159 public void setValue(int index, double value) throws IOException {
160 int arrayIndex = (pointer.get() + index) % rows;
161 values.set(arrayIndex, value);
162 }
163
164 double[] getValues(int index, int count) throws IOException {
165 assert count <= rows: "Too many values requested: " + count + " rows=" + rows;
166 int startIndex = (pointer.get() + index) % rows;
167 int tailReadCount = Math.min(rows - startIndex, count);
168 double[] tailValues = values.get(startIndex, tailReadCount);
169 if (tailReadCount < count) {
170 int headReadCount = count - tailReadCount;
171 double[] headValues = values.get(0, headReadCount);
172 double[] values = new double[count];
173 int k = 0;
174 for (double tailValue : tailValues) {
175 values[k++] = tailValue;
176 }
177 for (double headValue : headValues) {
178 values[k++] = headValue;
179 }
180 return values;
181 }
182 else {
183 return tailValues;
184 }
185 }
186
187
188
189
190
191
192 public Archive getParent() {
193 return parentArc;
194 }
195
196
197
198
199
200
201 public int getSize() {
202 return rows;
203 }
204
205
206
207
208
209
210
211
212 public void copyStateTo(RrdUpdater other) throws IOException, RrdException {
213 if (!(other instanceof Robin)) {
214 throw new RrdException(
215 "Cannot copy Robin object to " + other.getClass().getName());
216 }
217 Robin robin = (Robin) other;
218 int rowsDiff = rows - robin.rows;
219 if (rowsDiff == 0) {
220
221 robin.pointer.set(pointer.get());
222 robin.values.writeBytes(values.readBytes());
223 }
224 else {
225
226 for (int i = 0; i < robin.rows; i++) {
227 int j = i + rowsDiff;
228 robin.store(j >= 0 ? getValue(j) : Double.NaN);
229 }
230 }
231 }
232
233
234
235
236
237
238
239
240
241
242 public void filterValues(double minValue, double maxValue) throws IOException {
243 for (int i = 0; i < rows; i++) {
244 double value = values.get(i);
245 if (!Double.isNaN(minValue) && !Double.isNaN(value) && minValue > value) {
246 values.set(i, Double.NaN);
247 }
248 if (!Double.isNaN(maxValue) && !Double.isNaN(value) && maxValue < value) {
249 values.set(i, Double.NaN);
250 }
251 }
252 }
253
254
255
256
257
258
259
260 public RrdBackend getRrdBackend() {
261 return parentArc.getRrdBackend();
262 }
263
264
265
266
267
268
269 public RrdAllocator getRrdAllocator() {
270 return parentArc.getRrdAllocator();
271 }
272 }