Loading src/main/java/org/torproject/metrics/stats/totalcw/Database.java +3 −12 Original line number Diff line number Diff line Loading @@ -66,10 +66,8 @@ class Database implements AutoCloseable { "SELECT EXISTS (SELECT 1 FROM vote " + "WHERE valid_after = ? AND authority_id = ?)"); this.psVoteInsert = this.connection.prepareStatement( "INSERT INTO vote (valid_after, authority_id, measured_count, " + "measured_sum, measured_mean, measured_min, measured_q1, " + "measured_median, measured_q3, measured_max) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", "INSERT INTO vote (valid_after, authority_id, measured_sum) " + "VALUES (?, ?, ?)", Statement.RETURN_GENERATED_KEYS); } Loading Loading @@ -124,14 +122,7 @@ class Database implements AutoCloseable { Timestamp.from(ZonedDateTime.of(vote.validAfter, ZoneId.of("UTC")).toInstant()), calendar); this.psVoteInsert.setInt(2, authorityId); this.psVoteInsert.setLong(3, vote.measuredCount); this.psVoteInsert.setLong(4, vote.measuredSum); this.psVoteInsert.setLong(5, vote.measuredMean); this.psVoteInsert.setLong(6, vote.measuredMin); this.psVoteInsert.setLong(7, vote.measuredQ1); this.psVoteInsert.setLong(8, vote.measuredMedian); this.psVoteInsert.setLong(9, vote.measuredQ3); this.psVoteInsert.setLong(10, vote.measuredMax); this.psVoteInsert.setLong(3, vote.measuredSum); this.psVoteInsert.execute(); try (ResultSet rs = this.psVoteInsert.getGeneratedKeys()) { if (rs.next()) { Loading src/main/java/org/torproject/metrics/stats/totalcw/Parser.java +9 −27 Original line number Diff line number Diff line Loading @@ -6,13 +6,8 @@ package org.torproject.metrics.stats.totalcw; import org.torproject.descriptor.NetworkStatusEntry; import org.torproject.descriptor.RelayNetworkStatusVote; import org.apache.commons.math3.stat.descriptive.rank.Percentile; import java.time.Instant; import java.time.ZoneId; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** Parser that extracts bandwidth measurement statistics from votes and creates * data objects for them. */ Loading @@ -22,13 +17,17 @@ class Parser { * contain any bandwidth measurements. */ TotalcwRelayNetworkStatusVote parseRelayNetworkStatusVote( RelayNetworkStatusVote vote) { List<Long> measuredBandwidths = new ArrayList<>(); Long measuredSum = null; for (NetworkStatusEntry entry : vote.getStatusEntries().values()) { if (entry.getMeasured() >= 0L) { measuredBandwidths.add(entry.getMeasured()); if (entry.getMeasured() < 0L) { continue; } if (null == measuredSum) { measuredSum = 0L; } measuredSum += entry.getMeasured(); } if (measuredBandwidths.isEmpty()) { if (null == measuredSum) { /* Return null, because we wouldn't want to add this vote to the database * anyway. */ return null; Loading @@ -39,24 +38,7 @@ class Parser { .atZone(ZoneId.of("UTC")).toLocalDateTime(); parsedVote.identityHex = vote.getIdentity(); parsedVote.nickname = vote.getNickname(); Collections.sort(measuredBandwidths); long totalValue = 0L; double[] values = new double[measuredBandwidths.size()]; for (int i = 0; i < measuredBandwidths.size(); i++) { values[i] = (double) measuredBandwidths.get(i); totalValue += measuredBandwidths.get(i); } parsedVote.measuredCount = values.length; parsedVote.measuredSum = totalValue; parsedVote.measuredMean = totalValue / values.length; parsedVote.measuredMin = (long) Math.floor(values[0]); parsedVote.measuredMax = (long) Math.floor(values[values.length - 1]); Percentile percentile = new Percentile().withEstimationType( Percentile.EstimationType.R_7); percentile.setData(values); parsedVote.measuredQ1 = (long) Math.floor(percentile.evaluate(25.0)); parsedVote.measuredMedian = (long) Math.floor(percentile.evaluate(50.0)); parsedVote.measuredQ3 = (long) Math.floor(percentile.evaluate(75.0)); parsedVote.measuredSum = measuredSum; return parsedVote; } } Loading src/main/java/org/torproject/metrics/stats/totalcw/TotalcwRelayNetworkStatusVote.java +0 −25 Original line number Diff line number Diff line Loading @@ -19,32 +19,7 @@ class TotalcwRelayNetworkStatusVote { * key. */ String identityHex; /** Count of status entries containing bandwidth measurements. */ long measuredCount; /** Sum of bandwidth measurements of all contained status entries. */ long measuredSum; /** Mean value of bandwidth measurements of all contained status entries. */ long measuredMean; /** Minimum value of bandwidth measurements of all contained status * entries. */ long measuredMin; /** First quartile value of bandwidth measurements of all contained status * entries. */ long measuredQ1; /** Median value of bandwidth measurements of all contained status entries. */ long measuredMedian; /** Third quartile value of bandwidth measurements of all contained status * entries. */ long measuredQ3; /** Maximum value of bandwidth measurements of all contained status * entries. */ long measuredMax; } src/main/sql/totalcw/init-totalcw.sql +0 −23 Original line number Diff line number Diff line Loading @@ -31,32 +31,9 @@ CREATE TABLE vote ( -- Numeric identifier uniquely identifying the authority generating this vote. authority_id INTEGER REFERENCES authority (authority_id), -- Count of status entries containing bandwidth measurements. measured_count BIGINT NOT NULL, -- Sum of bandwidth measurements of all contained status entries. measured_sum BIGINT NOT NULL, -- Mean value of bandwidth measurements of all contained status entries. measured_mean BIGINT NOT NULL, -- Minimum value of bandwidth measurements of all contained status entries. measured_min BIGINT NOT NULL, -- First quartile value of bandwidth measurements of all contained status -- entries. measured_q1 BIGINT NOT NULL, -- Median value of bandwidth measurements of all contained status entries. measured_median BIGINT NOT NULL, -- Third quartile value of bandwidth measurements of all contained status -- entries. measured_q3 BIGINT NOT NULL, -- Maximum value of bandwidth measurements of all contained status entries. measured_max BIGINT NOT NULL, UNIQUE (valid_after, authority_id) ); Loading src/test/java/org/torproject/metrics/stats/totalcw/TotalcwRelayNetworkStatusVoteTest.java +5 −37 Original line number Diff line number Diff line Loading @@ -35,23 +35,19 @@ public class TotalcwRelayNetworkStatusVoteTest { { "2018-10-15-00-00-00-vote-0232AF901C31A04EE9848595AF9BB7620D4C5B2E-" + "55A38ED50848BE1F13C6A35C3CA637B0D962C2EF.part", ZonedDateTime.parse("2018-10-15T00:00:00Z").toLocalDateTime(), "dannenberg", "0232AF901C31A04EE9848595AF9BB7620D4C5B2E", 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L }, "dannenberg", "0232AF901C31A04EE9848595AF9BB7620D4C5B2E", -1L }, { "2018-10-15-00-00-00-vote-27102BC123E7AF1D4741AE047E160C91ADC76B21-" + "049AB3179B12DACC391F06A10C2A8904E4339D33.part", ZonedDateTime.parse("2018-10-15T00:00:00Z").toLocalDateTime(), "bastet", "27102BC123E7AF1D4741AE047E160C91ADC76B21", 20L, 138803L, 6940L, 5L, 76L, 2490L, 9732L, 34800L }, "bastet", "27102BC123E7AF1D4741AE047E160C91ADC76B21", 138803L }, { "2018-10-15-00-00-00-vote-ED03BB616EB2F60BEC80151114BB25CEF515B226-" + "2669AD153408F88E416CE6206D1A75EC3324A2F4.part", ZonedDateTime.parse("2018-10-15T00:00:00Z").toLocalDateTime(), "gabelmoo", "ED03BB616EB2F60BEC80151114BB25CEF515B226", 19, 133441L, 7023L, 2L, 153L, 3920L, 11030L, 31600L }, "gabelmoo", "ED03BB616EB2F60BEC80151114BB25CEF515B226", 133441L }, { "2018-10-15-00-00-00-vote-EFCBE720AB3A82B99F9E953CD5BF50F7EEFC7B97-" + "38C6A19F78948B689345EE41D7119D76246C4D3E.part", ZonedDateTime.parse("2018-10-15T00:00:00Z").toLocalDateTime(), "Faravahar", "EFCBE720AB3A82B99F9E953CD5BF50F7EEFC7B97", 20, 158534L, 7926L, 6L, 109L, 3215L, 9582L, 40700L } "Faravahar", "EFCBE720AB3A82B99F9E953CD5BF50F7EEFC7B97", 158534L } }); } Loading @@ -68,29 +64,8 @@ public class TotalcwRelayNetworkStatusVoteTest { public String expectedIdentityHex; @Parameter(4) public long expectedMeasuredCount; @Parameter(5) public long expectedMeasuredSum; @Parameter(6) public long expectedMeasuredMean; @Parameter(7) public long expectedMeasuredMin; @Parameter(8) public long expectedMeasuredQ1; @Parameter(9) public long expectedMeasuredMedian; @Parameter(10) public long expectedMeasuredQ3; @Parameter(11) public long expectedMeasuredMax; @Test public void testParseVote() throws Exception { InputStream is = getClass().getClassLoader().getResourceAsStream( Loading @@ -107,20 +82,13 @@ public class TotalcwRelayNetworkStatusVoteTest { sb.toString().getBytes(), new File(this.fileName), this.fileName)) { TotalcwRelayNetworkStatusVote parsedVote = new Parser() .parseRelayNetworkStatusVote((RelayNetworkStatusVote) descriptor); if (0L == expectedMeasuredCount) { if (this.expectedMeasuredSum < 0L) { assertNull(parsedVote); } else { assertEquals(this.expectedValidAfter, parsedVote.validAfter); assertEquals(this.expectedNickname, parsedVote.nickname); assertEquals(this.expectedIdentityHex, parsedVote.identityHex); assertEquals(this.expectedMeasuredCount, parsedVote.measuredCount); assertEquals(this.expectedMeasuredSum, parsedVote.measuredSum); assertEquals(this.expectedMeasuredMean, parsedVote.measuredMean); assertEquals(this.expectedMeasuredMin, parsedVote.measuredMin); assertEquals(this.expectedMeasuredQ1, parsedVote.measuredQ1); assertEquals(this.expectedMeasuredMedian, parsedVote.measuredMedian); assertEquals(this.expectedMeasuredQ3, parsedVote.measuredQ3); assertEquals(this.expectedMeasuredMax, parsedVote.measuredMax); } } } Loading Loading
src/main/java/org/torproject/metrics/stats/totalcw/Database.java +3 −12 Original line number Diff line number Diff line Loading @@ -66,10 +66,8 @@ class Database implements AutoCloseable { "SELECT EXISTS (SELECT 1 FROM vote " + "WHERE valid_after = ? AND authority_id = ?)"); this.psVoteInsert = this.connection.prepareStatement( "INSERT INTO vote (valid_after, authority_id, measured_count, " + "measured_sum, measured_mean, measured_min, measured_q1, " + "measured_median, measured_q3, measured_max) " + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", "INSERT INTO vote (valid_after, authority_id, measured_sum) " + "VALUES (?, ?, ?)", Statement.RETURN_GENERATED_KEYS); } Loading Loading @@ -124,14 +122,7 @@ class Database implements AutoCloseable { Timestamp.from(ZonedDateTime.of(vote.validAfter, ZoneId.of("UTC")).toInstant()), calendar); this.psVoteInsert.setInt(2, authorityId); this.psVoteInsert.setLong(3, vote.measuredCount); this.psVoteInsert.setLong(4, vote.measuredSum); this.psVoteInsert.setLong(5, vote.measuredMean); this.psVoteInsert.setLong(6, vote.measuredMin); this.psVoteInsert.setLong(7, vote.measuredQ1); this.psVoteInsert.setLong(8, vote.measuredMedian); this.psVoteInsert.setLong(9, vote.measuredQ3); this.psVoteInsert.setLong(10, vote.measuredMax); this.psVoteInsert.setLong(3, vote.measuredSum); this.psVoteInsert.execute(); try (ResultSet rs = this.psVoteInsert.getGeneratedKeys()) { if (rs.next()) { Loading
src/main/java/org/torproject/metrics/stats/totalcw/Parser.java +9 −27 Original line number Diff line number Diff line Loading @@ -6,13 +6,8 @@ package org.torproject.metrics.stats.totalcw; import org.torproject.descriptor.NetworkStatusEntry; import org.torproject.descriptor.RelayNetworkStatusVote; import org.apache.commons.math3.stat.descriptive.rank.Percentile; import java.time.Instant; import java.time.ZoneId; import java.util.ArrayList; import java.util.Collections; import java.util.List; /** Parser that extracts bandwidth measurement statistics from votes and creates * data objects for them. */ Loading @@ -22,13 +17,17 @@ class Parser { * contain any bandwidth measurements. */ TotalcwRelayNetworkStatusVote parseRelayNetworkStatusVote( RelayNetworkStatusVote vote) { List<Long> measuredBandwidths = new ArrayList<>(); Long measuredSum = null; for (NetworkStatusEntry entry : vote.getStatusEntries().values()) { if (entry.getMeasured() >= 0L) { measuredBandwidths.add(entry.getMeasured()); if (entry.getMeasured() < 0L) { continue; } if (null == measuredSum) { measuredSum = 0L; } measuredSum += entry.getMeasured(); } if (measuredBandwidths.isEmpty()) { if (null == measuredSum) { /* Return null, because we wouldn't want to add this vote to the database * anyway. */ return null; Loading @@ -39,24 +38,7 @@ class Parser { .atZone(ZoneId.of("UTC")).toLocalDateTime(); parsedVote.identityHex = vote.getIdentity(); parsedVote.nickname = vote.getNickname(); Collections.sort(measuredBandwidths); long totalValue = 0L; double[] values = new double[measuredBandwidths.size()]; for (int i = 0; i < measuredBandwidths.size(); i++) { values[i] = (double) measuredBandwidths.get(i); totalValue += measuredBandwidths.get(i); } parsedVote.measuredCount = values.length; parsedVote.measuredSum = totalValue; parsedVote.measuredMean = totalValue / values.length; parsedVote.measuredMin = (long) Math.floor(values[0]); parsedVote.measuredMax = (long) Math.floor(values[values.length - 1]); Percentile percentile = new Percentile().withEstimationType( Percentile.EstimationType.R_7); percentile.setData(values); parsedVote.measuredQ1 = (long) Math.floor(percentile.evaluate(25.0)); parsedVote.measuredMedian = (long) Math.floor(percentile.evaluate(50.0)); parsedVote.measuredQ3 = (long) Math.floor(percentile.evaluate(75.0)); parsedVote.measuredSum = measuredSum; return parsedVote; } } Loading
src/main/java/org/torproject/metrics/stats/totalcw/TotalcwRelayNetworkStatusVote.java +0 −25 Original line number Diff line number Diff line Loading @@ -19,32 +19,7 @@ class TotalcwRelayNetworkStatusVote { * key. */ String identityHex; /** Count of status entries containing bandwidth measurements. */ long measuredCount; /** Sum of bandwidth measurements of all contained status entries. */ long measuredSum; /** Mean value of bandwidth measurements of all contained status entries. */ long measuredMean; /** Minimum value of bandwidth measurements of all contained status * entries. */ long measuredMin; /** First quartile value of bandwidth measurements of all contained status * entries. */ long measuredQ1; /** Median value of bandwidth measurements of all contained status entries. */ long measuredMedian; /** Third quartile value of bandwidth measurements of all contained status * entries. */ long measuredQ3; /** Maximum value of bandwidth measurements of all contained status * entries. */ long measuredMax; }
src/main/sql/totalcw/init-totalcw.sql +0 −23 Original line number Diff line number Diff line Loading @@ -31,32 +31,9 @@ CREATE TABLE vote ( -- Numeric identifier uniquely identifying the authority generating this vote. authority_id INTEGER REFERENCES authority (authority_id), -- Count of status entries containing bandwidth measurements. measured_count BIGINT NOT NULL, -- Sum of bandwidth measurements of all contained status entries. measured_sum BIGINT NOT NULL, -- Mean value of bandwidth measurements of all contained status entries. measured_mean BIGINT NOT NULL, -- Minimum value of bandwidth measurements of all contained status entries. measured_min BIGINT NOT NULL, -- First quartile value of bandwidth measurements of all contained status -- entries. measured_q1 BIGINT NOT NULL, -- Median value of bandwidth measurements of all contained status entries. measured_median BIGINT NOT NULL, -- Third quartile value of bandwidth measurements of all contained status -- entries. measured_q3 BIGINT NOT NULL, -- Maximum value of bandwidth measurements of all contained status entries. measured_max BIGINT NOT NULL, UNIQUE (valid_after, authority_id) ); Loading
src/test/java/org/torproject/metrics/stats/totalcw/TotalcwRelayNetworkStatusVoteTest.java +5 −37 Original line number Diff line number Diff line Loading @@ -35,23 +35,19 @@ public class TotalcwRelayNetworkStatusVoteTest { { "2018-10-15-00-00-00-vote-0232AF901C31A04EE9848595AF9BB7620D4C5B2E-" + "55A38ED50848BE1F13C6A35C3CA637B0D962C2EF.part", ZonedDateTime.parse("2018-10-15T00:00:00Z").toLocalDateTime(), "dannenberg", "0232AF901C31A04EE9848595AF9BB7620D4C5B2E", 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L }, "dannenberg", "0232AF901C31A04EE9848595AF9BB7620D4C5B2E", -1L }, { "2018-10-15-00-00-00-vote-27102BC123E7AF1D4741AE047E160C91ADC76B21-" + "049AB3179B12DACC391F06A10C2A8904E4339D33.part", ZonedDateTime.parse("2018-10-15T00:00:00Z").toLocalDateTime(), "bastet", "27102BC123E7AF1D4741AE047E160C91ADC76B21", 20L, 138803L, 6940L, 5L, 76L, 2490L, 9732L, 34800L }, "bastet", "27102BC123E7AF1D4741AE047E160C91ADC76B21", 138803L }, { "2018-10-15-00-00-00-vote-ED03BB616EB2F60BEC80151114BB25CEF515B226-" + "2669AD153408F88E416CE6206D1A75EC3324A2F4.part", ZonedDateTime.parse("2018-10-15T00:00:00Z").toLocalDateTime(), "gabelmoo", "ED03BB616EB2F60BEC80151114BB25CEF515B226", 19, 133441L, 7023L, 2L, 153L, 3920L, 11030L, 31600L }, "gabelmoo", "ED03BB616EB2F60BEC80151114BB25CEF515B226", 133441L }, { "2018-10-15-00-00-00-vote-EFCBE720AB3A82B99F9E953CD5BF50F7EEFC7B97-" + "38C6A19F78948B689345EE41D7119D76246C4D3E.part", ZonedDateTime.parse("2018-10-15T00:00:00Z").toLocalDateTime(), "Faravahar", "EFCBE720AB3A82B99F9E953CD5BF50F7EEFC7B97", 20, 158534L, 7926L, 6L, 109L, 3215L, 9582L, 40700L } "Faravahar", "EFCBE720AB3A82B99F9E953CD5BF50F7EEFC7B97", 158534L } }); } Loading @@ -68,29 +64,8 @@ public class TotalcwRelayNetworkStatusVoteTest { public String expectedIdentityHex; @Parameter(4) public long expectedMeasuredCount; @Parameter(5) public long expectedMeasuredSum; @Parameter(6) public long expectedMeasuredMean; @Parameter(7) public long expectedMeasuredMin; @Parameter(8) public long expectedMeasuredQ1; @Parameter(9) public long expectedMeasuredMedian; @Parameter(10) public long expectedMeasuredQ3; @Parameter(11) public long expectedMeasuredMax; @Test public void testParseVote() throws Exception { InputStream is = getClass().getClassLoader().getResourceAsStream( Loading @@ -107,20 +82,13 @@ public class TotalcwRelayNetworkStatusVoteTest { sb.toString().getBytes(), new File(this.fileName), this.fileName)) { TotalcwRelayNetworkStatusVote parsedVote = new Parser() .parseRelayNetworkStatusVote((RelayNetworkStatusVote) descriptor); if (0L == expectedMeasuredCount) { if (this.expectedMeasuredSum < 0L) { assertNull(parsedVote); } else { assertEquals(this.expectedValidAfter, parsedVote.validAfter); assertEquals(this.expectedNickname, parsedVote.nickname); assertEquals(this.expectedIdentityHex, parsedVote.identityHex); assertEquals(this.expectedMeasuredCount, parsedVote.measuredCount); assertEquals(this.expectedMeasuredSum, parsedVote.measuredSum); assertEquals(this.expectedMeasuredMean, parsedVote.measuredMean); assertEquals(this.expectedMeasuredMin, parsedVote.measuredMin); assertEquals(this.expectedMeasuredQ1, parsedVote.measuredQ1); assertEquals(this.expectedMeasuredMedian, parsedVote.measuredMedian); assertEquals(this.expectedMeasuredQ3, parsedVote.measuredQ3); assertEquals(this.expectedMeasuredMax, parsedVote.measuredMax); } } } Loading