Skip to content

Commit

Permalink
MultiMap (#34)
Browse files Browse the repository at this point in the history
Co-authored-by: Tilmann Zäschke <tilmann.zaeschke@inf.ethz.ch>
  • Loading branch information
tzaeschke and Tilmann Zäschke authored Mar 13, 2024
1 parent dff4a70 commit 4f51a99
Show file tree
Hide file tree
Showing 4 changed files with 94 additions and 23 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
[#22](https://github.com/netsec-ethz/scion-java-client/pull/22)
- BREAKING CHANGE: `getCurrentPath()` renamed to `getConnectionPath()`
[#30](https://github.com/netsec-ethz/scion-java-client/pull/30)
- Cleaned up `MultiMap` utility class
[#34](https://github.com/netsec-ethz/scion-java-client/pull/34)

### Fixed
- Fixed: SCMP problem when pinging local AS.
Expand Down
20 changes: 4 additions & 16 deletions src/main/java/org/scion/internal/MultiMap.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,18 @@ public class MultiMap<K, V> {
private final HashMap<K, ArrayList<V>> map = new HashMap<>();

public void put(K key, V value) {
ArrayList<V> entry = map.get(key);
if (entry == null) {
entry = new ArrayList<>();
map.put(key, entry);
}
entry.add(value);
map.computeIfAbsent(key, k -> new ArrayList<>()).add(value);
}

public ArrayList<V> get(K key) {
return map.get(key);
public List<V> get(K key) {
ArrayList<V> result = map.get(key);
return result == null ? Collections.emptyList() : result;
}

public boolean contains(K key) {
return map.containsKey(key);
}

public Set<Map.Entry<K, ArrayList<V>>> entrySet() {
return map.entrySet();
}

public Collection<ArrayList<V>> values() {
return map.values();
}

public boolean isEmpty() {
return map.isEmpty();
}
Expand Down
11 changes: 4 additions & 7 deletions src/main/java/org/scion/internal/Segments.java
Original file line number Diff line number Diff line change
Expand Up @@ -239,11 +239,8 @@ private static List<Daemon.Path> combineTwoSegments(
List<Daemon.Path> paths = new ArrayList<>();
for (Seg.PathSegment pathSegment0 : segments0) {
long middleIsdAs = getOtherIsdAs(srcIsdAs, pathSegment0);
ArrayList<Seg.PathSegment> segmentList1 = segmentsMap1.get(middleIsdAs);
if (segmentList1 != null) {
for (Seg.PathSegment pathSegment1 : segmentList1) {
paths.add(buildPath(brLookup, pathSegment0, pathSegment1));
}
for (Seg.PathSegment pathSegment1 : segmentsMap1.get(middleIsdAs)) {
paths.add(buildPath(brLookup, pathSegment0, pathSegment1));
}
}
return paths;
Expand All @@ -263,9 +260,9 @@ private static List<Daemon.Path> combineThreeSegments(
List<Daemon.Path> paths = new ArrayList<>();
for (Seg.PathSegment pathSeg : segmentsCore) {
long[] endIAs = getEndingIAs(pathSeg);
if (upSegments.get(endIAs[0]) != null && downSegments.get(endIAs[1]) != null) {
if (upSegments.contains(endIAs[0]) && downSegments.contains(endIAs[1])) {
buildPath(paths, upSegments.get(endIAs[0]), pathSeg, downSegments.get(endIAs[1]), brLookup);
} else if (upSegments.get(endIAs[1]) != null && downSegments.get(endIAs[0]) != null) {
} else if (upSegments.contains(endIAs[1]) && downSegments.contains(endIAs[0])) {
buildPath(paths, upSegments.get(endIAs[1]), pathSeg, downSegments.get(endIAs[0]), brLookup);
}
}
Expand Down
84 changes: 84 additions & 0 deletions src/test/java/org/scion/internal/MultiMapTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
// Copyright 2024 ETH Zurich
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package org.scion.internal;

import static org.junit.jupiter.api.Assertions.*;

import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;

class MultiMapTest {

private static class Pair {
int i;
String s;

Pair(int i, String s) {
this.i = i;
this.s = s;
}
}

@Test
void testSmoke() {
MultiMap<Integer, String> map = new MultiMap<>();
ArrayList<Pair> list = new ArrayList<>();
for (int i = 0; i < 1000; i++) {
// Use duplicate keys as well as duplicate values
Pair p = new Pair(i % 10, Integer.toString(i % 100));
map.put(p.i, p.s);
list.add(p);
}

assertFalse(map.isEmpty());

for (Pair p : list) {
assertTrue(map.contains(p.i));
List<String> entries = map.get(p.i);
assertEquals(100, entries.size());
int matches = 0;
int identity = 0;
for (String s : entries) {
assertEquals(p.i, Integer.parseInt(s) % 10);
if (p.s.equals(s)) {
matches++;
}
if (p.s == s) {
identity++;
}
}
assertEquals(10, matches);
assertEquals(1, identity);
}

map.clear();
assertTrue(map.isEmpty());
assertFalse(map.contains(0));
assertNotNull(map.get(0));
assertTrue(map.get(0).isEmpty());
}

@Test
void testEmptyMap() {
// Check that basic function don´t fail on empty map
MultiMap<Integer, String> map = new MultiMap<>();
assertTrue(map.isEmpty());
// assertEquals(0, map.size());
assertFalse(map.contains(0));
assertNotNull(map.get(0));
assertTrue(map.get(0).isEmpty());
}
}

0 comments on commit 4f51a99

Please sign in to comment.