1 package org.csc.phynixx.common.utils;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 import java.util.*;
25
26
27
28
29
30 public class GroupingAssociation<X, Y, A> {
31
32
33 private final Map<X, Set<Y>> mapA = new HashMap<X, Set<Y>>();
34
35 private final Map<Y, Set<X>> mapB = new HashMap<Y, Set<X>>();
36
37
38 public void associate(X x, Y y) {
39 assertSet(mapA, x).add(y);
40 assertSet(mapB, y).add(x);
41 }
42
43
44 public Set<Y> getX(X x) {
45 return getEndpoints(x, mapA);
46 }
47
48 public Set<X> getY(Y y) {
49 return getEndpoints(y, mapB);
50 }
51
52
53 public void removeX(X x) {
54 removeDependents(x, mapA, mapB);
55 mapA.remove(x);
56 }
57
58
59 public void removeY(Y y) {
60 removeDependents(y, mapB, mapA);
61 mapB.remove(y);
62 }
63
64
65 public void disassociate(X x, Y y) {
66 removeDependent(x, y, mapA);
67 removeDependent(y, x, mapB);
68 }
69
70
71 static <K, V> Set<V> getEndpoints(K k, Map<K, Set<V>> map) {
72 Set<V> value = map.get(k);
73 if (value == null) {
74 return Collections.emptySet();
75 }
76 return Collections.unmodifiableSet(value);
77 }
78
79
80 static <K, V> void removeDependents(K key, Map<K, Set<V>> map, Map<V, Set<K>> inverseMap) {
81 Set<V> value = map.get(key);
82 if (value != null && !value.isEmpty()) {
83 for (V v : value) {
84 Set<K> keys = inverseMap.get(v);
85 if (keys != null && !keys.isEmpty()) {
86 keys.remove(key);
87 }
88 }
89 }
90 }
91
92 static <K, V> void removeDependent(K k, V v, Map<K, Set<V>> map) {
93 Set<V> value = map.get(k);
94 if (value != null && !value.isEmpty()) {
95 value.remove(v);
96 }
97 }
98
99
100 static <K, V> Set<V> assertSet(Map<K, Set<V>> map, K key) {
101 Set<V> value = map.get(key);
102 if (value == null) {
103 value = new HashSet<V>();
104 map.put(key, value);
105 }
106 return value;
107 }
108
109
110 }