Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

- ISD-AS assignment parser broken after website change
[#13](https://github.com/netsec-ethz/scion-java-multiping/pull/13)
- Fixed calculation of average and median values
[#17](https://github.com/netsec-ethz/scion-java-multiping/pull/17)

## [0.4.0] - 2025-04-04

Expand Down
54 changes: 33 additions & 21 deletions src/main/java/org/scion/multiping/PingAll.java
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,12 @@ public static void main(String[] args) throws IOException {
println(" printOnlyICMP=" + SHOW_ONLY_ICMP);

PingAll demo = new PingAll();
List<ParseAssignments.HostEntry> list = DownloadAssignmentsFromWeb.getList();
for (ParseAssignments.HostEntry e : list) {
List<ParseAssignments.HostEntry> allASes = DownloadAssignmentsFromWeb.getList();
// remove entry for local AS
long localAS = Scion.defaultService().getLocalIsdAs();
allASes = allASes.stream().filter(e -> e.getIsdAs() != localAS).collect(Collectors.toList());
// Process all ASes
for (ParseAssignments.HostEntry e : allASes) {
print(ScionUtil.toStringIA(e.getIsdAs()) + " \"" + e.getName() + "\" ");
demo.runDemo(e);
listedAs.add(e.getIsdAs());
Expand All @@ -120,27 +124,26 @@ public static void main(String[] args) throws IOException {
}

// max:
Result maxPing =
results.stream().max((o1, o2) -> (int) (o1.getPingMs() - o2.getPingMs())).get();
Result maxHops = results.stream().max(Comparator.comparingInt(Result::getHopCount)).get();
Result maxPaths = results.stream().max(Comparator.comparingInt(Result::getPathCount)).get();
Result maxPing = max(Result::isSuccess, (o1, o2) -> (int) (o1.getPingMs() - o2.getPingMs()));
Result maxHops = max(r -> r.getHopCount() > 0, Comparator.comparingInt(Result::getHopCount));
Result maxPaths = max(r -> r.getPathCount() > 0, Comparator.comparingInt(Result::getPathCount));

// avg/median:
double avgPing = avg(results, Result::isSuccess, Result::getPingMs);
double avgHops = avg(results, r -> r.getHopCount() > 0, Result::getHopCount);
double avgPaths = avg(results, r -> r.getPathCount() > 0, Result::getPathCount);
double medianPing = median(results, Result::isSuccess, Result::getPingMs).orElse(-1.0);
int medianHops = median(results, r -> r.getHopCount() > 0, Result::getHopCount).orElse(-1);
int medianPaths = median(results, r -> r.getPathCount() > 0, Result::getPathCount).orElse(-1);
double avgPing = avg(Result::isSuccess, Result::getPingMs);
double avgHops = avg(r -> r.getHopCount() > 0, Result::getHopCount);
double avgPaths = avg(r -> r.getPathCount() > 0, Result::getPathCount);
double medianPing = median(Result::isSuccess, Result::getPingMs);
double medianHops = median(r -> r.getHopCount() > 0, Result::getHopCount);
double medianPaths = median(r -> r.getPathCount() > 0, Result::getPathCount);

println("");
println("Max hops = " + maxHops.getHopCount() + ": " + maxHops);
println("Max ping [ms] = " + round(maxPing.getPingMs(), 2) + ": " + maxPing);
println("Max paths = " + maxPaths.getPathCount() + ": " + maxPaths);

println("Median hops = " + medianHops);
println("Median hops = " + (int) medianHops);
println("Median ping [ms] = " + round(medianPing, 2));
println("Median paths = " + medianPaths);
println("Median paths = " + (int) medianPaths);

println("Avg hops = " + round(avgHops, 1));
println("Avg ping [ms] = " + round(avgPing, 2));
Expand Down Expand Up @@ -439,14 +442,23 @@ public void onException(Throwable t) {
return best;
}

private static double avg(
List<Result> list, Predicate<Result> filter, ToDoubleFunction<Result> mapper) {
return list.stream().filter(filter).mapToDouble(mapper).average().orElse(-1);
private static double avg(Predicate<Result> filter, ToDoubleFunction<Result> mapper) {
return results.stream().filter(filter).mapToDouble(mapper).average().orElse(-1);
}

private static <T> Optional<T> median(
List<Result> list, Predicate<Result> filter, Function<Result, T> mapper) {
List<T> list2 = list.stream().filter(filter).map(mapper).sorted().collect(Collectors.toList());
return list2.isEmpty() ? Optional.empty() : Optional.of(list2.get(list2.size() / 2));
private static Result max(Predicate<Result> filter, Comparator<Result> comparator) {
return results.stream().filter(filter).max(comparator).orElseThrow(NoSuchElementException::new);
}

private static <T> double median(Predicate<Result> filter, Function<Result, T> mapper) {
List<T> list =
results.stream().filter(filter).map(mapper).sorted().collect(Collectors.toList());
if (list.isEmpty()) {
return -1;
}
if (list.get(0) instanceof Double) {
return (Double) list.get(list.size() / 2);
}
return (Integer) list.get(list.size() / 2);
}
}
Loading