[tor-commits] [onionoo/master] Speed up updating weights files by using 4 updater threads.
karsten at torproject.org
karsten at torproject.org
Fri Jul 27 08:11:17 UTC 2012
commit 752cff0f5d0af833235d48a916f5e9be71a03b0b
Author: Karsten Loesing <karsten.loesing at gmx.net>
Date: Thu Jul 26 13:47:19 2012 +0200
Speed up updating weights files by using 4 updater threads.
Using 4 updater threads reduces the time to process 1 consensus from 20 to
11 seconds here.
---
src/org/torproject/onionoo/WeightsDataWriter.java | 101 ++++++++++++++++-----
1 files changed, 78 insertions(+), 23 deletions(-)
diff --git a/src/org/torproject/onionoo/WeightsDataWriter.java b/src/org/torproject/onionoo/WeightsDataWriter.java
index d3a37fc..c4a887b 100644
--- a/src/org/torproject/onionoo/WeightsDataWriter.java
+++ b/src/org/torproject/onionoo/WeightsDataWriter.java
@@ -13,6 +13,7 @@ import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
+import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
@@ -34,13 +35,6 @@ import org.torproject.descriptor.ServerDescriptor;
public class WeightsDataWriter {
- private SimpleDateFormat dateTimeFormat = new SimpleDateFormat(
- "yyyy-MM-dd HH:mm:ss");
- public WeightsDataWriter() {
- this.dateTimeFormat.setLenient(false);
- this.dateTimeFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
- }
-
private SortedSet<String> currentFingerprints = new TreeSet<String>();
public void setCurrentRelays(SortedMap<String, Node> currentRelays) {
this.currentFingerprints.addAll(currentRelays.keySet());
@@ -97,19 +91,72 @@ public class WeightsDataWriter {
freshUntilMillis = consensus.getFreshUntilMillis();
SortedMap<String, double[]> pathSelectionWeights =
this.calculatePathSelectionProbabilities(consensus);
- for (Map.Entry<String, double[]> e :
- pathSelectionWeights.entrySet()) {
- String fingerprint = e.getKey();
- double[] weights = e.getValue();
- this.addToHistory(fingerprint, validAfterMillis,
- freshUntilMillis, weights);
- }
+ this.updateWeightsHistory(validAfterMillis, freshUntilMillis,
+ pathSelectionWeights);
}
}
}
}
}
+ private static final int HISTORY_UPDATER_WORKERS_NUM = 4;
+ private void updateWeightsHistory(long validAfterMillis,
+ long freshUntilMillis,
+ SortedMap<String, double[]> pathSelectionWeights) {
+ int files = pathSelectionWeights.size();
+ List<HistoryUpdateWorker> historyUpdateWorkers =
+ new ArrayList<HistoryUpdateWorker>();
+ for (int i = 0; i < HISTORY_UPDATER_WORKERS_NUM; i++) {
+ HistoryUpdateWorker historyUpdateWorker =
+ new HistoryUpdateWorker(validAfterMillis, freshUntilMillis,
+ pathSelectionWeights, this);
+ historyUpdateWorkers.add(historyUpdateWorker);
+ historyUpdateWorker.setDaemon(true);
+ historyUpdateWorker.start();
+ }
+ for (HistoryUpdateWorker historyUpdateWorker : historyUpdateWorkers) {
+ try {
+ historyUpdateWorker.join();
+ } catch (InterruptedException e) {
+ /* This is not something that we can take care of. Just leave the
+ * worker thread alone. */
+ }
+ }
+ }
+
+ private class HistoryUpdateWorker extends Thread {
+ private long validAfterMillis;
+ private long freshUntilMillis;
+ private SortedMap<String, double[]> pathSelectionWeights;
+ private WeightsDataWriter parent;
+ public HistoryUpdateWorker(long validAfterMillis,
+ long freshUntilMillis,
+ SortedMap<String, double[]> pathSelectionWeights,
+ WeightsDataWriter parent) {
+ this.validAfterMillis = validAfterMillis;
+ this.freshUntilMillis = freshUntilMillis;
+ this.pathSelectionWeights = pathSelectionWeights;
+ this.parent = parent;
+ }
+ public void run() {
+ String fingerprint = null;
+ double[] weights = null;
+ do {
+ fingerprint = null;
+ synchronized (pathSelectionWeights) {
+ if (!pathSelectionWeights.isEmpty()) {
+ fingerprint = pathSelectionWeights.firstKey();
+ weights = pathSelectionWeights.remove(fingerprint);
+ }
+ }
+ if (fingerprint != null) {
+ this.parent.addToHistory(fingerprint, this.validAfterMillis,
+ this.freshUntilMillis, weights);
+ }
+ } while (fingerprint != null);
+ }
+ }
+
private SortedMap<String, double[]> calculatePathSelectionProbabilities(
RelayNetworkStatusConsensus consensus) {
double wgg = 1.0, wgd = 1.0, wmg = 1.0, wmm = 1.0, wme = 1.0,
@@ -233,6 +280,10 @@ public class WeightsDataWriter {
});
File historyFile = new File("status/weights", fingerprint);
if (historyFile.exists()) {
+ SimpleDateFormat dateTimeFormat = new SimpleDateFormat(
+ "yyyy-MM-dd HH:mm:ss");
+ dateTimeFormat.setLenient(false);
+ dateTimeFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
BufferedReader br = new BufferedReader(new FileReader(
historyFile));
@@ -245,9 +296,9 @@ public class WeightsDataWriter {
+ "'. Skipping this line.");
continue;
}
- long validAfterMillis = this.dateTimeFormat.parse(parts[0]
+ long validAfterMillis = dateTimeFormat.parse(parts[0]
+ " " + parts[1]).getTime();
- long freshUntilMillis = this.dateTimeFormat.parse(parts[2]
+ long freshUntilMillis = dateTimeFormat.parse(parts[2]
+ " " + parts[3]).getTime();
long[] interval = new long[] { validAfterMillis,
freshUntilMillis };
@@ -330,13 +381,16 @@ public class WeightsDataWriter {
SortedMap<long[], double[]> history) {
File historyFile = new File("status/weights", fingerprint);
try {
+ SimpleDateFormat dateTimeFormat = new SimpleDateFormat(
+ "yyyy-MM-dd HH:mm:ss");
+ dateTimeFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
historyFile.getParentFile().mkdirs();
BufferedWriter bw = new BufferedWriter(new FileWriter(historyFile));
for (Map.Entry<long[], double[]> e : history.entrySet()) {
long[] fresh = e.getKey();
double[] weights = e.getValue();
- bw.write(this.dateTimeFormat.format(fresh[0]) + " "
- + this.dateTimeFormat.format(fresh[1]));
+ bw.write(dateTimeFormat.format(fresh[0]) + " "
+ + dateTimeFormat.format(fresh[1]));
for (double weight : weights) {
bw.write(String.format(" %.12f", weight));
}
@@ -492,12 +546,13 @@ public class WeightsDataWriter {
double factor = ((double) maxValue) / 999.0;
int count = lastNonNullIndex - firstNonNullIndex + 1;
StringBuilder sb = new StringBuilder();
+ SimpleDateFormat dateTimeFormat = new SimpleDateFormat(
+ "yyyy-MM-dd HH:mm:ss");
+ dateTimeFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
sb.append("\"" + graphName + "\":{"
- + "\"first\":\""
- + this.dateTimeFormat.format(firstDataPointMillis) + "\","
- + "\"last\":\""
- + this.dateTimeFormat.format(lastDataPointMillis) + "\","
- + "\"interval\":" + String.valueOf(dataPointInterval / 1000L)
+ + "\"first\":\"" + dateTimeFormat.format(firstDataPointMillis)
+ + "\",\"last\":\"" + dateTimeFormat.format(lastDataPointMillis)
+ + "\",\"interval\":" + String.valueOf(dataPointInterval / 1000L)
+ ",\"factor\":" + String.format(Locale.US, "%.9f", factor)
+ ",\"count\":" + String.valueOf(count) + ",\"values\":[");
int dataPointsWritten = 0, previousNonNullIndex = -2;
More information about the tor-commits
mailing list