[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[tor-commits] [onionoo/master] Make WeightsStatus smarter about itself.
commit a902feb6bac7b03cedfa3148671039cca00ea8ee
Author: Karsten Loesing <karsten.loesing@xxxxxxx>
Date: Fri Aug 15 11:13:14 2014 +0200
Make WeightsStatus smarter about itself.
Removes another dependency on DateTimeHelper, which gets us closer to
implementing #12866.
---
.../org/torproject/onionoo/docs/WeightsStatus.java | 93 +++++++++++++++++
.../onionoo/updater/WeightsStatusUpdater.java | 106 ++------------------
2 files changed, 104 insertions(+), 95 deletions(-)
diff --git a/src/main/java/org/torproject/onionoo/docs/WeightsStatus.java b/src/main/java/org/torproject/onionoo/docs/WeightsStatus.java
index 678789b..ccc818a 100644
--- a/src/main/java/org/torproject/onionoo/docs/WeightsStatus.java
+++ b/src/main/java/org/torproject/onionoo/docs/WeightsStatus.java
@@ -8,9 +8,18 @@ import java.util.SortedMap;
import java.util.TreeMap;
import org.torproject.onionoo.util.DateTimeHelper;
+import org.torproject.onionoo.util.TimeFactory;
public class WeightsStatus extends Document {
+ private transient boolean isDirty = false;
+ public boolean isDirty() {
+ return this.isDirty;
+ }
+ public void clearDirty() {
+ this.isDirty = false;
+ }
+
private SortedMap<long[], double[]> history =
new TreeMap<long[], double[]>(new Comparator<long[]>() {
public int compare(long[] a, long[] b) {
@@ -77,6 +86,90 @@ public class WeightsStatus extends Document {
s.close();
}
+ public void addToHistory(long validAfterMillis, long freshUntilMillis,
+ double[] weights) {
+ long[] interval = new long[] { validAfterMillis, freshUntilMillis };
+ if ((this.history.headMap(interval).isEmpty() ||
+ this.history.headMap(interval).lastKey()[1] <=
+ validAfterMillis) &&
+ (this.history.tailMap(interval).isEmpty() ||
+ this.history.tailMap(interval).firstKey()[0] >=
+ freshUntilMillis)) {
+ this.history.put(interval, weights);
+ this.isDirty = true;
+ }
+ }
+
+ public void compressHistory() {
+ SortedMap<long[], double[]> uncompressedHistory =
+ new TreeMap<long[], double[]>(this.history);
+ history.clear();
+ long lastStartMillis = 0L, lastEndMillis = 0L;
+ double[] lastWeights = null;
+ String lastMonthString = "1970-01";
+ int lastMissingValues = -1;
+ long now = TimeFactory.getTime().currentTimeMillis();
+ for (Map.Entry<long[], double[]> e : uncompressedHistory.entrySet()) {
+ long startMillis = e.getKey()[0], endMillis = e.getKey()[1];
+ double[] weights = e.getValue();
+ long intervalLengthMillis;
+ if (now - endMillis <= DateTimeHelper.ONE_WEEK) {
+ intervalLengthMillis = DateTimeHelper.ONE_HOUR;
+ } else if (now - endMillis <=
+ DateTimeHelper.ROUGHLY_ONE_MONTH) {
+ intervalLengthMillis = DateTimeHelper.FOUR_HOURS;
+ } else if (now - endMillis <=
+ DateTimeHelper.ROUGHLY_THREE_MONTHS) {
+ intervalLengthMillis = DateTimeHelper.TWELVE_HOURS;
+ } else if (now - endMillis <=
+ DateTimeHelper.ROUGHLY_ONE_YEAR) {
+ intervalLengthMillis = DateTimeHelper.TWO_DAYS;
+ } else {
+ intervalLengthMillis = DateTimeHelper.TEN_DAYS;
+ }
+ String monthString = DateTimeHelper.format(startMillis,
+ DateTimeHelper.ISO_YEARMONTH_FORMAT);
+ int missingValues = 0;
+ for (int i = 0; i < weights.length; i++) {
+ if (weights[i] < -0.5) {
+ missingValues += 1 << i;
+ }
+ }
+ if (lastEndMillis == startMillis &&
+ ((lastEndMillis - 1L) / intervalLengthMillis) ==
+ ((endMillis - 1L) / intervalLengthMillis) &&
+ lastMonthString.equals(monthString) &&
+ lastMissingValues == missingValues) {
+ double lastIntervalInHours = (double) ((lastEndMillis
+ - lastStartMillis) / DateTimeHelper.ONE_HOUR);
+ double currentIntervalInHours = (double) ((endMillis
+ - startMillis) / DateTimeHelper.ONE_HOUR);
+ double newIntervalInHours = (double) ((endMillis
+ - lastStartMillis) / DateTimeHelper.ONE_HOUR);
+ for (int i = 0; i < lastWeights.length; i++) {
+ lastWeights[i] *= lastIntervalInHours;
+ lastWeights[i] += weights[i] * currentIntervalInHours;
+ lastWeights[i] /= newIntervalInHours;
+ }
+ lastEndMillis = endMillis;
+ } else {
+ if (lastStartMillis > 0L) {
+ this.history.put(new long[] { lastStartMillis, lastEndMillis },
+ lastWeights);
+ }
+ lastStartMillis = startMillis;
+ lastEndMillis = endMillis;
+ lastWeights = weights;
+ }
+ lastMonthString = monthString;
+ lastMissingValues = missingValues;
+ }
+ if (lastStartMillis > 0L) {
+ this.history.put(new long[] { lastStartMillis, lastEndMillis },
+ lastWeights);
+ }
+ }
+
public String toDocumentString() {
StringBuilder sb = new StringBuilder();
for (Map.Entry<String, Integer> e :
diff --git a/src/main/java/org/torproject/onionoo/updater/WeightsStatusUpdater.java b/src/main/java/org/torproject/onionoo/updater/WeightsStatusUpdater.java
index f13ad14..2be213f 100644
--- a/src/main/java/org/torproject/onionoo/updater/WeightsStatusUpdater.java
+++ b/src/main/java/org/torproject/onionoo/updater/WeightsStatusUpdater.java
@@ -16,8 +16,6 @@ import org.torproject.descriptor.ServerDescriptor;
import org.torproject.onionoo.docs.DocumentStore;
import org.torproject.onionoo.docs.DocumentStoreFactory;
import org.torproject.onionoo.docs.WeightsStatus;
-import org.torproject.onionoo.util.DateTimeHelper;
-import org.torproject.onionoo.util.TimeFactory;
public class WeightsStatusUpdater implements DescriptorListener,
StatusUpdater {
@@ -26,12 +24,9 @@ public class WeightsStatusUpdater implements DescriptorListener,
private DocumentStore documentStore;
- private long now;
-
public WeightsStatusUpdater() {
this.descriptorSource = DescriptorSourceFactory.getDescriptorSource();
this.documentStore = DocumentStoreFactory.getDocumentStore();
- this.now = TimeFactory.getTime().currentTimeMillis();
this.registerDescriptorListeners();
}
@@ -90,9 +85,19 @@ public class WeightsStatusUpdater implements DescriptorListener,
for (Map.Entry<String, double[]> e
: pathSelectionWeights.entrySet()) {
String fingerprint = e.getKey();
+ WeightsStatus weightsStatus = this.documentStore.retrieve(
+ WeightsStatus.class, true, fingerprint);
+ if (weightsStatus == null) {
+ weightsStatus = new WeightsStatus();
+ }
double[] weights = e.getValue();
- this.addToHistory(fingerprint, validAfterMillis, freshUntilMillis,
+ weightsStatus.addToHistory(validAfterMillis, freshUntilMillis,
weights);
+ if (weightsStatus.isDirty()) {
+ weightsStatus.compressHistory();
+ this.documentStore.store(weightsStatus, fingerprint);
+ weightsStatus.clearDirty();
+ }
}
}
@@ -228,95 +233,6 @@ public class WeightsStatusUpdater implements DescriptorListener,
return pathSelectionProbabilities;
}
- private void addToHistory(String fingerprint, long validAfterMillis,
- long freshUntilMillis, double[] weights) {
- WeightsStatus weightsStatus = this.documentStore.retrieve(
- WeightsStatus.class, true, fingerprint);
- if (weightsStatus == null) {
- weightsStatus = new WeightsStatus();
- }
- SortedMap<long[], double[]> history = weightsStatus.getHistory();
- long[] interval = new long[] { validAfterMillis, freshUntilMillis };
- if ((history.headMap(interval).isEmpty() ||
- history.headMap(interval).lastKey()[1] <= validAfterMillis) &&
- (history.tailMap(interval).isEmpty() ||
- history.tailMap(interval).firstKey()[0] >= freshUntilMillis)) {
- history.put(interval, weights);
- this.compressHistory(weightsStatus);
- this.documentStore.store(weightsStatus, fingerprint);
- }
- }
-
- private void compressHistory(WeightsStatus weightsStatus) {
- SortedMap<long[], double[]> history = weightsStatus.getHistory();
- SortedMap<long[], double[]> compressedHistory =
- new TreeMap<long[], double[]>(history.comparator());
- long lastStartMillis = 0L, lastEndMillis = 0L;
- double[] lastWeights = null;
- String lastMonthString = "1970-01";
- int lastMissingValues = -1;
- for (Map.Entry<long[], double[]> e : history.entrySet()) {
- long startMillis = e.getKey()[0], endMillis = e.getKey()[1];
- double[] weights = e.getValue();
- long intervalLengthMillis;
- if (this.now - endMillis <= DateTimeHelper.ONE_WEEK) {
- intervalLengthMillis = DateTimeHelper.ONE_HOUR;
- } else if (this.now - endMillis <=
- DateTimeHelper.ROUGHLY_ONE_MONTH) {
- intervalLengthMillis = DateTimeHelper.FOUR_HOURS;
- } else if (this.now - endMillis <=
- DateTimeHelper.ROUGHLY_THREE_MONTHS) {
- intervalLengthMillis = DateTimeHelper.TWELVE_HOURS;
- } else if (this.now - endMillis <=
- DateTimeHelper.ROUGHLY_ONE_YEAR) {
- intervalLengthMillis = DateTimeHelper.TWO_DAYS;
- } else {
- intervalLengthMillis = DateTimeHelper.TEN_DAYS;
- }
- String monthString = DateTimeHelper.format(startMillis,
- DateTimeHelper.ISO_YEARMONTH_FORMAT);
- int missingValues = 0;
- for (int i = 0; i < weights.length; i++) {
- if (weights[i] < -0.5) {
- missingValues += 1 << i;
- }
- }
- if (lastEndMillis == startMillis &&
- ((lastEndMillis - 1L) / intervalLengthMillis) ==
- ((endMillis - 1L) / intervalLengthMillis) &&
- lastMonthString.equals(monthString) &&
- lastMissingValues == missingValues) {
- double lastIntervalInHours = (double) ((lastEndMillis
- - lastStartMillis) / DateTimeHelper.ONE_HOUR);
- double currentIntervalInHours = (double) ((endMillis
- - startMillis) / DateTimeHelper.ONE_HOUR);
- double newIntervalInHours = (double) ((endMillis
- - lastStartMillis) / DateTimeHelper.ONE_HOUR);
- for (int i = 0; i < lastWeights.length; i++) {
- lastWeights[i] *= lastIntervalInHours;
- lastWeights[i] += weights[i] * currentIntervalInHours;
- lastWeights[i] /= newIntervalInHours;
- }
- lastEndMillis = endMillis;
- } else {
- if (lastStartMillis > 0L) {
- compressedHistory.put(new long[] { lastStartMillis,
- lastEndMillis }, lastWeights);
- }
- lastStartMillis = startMillis;
- lastEndMillis = endMillis;
- lastWeights = weights;
- }
- lastMonthString = monthString;
- lastMissingValues = missingValues;
- }
- if (lastStartMillis > 0L) {
- compressedHistory.put(new long[] { lastStartMillis, lastEndMillis },
- lastWeights);
- }
- weightsStatus.setHistory(compressedHistory);
- }
-
public String getStatsString() {
/* TODO Add statistics string. */
return null;
_______________________________________________
tor-commits mailing list
tor-commits@xxxxxxxxxxxxxxxxxxxx
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits