KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jrobin > core > jrrd > Archive


1 /*
2  * Copyright (C) 2001 Ciaran Treanor <ciaran@codeloop.com>
3  *
4  * Distributable under GPL license.
5  * See terms of license at gnu.org.
6  *
7  * $Id: Archive.java,v 1.1 2004/07/22 09:34:10 saxon64 Exp $
8  */

9 package org.jrobin.core.jrrd;
10
11 import java.io.IOException JavaDoc;
12 import java.io.PrintStream JavaDoc;
13 import java.text.*;
14 import java.util.*;
15
16 /**
17  * Instances of this class model an archive section of an RRD file.
18  *
19  * @author <a HREF="mailto:ciaran@codeloop.com">Ciaran Treanor</a>
20  * @version $Revision: 1.1 $
21  */

22 public class Archive {
23
24     RRDatabase db;
25     long offset;
26     long dataOffset;
27     long size;
28     ConsolidationFunctionType type;
29     int rowCount;
30     int pdpCount;
31     double xff;
32     ArrayList cdpStatusBlocks;
33     int currentRow;
34
35     private double[][] values;
36
37     Archive(RRDatabase db) throws IOException JavaDoc {
38
39         this.db = db;
40
41         RRDFile file = db.rrdFile;
42
43         offset = file.getFilePointer();
44         type =
45                 ConsolidationFunctionType.get(file.readString(Constants.CF_NAM_SIZE));
46         rowCount = file.readInt();
47         pdpCount = file.readInt();
48
49         file.align();
50
51         xff = file.readDouble();
52
53         // Skip rest of rra_def_t.par[]
54
file.align();
55         file.skipBytes(72);
56
57         size = file.getFilePointer() - offset;
58     }
59
60     /**
61      * Returns the type of function used to calculate the consolidated data point.
62      *
63      * @return the type of function used to calculate the consolidated data point.
64      */

65     public ConsolidationFunctionType getType() {
66         return type;
67     }
68
69     void loadCDPStatusBlocks(RRDFile file, int numBlocks) throws IOException JavaDoc {
70
71         cdpStatusBlocks = new ArrayList();
72
73         for (int i = 0; i < numBlocks; i++) {
74             cdpStatusBlocks.add(new CDPStatusBlock(file));
75         }
76     }
77
78     /**
79      * Returns the <code>CDPStatusBlock</code> at the specified position in this archive.
80      *
81      * @param index index of <code>CDPStatusBlock</code> to return.
82      * @return the <code>CDPStatusBlock</code> at the specified position in this archive.
83      */

84     public CDPStatusBlock getCDPStatusBlock(int index) {
85         return (CDPStatusBlock) cdpStatusBlocks.get(index);
86     }
87
88     /**
89      * Returns an iterator over the CDP status blocks in this archive in proper sequence.
90      *
91      * @return an iterator over the CDP status blocks in this archive in proper sequence.
92      * @see CDPStatusBlock
93      */

94     public Iterator getCDPStatusBlocks() {
95         return cdpStatusBlocks.iterator();
96     }
97
98     void loadCurrentRow(RRDFile file) throws IOException JavaDoc {
99         currentRow = file.readInt();
100     }
101
102     void loadData(RRDFile file, int dsCount) throws IOException JavaDoc {
103
104         dataOffset = file.getFilePointer();
105
106         // Skip over the data to position ourselves at the start of the next archive
107
file.skipBytes(8 * rowCount * dsCount);
108     }
109
110     DataChunk loadData(DataChunk chunk) throws IOException JavaDoc {
111
112         Calendar end = Calendar.getInstance();
113         Calendar start = (Calendar) end.clone();
114
115         start.add(Calendar.DATE, -1);
116
117         loadData(chunk, start.getTime().getTime() / 1000,
118                 end.getTime().getTime() / 1000);
119         return chunk;
120     }
121
122     void loadData(DataChunk chunk, long startTime, long endTime)
123             throws IOException JavaDoc {
124
125         long pointer;
126
127         if (chunk.start < 0) {
128             pointer = currentRow + 1;
129         } else {
130             pointer = currentRow + chunk.start + 1;
131         }
132
133         db.rrdFile.ras.seek(dataOffset + (pointer * 8));
134         //cat.debug("Archive Base: " + dataOffset + " Archive Pointer: " + pointer);
135
//cat.debug("Start Offset: " + chunk.start + " End Offset: "
136
// + (rowCount - chunk.end));
137

138         double[][] data = chunk.data;
139
140         /*
141          * This is also terrible - cleanup - CT
142          */

143         int row = 0;
144         for (int i = chunk.start; i < rowCount - chunk.end; i++, row++) {
145             if (i < 0) { // no valid data yet
146
for (int ii = 0; ii < chunk.dsCount; ii++) {
147                     data[row][ii] = Double.NaN;
148                 }
149             } else if (i >= rowCount) { // past valid data area
150
for (int ii = 0; ii < chunk.dsCount; ii++) {
151                     data[row][ii] = Double.NaN;
152                 }
153             } else { // inside the valid are but the pointer has to be wrapped
154
if (pointer >= rowCount) {
155                     pointer -= rowCount;
156
157                     db.rrdFile.ras.seek(dataOffset + (pointer * 8));
158                 }
159
160                 for (int ii = 0; ii < chunk.dsCount; ii++) {
161                     data[row][ii] = db.rrdFile.readDouble();
162                 }
163
164                 pointer++;
165             }
166         }
167     }
168
169     void printInfo(PrintStream JavaDoc s, NumberFormat numberFormat, int index) {
170
171         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("rra[");
172
173         sb.append(index);
174         s.print(sb);
175         s.print("].cf = \"");
176         s.print(type);
177         s.println("\"");
178         s.print(sb);
179         s.print("].rows = ");
180         s.println(rowCount);
181         s.print(sb);
182         s.print("].pdp_per_row = ");
183         s.println(pdpCount);
184         s.print(sb);
185         s.print("].xff = ");
186         s.println(xff);
187         sb.append("].cdp_prep[");
188
189         int cdpIndex = 0;
190
191         for (Iterator i = cdpStatusBlocks.iterator(); i.hasNext();) {
192             CDPStatusBlock cdp = (CDPStatusBlock) i.next();
193
194             s.print(sb);
195             s.print(cdpIndex);
196             s.print("].value = ");
197
198             double value = cdp.value;
199
200             s.println(Double.isNaN(value)
201                     ? "NaN"
202                     : numberFormat.format(value));
203             s.print(sb);
204             s.print(cdpIndex++);
205             s.print("].unknown_datapoints = ");
206             s.println(cdp.unknownDatapoints);
207         }
208     }
209
210     void toXml(PrintStream JavaDoc s) {
211
212         try {
213             s.println("\t<rra>");
214             s.print("\t\t<cf> ");
215             s.print(type);
216             s.println(" </cf>");
217             s.print("\t\t<pdp_per_row> ");
218             s.print(pdpCount);
219             s.print(" </pdp_per_row> <!-- ");
220             s.print(db.header.pdpStep * pdpCount);
221             s.println(" seconds -->");
222             s.print("\t\t<xff> ");
223             s.print(xff);
224             s.println(" </xff>");
225             s.println();
226             s.println("\t\t<cdp_prep>");
227
228             for (int i = 0; i < cdpStatusBlocks.size(); i++) {
229                 ((CDPStatusBlock) cdpStatusBlocks.get(i)).toXml(s);
230             }
231
232             s.println("\t\t</cdp_prep>");
233             s.println("\t\t<database>");
234
235             long timer = -(rowCount - 1);
236             int counter = 0;
237             int row = currentRow;
238
239             db.rrdFile.ras.seek(dataOffset + (row + 1) * 16);
240
241             long lastUpdate = db.lastUpdate.getTime() / 1000;
242             int pdpStep = db.header.pdpStep;
243             NumberFormat numberFormat = new DecimalFormat("0.0000000000E0");
244             SimpleDateFormat dateFormat =
245                     new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z");
246
247             while (counter++ < rowCount) {
248                 row++;
249
250                 if (row == rowCount) {
251                     row = 0;
252
253                     db.rrdFile.ras.seek(dataOffset);
254                 }
255
256                 long now = (lastUpdate - lastUpdate % (pdpCount * pdpStep))
257                         + (timer * pdpCount * pdpStep);
258
259                 timer++;
260
261                 s.print("\t\t\t<!-- ");
262                 s.print(dateFormat.format(new Date(now * 1000)));
263                 s.print(" / ");
264                 s.print(now);
265                 s.print(" --> ");
266
267                 for (int col = 0; col < db.header.dsCount; col++) {
268                     s.print("<v> ");
269
270                     double value = db.rrdFile.readDouble();
271
272                     // NumberFormat doesn't know how to handle NaN
273
if (Double.isNaN(value)) {
274                         s.print("NaN");
275                     } else {
276                         s.print(numberFormat.format(value));
277                     }
278
279                     s.print(" </v>");
280                 }
281
282                 s.println("</row>");
283             }
284
285             s.println("\t\t</database>");
286             s.println("\t</rra>");
287         } catch (IOException JavaDoc e) { // Is the best thing to do here?
288
throw new RuntimeException JavaDoc(e.getMessage());
289         }
290     }
291
292     public double[][] getValues() throws IOException JavaDoc {
293         if (values != null) {
294             return values;
295         }
296         values = new double[db.header.dsCount][rowCount];
297         int row = currentRow;
298         db.rrdFile.ras.seek(dataOffset + (row + 1) * 16);
299         for (int counter = 0; counter < rowCount; counter++) {
300             row++;
301             if (row == rowCount) {
302                 row = 0;
303                 db.rrdFile.ras.seek(dataOffset);
304             }
305             for (int col = 0; col < db.header.dsCount; col++) {
306                 double value = db.rrdFile.readDouble();
307                 values[col][counter] = value;
308             }
309         }
310         return values;
311     }
312
313     /**
314      * Returns the number of primary data points required for a consolidated
315      * data point in this archive.
316      *
317      * @return the number of primary data points required for a consolidated
318      * data point in this archive.
319      */

320     public int getPdpCount() {
321         return pdpCount;
322     }
323
324     /**
325      * Returns the number of entries in this archive.
326      *
327      * @return the number of entries in this archive.
328      */

329     public int getRowCount() {
330         return rowCount;
331     }
332
333     /**
334      * Returns the X-Files Factor for this archive.
335      *
336      * @return the X-Files Factor for this archive.
337      */

338     public double getXff() {
339         return xff;
340     }
341
342     /**
343      * Returns a summary the contents of this archive.
344      *
345      * @return a summary of the information contained in this archive.
346      */

347     public String JavaDoc toString() {
348
349         StringBuffer JavaDoc sb = new StringBuffer JavaDoc("[Archive: OFFSET=0x");
350
351         sb.append(Long.toHexString(offset));
352         sb.append(", SIZE=0x");
353         sb.append(Long.toHexString(size));
354         sb.append(", type=");
355         sb.append(type);
356         sb.append(", rowCount=");
357         sb.append(rowCount);
358         sb.append(", pdpCount=");
359         sb.append(pdpCount);
360         sb.append(", xff=");
361         sb.append(xff);
362         sb.append(", currentRow=");
363         sb.append(currentRow);
364         sb.append("]");
365
366         for (Iterator i = cdpStatusBlocks.iterator(); i.hasNext();) {
367             CDPStatusBlock cdp = (CDPStatusBlock) i.next();
368
369             sb.append("\n\t\t");
370             sb.append(cdp.toString());
371         }
372
373         return sb.toString();
374     }
375 }
376
Popular Tags