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