1 9 package org.jrobin.core.jrrd; 10 11 import java.io.*; 12 import java.util.*; 13 import java.text.NumberFormat ; 14 import java.text.DecimalFormat ; 15 16 24 public class RRDatabase { 25 26 RRDFile rrdFile; 27 28 private String name; 30 Header header; 31 ArrayList dataSources; 32 ArrayList archives; 33 Date lastUpdate; 34 35 41 public RRDatabase(String name) throws IOException { 42 this(new File(name)); 43 } 44 45 51 public RRDatabase(File file) throws IOException { 52 53 name = file.getName(); 54 rrdFile = new RRDFile(file); 55 header = new Header(rrdFile); 56 57 dataSources = new ArrayList(); 59 60 for (int i = 0; i < header.dsCount; i++) { 61 DataSource ds = new DataSource(rrdFile); 62 63 dataSources.add(ds); 64 } 65 66 archives = new ArrayList(); 68 69 for (int i = 0; i < header.rraCount; i++) { 70 Archive archive = new Archive(this); 71 72 archives.add(archive); 73 } 74 75 rrdFile.align(); 76 77 lastUpdate = new Date((long) (rrdFile.readInt()) * 1000); 78 79 for (int i = 0; i < header.dsCount; i++) { 81 DataSource ds = (DataSource) dataSources.get(i); 82 83 ds.loadPDPStatusBlock(rrdFile); 84 } 85 86 for (int i = 0; i < header.rraCount; i++) { 88 Archive archive = (Archive) archives.get(i); 89 90 archive.loadCDPStatusBlocks(rrdFile, header.dsCount); 91 } 92 93 for (int i = 0; i < header.rraCount; i++) { 95 Archive archive = (Archive) archives.get(i); 96 97 archive.loadCurrentRow(rrdFile); 98 } 99 100 for (int i = 0; i < header.rraCount; i++) { 102 Archive archive = (Archive) archives.get(i); 103 104 archive.loadData(rrdFile, header.dsCount); 105 } 106 } 107 108 113 public Header getHeader() { 114 return header; 115 } 116 117 124 public Date getLastUpdate() { 125 return lastUpdate; 126 } 127 128 134 public DataSource getDataSource(int index) { 135 return (DataSource) dataSources.get(index); 136 } 137 138 143 public Iterator getDataSources() { 144 return dataSources.iterator(); 145 } 146 147 153 public Archive getArchive(int index) { 154 return (Archive) archives.get(index); 155 } 156 157 162 public Iterator getArchives() { 163 return archives.iterator(); 164 } 165 166 171 public int getNumArchives() { 172 return header.rraCount; 173 } 174 175 184 public Iterator getArchives(ConsolidationFunctionType type) { 185 return getArchiveList(type).iterator(); 186 } 187 188 ArrayList getArchiveList(ConsolidationFunctionType type) { 189 190 ArrayList subset = new ArrayList(); 191 192 for (int i = 0; i < archives.size(); i++) { 193 Archive archive = (Archive) archives.get(i); 194 195 if (archive.getType().equals(type)) { 196 subset.add(archive); 197 } 198 } 199 200 return subset; 201 } 202 203 208 public void close() throws IOException { 209 rrdFile.close(); 210 } 211 212 219 public void printInfo(PrintStream s) { 220 221 NumberFormat numberFormat = new DecimalFormat ("0.0000000000E0"); 222 223 printInfo(s, numberFormat); 224 } 225 226 237 public DataChunk getData(ConsolidationFunctionType type) 238 throws RRDException, IOException { 239 return getData(type, 1L); 240 } 241 242 254 public DataChunk getData(ConsolidationFunctionType type, long step) 255 throws RRDException, IOException { 256 257 ArrayList possibleArchives = getArchiveList(type); 258 259 if (possibleArchives.size() == 0) { 260 throw new RRDException("Database does not contain an Archive of consolidation function type " 261 + type); 262 } 263 264 Calendar endCal = Calendar.getInstance(); 265 266 endCal.set(Calendar.MILLISECOND, 0); 267 268 Calendar startCal = (Calendar) endCal.clone(); 269 270 startCal.add(Calendar.DATE, -1); 271 272 long end = endCal.getTime().getTime() / 1000; 273 long start = startCal.getTime().getTime() / 1000; 274 Archive archive = findBestArchive(start, end, step, possibleArchives); 275 276 step = header.pdpStep * archive.pdpCount; 278 start -= start % step; 279 280 if (end % step != 0) { 281 end += step - end % step; 282 } 283 284 int rows = (int) ((end - start) / step + 1); 285 286 289 long lastUpdateLong = lastUpdate.getTime() / 1000; 292 long archiveEndTime = lastUpdateLong - (lastUpdateLong % step); 293 long archiveStartTime = archiveEndTime - (step * (archive.rowCount - 1)); 294 int startOffset = (int) ((start - archiveStartTime) / step); 295 int endOffset = (int) ((archiveEndTime - end) / step); 296 297 301 DataChunk chunk = new DataChunk(start, startOffset, endOffset, step, 302 header.dsCount, rows); 303 304 archive.loadData(chunk); 305 306 return chunk; 307 } 308 309 313 private Archive findBestArchive(long start, long end, long step, 314 ArrayList archives) { 315 316 Archive archive = null; 317 Archive bestFullArchive = null; 318 Archive bestPartialArchive = null; 319 long lastUpdateLong = lastUpdate.getTime() / 1000; 320 int firstPart = 1; 321 int firstFull = 1; 322 long bestMatch = 0; 323 long bestStepDiff = 0; 325 long tmpStepDiff = 0; 326 327 for (int i = 0; i < archives.size(); i++) { 328 archive = (Archive) archives.get(i); 329 330 long calEnd = lastUpdateLong 331 - (lastUpdateLong 332 % (archive.pdpCount * header.pdpStep)); 333 long calStart = calEnd 334 - (archive.pdpCount * archive.rowCount 335 * header.pdpStep); 336 long fullMatch = end - start; 337 338 if ((calEnd >= end) && (calStart < start)) { tmpStepDiff = Math.abs(step - (header.pdpStep * archive.pdpCount)); 340 341 if ((firstFull != 0) || (tmpStepDiff < bestStepDiff)) { 342 firstFull = 0; 343 bestStepDiff = tmpStepDiff; 344 bestFullArchive = archive; 345 } 346 } else { long tmpMatch = fullMatch; 348 349 if (calStart > start) { 350 tmpMatch -= calStart - start; 351 } 352 353 if (calEnd < end) { 354 tmpMatch -= end - calEnd; 355 } 356 357 if ((firstPart != 0) || (bestMatch < tmpMatch)) { 358 firstPart = 0; 359 bestMatch = tmpMatch; 360 bestPartialArchive = archive; 361 } 362 } 363 } 364 365 if (firstFull == 0) { 368 archive = bestFullArchive; 369 } else if (firstPart == 0) { 370 archive = bestPartialArchive; 371 } 372 373 return archive; 374 } 375 376 385 public void printInfo(PrintStream s, NumberFormat numberFormat) { 386 387 s.print("filename = \""); 388 s.print(name); 389 s.println("\""); 390 s.print("rrd_version = \""); 391 s.print(header.version); 392 s.println("\""); 393 s.print("step = "); 394 s.println(header.pdpStep); 395 s.print("last_update = "); 396 s.println(lastUpdate.getTime() / 1000); 397 398 for (Iterator i = dataSources.iterator(); i.hasNext();) { 399 DataSource ds = (DataSource) i.next(); 400 401 ds.printInfo(s, numberFormat); 402 } 403 404 int index = 0; 405 406 for (Iterator i = archives.iterator(); i.hasNext();) { 407 Archive archive = (Archive) i.next(); 408 409 archive.printInfo(s, numberFormat, index++); 410 } 411 } 412 413 420 public void toXml(PrintStream s) { 421 422 s.println("<!--"); 423 s.println(" -- Round Robin RRDatabase Dump "); 424 s.println(" -- Generated by jRRD <ciaran@codeloop.com>"); 425 s.println(" -->"); 426 s.println("<rrd>"); 427 s.print("\t<version> "); 428 s.print(header.version); 429 s.println(" </version>"); 430 s.print("\t<step> "); 431 s.print(header.pdpStep); 432 s.println(" </step> <!-- Seconds -->"); 433 s.print("\t<lastupdate> "); 434 s.print(lastUpdate.getTime() / 1000); 435 s.print(" </lastupdate> <!-- "); 436 s.print(lastUpdate.toString()); 437 s.println(" -->"); 438 s.println(); 439 440 for (int i = 0; i < header.dsCount; i++) { 441 DataSource ds = (DataSource) dataSources.get(i); 442 443 ds.toXml(s); 444 } 445 446 s.println("<!-- Round Robin Archives -->"); 447 448 for (int i = 0; i < header.rraCount; i++) { 449 Archive archive = (Archive) archives.get(i); 450 451 archive.toXml(s); 452 } 453 454 s.println("</rrd>"); 455 } 456 457 462 public String toString() { 463 464 StringBuffer sb = new StringBuffer ("\n"); 465 466 sb.append(header.toString()); 467 468 for (Iterator i = dataSources.iterator(); i.hasNext();) { 469 DataSource ds = (DataSource) i.next(); 470 471 sb.append("\n\t"); 472 sb.append(ds.toString()); 473 } 474 475 for (Iterator i = archives.iterator(); i.hasNext();) { 476 Archive archive = (Archive) i.next(); 477 478 sb.append("\n\t"); 479 sb.append(archive.toString()); 480 } 481 482 return sb.toString(); 483 } 484 } 485 | Popular Tags |