commit 9a5d33d7b2f76959ce162e83e831f7b8953ec892 Author: Karsten Loesing karsten.loesing@gmx.net Date: Tue Apr 8 23:57:10 2014 +0200
Move (de-)serialization code into UptimeStatus. --- src/org/torproject/onionoo/Document.java | 10 ++ src/org/torproject/onionoo/DocumentStore.java | 24 ++++ src/org/torproject/onionoo/UptimeDataWriter.java | 151 +++++----------------- src/org/torproject/onionoo/UptimeStatus.java | 116 +++++++++++++++++ 4 files changed, 183 insertions(+), 118 deletions(-)
diff --git a/src/org/torproject/onionoo/Document.java b/src/org/torproject/onionoo/Document.java index 9730d66..f0fac2c 100644 --- a/src/org/torproject/onionoo/Document.java +++ b/src/org/torproject/onionoo/Document.java @@ -3,6 +3,16 @@ package org.torproject.onionoo;
abstract class Document { + transient String documentString; + + public void fromDocumentString(String documentString) { + /* Subclasses may override this method to parse documentString. */ + } + + public String toDocumentString() { + /* Subclasses may override this method to write documentString. */ + return null; + } }
diff --git a/src/org/torproject/onionoo/DocumentStore.java b/src/org/torproject/onionoo/DocumentStore.java index 519b4f2..f786d01 100644 --- a/src/org/torproject/onionoo/DocumentStore.java +++ b/src/org/torproject/onionoo/DocumentStore.java @@ -196,6 +196,8 @@ public class DocumentStore { document instanceof UptimeDocument) { Gson gson = new Gson(); documentString = gson.toJson(this); + } else if (document instanceof UptimeStatus) { + documentString = document.toDocumentString(); } else { System.err.println("Serializing is not supported for type " + document.getClass().getName() + "."); @@ -286,6 +288,8 @@ public class DocumentStore { documentType.equals(UptimeDocument.class)) { return this.retrieveParsedDocumentFile(documentType, documentString); + } else if (documentType.equals(UptimeStatus.class)) { + return this.retrieveParsedStatusFile(documentType, documentString); } else { System.err.println("Parsing is not supported for type " + documentType.getName() + "."); @@ -293,6 +297,26 @@ public class DocumentStore { return result; }
+ private <T extends Document> T retrieveParsedStatusFile( + Class<T> documentType, String documentString) { + T result = null; + try { + result = documentType.newInstance(); + result.fromDocumentString(documentString); + } catch (InstantiationException e) { + /* Handle below. */ + e.printStackTrace(); + } catch (IllegalAccessException e) { + /* Handle below. */ + e.printStackTrace(); + } + if (result == null) { + System.err.println("Could not initialize parsed status file of " + + "type " + documentType.getName() + "."); + } + return result; + } + private <T extends Document> T retrieveParsedDocumentFile( Class<T> documentType, String documentString) { T result = null; diff --git a/src/org/torproject/onionoo/UptimeDataWriter.java b/src/org/torproject/onionoo/UptimeDataWriter.java index 4692b18..a2b2d29 100644 --- a/src/org/torproject/onionoo/UptimeDataWriter.java +++ b/src/org/torproject/onionoo/UptimeDataWriter.java @@ -2,13 +2,11 @@ * See LICENSE for licensing information */ package org.torproject.onionoo;
-import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.Scanner; import java.util.SortedMap; import java.util.SortedSet; import java.util.TimeZone; @@ -127,112 +125,26 @@ public class UptimeDataWriter implements DescriptorListener, Logger.printStatusTime("Updated uptime status files"); }
- private static class UptimeHistory - implements Comparable<UptimeHistory> { - private boolean relay; - private long startMillis; - private int uptimeHours; - private UptimeHistory(boolean relay, long startMillis, - int uptimeHours) { - this.relay = relay; - this.startMillis = startMillis; - this.uptimeHours = uptimeHours; - } - public static UptimeHistory fromString(String uptimeHistoryString) { - String[] parts = uptimeHistoryString.split(" ", 3); - if (parts.length != 3) { - return null; - } - boolean relay = false; - if (parts[0].equals("r")) { - relay = true; - } else if (!parts[0].equals("b")) { - return null; - } - long startMillis = -1L; - SimpleDateFormat dateHourFormat = new SimpleDateFormat( - "yyyy-MM-dd-HH"); - dateHourFormat.setLenient(false); - dateHourFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - try { - startMillis = dateHourFormat.parse(parts[1]).getTime(); - } catch (ParseException e) { - return null; - } - int uptimeHours = -1; - try { - uptimeHours = Integer.parseInt(parts[2]); - } catch (NumberFormatException e) { - return null; - } - return new UptimeHistory(relay, startMillis, uptimeHours); - } - public String toString() { - StringBuilder sb = new StringBuilder(); - SimpleDateFormat dateHourFormat = new SimpleDateFormat( - "yyyy-MM-dd-HH"); - dateHourFormat.setLenient(false); - dateHourFormat.setTimeZone(TimeZone.getTimeZone("UTC")); - sb.append(this.relay ? "r" : "b"); - sb.append(" " + dateHourFormat.format(this.startMillis)); - sb.append(" " + String.format("%d", this.uptimeHours)); - return sb.toString(); - } - public void addUptime(UptimeHistory other) { - this.uptimeHours += other.uptimeHours; - if (this.startMillis > other.startMillis) { - this.startMillis = other.startMillis; - } - } - public int compareTo(UptimeHistory other) { - if (this.relay && !other.relay) { - return -1; - } else if (!this.relay && other.relay) { - return 1; - } - return this.startMillis < other.startMillis ? -1 : - this.startMillis > other.startMillis ? 1 : 0; - } - public boolean equals(Object other) { - return other instanceof UptimeHistory && - this.relay == ((UptimeHistory) other).relay && - this.startMillis == ((UptimeHistory) other).startMillis; - } - } - private void updateStatus(boolean relay, String fingerprint, SortedSet<Long> newUptimeHours) { - SortedSet<UptimeHistory> history = this.readHistory(fingerprint); - this.addToHistory(history, relay, newUptimeHours); - history = this.compressHistory(history); - this.writeHistory(fingerprint, history); + UptimeStatus uptimeStatus = this.readHistory(fingerprint); + if (uptimeStatus == null) { + uptimeStatus = new UptimeStatus(); + } + this.addToHistory(uptimeStatus, relay, newUptimeHours); + this.compressHistory(uptimeStatus); + this.writeHistory(fingerprint, uptimeStatus); }
- private SortedSet<UptimeHistory> readHistory(String fingerprint) { - SortedSet<UptimeHistory> history = new TreeSet<UptimeHistory>(); - UptimeStatus uptimeStatus = fingerprint == null ? - documentStore.retrieve(UptimeStatus.class, false) : - documentStore.retrieve(UptimeStatus.class, false, fingerprint); - if (uptimeStatus != null) { - Scanner s = new Scanner(uptimeStatus.documentString); - while (s.hasNextLine()) { - String line = s.nextLine(); - UptimeHistory parsedLine = UptimeHistory.fromString(line); - if (parsedLine != null) { - history.add(parsedLine); - } else { - System.err.println("Could not parse uptime history line '" - + line + "' for fingerprint '" + fingerprint - + "'. Skipping."); - } - } - s.close(); - } - return history; + private UptimeStatus readHistory(String fingerprint) { + return fingerprint == null ? + documentStore.retrieve(UptimeStatus.class, true) : + documentStore.retrieve(UptimeStatus.class, true, fingerprint); }
- private void addToHistory(SortedSet<UptimeHistory> history, - boolean relay, SortedSet<Long> newIntervals) { + private void addToHistory(UptimeStatus uptimeStatus, boolean relay, + SortedSet<Long> newIntervals) { + SortedSet<UptimeHistory> history = uptimeStatus.history; for (long startMillis : newIntervals) { UptimeHistory interval = new UptimeHistory(relay, startMillis, 1); if (!history.headSet(interval).isEmpty()) { @@ -254,8 +166,8 @@ public class UptimeDataWriter implements DescriptorListener, } }
- private SortedSet<UptimeHistory> compressHistory( - SortedSet<UptimeHistory> history) { + private void compressHistory(UptimeStatus uptimeStatus) { + SortedSet<UptimeHistory> history = uptimeStatus.history; SortedSet<UptimeHistory> compressedHistory = new TreeSet<UptimeHistory>(); UptimeHistory lastInterval = null; @@ -275,17 +187,11 @@ public class UptimeDataWriter implements DescriptorListener, if (lastInterval != null) { compressedHistory.add(lastInterval); } - return compressedHistory; + uptimeStatus.history = compressedHistory; }
private void writeHistory(String fingerprint, - SortedSet<UptimeHistory> history) { - StringBuilder sb = new StringBuilder(); - for (UptimeHistory interval : history) { - sb.append(interval.toString() + "\n"); - } - UptimeStatus uptimeStatus = new UptimeStatus(); - uptimeStatus.documentString = sb.toString(); + UptimeStatus uptimeStatus) { if (fingerprint == null) { this.documentStore.store(uptimeStatus); } else { @@ -309,7 +215,12 @@ public class UptimeDataWriter implements DescriptorListener, SortedSet<UptimeHistory> knownRelayStatuses = new TreeSet<UptimeHistory>(), knownBridgeStatuses = new TreeSet<UptimeHistory>(); - SortedSet<UptimeHistory> knownStatuses = this.readHistory(null); + UptimeStatus uptimeStatus = this.documentStore.retrieve( + UptimeStatus.class, true); + if (uptimeStatus == null) { + return; + } + SortedSet<UptimeHistory> knownStatuses = uptimeStatus.history; for (UptimeHistory status : knownStatuses) { if (status.relay) { knownRelayStatuses.add(status); @@ -328,11 +239,15 @@ public class UptimeDataWriter implements DescriptorListener,
private void updateDocument(boolean relay, String fingerprint, SortedSet<UptimeHistory> knownStatuses) { - SortedSet<UptimeHistory> history = this.readHistory(fingerprint); - UptimeDocument uptimeDocument = new UptimeDocument(); - uptimeDocument.documentString = this.formatHistoryString(relay, - fingerprint, history, knownStatuses); - this.documentStore.store(uptimeDocument, fingerprint); + UptimeStatus uptimeStatus = this.documentStore.retrieve( + UptimeStatus.class, true, fingerprint); + if (uptimeStatus != null) { + SortedSet<UptimeHistory> history = uptimeStatus.history; + UptimeDocument uptimeDocument = new UptimeDocument(); + uptimeDocument.documentString = this.formatHistoryString(relay, + fingerprint, history, knownStatuses); + this.documentStore.store(uptimeDocument, fingerprint); + } }
private String[] graphNames = new String[] { diff --git a/src/org/torproject/onionoo/UptimeStatus.java b/src/org/torproject/onionoo/UptimeStatus.java index d16c8fc..fedf1a1 100644 --- a/src/org/torproject/onionoo/UptimeStatus.java +++ b/src/org/torproject/onionoo/UptimeStatus.java @@ -1,5 +1,121 @@ +/* Copyright 2014 The Tor Project + * See LICENSE for licensing information */ package org.torproject.onionoo;
+import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Scanner; +import java.util.SortedSet; +import java.util.TimeZone; +import java.util.TreeSet; + +class UptimeHistory + implements Comparable<UptimeHistory> { + + boolean relay; + + long startMillis; + + int uptimeHours; + + UptimeHistory(boolean relay, long startMillis, + int uptimeHours) { + this.relay = relay; + this.startMillis = startMillis; + this.uptimeHours = uptimeHours; + } + + public static UptimeHistory fromString(String uptimeHistoryString) { + String[] parts = uptimeHistoryString.split(" ", 3); + if (parts.length != 3) { + return null; + } + boolean relay = false; + if (parts[0].equals("r")) { + relay = true; + } else if (!parts[0].equals("b")) { + return null; + } + long startMillis = -1L; + SimpleDateFormat dateHourFormat = new SimpleDateFormat( + "yyyy-MM-dd-HH"); + dateHourFormat.setLenient(false); + dateHourFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + try { + startMillis = dateHourFormat.parse(parts[1]).getTime(); + } catch (ParseException e) { + return null; + } + int uptimeHours = -1; + try { + uptimeHours = Integer.parseInt(parts[2]); + } catch (NumberFormatException e) { + return null; + } + return new UptimeHistory(relay, startMillis, uptimeHours); + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + SimpleDateFormat dateHourFormat = new SimpleDateFormat( + "yyyy-MM-dd-HH"); + dateHourFormat.setLenient(false); + dateHourFormat.setTimeZone(TimeZone.getTimeZone("UTC")); + sb.append(this.relay ? "r" : "b"); + sb.append(" " + dateHourFormat.format(this.startMillis)); + sb.append(" " + String.format("%d", this.uptimeHours)); + return sb.toString(); + } + + public void addUptime(UptimeHistory other) { + this.uptimeHours += other.uptimeHours; + if (this.startMillis > other.startMillis) { + this.startMillis = other.startMillis; + } + } + + public int compareTo(UptimeHistory other) { + if (this.relay && !other.relay) { + return -1; + } else if (!this.relay && other.relay) { + return 1; + } + return this.startMillis < other.startMillis ? -1 : + this.startMillis > other.startMillis ? 1 : 0; + } + + public boolean equals(Object other) { + return other instanceof UptimeHistory && + this.relay == ((UptimeHistory) other).relay && + this.startMillis == ((UptimeHistory) other).startMillis; + } +} + class UptimeStatus extends Document { + + SortedSet<UptimeHistory> history = new TreeSet<UptimeHistory>(); + + public void fromDocumentString(String documentString) { + Scanner s = new Scanner(documentString); + while (s.hasNextLine()) { + String line = s.nextLine(); + UptimeHistory parsedLine = UptimeHistory.fromString(line); + if (parsedLine != null) { + this.history.add(parsedLine); + } else { + System.err.println("Could not parse uptime history line '" + + line + "'. Skipping."); + } + } + s.close(); + } + + public String toDocumentString() { + StringBuilder sb = new StringBuilder(); + for (UptimeHistory interval : this.history) { + sb.append(interval.toString() + "\n"); + } + return sb.toString(); + } }