]> gitweb.fperrin.net Git - Dictionary.git/blob - jars/icu4j-52_1/main/tests/framework/src/com/ibm/icu/dev/util/XEquivalenceMap.java
Upgrade ICU4J.
[Dictionary.git] / jars / icu4j-52_1 / main / tests / framework / src / com / ibm / icu / dev / util / XEquivalenceMap.java
1 /*
2  *******************************************************************************
3  * Copyright (C) 1996-2012, International Business Machines Corporation and    *
4  * others. All Rights Reserved.                                                *
5  *******************************************************************************
6  */
7 package com.ibm.icu.dev.util;
8
9 import java.util.Collections;
10 import java.util.HashMap;
11 import java.util.HashSet;
12 import java.util.Iterator;
13 import java.util.Map;
14 import java.util.Set;
15
16 import com.ibm.icu.impl.Row;
17 import com.ibm.icu.impl.Row.R2;
18
19 /**
20  * Everything that maps to the same value is part of the same equivalence class
21  * @author davis
22  *
23  */
24 public class XEquivalenceMap<K,V,R> implements Iterable<Set<K>> {
25     
26     Map<K,Row.R2<V,Set<R>>> source_target_reasons = new HashMap<K,Row.R2<V,Set<R>>>();
27
28     Map<V,Set<K>> target_sourceSet;
29     Map<K,Set<K>> source_Set = new HashMap<K,Set<K>>(); // not really needed: could go source-target-sourceset
30     
31     public XEquivalenceMap() {
32         this(new HashMap<V,Set<K>>());
33     }
34     
35     public XEquivalenceMap(Map<V,Set<K>> storage) {
36         target_sourceSet = storage;
37     }
38     
39     public XEquivalenceMap clear() {
40         source_target_reasons.clear();
41         target_sourceSet.clear();
42         source_Set.clear();
43         return this;
44     }
45     
46     public XEquivalenceMap add(K source, V target) {
47         return add(source, target, null);
48     }
49     
50     public XEquivalenceMap add(K source, V target, R reason) {
51         R2<V, Set<R>> target_reasons = source_target_reasons.get(source);
52         if (target_reasons == null) {
53             Set<R> reasons = new HashSet<R>();
54             if (reason != null) {
55                 reasons.add(reason);
56             }
57             target_reasons = Row.of(target, reasons);
58             source_target_reasons.put(source, target_reasons);
59         } else {
60             V otherTarget = target_reasons.get0();
61             Set<R> reasons = target_reasons.get1();
62             if (otherTarget.equals(target)) {
63                 if (reason != null) {
64                     reasons.add(reason);
65                 }
66                 return this;
67             }
68             throw new IllegalArgumentException("Same source mapping to different targets: "
69                     + source + " => " + otherTarget + " & " + target);
70         }
71
72         Set<K> s = target_sourceSet.get(target);
73         if (s == null) target_sourceSet.put(target, s = new HashSet<K>());
74         s.add(source);
75         source_Set.put(source, s);
76         return this;
77     }
78     
79     public Set<K> getEquivalences (K source) {
80         Set<K> s = source_Set.get(source);
81         if (s == null) return null;
82         return Collections.unmodifiableSet(s);
83     }
84     
85     public boolean areEquivalent (K source1, K source2) {
86         Set<K> s = (Set) source_Set.get(source1);
87         if (s == null) return false;
88         return s.contains(source2);
89     }
90     
91     public V getTarget(K source) {
92         return source_target_reasons.get(source).get0();
93     }
94     
95     public Set<R> getReasons(K source) {
96         return Collections.unmodifiableSet(source_target_reasons.get(source).get1());
97     }
98     
99     public Set<K> getSources(V target) {
100         Set<K> s = target_sourceSet.get(target);
101         return Collections.unmodifiableSet(s);
102     }
103     
104     public Iterator<Set<K>> iterator() {
105         return UnmodifiableIterator.from(target_sourceSet.values());
106     }
107     
108     public int size() {
109         return target_sourceSet.size();
110     }
111     
112     public boolean isEmpty() {
113         return target_sourceSet.isEmpty();
114     }
115
116     // Should be moved out on its own
117     public static class UnmodifiableIterator<T> implements Iterator<T> {
118         private Iterator<T> source;
119         
120         public static <T> UnmodifiableIterator<T> from(Iterator<T> source) {
121             UnmodifiableIterator<T> result = new UnmodifiableIterator<T>();
122             result.source = source;
123             return result;
124         }
125         
126         public static <T> UnmodifiableIterator<T> from(Iterable<T> source) {
127             return from(source.iterator());
128         }
129         
130         public void remove() {
131             throw new UnsupportedOperationException();
132         }
133         
134         public boolean hasNext() {
135             return source.hasNext();
136         }
137         
138         public T next() {
139             return source.next();
140         }
141     }
142 }