tor-commits
Threads by month
- ----- 2025 -----
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
February 2018
- 19 participants
- 1579 discussions

[onionoo/release] Add a comment to avoid future 'detective work'.
by karsten@torproject.org 07 Feb '18
by karsten@torproject.org 07 Feb '18
07 Feb '18
commit 70e5f3f741fa899531e0ad42e3a702db6bfcb122
Author: iwakeh <iwakeh(a)torproject.org>
Date: Wed Jan 17 19:29:14 2018 +0000
Add a comment to avoid future 'detective work'.
---
src/main/java/org/torproject/onionoo/server/NodeIndexer.java | 1 +
1 file changed, 1 insertion(+)
diff --git a/src/main/java/org/torproject/onionoo/server/NodeIndexer.java b/src/main/java/org/torproject/onionoo/server/NodeIndexer.java
index 69baa53..e95eda9 100644
--- a/src/main/java/org/torproject/onionoo/server/NodeIndexer.java
+++ b/src/main/java/org/torproject/onionoo/server/NodeIndexer.java
@@ -125,6 +125,7 @@ public class NodeIndexer implements ServletContextListener, Runnable {
indexerThread.interrupt();
}
+ /* specialTime is only used for testing, see ResourceServletTest */
private long specialTime = -1L;
private void indexNodeStatuses() {
1
0

[onionoo/release] Rename lastSeenMillis to mostRecentStatusMillis.
by karsten@torproject.org 07 Feb '18
by karsten@torproject.org 07 Feb '18
07 Feb '18
commit 88bc0219725b01d24110f6d48528dc88d4fa3839
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Wed Feb 7 10:56:45 2018 +0100
Rename lastSeenMillis to mostRecentStatusMillis.
---
.../onionoo/writer/BandwidthDocumentWriter.java | 20 ++++++++++----------
.../onionoo/writer/ClientsDocumentWriter.java | 8 ++++----
.../onionoo/writer/DetailsDocumentWriter.java | 2 +-
.../torproject/onionoo/writer/DocumentWriter.java | 2 +-
.../onionoo/writer/DocumentWriterRunner.java | 13 +++++++------
.../onionoo/writer/SummaryDocumentWriter.java | 2 +-
.../onionoo/writer/UptimeDocumentWriter.java | 18 +++++++++---------
.../onionoo/writer/WeightsDocumentWriter.java | 20 ++++++++++----------
8 files changed, 43 insertions(+), 42 deletions(-)
diff --git a/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java b/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
index ad66bde..47eaa3e 100644
--- a/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
@@ -31,7 +31,7 @@ public class BandwidthDocumentWriter implements DocumentWriter {
}
@Override
- public void writeDocuments(long lastSeenMillis) {
+ public void writeDocuments(long mostRecentStatusMillis) {
UpdateStatus updateStatus = this.documentStore.retrieve(
UpdateStatus.class, true);
long updatedMillis = updateStatus != null
@@ -45,7 +45,7 @@ public class BandwidthDocumentWriter implements DocumentWriter {
continue;
}
BandwidthDocument bandwidthDocument = this.compileBandwidthDocument(
- fingerprint, lastSeenMillis, bandwidthStatus);
+ fingerprint, mostRecentStatusMillis, bandwidthStatus);
this.documentStore.store(bandwidthDocument, fingerprint);
}
log.info("Wrote bandwidth document files");
@@ -53,13 +53,13 @@ public class BandwidthDocumentWriter implements DocumentWriter {
private BandwidthDocument compileBandwidthDocument(String fingerprint,
- long lastSeenMillis, BandwidthStatus bandwidthStatus) {
+ long mostRecentStatusMillis, BandwidthStatus bandwidthStatus) {
BandwidthDocument bandwidthDocument = new BandwidthDocument();
bandwidthDocument.setFingerprint(fingerprint);
- bandwidthDocument.setWriteHistory(this.compileGraphType(lastSeenMillis,
- bandwidthStatus.getWriteHistory()));
- bandwidthDocument.setReadHistory(this.compileGraphType(lastSeenMillis,
- bandwidthStatus.getReadHistory()));
+ bandwidthDocument.setWriteHistory(this.compileGraphType(
+ mostRecentStatusMillis, bandwidthStatus.getWriteHistory()));
+ bandwidthDocument.setReadHistory(this.compileGraphType(
+ mostRecentStatusMillis, bandwidthStatus.getReadHistory()));
return bandwidthDocument;
}
@@ -87,10 +87,10 @@ public class BandwidthDocumentWriter implements DocumentWriter {
DateTimeHelper.TWO_DAYS,
DateTimeHelper.TEN_DAYS };
- private Map<String, GraphHistory> compileGraphType(long lastSeenMillis,
- SortedMap<Long, long[]> history) {
+ private Map<String, GraphHistory> compileGraphType(
+ long mostRecentStatusMillis, SortedMap<Long, long[]> history) {
GraphHistoryCompiler ghc = new GraphHistoryCompiler(
- lastSeenMillis + DateTimeHelper.ONE_HOUR);
+ mostRecentStatusMillis + DateTimeHelper.ONE_HOUR);
for (int i = 0; i < this.graphIntervals.length; i++) {
ghc.addGraphType(this.graphNames[i], this.graphIntervals[i],
this.dataPointIntervals[i]);
diff --git a/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java b/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java
index 7ed2048..de63893 100644
--- a/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java
@@ -55,7 +55,7 @@ public class ClientsDocumentWriter implements DocumentWriter {
private int writtenDocuments = 0;
@Override
- public void writeDocuments(long lastSeenMillis) {
+ public void writeDocuments(long mostRecentStatusMillis) {
UpdateStatus updateStatus = this.documentStore.retrieve(
UpdateStatus.class, true);
long updatedMillis = updateStatus != null
@@ -70,7 +70,7 @@ public class ClientsDocumentWriter implements DocumentWriter {
}
SortedSet<ClientsHistory> history = clientsStatus.getHistory();
ClientsDocument clientsDocument = this.compileClientsDocument(
- hashedFingerprint, lastSeenMillis, history);
+ hashedFingerprint, mostRecentStatusMillis, history);
this.documentStore.store(clientsDocument, hashedFingerprint);
this.writtenDocuments++;
}
@@ -99,10 +99,10 @@ public class ClientsDocumentWriter implements DocumentWriter {
DateTimeHelper.TEN_DAYS };
private ClientsDocument compileClientsDocument(String hashedFingerprint,
- long lastSeenMillis, SortedSet<ClientsHistory> history) {
+ long mostRecentStatusMillis, SortedSet<ClientsHistory> history) {
ClientsDocument clientsDocument = new ClientsDocument();
clientsDocument.setFingerprint(hashedFingerprint);
- GraphHistoryCompiler ghc = new GraphHistoryCompiler(lastSeenMillis
+ GraphHistoryCompiler ghc = new GraphHistoryCompiler(mostRecentStatusMillis
+ DateTimeHelper.ONE_HOUR);
ghc.setThreshold(2L);
for (int i = 0; i < this.graphIntervals.length; i++) {
diff --git a/src/main/java/org/torproject/onionoo/writer/DetailsDocumentWriter.java b/src/main/java/org/torproject/onionoo/writer/DetailsDocumentWriter.java
index 7ffaa07..8490f05 100644
--- a/src/main/java/org/torproject/onionoo/writer/DetailsDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/DetailsDocumentWriter.java
@@ -32,7 +32,7 @@ public class DetailsDocumentWriter implements DocumentWriter {
}
@Override
- public void writeDocuments(long lastSeenMillis) {
+ public void writeDocuments(long mostRecentStatusMillis) {
UpdateStatus updateStatus = this.documentStore.retrieve(
UpdateStatus.class, true);
long updatedMillis = updateStatus != null
diff --git a/src/main/java/org/torproject/onionoo/writer/DocumentWriter.java b/src/main/java/org/torproject/onionoo/writer/DocumentWriter.java
index 359de6f..9fc893f 100644
--- a/src/main/java/org/torproject/onionoo/writer/DocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/DocumentWriter.java
@@ -5,7 +5,7 @@ package org.torproject.onionoo.writer;
public interface DocumentWriter {
- public abstract void writeDocuments(long lastSeenMillis);
+ public abstract void writeDocuments(long mostRecentStatusMillis);
public abstract String getStatsString();
}
diff --git a/src/main/java/org/torproject/onionoo/writer/DocumentWriterRunner.java b/src/main/java/org/torproject/onionoo/writer/DocumentWriterRunner.java
index 968ab72..4ab8f7e 100644
--- a/src/main/java/org/torproject/onionoo/writer/DocumentWriterRunner.java
+++ b/src/main/java/org/torproject/onionoo/writer/DocumentWriterRunner.java
@@ -32,22 +32,23 @@ public class DocumentWriterRunner {
/** Lets each configured document writer write its documents. */
public void writeDocuments() {
- long lastSeenMillis = retrieveLastSeenMillis();
+ long mostRecentStatusMillis = retrieveMostRecentStatusMillis();
for (DocumentWriter dw : this.documentWriters) {
log.debug("Writing " + dw.getClass().getSimpleName());
- dw.writeDocuments(lastSeenMillis);
+ dw.writeDocuments(mostRecentStatusMillis);
}
}
- private long retrieveLastSeenMillis() {
+ private long retrieveMostRecentStatusMillis() {
DocumentStore documentStore = DocumentStoreFactory.getDocumentStore();
- long lastSeenMillis = -1L;
+ long mostRecentStatusMillis = -1L;
for (String fingerprint : documentStore.list(NodeStatus.class)) {
NodeStatus nodeStatus = documentStore.retrieve(
NodeStatus.class, true, fingerprint);
- lastSeenMillis = Math.max(lastSeenMillis, nodeStatus.getLastSeenMillis());
+ mostRecentStatusMillis = Math.max(mostRecentStatusMillis,
+ nodeStatus.getLastSeenMillis());
}
- return lastSeenMillis;
+ return mostRecentStatusMillis;
}
/** Logs statistics of all configured document writers. */
diff --git a/src/main/java/org/torproject/onionoo/writer/SummaryDocumentWriter.java b/src/main/java/org/torproject/onionoo/writer/SummaryDocumentWriter.java
index 74ef31c..356feab 100644
--- a/src/main/java/org/torproject/onionoo/writer/SummaryDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/SummaryDocumentWriter.java
@@ -33,7 +33,7 @@ public class SummaryDocumentWriter implements DocumentWriter {
private int deletedDocuments = 0;
@Override
- public void writeDocuments(long lastSeenAllRelaysAndBridgesMillis) {
+ public void writeDocuments(long mostRecentStatusMillis) {
long relaysLastValidAfterMillis = -1L;
long bridgesLastPublishedMillis = -1L;
for (String fingerprint : this.documentStore.list(NodeStatus.class)) {
diff --git a/src/main/java/org/torproject/onionoo/writer/UptimeDocumentWriter.java b/src/main/java/org/torproject/onionoo/writer/UptimeDocumentWriter.java
index db09e3d..22b7ba5 100644
--- a/src/main/java/org/torproject/onionoo/writer/UptimeDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/UptimeDocumentWriter.java
@@ -36,7 +36,7 @@ public class UptimeDocumentWriter implements DocumentWriter {
}
@Override
- public void writeDocuments(long lastSeenMillis) {
+ public void writeDocuments(long mostRecentStatusMillis) {
UptimeStatus uptimeStatus = this.documentStore.retrieve(
UptimeStatus.class, true);
if (uptimeStatus == null) {
@@ -50,14 +50,14 @@ public class UptimeDocumentWriter implements DocumentWriter {
SortedSet<String> updatedUptimeStatuses = this.documentStore.list(
UptimeStatus.class, updatedMillis);
for (String fingerprint : updatedUptimeStatuses) {
- this.updateDocument(fingerprint, lastSeenMillis, uptimeStatus);
+ this.updateDocument(fingerprint, mostRecentStatusMillis, uptimeStatus);
}
log.info("Wrote uptime document files");
}
private int writtenDocuments = 0;
- private void updateDocument(String fingerprint, long lastSeenMillis,
+ private void updateDocument(String fingerprint, long mostRecentStatusMillis,
UptimeStatus knownStatuses) {
UptimeStatus uptimeStatus = this.documentStore.retrieve(
UptimeStatus.class, true, fingerprint);
@@ -70,7 +70,7 @@ public class UptimeDocumentWriter implements DocumentWriter {
? knownStatuses.getRelayHistory()
: knownStatuses.getBridgeHistory();
UptimeDocument uptimeDocument = this.compileUptimeDocument(relay,
- fingerprint, history, knownStatusesHistory, lastSeenMillis);
+ fingerprint, history, knownStatusesHistory, mostRecentStatusMillis);
this.documentStore.store(uptimeDocument, fingerprint);
this.writtenDocuments++;
}
@@ -99,11 +99,11 @@ public class UptimeDocumentWriter implements DocumentWriter {
private UptimeDocument compileUptimeDocument(boolean relay,
String fingerprint, SortedSet<UptimeHistory> history,
- SortedSet<UptimeHistory> knownStatuses, long lastSeenMillis) {
+ SortedSet<UptimeHistory> knownStatuses, long mostRecentStatusMillis) {
UptimeDocument uptimeDocument = new UptimeDocument();
uptimeDocument.setFingerprint(fingerprint);
uptimeDocument.setUptime(this.compileUptimeHistory(relay, history,
- knownStatuses, lastSeenMillis, null));
+ knownStatuses, mostRecentStatusMillis, null));
SortedMap<String, Map<String, GraphHistory>> flags = new TreeMap<>();
SortedSet<String> allFlags = new TreeSet<>();
for (UptimeHistory hist : history) {
@@ -113,7 +113,7 @@ public class UptimeDocumentWriter implements DocumentWriter {
}
for (String flag : allFlags) {
Map<String, GraphHistory> graphsForFlags = this.compileUptimeHistory(
- relay, history, knownStatuses, lastSeenMillis, flag);
+ relay, history, knownStatuses, mostRecentStatusMillis, flag);
if (!graphsForFlags.isEmpty()) {
flags.put(flag, graphsForFlags);
}
@@ -126,7 +126,7 @@ public class UptimeDocumentWriter implements DocumentWriter {
private Map<String, GraphHistory> compileUptimeHistory(boolean relay,
SortedSet<UptimeHistory> history, SortedSet<UptimeHistory> knownStatuses,
- long lastSeenMillis, String flag) {
+ long mostRecentStatusMillis, String flag) {
/* Extracting history entries for compiling GraphHistory objects is a bit
* harder than for the other document types. The reason is that we have to
@@ -143,7 +143,7 @@ public class UptimeDocumentWriter implements DocumentWriter {
/* Initialize the graph history compiler, and tell it that history entries
* are divisible. This is different from the other history writers. */
GraphHistoryCompiler ghc = new GraphHistoryCompiler(
- lastSeenMillis + DateTimeHelper.ONE_HOUR);
+ mostRecentStatusMillis + DateTimeHelper.ONE_HOUR);
for (int i = 0; i < this.graphIntervals.length; i++) {
ghc.addGraphType(this.graphNames[i], this.graphIntervals[i],
this.dataPointIntervals[i]);
diff --git a/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java b/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java
index 2d2239b..c701f41 100644
--- a/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java
@@ -31,7 +31,7 @@ public class WeightsDocumentWriter implements DocumentWriter {
}
@Override
- public void writeDocuments(long lastSeenMillis) {
+ public void writeDocuments(long mostRecentStatusMillis) {
UpdateStatus updateStatus = this.documentStore.retrieve(
UpdateStatus.class, true);
long updatedMillis = updateStatus != null
@@ -46,7 +46,7 @@ public class WeightsDocumentWriter implements DocumentWriter {
}
SortedMap<long[], double[]> history = weightsStatus.getHistory();
WeightsDocument weightsDocument = this.compileWeightsDocument(
- fingerprint, history, lastSeenMillis);
+ fingerprint, history, mostRecentStatusMillis);
this.documentStore.store(weightsDocument, fingerprint);
}
log.info("Wrote weights document files");
@@ -74,27 +74,27 @@ public class WeightsDocumentWriter implements DocumentWriter {
DateTimeHelper.TEN_DAYS };
private WeightsDocument compileWeightsDocument(String fingerprint,
- SortedMap<long[], double[]> history, long lastSeenMillis) {
+ SortedMap<long[], double[]> history, long mostRecentStatusMillis) {
WeightsDocument weightsDocument = new WeightsDocument();
weightsDocument.setFingerprint(fingerprint);
weightsDocument.setConsensusWeightFraction(
- this.compileGraphType(history, lastSeenMillis, 1));
+ this.compileGraphType(history, mostRecentStatusMillis, 1));
weightsDocument.setGuardProbability(
- this.compileGraphType(history, lastSeenMillis, 2));
+ this.compileGraphType(history, mostRecentStatusMillis, 2));
weightsDocument.setMiddleProbability(
- this.compileGraphType(history, lastSeenMillis, 3));
+ this.compileGraphType(history, mostRecentStatusMillis, 3));
weightsDocument.setExitProbability(
- this.compileGraphType(history, lastSeenMillis, 4));
+ this.compileGraphType(history, mostRecentStatusMillis, 4));
weightsDocument.setConsensusWeight(
- this.compileGraphType(history, lastSeenMillis, 6));
+ this.compileGraphType(history, mostRecentStatusMillis, 6));
return weightsDocument;
}
private Map<String, GraphHistory> compileGraphType(
- SortedMap<long[], double[]> history, long lastSeenMillis,
+ SortedMap<long[], double[]> history, long mostRecentStatusMillis,
int graphTypeIndex) {
GraphHistoryCompiler ghc = new GraphHistoryCompiler(
- lastSeenMillis + DateTimeHelper.ONE_HOUR);
+ mostRecentStatusMillis + DateTimeHelper.ONE_HOUR);
for (int i = 0; i < this.graphIntervals.length; i++) {
ghc.addGraphType(this.graphNames[i], this.graphIntervals[i],
this.dataPointIntervals[i]);
1
0

[onionoo/release] Retain more detailed histories for a longer time.
by karsten@torproject.org 07 Feb '18
by karsten@torproject.org 07 Feb '18
07 Feb '18
commit d153681176ba492af159e1126f9dde7d133d2720
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Fri Feb 2 15:38:03 2018 +0100
Retain more detailed histories for a longer time.
Previously, we'd have compressed histories to a resolution of 48 hours
after 3 months. But we're now planning to introduce a 6 month graph
with a resolution of 24 hours. With this change we're retaining
detailed histories for three months longer.
Related to #24729.
---
src/main/java/org/torproject/onionoo/docs/BandwidthStatus.java | 4 ++--
src/main/java/org/torproject/onionoo/docs/ClientsStatus.java | 2 +-
src/main/java/org/torproject/onionoo/docs/DateTimeHelper.java | 2 ++
src/main/java/org/torproject/onionoo/docs/WeightsStatus.java | 4 ++--
4 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/src/main/java/org/torproject/onionoo/docs/BandwidthStatus.java b/src/main/java/org/torproject/onionoo/docs/BandwidthStatus.java
index ba22dd4..252a018 100644
--- a/src/main/java/org/torproject/onionoo/docs/BandwidthStatus.java
+++ b/src/main/java/org/torproject/onionoo/docs/BandwidthStatus.java
@@ -134,8 +134,8 @@ public class BandwidthStatus extends Document {
<= DateTimeHelper.ROUGHLY_ONE_MONTH) {
intervalLengthMillis = DateTimeHelper.FOUR_HOURS;
} else if (lastSeenMillis - endMillis
- <= DateTimeHelper.ROUGHLY_THREE_MONTHS) {
- intervalLengthMillis = DateTimeHelper.TWELVE_HOURS;
+ <= DateTimeHelper.ROUGHLY_SIX_MONTHS) {
+ intervalLengthMillis = DateTimeHelper.ONE_DAY;
} else if (lastSeenMillis - endMillis
<= DateTimeHelper.ROUGHLY_ONE_YEAR) {
intervalLengthMillis = DateTimeHelper.TWO_DAYS;
diff --git a/src/main/java/org/torproject/onionoo/docs/ClientsStatus.java b/src/main/java/org/torproject/onionoo/docs/ClientsStatus.java
index a5bc8e8..2e11b50 100644
--- a/src/main/java/org/torproject/onionoo/docs/ClientsStatus.java
+++ b/src/main/java/org/torproject/onionoo/docs/ClientsStatus.java
@@ -77,7 +77,7 @@ public class ClientsStatus extends Document {
for (ClientsHistory responses : uncompressedHistory) {
long intervalLengthMillis;
if (lastSeenMillis - responses.getEndMillis()
- <= DateTimeHelper.ROUGHLY_THREE_MONTHS) {
+ <= DateTimeHelper.ROUGHLY_SIX_MONTHS) {
intervalLengthMillis = DateTimeHelper.ONE_DAY;
} else if (lastSeenMillis - responses.getEndMillis()
<= DateTimeHelper.ROUGHLY_ONE_YEAR) {
diff --git a/src/main/java/org/torproject/onionoo/docs/DateTimeHelper.java b/src/main/java/org/torproject/onionoo/docs/DateTimeHelper.java
index c80514e..7966af8 100644
--- a/src/main/java/org/torproject/onionoo/docs/DateTimeHelper.java
+++ b/src/main/java/org/torproject/onionoo/docs/DateTimeHelper.java
@@ -57,6 +57,8 @@ public class DateTimeHelper {
public static final long ROUGHLY_THREE_MONTHS = 92L * ONE_DAY;
+ public static final long ROUGHLY_SIX_MONTHS = 183L * ONE_DAY;
+
public static final long ROUGHLY_ONE_YEAR = 366L * ONE_DAY;
public static final long ROUGHLY_FIVE_YEARS = 5L * ROUGHLY_ONE_YEAR;
diff --git a/src/main/java/org/torproject/onionoo/docs/WeightsStatus.java b/src/main/java/org/torproject/onionoo/docs/WeightsStatus.java
index 94efda6..c221fdd 100644
--- a/src/main/java/org/torproject/onionoo/docs/WeightsStatus.java
+++ b/src/main/java/org/torproject/onionoo/docs/WeightsStatus.java
@@ -146,8 +146,8 @@ public class WeightsStatus extends Document {
<= DateTimeHelper.ROUGHLY_ONE_MONTH) {
intervalLengthMillis = DateTimeHelper.FOUR_HOURS;
} else if (lastSeenMillis - endMillis
- <= DateTimeHelper.ROUGHLY_THREE_MONTHS) {
- intervalLengthMillis = DateTimeHelper.TWELVE_HOURS;
+ <= DateTimeHelper.ROUGHLY_SIX_MONTHS) {
+ intervalLengthMillis = DateTimeHelper.ONE_DAY;
} else if (lastSeenMillis - endMillis
<= DateTimeHelper.ROUGHLY_ONE_YEAR) {
intervalLengthMillis = DateTimeHelper.TWO_DAYS;
1
0

07 Feb '18
commit 314feacaf18dae7e1f29861b39a74fc3df2d1330
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Wed Jan 17 20:29:11 2018 +0100
Compile graph histories in a single place.
---
.../org/torproject/onionoo/docs/UptimeHistory.java | 4 +
.../onionoo/writer/BandwidthDocumentWriter.java | 120 +-------
.../onionoo/writer/ClientsDocumentWriter.java | 130 +--------
.../onionoo/writer/GraphHistoryCompiler.java | 254 +++++++++++++++++
.../onionoo/writer/UptimeDocumentWriter.java | 312 +++++++--------------
.../onionoo/writer/WeightsDocumentWriter.java | 124 +-------
.../writer/BandwidthDocumentWriterTest.java | 4 +-
.../onionoo/writer/GraphHistoryCompilerTest.java | 203 ++++++++++++++
.../onionoo/writer/UptimeDocumentWriterTest.java | 14 +-
9 files changed, 606 insertions(+), 559 deletions(-)
diff --git a/src/main/java/org/torproject/onionoo/docs/UptimeHistory.java b/src/main/java/org/torproject/onionoo/docs/UptimeHistory.java
index 60e283f..f8cc116 100644
--- a/src/main/java/org/torproject/onionoo/docs/UptimeHistory.java
+++ b/src/main/java/org/torproject/onionoo/docs/UptimeHistory.java
@@ -32,6 +32,10 @@ public class UptimeHistory implements Comparable<UptimeHistory> {
return this.uptimeHours;
}
+ public long getEndMillis() {
+ return this.startMillis + DateTimeHelper.ONE_HOUR * this.uptimeHours;
+ }
+
private SortedSet<String> flags;
public SortedSet<String> getFlags() {
diff --git a/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java b/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
index 2f27271..71595e2 100644
--- a/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/BandwidthDocumentWriter.java
@@ -15,12 +15,7 @@ import org.torproject.onionoo.docs.UpdateStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.time.LocalDateTime;
import java.time.Period;
-import java.time.ZoneOffset;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.SortedSet;
@@ -100,114 +95,17 @@ public class BandwidthDocumentWriter implements DocumentWriter {
private Map<String, GraphHistory> compileGraphType(long lastSeenMillis,
SortedMap<Long, long[]> history) {
- Map<String, GraphHistory> graphs = new LinkedHashMap<>();
+ GraphHistoryCompiler ghc = new GraphHistoryCompiler(
+ lastSeenMillis + DateTimeHelper.ONE_HOUR);
for (int i = 0; i < this.graphIntervals.length; i++) {
- String graphName = this.graphNames[i];
- Period graphInterval = this.graphIntervals[i];
- long dataPointInterval = this.dataPointIntervals[i];
- List<Long> dataPoints = new ArrayList<>();
- long graphEndMillis = ((lastSeenMillis + DateTimeHelper.ONE_HOUR)
- / dataPointInterval) * dataPointInterval;
- long graphStartMillis = LocalDateTime
- .ofEpochSecond(graphEndMillis / 1000L, 0, ZoneOffset.UTC)
- .minus(graphInterval)
- .toEpochSecond(ZoneOffset.UTC) * 1000L;
- long intervalStartMillis = graphStartMillis;
- long totalMillis = 0L;
- long totalBandwidth = 0L;
- for (long[] v : history.values()) {
- long endMillis = v[1];
- if (endMillis <= intervalStartMillis) {
- continue;
- } else if (endMillis > graphEndMillis) {
- break;
- }
- long startMillis = v[0];
- if (endMillis - startMillis > dataPointInterval) {
- /* This history interval is too long for this graph's data point
- * interval. Maybe the next graph will contain it, but not this
- * one. */
- continue;
- }
- while ((intervalStartMillis / dataPointInterval)
- != ((endMillis - 1L) / dataPointInterval)) {
- dataPoints.add(totalMillis * 5L < dataPointInterval
- ? -1L : (totalBandwidth * DateTimeHelper.ONE_SECOND)
- / totalMillis);
- totalBandwidth = 0L;
- totalMillis = 0L;
- intervalStartMillis += dataPointInterval;
- }
- long bandwidth = v[2];
- totalBandwidth += bandwidth;
- totalMillis += (endMillis - startMillis);
- }
- dataPoints.add(totalMillis * 5L < dataPointInterval
- ? -1L : (totalBandwidth * DateTimeHelper.ONE_SECOND)
- / totalMillis);
- long maxValue = 1L;
- int firstNonNullIndex = -1;
- int lastNonNullIndex = -1;
- for (int j = 0; j < dataPoints.size(); j++) {
- long dataPoint = dataPoints.get(j);
- if (dataPoint >= 0L) {
- if (firstNonNullIndex < 0) {
- firstNonNullIndex = j;
- }
- lastNonNullIndex = j;
- if (dataPoint > maxValue) {
- maxValue = dataPoint;
- }
- }
- }
- if (firstNonNullIndex < 0) {
- continue;
- }
- long firstDataPointMillis = graphStartMillis + firstNonNullIndex
- * dataPointInterval + dataPointInterval / 2L;
- if (i > 0 && !graphs.isEmpty() && firstDataPointMillis >= LocalDateTime
- .ofEpochSecond(graphEndMillis / 1000L, 0, ZoneOffset.UTC)
- .minus(graphIntervals[i - 1])
- .toEpochSecond(ZoneOffset.UTC) * 1000L) {
-
- /* Skip bandwidth history object, because it doesn't contain
- * anything new that wasn't already contained in the last
- * bandwidth history object(s). Unless we did not include any of
- * the previous bandwidth history objects for other reasons, in
- * which case we should include this one. */
- continue;
- }
- long lastDataPointMillis = firstDataPointMillis
- + (lastNonNullIndex - firstNonNullIndex) * dataPointInterval;
- double factor = ((double) maxValue) / 999.0;
- int count = lastNonNullIndex - firstNonNullIndex + 1;
- GraphHistory graphHistory = new GraphHistory();
- graphHistory.setFirst(firstDataPointMillis);
- graphHistory.setLast(lastDataPointMillis);
- graphHistory.setInterval((int) (dataPointInterval
- / DateTimeHelper.ONE_SECOND));
- graphHistory.setFactor(factor);
- graphHistory.setCount(count);
- int previousNonNullIndex = -2;
- boolean foundTwoAdjacentDataPoints = false;
- List<Integer> values = new ArrayList<>();
- for (int j = firstNonNullIndex; j <= lastNonNullIndex; j++) {
- long dataPoint = dataPoints.get(j);
- if (dataPoint >= 0L) {
- if (j - previousNonNullIndex == 1) {
- foundTwoAdjacentDataPoints = true;
- }
- previousNonNullIndex = j;
- }
- values.add(dataPoint < 0L ? null
- : (int) ((dataPoint * 999L) / maxValue));
- }
- graphHistory.setValues(values);
- if (foundTwoAdjacentDataPoints) {
- graphs.put(graphName, graphHistory);
- }
+ ghc.addGraphType(this.graphNames[i], this.graphIntervals[i],
+ this.dataPointIntervals[i]);
+ }
+ for (long[] v : history.values()) {
+ ghc.addHistoryEntry(v[0], v[1],
+ (double) (v[2] * DateTimeHelper.ONE_SECOND));
}
- return graphs;
+ return ghc.compileGraphHistories();
}
@Override
diff --git a/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java b/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java
index 4eca33a..aba45cf 100644
--- a/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/ClientsDocumentWriter.java
@@ -9,7 +9,6 @@ import org.torproject.onionoo.docs.ClientsStatus;
import org.torproject.onionoo.docs.DateTimeHelper;
import org.torproject.onionoo.docs.DocumentStore;
import org.torproject.onionoo.docs.DocumentStoreFactory;
-import org.torproject.onionoo.docs.GraphHistory;
import org.torproject.onionoo.docs.NodeStatus;
import org.torproject.onionoo.docs.UpdateStatus;
import org.torproject.onionoo.util.FormattingUtils;
@@ -17,13 +16,7 @@ import org.torproject.onionoo.util.FormattingUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.time.LocalDateTime;
import java.time.Period;
-import java.time.ZoneOffset;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
-import java.util.Map;
import java.util.SortedSet;
/*
@@ -115,122 +108,19 @@ public class ClientsDocumentWriter implements DocumentWriter {
NodeStatus nodeStatus, SortedSet<ClientsHistory> history) {
ClientsDocument clientsDocument = new ClientsDocument();
clientsDocument.setFingerprint(hashedFingerprint);
- Map<String, GraphHistory> averageClients = new LinkedHashMap<>();
- for (int graphIntervalIndex = 0; graphIntervalIndex
- < this.graphIntervals.length; graphIntervalIndex++) {
- String graphName = this.graphNames[graphIntervalIndex];
- GraphHistory graphHistory = this.compileClientsHistory(
- graphIntervalIndex, history, nodeStatus.getLastSeenMillis());
- if (graphHistory != null) {
- averageClients.put(graphName, graphHistory);
- }
+ GraphHistoryCompiler ghc = new GraphHistoryCompiler(
+ nodeStatus.getLastSeenMillis() + DateTimeHelper.ONE_HOUR);
+ ghc.setThreshold(2L);
+ for (int i = 0; i < this.graphIntervals.length; i++) {
+ ghc.addGraphType(this.graphNames[i], this.graphIntervals[i],
+ this.dataPointIntervals[i]);
}
- clientsDocument.setAverageClients(averageClients);
- return clientsDocument;
- }
-
- private GraphHistory compileClientsHistory(
- int graphIntervalIndex, SortedSet<ClientsHistory> history,
- long lastSeenMillis) {
- Period graphInterval = this.graphIntervals[graphIntervalIndex];
- long dataPointInterval =
- this.dataPointIntervals[graphIntervalIndex];
- List<Double> dataPoints = new ArrayList<>();
- long graphEndMillis = ((lastSeenMillis + DateTimeHelper.ONE_HOUR)
- / dataPointInterval) * dataPointInterval;
- long graphStartMillis = LocalDateTime
- .ofEpochSecond(graphEndMillis / 1000L, 0, ZoneOffset.UTC)
- .minus(graphInterval)
- .toEpochSecond(ZoneOffset.UTC) * 1000L;
- long intervalStartMillis = graphStartMillis;
- long millis = 0L;
- double responses = 0.0;
for (ClientsHistory hist : history) {
- if (hist.getEndMillis() <= intervalStartMillis) {
- continue;
- } else if (hist.getEndMillis() > graphEndMillis) {
- break;
- }
- while ((intervalStartMillis / dataPointInterval)
- != ((hist.getEndMillis() - 1L) / dataPointInterval)) {
- dataPoints.add(millis * 2L < dataPointInterval
- ? -1.0 : responses * ((double) DateTimeHelper.ONE_DAY)
- / (((double) millis) * 10.0));
- responses = 0.0;
- millis = 0L;
- intervalStartMillis += dataPointInterval;
- }
- responses += hist.getTotalResponses();
- millis += (hist.getEndMillis() - hist.getStartMillis());
- }
- dataPoints.add(millis * 2L < dataPointInterval
- ? -1.0 : responses * ((double) DateTimeHelper.ONE_DAY)
- / (((double) millis) * 10.0));
- double maxValue = 0.0;
- int firstNonNullIndex = -1;
- int lastNonNullIndex = -1;
- for (int dataPointIndex = 0; dataPointIndex < dataPoints.size();
- dataPointIndex++) {
- double dataPoint = dataPoints.get(dataPointIndex);
- if (dataPoint >= 0.0) {
- if (firstNonNullIndex < 0) {
- firstNonNullIndex = dataPointIndex;
- }
- lastNonNullIndex = dataPointIndex;
- if (dataPoint > maxValue) {
- maxValue = dataPoint;
- }
- }
- }
- if (firstNonNullIndex < 0) {
- /* Not a single non-negative value in the data points. */
- return null;
- }
- long firstDataPointMillis = graphStartMillis + firstNonNullIndex
- * dataPointInterval + dataPointInterval / 2L;
- if (graphIntervalIndex > 0 && firstDataPointMillis >= LocalDateTime
- .ofEpochSecond(graphEndMillis / 1000L, 0, ZoneOffset.UTC)
- .minus(graphIntervals[graphIntervalIndex - 1])
- .toEpochSecond(ZoneOffset.UTC) * 1000L) {
- /* Skip clients history object, because it doesn't contain
- * anything new that wasn't already contained in the last
- * clients history object(s). */
- return null;
- }
- long lastDataPointMillis = firstDataPointMillis
- + (lastNonNullIndex - firstNonNullIndex) * dataPointInterval;
- double factor = ((double) maxValue) / 999.0;
- int count = lastNonNullIndex - firstNonNullIndex + 1;
- GraphHistory graphHistory = new GraphHistory();
- graphHistory.setFirst(firstDataPointMillis);
- graphHistory.setLast(lastDataPointMillis);
- graphHistory.setInterval((int) (dataPointInterval
- / DateTimeHelper.ONE_SECOND));
- graphHistory.setFactor(factor);
- graphHistory.setCount(count);
- int previousNonNullIndex = -2;
- boolean foundTwoAdjacentDataPoints = false;
- List<Integer> values = new ArrayList<>();
- for (int dataPointIndex = firstNonNullIndex; dataPointIndex
- <= lastNonNullIndex; dataPointIndex++) {
- double dataPoint = dataPoints.get(dataPointIndex);
- if (dataPoint >= 0.0) {
- if (dataPointIndex - previousNonNullIndex == 1) {
- foundTwoAdjacentDataPoints = true;
- }
- previousNonNullIndex = dataPointIndex;
- }
- values.add(dataPoint < 0.0 ? null :
- (int) ((dataPoint * 999.0) / maxValue));
- }
- graphHistory.setValues(values);
- if (foundTwoAdjacentDataPoints) {
- return graphHistory;
- } else {
- /* There are no two adjacent values in the data points that are
- * required to draw a line graph. */
- return null;
+ ghc.addHistoryEntry(hist.getStartMillis(), hist.getEndMillis(),
+ hist.getTotalResponses() * ((double) DateTimeHelper.ONE_DAY) / 10.0);
}
+ clientsDocument.setAverageClients(ghc.compileGraphHistories());
+ return clientsDocument;
}
@Override
diff --git a/src/main/java/org/torproject/onionoo/writer/GraphHistoryCompiler.java b/src/main/java/org/torproject/onionoo/writer/GraphHistoryCompiler.java
new file mode 100644
index 0000000..853ab32
--- /dev/null
+++ b/src/main/java/org/torproject/onionoo/writer/GraphHistoryCompiler.java
@@ -0,0 +1,254 @@
+/* Copyright 2018 The Tor Project
+ * See LICENSE for licensing information */
+
+package org.torproject.onionoo.writer;
+
+import org.torproject.onionoo.docs.DateTimeHelper;
+import org.torproject.onionoo.docs.GraphHistory;
+
+import java.time.LocalDateTime;
+import java.time.Period;
+import java.time.ZoneOffset;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+
+/** Helper class to compile graph histories. */
+public class GraphHistoryCompiler {
+
+ private long graphsEndMillis;
+
+ /**
+ * Instantiates a new graph history compiler with the provided end time for
+ * all compiled graphs.
+ *
+ * @param graphsEndMillis End time for all compiled graphs.
+ */
+ GraphHistoryCompiler(long graphsEndMillis) {
+ this.graphsEndMillis = graphsEndMillis;
+ }
+
+ private boolean divisible = false;
+
+ /**
+ * Set whether history elements are divisible in the sense that they may be
+ * longer than one data point; this is the case for uptime intervals where
+ * uptime is equally distributed over potentially many data point intervals,
+ * but it's not the case for bandwidth/weights/clients intervals where
+ * observations are given for fixed-size reporting intervals. */
+ void setDivisible(boolean divisible) {
+ this.divisible = divisible;
+ }
+
+ private long threshold = 5;
+
+ /**
+ * Set the threshold (given as reciprocal value) of available history entries
+ * for any given data points below which the data point will be counted as
+ * null (missing); default is 5 for 1/5 = 20%.
+ */
+ void setThreshold(long threshold) {
+ this.threshold = threshold;
+ }
+
+ private List<String> graphNames = new ArrayList<>();
+
+ private List<Period> graphIntervals = new ArrayList<>();
+
+ private List<Long> dataPointIntervals = new ArrayList<>();
+
+ /**
+ * Add a graph type with the given graph name, graph interval, and data point
+ * interval.
+ *
+ * @param graphName Graph name, like "1_week".
+ * @param graphInterval Graph interval, like Period.ofWeeks(1).
+ * @param dataPointInterval Data point interval, like 1 hour in milliseconds.
+ */
+ void addGraphType(String graphName, Period graphInterval,
+ Long dataPointInterval) {
+ this.graphNames.add(graphName);
+ this.graphIntervals.add(graphInterval);
+ this.dataPointIntervals.add(dataPointInterval);
+ }
+
+ private Map<long[], Double> history = new LinkedHashMap<>();
+
+ /**
+ * Add a history entry with given start and end time and value.
+ *
+ * @param startMillis Start time in milliseconds.
+ * @param endMillis End time in milliseconds.
+ * @param value History entry value.
+ */
+ void addHistoryEntry(long startMillis, long endMillis, double value) {
+ this.history.put(new long[] { startMillis, endMillis }, value);
+ }
+
+ /**
+ * Compile graph histories from the history entries provided earlier.
+ *
+ * @return Map with graph names as keys and GraphHistory instances as values.
+ */
+ Map<String, GraphHistory> compileGraphHistories() {
+ Map<String, GraphHistory> graphs = new LinkedHashMap<>();
+ for (int graphIntervalIndex = 0;
+ graphIntervalIndex < this.graphIntervals.size();
+ graphIntervalIndex++) {
+
+ /* Look up graph name, graph interval, and data point interval from the
+ * graph type details provided earlier. */
+ final String graphName = this.graphNames.get(graphIntervalIndex);
+ Period graphInterval = this.graphIntervals.get(graphIntervalIndex);
+ long dataPointInterval = this.dataPointIntervals.get(graphIntervalIndex);
+
+ /* Determine graph end time as the end time for all graphs, rounded down
+ * to the last full data point interval. */
+ long graphEndMillis = (this.graphsEndMillis / dataPointInterval)
+ * dataPointInterval;
+
+ /* Determine graph start time as graph end time minus graph interval,
+ * rounded down to the last full data point interval. */
+ long graphStartMillis = ((LocalDateTime
+ .ofEpochSecond(graphEndMillis / 1000L, 0, ZoneOffset.UTC)
+ .minus(graphInterval)
+ .toEpochSecond(ZoneOffset.UTC) * 1000L) / dataPointInterval)
+ * dataPointInterval;
+
+ /* Keep input for graph values in two arrays, one for values * millis,
+ * another one for millis. */
+ int dataPoints = (int) ((graphEndMillis - graphStartMillis)
+ / dataPointInterval);
+ double[] totalValues = new double[dataPoints];
+ long[] totalMillis = new long[dataPoints];
+
+ /* Iterate over all history entries and see which ones we need for this
+ * graph. */
+ for (Map.Entry<long[], Double> h : this.history.entrySet()) {
+ long startMillis = h.getKey()[0];
+ long endMillis = h.getKey()[1];
+ double value = h.getValue();
+
+ /* If a history entry ends before this graph starts or starts before
+ * this graph ends, skip it. */
+ if (endMillis <= graphStartMillis || startMillis >= graphEndMillis) {
+ continue;
+ }
+
+ /* If history entries are not divisible and this entry is longer than
+ * the data point interval, skip it. Maybe the next graph will contain
+ * it, but not this one. */
+ if (!this.divisible && endMillis - startMillis > dataPointInterval) {
+ continue;
+ }
+
+ /* Iterate over all data points that this history element falls into.
+ * Even if history entries are not divisible, we may have to split it
+ * over two data points, because reported statistics rarely align with
+ * our data point intervals. And if history entries are divisible, we
+ * may have to split them over many data points. */
+ for (long intervalStartMillis = startMillis;
+ intervalStartMillis < endMillis;
+ intervalStartMillis = ((intervalStartMillis + dataPointInterval)
+ / dataPointInterval) * dataPointInterval) {
+
+ /* Determine the data point that this (partial) history entry falls
+ * into. And if it's out of bounds, skip it. */
+ int dataPointIndex = (int) ((intervalStartMillis - graphStartMillis)
+ / dataPointInterval);
+ if (dataPointIndex < 0 || dataPointIndex >= dataPoints) {
+ continue;
+ }
+
+ /* Determine the interval end, which may be the end of the data point
+ * or the end of the history entry, whichever comes first. Then add
+ * values and millis to the data point. */
+ long intervalEndMillis = Math.min(endMillis, ((intervalStartMillis
+ + dataPointInterval) / dataPointInterval) * dataPointInterval);
+ long millis = intervalEndMillis - intervalStartMillis;
+ totalValues[dataPointIndex] += (value * (double) millis)
+ / (double) (endMillis - startMillis);
+ totalMillis[dataPointIndex] += millis;
+ }
+ }
+
+ /* Go through the previously compiled data points and extract some pieces
+ * that will be relevant for deciding whether to include this graph and
+ * for adding meta data to the GraphHistory object. */
+ double maxValue = 0.0;
+ int firstNonNullIndex = -1;
+ int lastNonNullIndex = -1;
+ boolean foundTwoAdjacentDataPoints = false;
+ for (int dataPointIndex = 0, previousNonNullIndex = -2;
+ dataPointIndex < dataPoints; dataPointIndex++) {
+
+ /* Only consider data points containing values for at least the given
+ * threshold of time (20% by default). If so, record first and last
+ * data point containing data, whether there exist two adjacent data
+ * points containing data, and determine the maximum value. */
+ if (totalMillis[dataPointIndex] * this.threshold >= dataPointInterval) {
+ if (firstNonNullIndex < 0) {
+ firstNonNullIndex = dataPointIndex;
+ }
+ lastNonNullIndex = dataPointIndex;
+ if (dataPointIndex - previousNonNullIndex == 1) {
+ foundTwoAdjacentDataPoints = true;
+ }
+ previousNonNullIndex = dataPointIndex;
+ maxValue = Math.max(maxValue, totalValues[dataPointIndex]
+ / totalMillis[dataPointIndex]);
+ }
+ }
+
+ /* If there are not at least two adjacent data points containing data,
+ * skip the graph. */
+ if (!foundTwoAdjacentDataPoints) {
+ continue;
+ }
+
+ /* Calculate the timestamp of the first data point containing data. */
+ long firstDataPointMillis = graphStartMillis + firstNonNullIndex
+ * dataPointInterval + dataPointInterval / 2L;
+
+ /* If the graph doesn't contain anything new that wasn't already contained
+ * in previously compiled graphs, skip this graph. */
+ if (graphIntervalIndex > 0 && !graphs.isEmpty()
+ && firstDataPointMillis >= LocalDateTime.ofEpochSecond(
+ graphEndMillis / 1000L, 0, ZoneOffset.UTC)
+ .minus(this.graphIntervals.get(graphIntervalIndex - 1))
+ .toEpochSecond(ZoneOffset.UTC) * 1000L) {
+ continue;
+ }
+
+ /* Put together the list of values that will go into the graph. */
+ List<Integer> values = new ArrayList<>();
+ for (int dataPointIndex = firstNonNullIndex;
+ dataPointIndex <= lastNonNullIndex; dataPointIndex++) {
+ if (totalMillis[dataPointIndex] * this.threshold >= dataPointInterval) {
+ values.add((int) ((totalValues[dataPointIndex] * 999.0)
+ / (maxValue * totalMillis[dataPointIndex])));
+ } else {
+ values.add(null);
+ }
+ }
+
+ /* Put together a GraphHistory object and add it to the map under the
+ * given graph name. */
+ GraphHistory graphHistory = new GraphHistory();
+ graphHistory.setFirst(firstDataPointMillis);
+ graphHistory.setLast(firstDataPointMillis + (lastNonNullIndex
+ - firstNonNullIndex) * dataPointInterval);
+ graphHistory.setInterval((int) (dataPointInterval
+ / DateTimeHelper.ONE_SECOND));
+ graphHistory.setFactor(maxValue / 999.0);
+ graphHistory.setCount(lastNonNullIndex - firstNonNullIndex + 1);
+ graphHistory.setValues(values);
+ graphs.put(graphName, graphHistory);
+ }
+
+ /* We're done. Return the map of compiled graphs. */
+ return graphs;
+ }
+}
+
diff --git a/src/main/java/org/torproject/onionoo/writer/UptimeDocumentWriter.java b/src/main/java/org/torproject/onionoo/writer/UptimeDocumentWriter.java
index d1e2003..12ba8fa 100644
--- a/src/main/java/org/torproject/onionoo/writer/UptimeDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/UptimeDocumentWriter.java
@@ -17,12 +17,8 @@ import org.torproject.onionoo.util.FormattingUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.time.LocalDateTime;
import java.time.Period;
-import java.time.ZoneOffset;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
+import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
import java.util.SortedSet;
@@ -110,18 +106,8 @@ public class UptimeDocumentWriter implements DocumentWriter {
SortedSet<UptimeHistory> knownStatuses, long lastSeenMillis) {
UptimeDocument uptimeDocument = new UptimeDocument();
uptimeDocument.setFingerprint(fingerprint);
- Map<String, GraphHistory> uptime = new LinkedHashMap<>();
- for (int graphIntervalIndex = 0; graphIntervalIndex
- < this.graphIntervals.length; graphIntervalIndex++) {
- String graphName = this.graphNames[graphIntervalIndex];
- GraphHistory graphHistory = this.compileUptimeHistory(
- graphIntervalIndex, relay, history, knownStatuses, lastSeenMillis,
- null);
- if (graphHistory != null) {
- uptime.put(graphName, graphHistory);
- }
- }
- uptimeDocument.setUptime(uptime);
+ uptimeDocument.setUptime(this.compileUptimeHistory(relay, history,
+ knownStatuses, lastSeenMillis, null));
SortedMap<String, Map<String, GraphHistory>> flags = new TreeMap<>();
SortedSet<String> allFlags = new TreeSet<>();
for (UptimeHistory hist : history) {
@@ -130,17 +116,8 @@ public class UptimeDocumentWriter implements DocumentWriter {
}
}
for (String flag : allFlags) {
- Map<String, GraphHistory> graphsForFlags = new LinkedHashMap<>();
- for (int graphIntervalIndex = 0; graphIntervalIndex
- < this.graphIntervals.length; graphIntervalIndex++) {
- String graphName = this.graphNames[graphIntervalIndex];
- GraphHistory graphHistory = this.compileUptimeHistory(
- graphIntervalIndex, relay, history, knownStatuses, lastSeenMillis,
- flag);
- if (graphHistory != null) {
- graphsForFlags.put(graphName, graphHistory);
- }
- }
+ Map<String, GraphHistory> graphsForFlags = this.compileUptimeHistory(
+ relay, history, knownStatuses, lastSeenMillis, flag);
if (!graphsForFlags.isEmpty()) {
flags.put(flag, graphsForFlags);
}
@@ -151,187 +128,116 @@ public class UptimeDocumentWriter implements DocumentWriter {
return uptimeDocument;
}
- private GraphHistory compileUptimeHistory(int graphIntervalIndex,
- boolean relay, SortedSet<UptimeHistory> history,
- SortedSet<UptimeHistory> knownStatuses, long lastSeenMillis,
- String flag) {
- Period graphInterval = this.graphIntervals[graphIntervalIndex];
- long dataPointInterval =
- this.dataPointIntervals[graphIntervalIndex];
- int dataPointIntervalHours = (int) (dataPointInterval
- / DateTimeHelper.ONE_HOUR);
- List<Integer> uptimeDataPoints = new ArrayList<>();
- long graphEndMillis = ((lastSeenMillis + DateTimeHelper.ONE_HOUR)
- / dataPointInterval) * dataPointInterval;
- long graphStartMillis = LocalDateTime
- .ofEpochSecond(graphEndMillis / 1000L, 0, ZoneOffset.UTC)
- .minus(graphInterval)
- .toEpochSecond(ZoneOffset.UTC) * 1000L;
- long intervalStartMillis = graphStartMillis;
- int uptimeHours = 0;
- long firstStatusStartMillis = -1L;
- for (UptimeHistory hist : history) {
- if (hist.isRelay() != relay
- || (flag != null && (hist.getFlags() == null
- || !hist.getFlags().contains(flag)))) {
- continue;
- }
- if (firstStatusStartMillis < 0L) {
- firstStatusStartMillis = hist.getStartMillis();
- }
- long histEndMillis = hist.getStartMillis() + DateTimeHelper.ONE_HOUR
- * hist.getUptimeHours();
- if (histEndMillis <= intervalStartMillis) {
- continue;
- } else if (histEndMillis > graphEndMillis) {
- histEndMillis = graphEndMillis;
- }
- while (hist.getStartMillis() >= intervalStartMillis
- + dataPointInterval) {
- if (firstStatusStartMillis < intervalStartMillis
- + dataPointInterval) {
- uptimeDataPoints.add(uptimeHours);
- } else {
- uptimeDataPoints.add(-1);
- }
- uptimeHours = 0;
- intervalStartMillis += dataPointInterval;
- }
- while (histEndMillis >= intervalStartMillis + dataPointInterval) {
- uptimeHours += (int) ((intervalStartMillis + dataPointInterval
- - Math.max(hist.getStartMillis(), intervalStartMillis))
- / DateTimeHelper.ONE_HOUR);
- uptimeDataPoints.add(uptimeHours);
- uptimeHours = 0;
- intervalStartMillis += dataPointInterval;
- }
- uptimeHours += (int) ((histEndMillis - Math.max(
- hist.getStartMillis(), intervalStartMillis))
- / DateTimeHelper.ONE_HOUR);
- }
- uptimeDataPoints.add(uptimeHours);
- List<Integer> statusDataPoints = new ArrayList<>();
- intervalStartMillis = graphStartMillis;
- int statusHours = -1;
- for (UptimeHistory hist : knownStatuses) {
- if (hist.getStartMillis() >= graphEndMillis) {
- break;
- }
- if (hist.isRelay() != relay
- || (flag != null && (hist.getFlags() == null
- || !hist.getFlags().contains(flag)))) {
- continue;
- }
- long histEndMillis = hist.getStartMillis() + DateTimeHelper.ONE_HOUR
- * hist.getUptimeHours();
- if (histEndMillis <= intervalStartMillis) {
- continue;
- } else if (histEndMillis > graphEndMillis) {
- histEndMillis = graphEndMillis;
- }
- while (hist.getStartMillis() >= intervalStartMillis
- + dataPointInterval) {
- statusDataPoints.add(statusHours * 5 < dataPointIntervalHours
- ? -1 : statusHours);
- statusHours = -1;
- intervalStartMillis += dataPointInterval;
- }
- while (histEndMillis >= intervalStartMillis + dataPointInterval) {
- if (statusHours < 0) {
- statusHours = 0;
- }
- statusHours += (int) ((intervalStartMillis + dataPointInterval
- - Math.max(Math.max(hist.getStartMillis(),
- firstStatusStartMillis), intervalStartMillis))
- / DateTimeHelper.ONE_HOUR);
- statusDataPoints.add(statusHours * 5 < dataPointIntervalHours
- ? -1 : statusHours);
- statusHours = -1;
- intervalStartMillis += dataPointInterval;
- }
- if (statusHours < 0) {
- statusHours = 0;
- }
- statusHours += (int) ((histEndMillis - Math.max(Math.max(
- hist.getStartMillis(), firstStatusStartMillis),
- intervalStartMillis)) / DateTimeHelper.ONE_HOUR);
- }
- if (statusHours > 0) {
- statusDataPoints.add(statusHours * 5 < dataPointIntervalHours
- ? -1 : statusHours);
- }
- List<Double> dataPoints = new ArrayList<>();
- for (int dataPointIndex = 0; dataPointIndex < statusDataPoints.size();
- dataPointIndex++) {
- if (dataPointIndex >= uptimeDataPoints.size()) {
- dataPoints.add(0.0);
- } else if (uptimeDataPoints.get(dataPointIndex) >= 0
- && statusDataPoints.get(dataPointIndex) > 0) {
- dataPoints.add(((double) uptimeDataPoints.get(dataPointIndex))
- / ((double) statusDataPoints.get(dataPointIndex)));
- } else {
- dataPoints.add(-1.0);
- }
- }
- int firstNonNullIndex = -1;
- int lastNonNullIndex = -1;
- for (int dataPointIndex = 0; dataPointIndex < dataPoints.size();
- dataPointIndex++) {
- double dataPoint = dataPoints.get(dataPointIndex);
- if (dataPoint >= 0.0) {
- if (firstNonNullIndex < 0) {
- firstNonNullIndex = dataPointIndex;
- }
- lastNonNullIndex = dataPointIndex;
- }
- }
- if (firstNonNullIndex < 0) {
- /* Not a single non-negative value in the data points. */
+ private Map<String, GraphHistory> compileUptimeHistory(boolean relay,
+ SortedSet<UptimeHistory> history, SortedSet<UptimeHistory> knownStatuses,
+ long lastSeenMillis, String flag) {
+
+ /* Extracting history entries for compiling GraphHistory objects is a bit
+ * harder than for the other document types. The reason is that we have to
+ * combine (A) uptime history of all relays/bridges and (B) uptime history
+ * of the relay/bridge that we're writing the document for. We're going to
+ * refer to A and B below, to simplify descriptions a bit. */
+
+ /* If there are either no A entries or no B entries, we can't compile
+ * graphs. */
+ if (history.isEmpty() || knownStatuses.isEmpty()) {
return null;
}
- long firstDataPointMillis = graphStartMillis + firstNonNullIndex
- * dataPointInterval + dataPointInterval / 2L;
- if (graphIntervalIndex > 0 && firstDataPointMillis >= LocalDateTime
- .ofEpochSecond(graphEndMillis / 1000L, 0, ZoneOffset.UTC)
- .minus(graphIntervals[graphIntervalIndex - 1])
- .toEpochSecond(ZoneOffset.UTC) * 1000L) {
- /* Skip uptime history object, because it doesn't contain
- * anything new that wasn't already contained in the last
- * uptime history object(s). */
+
+ /* Initialize the graph history compiler, and tell it that history entries
+ * are divisible. This is different from the other history writers. */
+ GraphHistoryCompiler ghc = new GraphHistoryCompiler(
+ lastSeenMillis + DateTimeHelper.ONE_HOUR);
+ for (int i = 0; i < this.graphIntervals.length; i++) {
+ ghc.addGraphType(this.graphNames[i], this.graphIntervals[i],
+ this.dataPointIntervals[i]);
+ }
+ ghc.setDivisible(true);
+
+ /* The general idea for extracting history entries and passing them to the
+ * graph history compiler is to iterate over A entries one by one and keep
+ * an Iterator for B entries to move forward as "time" proceeds. */
+ Iterator<UptimeHistory> historyIterator = history.iterator();
+ UptimeHistory hist;
+ do {
+ hist = historyIterator.hasNext() ? historyIterator.next() : null;
+ } while (null != hist && (hist.isRelay() != relay
+ || (null != flag && (null == hist.getFlags()
+ || !hist.getFlags().contains(flag)))));
+
+ /* If there is not at least one B entry, we can't compile graphs. */
+ if (null == hist) {
return null;
}
- long lastDataPointMillis = firstDataPointMillis
- + (lastNonNullIndex - firstNonNullIndex) * dataPointInterval;
- int count = lastNonNullIndex - firstNonNullIndex + 1;
- GraphHistory graphHistory = new GraphHistory();
- graphHistory.setFirst(firstDataPointMillis);
- graphHistory.setLast(lastDataPointMillis);
- graphHistory.setInterval((int) (dataPointInterval
- / DateTimeHelper.ONE_SECOND));
- graphHistory.setFactor(1.0 / 999.0);
- graphHistory.setCount(count);
- int previousNonNullIndex = -2;
- boolean foundTwoAdjacentDataPoints = false;
- List<Integer> values = new ArrayList<>();
- for (int dataPointIndex = firstNonNullIndex; dataPointIndex
- <= lastNonNullIndex; dataPointIndex++) {
- double dataPoint = dataPoints.get(dataPointIndex);
- if (dataPoint >= 0.0) {
- if (dataPointIndex - previousNonNullIndex == 1) {
- foundTwoAdjacentDataPoints = true;
- }
- previousNonNullIndex = dataPointIndex;
+
+ for (UptimeHistory statuses : knownStatuses) {
+
+ /* If this A entry contains uptime information that we're not interested
+ * in, skip it. */
+ if (statuses.isRelay() != relay
+ || (null != flag && (null == statuses.getFlags()
+ || !statuses.getFlags().contains(flag)))) {
+ continue;
}
- values.add(dataPoint < -0.5 ? null : ((int) (dataPoint * 999.0)));
- }
- graphHistory.setValues(values);
- if (foundTwoAdjacentDataPoints) {
- return graphHistory;
- } else {
- /* There are no two adjacent values in the data points that are
- * required to draw a line graph. */
- return null;
+
+ /* The "current" time is the time that we're currently considering as part
+ * of the A entry. It starts out as the interval start, but as we may
+ * consider multiple B entries, it may proceed. The loop ends when
+ * "current" time has reached the end of the considered A entry. */
+ long currentTimeMillis = statuses.getStartMillis();
+ do {
+ if (null == hist) {
+
+ /* There is no B entry left, which means that the relay/bridge was
+ * offline from "current" time to the end of the A entry. */
+ ghc.addHistoryEntry(currentTimeMillis, statuses.getEndMillis(),0.0);
+ currentTimeMillis = statuses.getEndMillis();
+ } else if (statuses.getEndMillis() <= hist.getStartMillis()) {
+
+ /* This A entry ends before the B entry starts. If there was an
+ * earlier B entry, count this time as offline time. */
+ if (history.first().getStartMillis() <= currentTimeMillis) {
+ ghc.addHistoryEntry(currentTimeMillis, statuses.getEndMillis(),
+ 0.0);
+ }
+ currentTimeMillis = statuses.getEndMillis();
+ } else {
+
+ /* A and B entries overlap. First, if there's time between "current"
+ * time and the time when B starts, possibly count that as offline
+ * time, but only if the relay was around earlier. */
+ if (currentTimeMillis < hist.getStartMillis()) {
+ if (history.first().getStartMillis() <= currentTimeMillis) {
+ ghc.addHistoryEntry(currentTimeMillis, hist.getStartMillis(),
+ 0.0);
+ }
+ currentTimeMillis = hist.getStartMillis();
+ }
+
+ /* Now handle the actually overlapping part. First determine when the
+ * overlap ends, then add a history entry with the number of uptime
+ * milliseconds as value. */
+ long overlapEndMillis = Math.min(statuses.getEndMillis(),
+ hist.getEndMillis());
+ ghc.addHistoryEntry(currentTimeMillis, overlapEndMillis,
+ overlapEndMillis - currentTimeMillis);
+ currentTimeMillis = overlapEndMillis;
+
+ /* If A ends after B, move on to the next B entry. */
+ if (statuses.getEndMillis() >= hist.getEndMillis()) {
+ do {
+ hist = historyIterator.hasNext() ? historyIterator.next() : null;
+ } while (null != hist && (hist.isRelay() != relay
+ || (null != flag && (null == hist.getFlags()
+ || !hist.getFlags().contains(flag)))));
+ }
+ }
+ } while (currentTimeMillis < statuses.getEndMillis());
}
+
+ /* Now that the graph history compiler knows all relevant history, ask it to
+ * compile graphs for us, and return them. */
+ return ghc.compileGraphHistories();
}
@Override
diff --git a/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java b/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java
index f4e2c3a..b34a9e6 100644
--- a/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java
+++ b/src/main/java/org/torproject/onionoo/writer/WeightsDocumentWriter.java
@@ -15,12 +15,7 @@ import org.torproject.onionoo.docs.WeightsStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import java.time.LocalDateTime;
import java.time.Period;
-import java.time.ZoneOffset;
-import java.util.ArrayList;
-import java.util.LinkedHashMap;
-import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.SortedSet;
@@ -105,125 +100,22 @@ public class WeightsDocumentWriter implements DocumentWriter {
private Map<String, GraphHistory> compileGraphType(
SortedMap<long[], double[]> history, long lastSeenMillis,
int graphTypeIndex) {
- Map<String, GraphHistory> graphs = new LinkedHashMap<>();
- for (int graphIntervalIndex = 0; graphIntervalIndex
- < this.graphIntervals.length; graphIntervalIndex++) {
- String graphName = this.graphNames[graphIntervalIndex];
- GraphHistory graphHistory = this.compileWeightsHistory(
- graphTypeIndex, graphIntervalIndex, history, lastSeenMillis);
- if (graphHistory != null) {
- graphs.put(graphName, graphHistory);
- }
+ GraphHistoryCompiler ghc = new GraphHistoryCompiler(
+ lastSeenMillis + DateTimeHelper.ONE_HOUR);
+ for (int i = 0; i < this.graphIntervals.length; i++) {
+ ghc.addGraphType(this.graphNames[i], this.graphIntervals[i],
+ this.dataPointIntervals[i]);
}
- return graphs;
- }
-
- private GraphHistory compileWeightsHistory(int graphTypeIndex,
- int graphIntervalIndex, SortedMap<long[], double[]> history,
- long lastSeenMillis) {
- Period graphInterval = this.graphIntervals[graphIntervalIndex];
- long dataPointInterval =
- this.dataPointIntervals[graphIntervalIndex];
- List<Double> dataPoints = new ArrayList<>();
- long graphEndMillis = ((lastSeenMillis + DateTimeHelper.ONE_HOUR)
- / dataPointInterval) * dataPointInterval;
- long graphStartMillis = LocalDateTime
- .ofEpochSecond(graphEndMillis / 1000L, 0, ZoneOffset.UTC)
- .minus(graphInterval)
- .toEpochSecond(ZoneOffset.UTC) * 1000L;
- long intervalStartMillis = graphStartMillis;
- long totalMillis = 0L;
- double totalWeightTimesMillis = 0.0;
for (Map.Entry<long[], double[]> e : history.entrySet()) {
long startMillis = e.getKey()[0];
long endMillis = e.getKey()[1];
double weight = e.getValue()[graphTypeIndex];
- if (endMillis <= intervalStartMillis) {
- continue;
- } else if (endMillis > graphEndMillis) {
- break;
- }
- while ((intervalStartMillis / dataPointInterval)
- != ((endMillis - 1L) / dataPointInterval)) {
- dataPoints.add(totalMillis * 5L < dataPointInterval
- ? -1.0 : totalWeightTimesMillis / (double) totalMillis);
- totalWeightTimesMillis = 0.0;
- totalMillis = 0L;
- intervalStartMillis += dataPointInterval;
- }
if (weight >= 0.0) {
- totalWeightTimesMillis += weight
- * ((double) (endMillis - startMillis));
- totalMillis += (endMillis - startMillis);
+ ghc.addHistoryEntry(startMillis, endMillis,
+ weight * ((double) (endMillis - startMillis)));
}
}
- dataPoints.add(totalMillis * 5L < dataPointInterval
- ? -1.0 : totalWeightTimesMillis / (double) totalMillis);
- double maxValue = 0.0;
- int firstNonNullIndex = -1;
- int lastNonNullIndex = -1;
- for (int dataPointIndex = 0; dataPointIndex < dataPoints.size();
- dataPointIndex++) {
- double dataPoint = dataPoints.get(dataPointIndex);
- if (dataPoint >= 0.0) {
- if (firstNonNullIndex < 0) {
- firstNonNullIndex = dataPointIndex;
- }
- lastNonNullIndex = dataPointIndex;
- if (dataPoint > maxValue) {
- maxValue = dataPoint;
- }
- }
- }
- if (firstNonNullIndex < 0) {
- /* Not a single non-negative value in the data points. */
- return null;
- }
- long firstDataPointMillis = graphStartMillis + firstNonNullIndex
- * dataPointInterval + dataPointInterval / 2L;
- if (graphIntervalIndex > 0 && firstDataPointMillis >= LocalDateTime
- .ofEpochSecond(graphEndMillis / 1000L, 0, ZoneOffset.UTC)
- .minus(graphIntervals[graphIntervalIndex - 1])
- .toEpochSecond(ZoneOffset.UTC) * 1000L) {
- /* Skip weights history object, because it doesn't contain
- * anything new that wasn't already contained in the last
- * weights history object(s). */
- return null;
- }
- long lastDataPointMillis = firstDataPointMillis
- + (lastNonNullIndex - firstNonNullIndex) * dataPointInterval;
- double factor = ((double) maxValue) / 999.0;
- int count = lastNonNullIndex - firstNonNullIndex + 1;
- GraphHistory graphHistory = new GraphHistory();
- graphHistory.setFirst(firstDataPointMillis);
- graphHistory.setLast(lastDataPointMillis);
- graphHistory.setInterval((int) (dataPointInterval
- / DateTimeHelper.ONE_SECOND));
- graphHistory.setFactor(factor);
- graphHistory.setCount(count);
- int previousNonNullIndex = -2;
- boolean foundTwoAdjacentDataPoints = false;
- List<Integer> values = new ArrayList<>();
- for (int dataPointIndex = firstNonNullIndex; dataPointIndex
- <= lastNonNullIndex; dataPointIndex++) {
- double dataPoint = dataPoints.get(dataPointIndex);
- if (dataPoint >= 0.0) {
- if (dataPointIndex - previousNonNullIndex == 1) {
- foundTwoAdjacentDataPoints = true;
- }
- previousNonNullIndex = dataPointIndex;
- }
- values.add(dataPoint < 0.0 ? null :
- (int) ((dataPoint * 999.0) / maxValue));
- }
- graphHistory.setValues(values);
- if (foundTwoAdjacentDataPoints) {
- return graphHistory;
- } else {
- /* There are no two adjacent values in the data points that are
- * required to draw a line graph. */
- return null;
- }
+ return ghc.compileGraphHistories();
}
@Override
diff --git a/src/test/java/org/torproject/onionoo/writer/BandwidthDocumentWriterTest.java b/src/test/java/org/torproject/onionoo/writer/BandwidthDocumentWriterTest.java
index 324122c..fa76699 100644
--- a/src/test/java/org/torproject/onionoo/writer/BandwidthDocumentWriterTest.java
+++ b/src/test/java/org/torproject/onionoo/writer/BandwidthDocumentWriterTest.java
@@ -74,9 +74,9 @@ public class BandwidthDocumentWriterTest {
assertEquals(1, document.getReadHistory().size());
assertTrue(document.getReadHistory().containsKey("1_month"));
GraphHistory history = document.getReadHistory().get("1_month");
- assertEquals(DateTimeHelper.parse(dayBeforeYesterday + " 14:00:00"),
+ assertEquals(DateTimeHelper.parse(dayBeforeYesterday + " 10:00:00"),
history.getFirst());
- assertEquals(DateTimeHelper.parse(yesterday + " 02:00:00"),
+ assertEquals(DateTimeHelper.parse(dayBeforeYesterday + " 22:00:00"),
history.getLast());
assertEquals(DateTimeHelper.FOUR_HOURS / DateTimeHelper.ONE_SECOND,
(int) history.getInterval());
diff --git a/src/test/java/org/torproject/onionoo/writer/GraphHistoryCompilerTest.java b/src/test/java/org/torproject/onionoo/writer/GraphHistoryCompilerTest.java
new file mode 100644
index 0000000..6d9c461
--- /dev/null
+++ b/src/test/java/org/torproject/onionoo/writer/GraphHistoryCompilerTest.java
@@ -0,0 +1,203 @@
+/* Copyright 2018 The Tor Project
+ * See LICENSE for licensing information */
+
+package org.torproject.onionoo.writer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import org.torproject.onionoo.docs.DateTimeHelper;
+import org.torproject.onionoo.docs.GraphHistory;
+
+import com.google.gson.Gson;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameter;
+import org.junit.runners.Parameterized.Parameters;
+
+import java.time.Period;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Map;
+
+(a)RunWith(Parameterized.class)
+public class GraphHistoryCompilerTest {
+
+ /** Provide test data. */
+ @Parameters
+ public static Collection<Object[]> data() {
+ return Arrays.asList(new Object[][] {
+ { "Empty history",
+ false, new String[0][], 0, null, null, null, null, null, null,
+ null },
+ { "Single entry right before graphs end",
+ false, new String[][] {
+ new String[] { "2017-12-31 23:00", "2018-01-01 00:00", "1" }},
+ 0, null, null, null, null, null, null, null },
+ { "Two consecutive entries right before graphs end",
+ false, new String[][] {
+ new String[] { "2017-12-31 22:00", "2017-12-31 23:00", "1" },
+ new String[] { "2017-12-31 23:00", "2018-01-01 00:00", "1" }},
+ 1, "1_week", "2017-12-31 22:30", "2017-12-31 23:30", 3600, 0.001, 2,
+ new Integer[] { 999, 999 } },
+ { "Two non-consecutive entries towards graphs end",
+ false, new String[][] {
+ new String[] { "2017-12-31 21:00", "2017-12-31 22:00", "1" },
+ new String[] { "2017-12-31 23:00", "2018-01-01 00:00", "1" }},
+ 0, null, null, null, null, null, null, null },
+ { "Two consecutive entries passing 1 week threshold",
+ false, new String[][] {
+ new String[] { "2017-12-24 23:00", "2017-12-25 00:00", "1" },
+ new String[] { "2017-12-25 00:00", "2017-12-25 01:00", "1" }},
+ 1, "1_month", "2017-12-24 22:00", "2017-12-25 02:00", 14400,
+ 2.7805583361138913E-10, 2, new Integer[] { 999, 999 } },
+ { "Two consecutive 1-hour entries over 1 week from graphs end",
+ false, new String[][] {
+ new String[] { "2017-12-21 22:00", "2017-12-21 23:00", "1" },
+ new String[] { "2017-12-21 23:00", "2017-12-22 00:00", "1" }},
+ 0, null, null, null, null, null, null, null },
+ { "Two consecutive 4-hour entries over 1 week from graphs end",
+ false, new String[][] {
+ new String[] { "2017-12-21 16:00", "2017-12-21 20:00", "1" },
+ new String[] { "2017-12-21 20:00", "2017-12-22 00:00", "1" }},
+ 1, "1_month", "2017-12-21 18:00", "2017-12-21 22:00", 14400, 0.001,
+ 2, new Integer[] { 999, 999 } },
+ { "Two consecutive 4-hour entries right before graphs end",
+ false, new String[][] {
+ new String[] { "2017-12-31 16:00", "2017-12-31 20:00", "1" },
+ new String[] { "2017-12-31 20:00", "2018-01-01 00:00", "1" }},
+ 1, "1_month", "2017-12-31 18:00", "2017-12-31 22:00", 14400, 0.001,
+ 2, new Integer[] { 999, 999 } },
+ { "Single 1-week divisible entry right before graphs end",
+ true, new String[][] {
+ new String[] { "2017-12-25 00:00", "2018-01-01 00:00", "1" }},
+ 1, "1_week", "2017-12-25 00:30", "2017-12-31 23:30", 3600, 0.001,
+ 168, null },
+ { "Single 1-week-and-1-hour divisible entry right before graphs end",
+ true, new String[][] {
+ new String[] { "2017-12-24 23:00", "2018-01-01 00:00", "1" }},
+ 2, "1_month", "2017-12-24 22:00", "2017-12-31 22:00", 14400, 0.001,
+ 43, null },
+ { "Single 66-minute divisible entry right before graphs end",
+ true, new String[][] {
+ new String[] { "2017-12-31 22:54", "2018-01-01 00:00", "1" }},
+ 0, null, null, null, null, null, null, null },
+ { "Single 72-minute divisible entry right before graphs end",
+ true, new String[][] {
+ new String[] { "2017-12-31 22:48", "2018-01-01 00:00", "1" }},
+ 1, "1_week", "2017-12-31 22:30", "2017-12-31 23:30", 3600, 0.001,
+ 2, null },
+ { "Single 6-month divisible entry 6 years before graphs end",
+ true, new String[][] {
+ new String[] { "2012-01-01 00:00", "2012-07-01 00:00", "1" }},
+ 0, null, null, null, null, null, null, null },
+ { "Two consecutive 1-hour entries right after graphs end",
+ false, new String[][] {
+ new String[] { "2018-01-01 00:00", "2018-01-01 01:00", "1" },
+ new String[] { "2018-01-01 01:00", "2018-01-01 02:00", "1" }},
+ 0, null, null, null, null, null, null, null }
+ });
+ }
+
+ @Parameter
+ public String testDescription;
+
+ @Parameter(1)
+ public boolean divisible;
+
+ @Parameter(2)
+ public String[][] historyEntries;
+
+ @Parameter(3)
+ public int expectedGraphs;
+
+ @Parameter(4)
+ public String expectedGraphName;
+
+ @Parameter(5)
+ public String expectedFirst;
+
+ @Parameter(6)
+ public String expectedLast;
+
+ @Parameter(7)
+ public Integer expectedInterval;
+
+ @Parameter(8)
+ public Double expectedFactor;
+
+ @Parameter(9)
+ public Integer expectedCount;
+
+ @Parameter(10)
+ public Integer[] expectedValues;
+
+ private final String[] graphNames = new String[] {
+ "1_week",
+ "1_month",
+ "3_months",
+ "1_year",
+ "5_years" };
+
+ private final Period[] graphIntervals = new Period[] {
+ Period.ofWeeks(1),
+ Period.ofMonths(1),
+ Period.ofMonths(3),
+ Period.ofYears(1),
+ Period.ofYears(5) };
+
+ private final long[] dataPointIntervals = new long[] {
+ DateTimeHelper.ONE_HOUR,
+ DateTimeHelper.FOUR_HOURS,
+ DateTimeHelper.TWELVE_HOURS,
+ DateTimeHelper.TWO_DAYS,
+ DateTimeHelper.TEN_DAYS };
+
+ @Test
+ public void test() {
+ GraphHistoryCompiler ghc = new GraphHistoryCompiler(DateTimeHelper.parse(
+ "2018-01-01 00:00:00"));
+ ghc.setDivisible(this.divisible);
+ for (int i = 0; i < this.graphIntervals.length; i++) {
+ ghc.addGraphType(this.graphNames[i], this.graphIntervals[i],
+ this.dataPointIntervals[i]);
+ }
+ for (String[] historyEntry : this.historyEntries) {
+ ghc.addHistoryEntry(DateTimeHelper.parse(historyEntry[0] + ":00"),
+ DateTimeHelper.parse(historyEntry[1] + ":00"),
+ Double.parseDouble(historyEntry[2]));
+ }
+ Map<String, GraphHistory> compiledGraphHistories =
+ ghc.compileGraphHistories();
+ String message = this.testDescription + "; "
+ + new Gson().toJson(compiledGraphHistories);
+ assertEquals(message, this.expectedGraphs, compiledGraphHistories.size());
+ if (null != this.expectedGraphName) {
+ GraphHistory gh = compiledGraphHistories.get(this.expectedGraphName);
+ assertNotNull(message, gh);
+ if (null != this.expectedFirst) {
+ assertEquals(message, DateTimeHelper.parse(this.expectedFirst + ":00"),
+ gh.getFirst());
+ }
+ if (null != this.expectedLast) {
+ assertEquals(message, DateTimeHelper.parse(this.expectedLast + ":00"),
+ gh.getLast());
+ }
+ if (null != this.expectedInterval) {
+ assertEquals(message, this.expectedInterval, gh.getInterval());
+ }
+ if (null != this.expectedFactor) {
+ assertEquals(message, this.expectedFactor, gh.getFactor(), 0.01);
+ }
+ if (null != this.expectedCount) {
+ assertEquals(message, this.expectedCount, gh.getCount());
+ }
+ if (null != this.expectedValues) {
+ assertEquals(message, Arrays.asList(this.expectedValues),
+ gh.getValues());
+ }
+ }
+ }
+}
diff --git a/src/test/java/org/torproject/onionoo/writer/UptimeDocumentWriterTest.java b/src/test/java/org/torproject/onionoo/writer/UptimeDocumentWriterTest.java
index b1ba2ed..030d100 100644
--- a/src/test/java/org/torproject/onionoo/writer/UptimeDocumentWriterTest.java
+++ b/src/test/java/org/torproject/onionoo/writer/UptimeDocumentWriterTest.java
@@ -248,7 +248,7 @@ public class UptimeDocumentWriterTest {
UptimeDocument.class, GABELMOO_FINGERPRINT);
this.assertOneMonthGraph(document, 2, "2014-03-16 10:00:00",
"2014-03-16 14:00:00", 2,
- Arrays.asList(new Integer[] { 499, 249 }));
+ Arrays.asList(new Integer[] { 999, 499 }));
}
@Test
@@ -256,8 +256,8 @@ public class UptimeDocumentWriterTest {
/* This relay was running for exactly 11 days and 23 hours over 2 years ago.
* This time period exactly matches 100% of a data point interval of 10 days
* plus a tiny bit less than 20% of the next data point interval. */
- this.addStatusOneWeekSample("r 2012-03-05-00 287\n",
- "r 2012-03-05-00 287\n");
+ this.addStatusOneWeekSample("r 2012-03-01-00 287\n",
+ "r 2012-03-01-00 287\n");
UptimeDocumentWriter writer = new UptimeDocumentWriter();
DescriptorSourceFactory.getDescriptorSource().readDescriptors();
writer.writeDocuments();
@@ -274,8 +274,8 @@ public class UptimeDocumentWriterTest {
/* This relay was running for exactly 12 days over 2 years ago. This time
* period exactly matches 100% of a data point interval of 10 days plus 20%
* of the next data point interval. */
- this.addStatusOneWeekSample("r 2012-03-05-00 288\n",
- "r 2012-03-05-00 288\n");
+ this.addStatusOneWeekSample("r 2012-03-01-00 288\n",
+ "r 2012-03-01-00 288\n");
UptimeDocumentWriter writer = new UptimeDocumentWriter();
DescriptorSourceFactory.getDescriptorSource().readDescriptors();
writer.writeDocuments();
@@ -283,8 +283,8 @@ public class UptimeDocumentWriterTest {
this.documentStore.getPerformedStoreOperations());
UptimeDocument document = this.documentStore.getDocument(
UptimeDocument.class, GABELMOO_FINGERPRINT);
- this.assertFiveYearGraph(document, 1, "2012-03-10 00:00:00",
- "2012-03-20 00:00:00", 2, Arrays.asList(new Integer[] { 999, 999 }));
+ this.assertFiveYearGraph(document, 1, "2012-03-06 00:00:00",
+ "2012-03-16 00:00:00", 2, Arrays.asList(new Integer[] { 999, 999 }));
}
}
1
0
commit 9830f7ae5736ad0e3b94d311328b3ef84589b183
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Wed Feb 7 11:27:57 2018 +0100
Prepare for 5.0-1.10.0 release.
---
CHANGELOG.md | 2 +-
build.xml | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 1873443..9ce16b1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,4 @@
-# Changes in version ??
+# Changes in version 5.0-1.10.0 - 2018-02-07
* Medium changes
- Make writing of bandwidth, clients, uptime, and weights documents
diff --git a/build.xml b/build.xml
index 7833807..762202c 100644
--- a/build.xml
+++ b/build.xml
@@ -10,7 +10,7 @@
<property name="implementation-title" value="Onionoo" />
<property name="onionoo.protocol.version" value="5.0"/>
<property name="release.version"
- value="${onionoo.protocol.version}-1.9.0-dev"/>
+ value="${onionoo.protocol.version}-1.10.0"/>
<property name="metricslibversion" value="2.1.1"/>
<property name="jetty.version" value="-9.2.21.v20170120" />
<property name="warfile"
1
0
commit 03bc88c23bee7e5bdea45987252ed5b6d28dbcf1
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Tue Oct 17 21:21:18 2017 +0200
Bump version to 2.1.1-dev.
---
build.xml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/build.xml b/build.xml
index badaf37..72c1de1 100644
--- a/build.xml
+++ b/build.xml
@@ -6,7 +6,7 @@
<project default="usage" name="metrics-lib" basedir=".">
- <property name="release.version" value="2.1.1" />
+ <property name="release.version" value="2.1.1-dev" />
<property name="javadoc-title" value="Tor Metrics Library API Documentation"/>
<property name="javadoc-excludes" value="**/impl/** **/index/** **/internal/** **/log/**" />
<property name="implementation-title" value="Tor Metrics Library" />
1
0
commit 2152ece320cf2ed797fe438ff61882ccc7a30b2f
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Tue Jan 9 10:24:25 2018 +0100
Update copyright to 2018.
---
src/main/java/org/torproject/descriptor/BandwidthHistory.java | 2 +-
src/main/java/org/torproject/descriptor/BridgeExtraInfoDescriptor.java | 2 +-
src/main/java/org/torproject/descriptor/BridgeNetworkStatus.java | 2 +-
src/main/java/org/torproject/descriptor/BridgePoolAssignment.java | 2 +-
src/main/java/org/torproject/descriptor/BridgeServerDescriptor.java | 2 +-
src/main/java/org/torproject/descriptor/Descriptor.java | 2 +-
src/main/java/org/torproject/descriptor/DescriptorCollector.java | 2 +-
src/main/java/org/torproject/descriptor/DescriptorParseException.java | 2 +-
src/main/java/org/torproject/descriptor/DescriptorParser.java | 2 +-
src/main/java/org/torproject/descriptor/DescriptorReader.java | 2 +-
src/main/java/org/torproject/descriptor/DescriptorSourceFactory.java | 2 +-
src/main/java/org/torproject/descriptor/DirSourceEntry.java | 2 +-
src/main/java/org/torproject/descriptor/DirectoryKeyCertificate.java | 2 +-
src/main/java/org/torproject/descriptor/DirectorySignature.java | 2 +-
src/main/java/org/torproject/descriptor/ExitList.java | 2 +-
src/main/java/org/torproject/descriptor/ExtraInfoDescriptor.java | 2 +-
src/main/java/org/torproject/descriptor/Microdescriptor.java | 2 +-
src/main/java/org/torproject/descriptor/NetworkStatusEntry.java | 2 +-
src/main/java/org/torproject/descriptor/RelayDirectory.java | 2 +-
src/main/java/org/torproject/descriptor/RelayExtraInfoDescriptor.java | 2 +-
src/main/java/org/torproject/descriptor/RelayNetworkStatus.java | 2 +-
.../java/org/torproject/descriptor/RelayNetworkStatusConsensus.java | 2 +-
src/main/java/org/torproject/descriptor/RelayNetworkStatusVote.java | 2 +-
src/main/java/org/torproject/descriptor/RelayServerDescriptor.java | 2 +-
src/main/java/org/torproject/descriptor/RouterStatusEntry.java | 2 +-
src/main/java/org/torproject/descriptor/ServerDescriptor.java | 2 +-
src/main/java/org/torproject/descriptor/TorperfResult.java | 2 +-
src/main/java/org/torproject/descriptor/UnparseableDescriptor.java | 2 +-
src/main/java/org/torproject/descriptor/impl/BandwidthHistoryImpl.java | 2 +-
src/main/java/org/torproject/descriptor/impl/BlockingIteratorImpl.java | 2 +-
.../org/torproject/descriptor/impl/BridgeExtraInfoDescriptorImpl.java | 2 +-
.../java/org/torproject/descriptor/impl/BridgeNetworkStatusImpl.java | 2 +-
.../java/org/torproject/descriptor/impl/BridgePoolAssignmentImpl.java | 2 +-
.../java/org/torproject/descriptor/impl/BridgeServerDescriptorImpl.java | 2 +-
src/main/java/org/torproject/descriptor/impl/DescriptorImpl.java | 2 +-
src/main/java/org/torproject/descriptor/impl/DescriptorParserImpl.java | 2 +-
src/main/java/org/torproject/descriptor/impl/DescriptorReaderImpl.java | 2 +-
src/main/java/org/torproject/descriptor/impl/DirSourceEntryImpl.java | 2 +-
.../org/torproject/descriptor/impl/DirectoryKeyCertificateImpl.java | 2 +-
.../java/org/torproject/descriptor/impl/DirectorySignatureImpl.java | 2 +-
src/main/java/org/torproject/descriptor/impl/ExitListEntryImpl.java | 2 +-
src/main/java/org/torproject/descriptor/impl/ExitListImpl.java | 2 +-
.../java/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java | 2 +-
src/main/java/org/torproject/descriptor/impl/KeyValueMap.java | 2 +-
src/main/java/org/torproject/descriptor/impl/MicrodescriptorImpl.java | 2 +-
.../java/org/torproject/descriptor/impl/NetworkStatusEntryImpl.java | 2 +-
src/main/java/org/torproject/descriptor/impl/NetworkStatusImpl.java | 2 +-
src/main/java/org/torproject/descriptor/impl/ParseHelper.java | 2 +-
src/main/java/org/torproject/descriptor/impl/RelayDirectoryImpl.java | 2 +-
.../org/torproject/descriptor/impl/RelayExtraInfoDescriptorImpl.java | 2 +-
.../org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java | 2 +-
.../java/org/torproject/descriptor/impl/RelayNetworkStatusImpl.java | 2 +-
.../java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java | 2 +-
.../java/org/torproject/descriptor/impl/RelayServerDescriptorImpl.java | 2 +-
src/main/java/org/torproject/descriptor/impl/RouterStatusEntryImpl.java | 2 +-
src/main/java/org/torproject/descriptor/impl/ServerDescriptorImpl.java | 2 +-
src/main/java/org/torproject/descriptor/impl/TorperfResultImpl.java | 2 +-
.../java/org/torproject/descriptor/impl/UnparseableDescriptorImpl.java | 2 +-
.../java/org/torproject/descriptor/index/DescriptorIndexCollector.java | 2 +-
src/main/java/org/torproject/descriptor/index/DirectoryNode.java | 2 +-
src/main/java/org/torproject/descriptor/index/FileNode.java | 2 +-
src/main/java/org/torproject/descriptor/index/IndexNode.java | 2 +-
src/main/java/org/torproject/descriptor/index/package-info.java | 2 +-
src/main/java/org/torproject/descriptor/internal/FileType.java | 2 +-
src/main/java/org/torproject/descriptor/package-info.java | 2 +-
src/main/resources/bootstrap-development.sh | 2 +-
src/main/resources/examples/ConsensusWeightByVersion.java | 2 +-
src/main/resources/examples/DownloadConsensuses.java | 2 +-
src/main/resources/examples/PluggableTransports.java | 2 +-
.../java/org/torproject/descriptor/DescriptorSourceFactoryTest.java | 2 +-
src/test/java/org/torproject/descriptor/DescriptorTest.java | 2 +-
.../java/org/torproject/descriptor/DummyCollectorImplementation.java | 2 +-
src/test/java/org/torproject/descriptor/DummyParserImplementation.java | 2 +-
src/test/java/org/torproject/descriptor/DummyReaderImplementation.java | 2 +-
.../java/org/torproject/descriptor/benchmark/MeasurePerformance.java | 2 +-
.../java/org/torproject/descriptor/impl/BridgeNetworkStatusTest.java | 2 +-
src/test/java/org/torproject/descriptor/impl/ConsensusBuilder.java | 2 +-
src/test/java/org/torproject/descriptor/impl/DescriptorImplTest.java | 2 +-
.../java/org/torproject/descriptor/impl/DescriptorParserImplTest.java | 2 +-
.../java/org/torproject/descriptor/impl/DescriptorReaderImplTest.java | 2 +-
src/test/java/org/torproject/descriptor/impl/ExitListImplTest.java | 2 +-
.../org/torproject/descriptor/impl/ExtraInfoDescriptorImplTest.java | 2 +-
.../java/org/torproject/descriptor/impl/MicrodescriptorImplTest.java | 2 +-
.../torproject/descriptor/impl/RelayNetworkStatusConsensusImplTest.java | 2 +-
.../java/org/torproject/descriptor/impl/RelayNetworkStatusImplTest.java | 2 +-
.../org/torproject/descriptor/impl/RelayNetworkStatusVoteImplTest.java | 2 +-
.../java/org/torproject/descriptor/impl/ServerDescriptorImplTest.java | 2 +-
src/test/java/org/torproject/descriptor/impl/TestDescriptor.java | 2 +-
src/test/java/org/torproject/descriptor/impl/TestServerDescriptor.java | 2 +-
src/test/java/org/torproject/descriptor/impl/TorperfResultImplTest.java | 2 +-
.../org/torproject/descriptor/index/DescriptorIndexCollectorTest.java | 2 +-
src/test/java/org/torproject/descriptor/index/DirectoryNodeTest.java | 2 +-
src/test/java/org/torproject/descriptor/index/FileNodeTest.java | 2 +-
src/test/java/org/torproject/descriptor/index/IndexNodeTest.java | 2 +-
94 files changed, 94 insertions(+), 94 deletions(-)
diff --git a/src/main/java/org/torproject/descriptor/BandwidthHistory.java b/src/main/java/org/torproject/descriptor/BandwidthHistory.java
index 344d0df..cc1e58f 100644
--- a/src/main/java/org/torproject/descriptor/BandwidthHistory.java
+++ b/src/main/java/org/torproject/descriptor/BandwidthHistory.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/BridgeExtraInfoDescriptor.java b/src/main/java/org/torproject/descriptor/BridgeExtraInfoDescriptor.java
index e3cd5d1..d2fa37d 100644
--- a/src/main/java/org/torproject/descriptor/BridgeExtraInfoDescriptor.java
+++ b/src/main/java/org/torproject/descriptor/BridgeExtraInfoDescriptor.java
@@ -1,4 +1,4 @@
-/* Copyright 2015--2017 The Tor Project
+/* Copyright 2015--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/BridgeNetworkStatus.java b/src/main/java/org/torproject/descriptor/BridgeNetworkStatus.java
index ca2979c..62f9edf 100644
--- a/src/main/java/org/torproject/descriptor/BridgeNetworkStatus.java
+++ b/src/main/java/org/torproject/descriptor/BridgeNetworkStatus.java
@@ -1,4 +1,4 @@
-/* Copyright 2011--2017 The Tor Project
+/* Copyright 2011--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/BridgePoolAssignment.java b/src/main/java/org/torproject/descriptor/BridgePoolAssignment.java
index 8f40a74..4d15b81 100644
--- a/src/main/java/org/torproject/descriptor/BridgePoolAssignment.java
+++ b/src/main/java/org/torproject/descriptor/BridgePoolAssignment.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/BridgeServerDescriptor.java b/src/main/java/org/torproject/descriptor/BridgeServerDescriptor.java
index 2a2fdc4..47ee9f4 100644
--- a/src/main/java/org/torproject/descriptor/BridgeServerDescriptor.java
+++ b/src/main/java/org/torproject/descriptor/BridgeServerDescriptor.java
@@ -1,4 +1,4 @@
-/* Copyright 2015--2017 The Tor Project
+/* Copyright 2015--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/Descriptor.java b/src/main/java/org/torproject/descriptor/Descriptor.java
index 35ef38b..da51ce2 100644
--- a/src/main/java/org/torproject/descriptor/Descriptor.java
+++ b/src/main/java/org/torproject/descriptor/Descriptor.java
@@ -1,4 +1,4 @@
-/* Copyright 2011--2017 The Tor Project
+/* Copyright 2011--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/DescriptorCollector.java b/src/main/java/org/torproject/descriptor/DescriptorCollector.java
index fb0668c..f27d8fc 100644
--- a/src/main/java/org/torproject/descriptor/DescriptorCollector.java
+++ b/src/main/java/org/torproject/descriptor/DescriptorCollector.java
@@ -1,4 +1,4 @@
-/* Copyright 2015--2017 The Tor Project
+/* Copyright 2015--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/DescriptorParseException.java b/src/main/java/org/torproject/descriptor/DescriptorParseException.java
index c9e7d93..7594b45 100644
--- a/src/main/java/org/torproject/descriptor/DescriptorParseException.java
+++ b/src/main/java/org/torproject/descriptor/DescriptorParseException.java
@@ -1,4 +1,4 @@
-/* Copyright 2014--2017 The Tor Project
+/* Copyright 2014--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/DescriptorParser.java b/src/main/java/org/torproject/descriptor/DescriptorParser.java
index 259510f..d530a2b 100644
--- a/src/main/java/org/torproject/descriptor/DescriptorParser.java
+++ b/src/main/java/org/torproject/descriptor/DescriptorParser.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/DescriptorReader.java b/src/main/java/org/torproject/descriptor/DescriptorReader.java
index 4adff39..d41e6b4 100644
--- a/src/main/java/org/torproject/descriptor/DescriptorReader.java
+++ b/src/main/java/org/torproject/descriptor/DescriptorReader.java
@@ -1,4 +1,4 @@
-/* Copyright 2011--2017 The Tor Project
+/* Copyright 2011--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/DescriptorSourceFactory.java b/src/main/java/org/torproject/descriptor/DescriptorSourceFactory.java
index f2c1a43..495968c 100644
--- a/src/main/java/org/torproject/descriptor/DescriptorSourceFactory.java
+++ b/src/main/java/org/torproject/descriptor/DescriptorSourceFactory.java
@@ -1,4 +1,4 @@
-/* Copyright 2011--2017 The Tor Project
+/* Copyright 2011--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/DirSourceEntry.java b/src/main/java/org/torproject/descriptor/DirSourceEntry.java
index 69e8525..7540c2c 100644
--- a/src/main/java/org/torproject/descriptor/DirSourceEntry.java
+++ b/src/main/java/org/torproject/descriptor/DirSourceEntry.java
@@ -1,4 +1,4 @@
-/* Copyright 2011--2017 The Tor Project
+/* Copyright 2011--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/DirectoryKeyCertificate.java b/src/main/java/org/torproject/descriptor/DirectoryKeyCertificate.java
index 2819fc3..6a02ac3 100644
--- a/src/main/java/org/torproject/descriptor/DirectoryKeyCertificate.java
+++ b/src/main/java/org/torproject/descriptor/DirectoryKeyCertificate.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/DirectorySignature.java b/src/main/java/org/torproject/descriptor/DirectorySignature.java
index 9ce44df..fb66faa 100644
--- a/src/main/java/org/torproject/descriptor/DirectorySignature.java
+++ b/src/main/java/org/torproject/descriptor/DirectorySignature.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/ExitList.java b/src/main/java/org/torproject/descriptor/ExitList.java
index 2623ee5..e549da8 100644
--- a/src/main/java/org/torproject/descriptor/ExitList.java
+++ b/src/main/java/org/torproject/descriptor/ExitList.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/ExtraInfoDescriptor.java b/src/main/java/org/torproject/descriptor/ExtraInfoDescriptor.java
index 333c853..b668eff 100644
--- a/src/main/java/org/torproject/descriptor/ExtraInfoDescriptor.java
+++ b/src/main/java/org/torproject/descriptor/ExtraInfoDescriptor.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/Microdescriptor.java b/src/main/java/org/torproject/descriptor/Microdescriptor.java
index ef69417..5490eba 100644
--- a/src/main/java/org/torproject/descriptor/Microdescriptor.java
+++ b/src/main/java/org/torproject/descriptor/Microdescriptor.java
@@ -1,4 +1,4 @@
-/* Copyright 2014--2017 The Tor Project
+/* Copyright 2014--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/NetworkStatusEntry.java b/src/main/java/org/torproject/descriptor/NetworkStatusEntry.java
index bbc0173..81efde0 100644
--- a/src/main/java/org/torproject/descriptor/NetworkStatusEntry.java
+++ b/src/main/java/org/torproject/descriptor/NetworkStatusEntry.java
@@ -1,4 +1,4 @@
-/* Copyright 2011--2017 The Tor Project
+/* Copyright 2011--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/RelayDirectory.java b/src/main/java/org/torproject/descriptor/RelayDirectory.java
index f05f65d..3e00ebb 100644
--- a/src/main/java/org/torproject/descriptor/RelayDirectory.java
+++ b/src/main/java/org/torproject/descriptor/RelayDirectory.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/RelayExtraInfoDescriptor.java b/src/main/java/org/torproject/descriptor/RelayExtraInfoDescriptor.java
index 8c7c06a..133d9e3 100644
--- a/src/main/java/org/torproject/descriptor/RelayExtraInfoDescriptor.java
+++ b/src/main/java/org/torproject/descriptor/RelayExtraInfoDescriptor.java
@@ -1,4 +1,4 @@
-/* Copyright 2015--2017 The Tor Project
+/* Copyright 2015--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/RelayNetworkStatus.java b/src/main/java/org/torproject/descriptor/RelayNetworkStatus.java
index 1197c2e..5080282 100644
--- a/src/main/java/org/torproject/descriptor/RelayNetworkStatus.java
+++ b/src/main/java/org/torproject/descriptor/RelayNetworkStatus.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/RelayNetworkStatusConsensus.java b/src/main/java/org/torproject/descriptor/RelayNetworkStatusConsensus.java
index 2b433dc..9885172 100644
--- a/src/main/java/org/torproject/descriptor/RelayNetworkStatusConsensus.java
+++ b/src/main/java/org/torproject/descriptor/RelayNetworkStatusConsensus.java
@@ -1,4 +1,4 @@
-/* Copyright 2011--2017 The Tor Project
+/* Copyright 2011--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/RelayNetworkStatusVote.java b/src/main/java/org/torproject/descriptor/RelayNetworkStatusVote.java
index 1e4b0a5..d14b39e 100644
--- a/src/main/java/org/torproject/descriptor/RelayNetworkStatusVote.java
+++ b/src/main/java/org/torproject/descriptor/RelayNetworkStatusVote.java
@@ -1,4 +1,4 @@
-/* Copyright 2011--2017 The Tor Project
+/* Copyright 2011--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/RelayServerDescriptor.java b/src/main/java/org/torproject/descriptor/RelayServerDescriptor.java
index eeb1c01..2e8118a 100644
--- a/src/main/java/org/torproject/descriptor/RelayServerDescriptor.java
+++ b/src/main/java/org/torproject/descriptor/RelayServerDescriptor.java
@@ -1,4 +1,4 @@
-/* Copyright 2015--2017 The Tor Project
+/* Copyright 2015--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/RouterStatusEntry.java b/src/main/java/org/torproject/descriptor/RouterStatusEntry.java
index c2ac5ec..a41b4bd 100644
--- a/src/main/java/org/torproject/descriptor/RouterStatusEntry.java
+++ b/src/main/java/org/torproject/descriptor/RouterStatusEntry.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/ServerDescriptor.java b/src/main/java/org/torproject/descriptor/ServerDescriptor.java
index 0aeb543..ac9c645 100644
--- a/src/main/java/org/torproject/descriptor/ServerDescriptor.java
+++ b/src/main/java/org/torproject/descriptor/ServerDescriptor.java
@@ -1,4 +1,4 @@
-/* Copyright 2011--2017 The Tor Project
+/* Copyright 2011--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/TorperfResult.java b/src/main/java/org/torproject/descriptor/TorperfResult.java
index 1958ed2..f66dbde 100644
--- a/src/main/java/org/torproject/descriptor/TorperfResult.java
+++ b/src/main/java/org/torproject/descriptor/TorperfResult.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/UnparseableDescriptor.java b/src/main/java/org/torproject/descriptor/UnparseableDescriptor.java
index 6282222..b4dc103 100644
--- a/src/main/java/org/torproject/descriptor/UnparseableDescriptor.java
+++ b/src/main/java/org/torproject/descriptor/UnparseableDescriptor.java
@@ -1,4 +1,4 @@
-/* Copyright 2017 The Tor Project
+/* Copyright 2017--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/main/java/org/torproject/descriptor/impl/BandwidthHistoryImpl.java b/src/main/java/org/torproject/descriptor/impl/BandwidthHistoryImpl.java
index ef29a3b..79c185d 100644
--- a/src/main/java/org/torproject/descriptor/impl/BandwidthHistoryImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/BandwidthHistoryImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/BlockingIteratorImpl.java b/src/main/java/org/torproject/descriptor/impl/BlockingIteratorImpl.java
index 4921ac4..0c171ed 100644
--- a/src/main/java/org/torproject/descriptor/impl/BlockingIteratorImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/BlockingIteratorImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2011--2017 The Tor Project
+/* Copyright 2011--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/BridgeExtraInfoDescriptorImpl.java b/src/main/java/org/torproject/descriptor/impl/BridgeExtraInfoDescriptorImpl.java
index d8941a6..0ca4cfd 100644
--- a/src/main/java/org/torproject/descriptor/impl/BridgeExtraInfoDescriptorImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/BridgeExtraInfoDescriptorImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2015--2017 The Tor Project
+/* Copyright 2015--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/BridgeNetworkStatusImpl.java b/src/main/java/org/torproject/descriptor/impl/BridgeNetworkStatusImpl.java
index 66a238e..c3e7cb4 100644
--- a/src/main/java/org/torproject/descriptor/impl/BridgeNetworkStatusImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/BridgeNetworkStatusImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/BridgePoolAssignmentImpl.java b/src/main/java/org/torproject/descriptor/impl/BridgePoolAssignmentImpl.java
index e0e5cd8..58fc872 100644
--- a/src/main/java/org/torproject/descriptor/impl/BridgePoolAssignmentImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/BridgePoolAssignmentImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/BridgeServerDescriptorImpl.java b/src/main/java/org/torproject/descriptor/impl/BridgeServerDescriptorImpl.java
index 8125102..f2de3f2 100644
--- a/src/main/java/org/torproject/descriptor/impl/BridgeServerDescriptorImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/BridgeServerDescriptorImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2015--2017 The Tor Project
+/* Copyright 2015--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/DescriptorImpl.java b/src/main/java/org/torproject/descriptor/impl/DescriptorImpl.java
index eec89a4..918fef8 100644
--- a/src/main/java/org/torproject/descriptor/impl/DescriptorImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/DescriptorImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/DescriptorParserImpl.java b/src/main/java/org/torproject/descriptor/impl/DescriptorParserImpl.java
index ac7ff9c..d32c031 100644
--- a/src/main/java/org/torproject/descriptor/impl/DescriptorParserImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/DescriptorParserImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/DescriptorReaderImpl.java b/src/main/java/org/torproject/descriptor/impl/DescriptorReaderImpl.java
index 2d58573..4da474e 100644
--- a/src/main/java/org/torproject/descriptor/impl/DescriptorReaderImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/DescriptorReaderImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2011--2017 The Tor Project
+/* Copyright 2011--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/DirSourceEntryImpl.java b/src/main/java/org/torproject/descriptor/impl/DirSourceEntryImpl.java
index 630b886..a00ffa1 100644
--- a/src/main/java/org/torproject/descriptor/impl/DirSourceEntryImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/DirSourceEntryImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2011--2017 The Tor Project
+/* Copyright 2011--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/DirectoryKeyCertificateImpl.java b/src/main/java/org/torproject/descriptor/impl/DirectoryKeyCertificateImpl.java
index 81ece3c..cdc9d44 100644
--- a/src/main/java/org/torproject/descriptor/impl/DirectoryKeyCertificateImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/DirectoryKeyCertificateImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/DirectorySignatureImpl.java b/src/main/java/org/torproject/descriptor/impl/DirectorySignatureImpl.java
index b638002..6430e7f 100644
--- a/src/main/java/org/torproject/descriptor/impl/DirectorySignatureImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/DirectorySignatureImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/ExitListEntryImpl.java b/src/main/java/org/torproject/descriptor/impl/ExitListEntryImpl.java
index 06b6a96..5389ce3 100644
--- a/src/main/java/org/torproject/descriptor/impl/ExitListEntryImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/ExitListEntryImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/ExitListImpl.java b/src/main/java/org/torproject/descriptor/impl/ExitListImpl.java
index 454efdc..bd5b2b6 100644
--- a/src/main/java/org/torproject/descriptor/impl/ExitListImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/ExitListImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java b/src/main/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java
index 3f84902..99ea13e 100644
--- a/src/main/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/KeyValueMap.java b/src/main/java/org/torproject/descriptor/impl/KeyValueMap.java
index a1eab05..c048b94 100644
--- a/src/main/java/org/torproject/descriptor/impl/KeyValueMap.java
+++ b/src/main/java/org/torproject/descriptor/impl/KeyValueMap.java
@@ -1,4 +1,4 @@
-/* Copyright 2017 The Tor Project
+/* Copyright 2017--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/MicrodescriptorImpl.java b/src/main/java/org/torproject/descriptor/impl/MicrodescriptorImpl.java
index 6acb845..f91362e 100644
--- a/src/main/java/org/torproject/descriptor/impl/MicrodescriptorImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/MicrodescriptorImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2014--2017 The Tor Project
+/* Copyright 2014--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/NetworkStatusEntryImpl.java b/src/main/java/org/torproject/descriptor/impl/NetworkStatusEntryImpl.java
index e6f7bad..f869918 100644
--- a/src/main/java/org/torproject/descriptor/impl/NetworkStatusEntryImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/NetworkStatusEntryImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2011--2017 The Tor Project
+/* Copyright 2011--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/NetworkStatusImpl.java b/src/main/java/org/torproject/descriptor/impl/NetworkStatusImpl.java
index b025c1b..60a9ff3 100644
--- a/src/main/java/org/torproject/descriptor/impl/NetworkStatusImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/NetworkStatusImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2011--2017 The Tor Project
+/* Copyright 2011--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/ParseHelper.java b/src/main/java/org/torproject/descriptor/impl/ParseHelper.java
index 1c7aa93..d0c83f0 100644
--- a/src/main/java/org/torproject/descriptor/impl/ParseHelper.java
+++ b/src/main/java/org/torproject/descriptor/impl/ParseHelper.java
@@ -1,4 +1,4 @@
-/* Copyright 2011--2017 The Tor Project
+/* Copyright 2011--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/RelayDirectoryImpl.java b/src/main/java/org/torproject/descriptor/impl/RelayDirectoryImpl.java
index a312f24..4c457f8 100644
--- a/src/main/java/org/torproject/descriptor/impl/RelayDirectoryImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/RelayDirectoryImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/RelayExtraInfoDescriptorImpl.java b/src/main/java/org/torproject/descriptor/impl/RelayExtraInfoDescriptorImpl.java
index 7ed696e..e24645f 100644
--- a/src/main/java/org/torproject/descriptor/impl/RelayExtraInfoDescriptorImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/RelayExtraInfoDescriptorImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2015--2017 The Tor Project
+/* Copyright 2015--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java
index 87ce59a..bb14c28 100644
--- a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2011--2017 The Tor Project
+/* Copyright 2011--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusImpl.java b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusImpl.java
index d2be570..6158a54 100644
--- a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java
index df36b26..bc87c66 100644
--- a/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2011--2017 The Tor Project
+/* Copyright 2011--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/RelayServerDescriptorImpl.java b/src/main/java/org/torproject/descriptor/impl/RelayServerDescriptorImpl.java
index fd2464b..0d1b7a0 100644
--- a/src/main/java/org/torproject/descriptor/impl/RelayServerDescriptorImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/RelayServerDescriptorImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2015--2017 The Tor Project
+/* Copyright 2015--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/RouterStatusEntryImpl.java b/src/main/java/org/torproject/descriptor/impl/RouterStatusEntryImpl.java
index 6f07b81..6678ce7 100644
--- a/src/main/java/org/torproject/descriptor/impl/RouterStatusEntryImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/RouterStatusEntryImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/ServerDescriptorImpl.java b/src/main/java/org/torproject/descriptor/impl/ServerDescriptorImpl.java
index 80ed473..ca79cd2 100644
--- a/src/main/java/org/torproject/descriptor/impl/ServerDescriptorImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/ServerDescriptorImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/TorperfResultImpl.java b/src/main/java/org/torproject/descriptor/impl/TorperfResultImpl.java
index 65b9117..d61afec 100644
--- a/src/main/java/org/torproject/descriptor/impl/TorperfResultImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/TorperfResultImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/impl/UnparseableDescriptorImpl.java b/src/main/java/org/torproject/descriptor/impl/UnparseableDescriptorImpl.java
index 7174621..eca29c9 100644
--- a/src/main/java/org/torproject/descriptor/impl/UnparseableDescriptorImpl.java
+++ b/src/main/java/org/torproject/descriptor/impl/UnparseableDescriptorImpl.java
@@ -1,4 +1,4 @@
-/* Copyright 2017 The Tor Project
+/* Copyright 2017--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/main/java/org/torproject/descriptor/index/DescriptorIndexCollector.java b/src/main/java/org/torproject/descriptor/index/DescriptorIndexCollector.java
index 4796263..be79386 100644
--- a/src/main/java/org/torproject/descriptor/index/DescriptorIndexCollector.java
+++ b/src/main/java/org/torproject/descriptor/index/DescriptorIndexCollector.java
@@ -1,4 +1,4 @@
-/* Copyright 2015--2017 The Tor Project
+/* Copyright 2015--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.index;
diff --git a/src/main/java/org/torproject/descriptor/index/DirectoryNode.java b/src/main/java/org/torproject/descriptor/index/DirectoryNode.java
index ad9ba74..859493b 100644
--- a/src/main/java/org/torproject/descriptor/index/DirectoryNode.java
+++ b/src/main/java/org/torproject/descriptor/index/DirectoryNode.java
@@ -1,4 +1,4 @@
-/* Copyright 2016--2017 The Tor Project
+/* Copyright 2016--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.index;
diff --git a/src/main/java/org/torproject/descriptor/index/FileNode.java b/src/main/java/org/torproject/descriptor/index/FileNode.java
index aa7c1fb..eb34131 100644
--- a/src/main/java/org/torproject/descriptor/index/FileNode.java
+++ b/src/main/java/org/torproject/descriptor/index/FileNode.java
@@ -1,4 +1,4 @@
-/* Copyright 2016--2017 The Tor Project
+/* Copyright 2016--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.index;
diff --git a/src/main/java/org/torproject/descriptor/index/IndexNode.java b/src/main/java/org/torproject/descriptor/index/IndexNode.java
index 8b61b75..4c4c884 100644
--- a/src/main/java/org/torproject/descriptor/index/IndexNode.java
+++ b/src/main/java/org/torproject/descriptor/index/IndexNode.java
@@ -1,4 +1,4 @@
-/* Copyright 2016--2017 The Tor Project
+/* Copyright 2016--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.index;
diff --git a/src/main/java/org/torproject/descriptor/index/package-info.java b/src/main/java/org/torproject/descriptor/index/package-info.java
index cfb77ca..c685c63 100644
--- a/src/main/java/org/torproject/descriptor/index/package-info.java
+++ b/src/main/java/org/torproject/descriptor/index/package-info.java
@@ -1,4 +1,4 @@
-/* Copyright 2016--2017 The Tor Project
+/* Copyright 2016--2018 The Tor Project
* See LICENSE for licensing information */
/**
diff --git a/src/main/java/org/torproject/descriptor/internal/FileType.java b/src/main/java/org/torproject/descriptor/internal/FileType.java
index 47bbd28..36b5df8 100644
--- a/src/main/java/org/torproject/descriptor/internal/FileType.java
+++ b/src/main/java/org/torproject/descriptor/internal/FileType.java
@@ -1,4 +1,4 @@
-/* Copyright 2016--2017 The Tor Project
+/* Copyright 2016--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.internal;
diff --git a/src/main/java/org/torproject/descriptor/package-info.java b/src/main/java/org/torproject/descriptor/package-info.java
index 5827115..0410bac 100644
--- a/src/main/java/org/torproject/descriptor/package-info.java
+++ b/src/main/java/org/torproject/descriptor/package-info.java
@@ -1,4 +1,4 @@
-/* Copyright 2016--2017 The Tor Project
+/* Copyright 2016--2018 The Tor Project
* See LICENSE for licensing information */
/**
diff --git a/src/main/resources/bootstrap-development.sh b/src/main/resources/bootstrap-development.sh
index 28fb975..d301e25 100755
--- a/src/main/resources/bootstrap-development.sh
+++ b/src/main/resources/bootstrap-development.sh
@@ -1,6 +1,6 @@
#!/bin/sh
#
-# Copyright 2016--2017 The Tor Project
+# Copyright 2016--2018 The Tor Project
# See LICENSE for licensing information
#
# Use for submodule initialization and checkout.
diff --git a/src/main/resources/examples/ConsensusWeightByVersion.java b/src/main/resources/examples/ConsensusWeightByVersion.java
index 5fc7c1c..5026999 100644
--- a/src/main/resources/examples/ConsensusWeightByVersion.java
+++ b/src/main/resources/examples/ConsensusWeightByVersion.java
@@ -1,4 +1,4 @@
-/* Copyright 2017 The Tor Project
+/* Copyright 2017--2018 The Tor Project
* See LICENSE for licensing information */
import org.torproject.descriptor.*;
diff --git a/src/main/resources/examples/DownloadConsensuses.java b/src/main/resources/examples/DownloadConsensuses.java
index a592928..359c76c 100644
--- a/src/main/resources/examples/DownloadConsensuses.java
+++ b/src/main/resources/examples/DownloadConsensuses.java
@@ -1,4 +1,4 @@
-/* Copyright 2017 The Tor Project
+/* Copyright 2017--2018 The Tor Project
* See LICENSE for licensing information */
import org.torproject.descriptor.*;
diff --git a/src/main/resources/examples/PluggableTransports.java b/src/main/resources/examples/PluggableTransports.java
index 65ce732..102adf0 100644
--- a/src/main/resources/examples/PluggableTransports.java
+++ b/src/main/resources/examples/PluggableTransports.java
@@ -1,4 +1,4 @@
-/* Copyright 2017 The Tor Project
+/* Copyright 2017--2018 The Tor Project
* See LICENSE for licensing information */
import org.torproject.descriptor.*;
diff --git a/src/test/java/org/torproject/descriptor/DescriptorSourceFactoryTest.java b/src/test/java/org/torproject/descriptor/DescriptorSourceFactoryTest.java
index 3a9d502..d9549e5 100644
--- a/src/test/java/org/torproject/descriptor/DescriptorSourceFactoryTest.java
+++ b/src/test/java/org/torproject/descriptor/DescriptorSourceFactoryTest.java
@@ -1,4 +1,4 @@
-/* Copyright 2016--2017 The Tor Project
+/* Copyright 2016--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/test/java/org/torproject/descriptor/DescriptorTest.java b/src/test/java/org/torproject/descriptor/DescriptorTest.java
index 9a07cdf..2dd72e7 100644
--- a/src/test/java/org/torproject/descriptor/DescriptorTest.java
+++ b/src/test/java/org/torproject/descriptor/DescriptorTest.java
@@ -1,4 +1,4 @@
-/* Copyright 2017 The Tor Project
+/* Copyright 2017--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/test/java/org/torproject/descriptor/DummyCollectorImplementation.java b/src/test/java/org/torproject/descriptor/DummyCollectorImplementation.java
index 130a718..219bd2a 100644
--- a/src/test/java/org/torproject/descriptor/DummyCollectorImplementation.java
+++ b/src/test/java/org/torproject/descriptor/DummyCollectorImplementation.java
@@ -1,4 +1,4 @@
-/* Copyright 2016--2017 The Tor Project
+/* Copyright 2016--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/test/java/org/torproject/descriptor/DummyParserImplementation.java b/src/test/java/org/torproject/descriptor/DummyParserImplementation.java
index 42e67c9..54fc254 100644
--- a/src/test/java/org/torproject/descriptor/DummyParserImplementation.java
+++ b/src/test/java/org/torproject/descriptor/DummyParserImplementation.java
@@ -1,4 +1,4 @@
-/* Copyright 2016--2017 The Tor Project
+/* Copyright 2016--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/test/java/org/torproject/descriptor/DummyReaderImplementation.java b/src/test/java/org/torproject/descriptor/DummyReaderImplementation.java
index 8f74337..f9d9f3d 100644
--- a/src/test/java/org/torproject/descriptor/DummyReaderImplementation.java
+++ b/src/test/java/org/torproject/descriptor/DummyReaderImplementation.java
@@ -1,4 +1,4 @@
-/* Copyright 2016--2017 The Tor Project
+/* Copyright 2016--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor;
diff --git a/src/test/java/org/torproject/descriptor/benchmark/MeasurePerformance.java b/src/test/java/org/torproject/descriptor/benchmark/MeasurePerformance.java
index 09c581d..20df999 100644
--- a/src/test/java/org/torproject/descriptor/benchmark/MeasurePerformance.java
+++ b/src/test/java/org/torproject/descriptor/benchmark/MeasurePerformance.java
@@ -1,4 +1,4 @@
-/* Copyright 2016--2017 The Tor Project
+/* Copyright 2016--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.benchmark;
diff --git a/src/test/java/org/torproject/descriptor/impl/BridgeNetworkStatusTest.java b/src/test/java/org/torproject/descriptor/impl/BridgeNetworkStatusTest.java
index 22d24fd..fd26eec 100644
--- a/src/test/java/org/torproject/descriptor/impl/BridgeNetworkStatusTest.java
+++ b/src/test/java/org/torproject/descriptor/impl/BridgeNetworkStatusTest.java
@@ -1,4 +1,4 @@
-/* Copyright 2015--2017 The Tor Project
+/* Copyright 2015--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/test/java/org/torproject/descriptor/impl/ConsensusBuilder.java b/src/test/java/org/torproject/descriptor/impl/ConsensusBuilder.java
index cb8d0aa..1c0fa81 100644
--- a/src/test/java/org/torproject/descriptor/impl/ConsensusBuilder.java
+++ b/src/test/java/org/torproject/descriptor/impl/ConsensusBuilder.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/test/java/org/torproject/descriptor/impl/DescriptorImplTest.java b/src/test/java/org/torproject/descriptor/impl/DescriptorImplTest.java
index 09bac87..a0a32cf 100644
--- a/src/test/java/org/torproject/descriptor/impl/DescriptorImplTest.java
+++ b/src/test/java/org/torproject/descriptor/impl/DescriptorImplTest.java
@@ -1,4 +1,4 @@
-/* Copyright 2017 The Tor Project
+/* Copyright 2017--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/test/java/org/torproject/descriptor/impl/DescriptorParserImplTest.java b/src/test/java/org/torproject/descriptor/impl/DescriptorParserImplTest.java
index 42d0cde..d9dd178 100644
--- a/src/test/java/org/torproject/descriptor/impl/DescriptorParserImplTest.java
+++ b/src/test/java/org/torproject/descriptor/impl/DescriptorParserImplTest.java
@@ -1,4 +1,4 @@
-/* Copyright 2017 The Tor Project
+/* Copyright 2017--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/test/java/org/torproject/descriptor/impl/DescriptorReaderImplTest.java b/src/test/java/org/torproject/descriptor/impl/DescriptorReaderImplTest.java
index 0a3791e..01d190b 100644
--- a/src/test/java/org/torproject/descriptor/impl/DescriptorReaderImplTest.java
+++ b/src/test/java/org/torproject/descriptor/impl/DescriptorReaderImplTest.java
@@ -1,4 +1,4 @@
-/* Copyright 2016--2017 The Tor Project
+/* Copyright 2016--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/test/java/org/torproject/descriptor/impl/ExitListImplTest.java b/src/test/java/org/torproject/descriptor/impl/ExitListImplTest.java
index 8365d4c..0b53250 100644
--- a/src/test/java/org/torproject/descriptor/impl/ExitListImplTest.java
+++ b/src/test/java/org/torproject/descriptor/impl/ExitListImplTest.java
@@ -1,4 +1,4 @@
-/* Copyright 2015--2017 The Tor Project
+/* Copyright 2015--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/test/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImplTest.java b/src/test/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImplTest.java
index 5a3f0f2..c90207a 100644
--- a/src/test/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImplTest.java
+++ b/src/test/java/org/torproject/descriptor/impl/ExtraInfoDescriptorImplTest.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/test/java/org/torproject/descriptor/impl/MicrodescriptorImplTest.java b/src/test/java/org/torproject/descriptor/impl/MicrodescriptorImplTest.java
index a99895f..890071a 100644
--- a/src/test/java/org/torproject/descriptor/impl/MicrodescriptorImplTest.java
+++ b/src/test/java/org/torproject/descriptor/impl/MicrodescriptorImplTest.java
@@ -1,4 +1,4 @@
-/* Copyright 2015--2017 The Tor Project
+/* Copyright 2015--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImplTest.java b/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImplTest.java
index cafbf31..ca8c8e3 100644
--- a/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImplTest.java
+++ b/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusConsensusImplTest.java
@@ -1,4 +1,4 @@
-/* Copyright 2011--2017 The Tor Project
+/* Copyright 2011--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusImplTest.java b/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusImplTest.java
index a2328d3..9ecf391 100644
--- a/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusImplTest.java
+++ b/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusImplTest.java
@@ -1,4 +1,4 @@
-/* Copyright 2016--2017 The Tor Project
+/* Copyright 2016--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImplTest.java b/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImplTest.java
index aba55f4..be6567c 100644
--- a/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImplTest.java
+++ b/src/test/java/org/torproject/descriptor/impl/RelayNetworkStatusVoteImplTest.java
@@ -1,4 +1,4 @@
-/* Copyright 2011--2017 The Tor Project
+/* Copyright 2011--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/test/java/org/torproject/descriptor/impl/ServerDescriptorImplTest.java b/src/test/java/org/torproject/descriptor/impl/ServerDescriptorImplTest.java
index e814b4c..f121cb3 100644
--- a/src/test/java/org/torproject/descriptor/impl/ServerDescriptorImplTest.java
+++ b/src/test/java/org/torproject/descriptor/impl/ServerDescriptorImplTest.java
@@ -1,4 +1,4 @@
-/* Copyright 2012--2017 The Tor Project
+/* Copyright 2012--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/test/java/org/torproject/descriptor/impl/TestDescriptor.java b/src/test/java/org/torproject/descriptor/impl/TestDescriptor.java
index 48dcb98..1309070 100644
--- a/src/test/java/org/torproject/descriptor/impl/TestDescriptor.java
+++ b/src/test/java/org/torproject/descriptor/impl/TestDescriptor.java
@@ -1,4 +1,4 @@
-/* Copyright 2017 The Tor Project
+/* Copyright 2017--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/test/java/org/torproject/descriptor/impl/TestServerDescriptor.java b/src/test/java/org/torproject/descriptor/impl/TestServerDescriptor.java
index 406e9c0..9649bb0 100644
--- a/src/test/java/org/torproject/descriptor/impl/TestServerDescriptor.java
+++ b/src/test/java/org/torproject/descriptor/impl/TestServerDescriptor.java
@@ -1,4 +1,4 @@
-/* Copyright 2017 The Tor Project
+/* Copyright 2017--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/test/java/org/torproject/descriptor/impl/TorperfResultImplTest.java b/src/test/java/org/torproject/descriptor/impl/TorperfResultImplTest.java
index d9e134d..7bc689e 100644
--- a/src/test/java/org/torproject/descriptor/impl/TorperfResultImplTest.java
+++ b/src/test/java/org/torproject/descriptor/impl/TorperfResultImplTest.java
@@ -1,4 +1,4 @@
-/* Copyright 2015--2017 The Tor Project
+/* Copyright 2015--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.impl;
diff --git a/src/test/java/org/torproject/descriptor/index/DescriptorIndexCollectorTest.java b/src/test/java/org/torproject/descriptor/index/DescriptorIndexCollectorTest.java
index 15ca5b5..1180301 100644
--- a/src/test/java/org/torproject/descriptor/index/DescriptorIndexCollectorTest.java
+++ b/src/test/java/org/torproject/descriptor/index/DescriptorIndexCollectorTest.java
@@ -1,4 +1,4 @@
-/* Copyright 2016--2017 The Tor Project
+/* Copyright 2016--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.index;
diff --git a/src/test/java/org/torproject/descriptor/index/DirectoryNodeTest.java b/src/test/java/org/torproject/descriptor/index/DirectoryNodeTest.java
index c98abb8..fc545f6 100644
--- a/src/test/java/org/torproject/descriptor/index/DirectoryNodeTest.java
+++ b/src/test/java/org/torproject/descriptor/index/DirectoryNodeTest.java
@@ -1,4 +1,4 @@
-/* Copyright 2016--2017 The Tor Project
+/* Copyright 2016--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.index;
diff --git a/src/test/java/org/torproject/descriptor/index/FileNodeTest.java b/src/test/java/org/torproject/descriptor/index/FileNodeTest.java
index 5af89ff..0fed293 100644
--- a/src/test/java/org/torproject/descriptor/index/FileNodeTest.java
+++ b/src/test/java/org/torproject/descriptor/index/FileNodeTest.java
@@ -1,4 +1,4 @@
-/* Copyright 2016--2017 The Tor Project
+/* Copyright 2016--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.index;
diff --git a/src/test/java/org/torproject/descriptor/index/IndexNodeTest.java b/src/test/java/org/torproject/descriptor/index/IndexNodeTest.java
index f1e044c..c733e47 100644
--- a/src/test/java/org/torproject/descriptor/index/IndexNodeTest.java
+++ b/src/test/java/org/torproject/descriptor/index/IndexNodeTest.java
@@ -1,4 +1,4 @@
-/* Copyright 2016--2017 The Tor Project
+/* Copyright 2016--2018 The Tor Project
* See LICENSE for licensing information */
package org.torproject.descriptor.index;
1
0

07 Feb '18
commit 663bdc285c4b5e0979691c44bf4790779df9bdf0
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Thu Oct 26 10:51:39 2017 +0200
Update to latest metrics-base.
---
src/build | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/build b/src/build
index 78e533f..4b34756 160000
--- a/src/build
+++ b/src/build
@@ -1 +1 @@
-Subproject commit 78e533fdc84e20769a8a155d1426cbea59c6e7cc
+Subproject commit 4b34756ddd71ccaf0fc30e5f5bf0a813a297d4a3
1
0

07 Feb '18
commit 79a4b9866f2a342159bd0811d83e9ec62169c6d9
Author: Karsten Loesing <karsten.loesing(a)gmx.net>
Date: Mon Dec 4 12:12:24 2017 +0100
Update to latest metrics-base.
---
src/build | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/build b/src/build
index 4b34756..23c6e0b 160000
--- a/src/build
+++ b/src/build
@@ -1 +1 @@
-Subproject commit 4b34756ddd71ccaf0fc30e5f5bf0a813a297d4a3
+Subproject commit 23c6e0be5fab9463f137615053ef412e4da2315e
1
0
commit 5903c105652f3aa11da0e3102e170a88a2374e65
Author: iwakeh <iwakeh(a)torproject.org>
Date: Fri Sep 15 14:07:07 2017 +0000
Added package-info.
---
.../org/torproject/descriptor/internal/package-info.java | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/src/main/java/org/torproject/descriptor/internal/package-info.java b/src/main/java/org/torproject/descriptor/internal/package-info.java
new file mode 100644
index 0000000..5bc7bcb
--- /dev/null
+++ b/src/main/java/org/torproject/descriptor/internal/package-info.java
@@ -0,0 +1,14 @@
+/* Copyright 2017 The Tor Project
+ * See LICENSE for licensing information */
+
+/**
+ * <h1>This package is part of the implementation not the public API.</h1>
+ * <p>The public interface might change in unexpected ways.</p>
+ *
+ * <p>Interfaces and essential classes for obtaining and processing
+ * descriptors.</p>
+ *
+ * @since 2.1.0
+ */
+package org.torproject.descriptor.internal;
+
1
0