1/* GENERATED SOURCE. DO NOT MODIFY. */
2// © 2016 and later: Unicode, Inc. and others.
3// License & terms of use: http://www.unicode.org/copyright.html#License
4/**
5 *******************************************************************************
6 * Copyright (C) 1996-2015, International Business Machines Corporation and    *
7 * others. All Rights Reserved.                                                *
8 *******************************************************************************
9 */
10
11package android.icu.dev.test.collator;
12
13
14import java.util.Collection;
15import java.util.Comparator;
16import java.util.Iterator;
17import java.util.LinkedHashMap;
18import java.util.LinkedHashSet;
19import java.util.Map;
20import java.util.Set;
21import java.util.TreeMap;
22import java.util.TreeSet;
23
24public class Counter<T> implements Iterable<T>, Comparable<Counter<T>> {
25  Map<T,RWLong> map;
26  Comparator<T> comparator;
27
28  public Counter() {
29    this(null);
30  }
31
32  public Counter(Comparator<T> comparator) {
33    if (comparator != null) {
34      this.comparator = comparator;
35      map = new TreeMap<T, RWLong>(comparator);
36    } else {
37      map = new LinkedHashMap<T, RWLong>();
38    }
39  }
40
41  static private final class RWLong implements Comparable<RWLong> {
42    // the uniqueCount ensures that two different RWIntegers will always be different
43    static int uniqueCount;
44    public long value;
45    private final int forceUnique;
46    {
47      synchronized (RWLong.class) { // make thread-safe
48        forceUnique = uniqueCount++;
49      }
50    }
51
52    public int compareTo(RWLong that) {
53      if (that.value < value) return -1;
54      if (that.value > value) return 1;
55      if (this == that) return 0;
56      synchronized (this) { // make thread-safe
57        if (that.forceUnique < forceUnique) return -1;
58      }
59      return 1; // the forceUnique values must be different, so this is the only remaining case
60    }
61    public String toString() {
62      return String.valueOf(value);
63    }
64  }
65
66  public Counter<T> add(T obj, long countValue) {
67    RWLong count = map.get(obj);
68    if (count == null) map.put(obj, count = new RWLong());
69    count.value += countValue;
70    return this;
71  }
72
73  public long getCount(T obj) {
74      return get(obj);
75    }
76
77  public long get(T obj) {
78      RWLong count = map.get(obj);
79      return count == null ? 0 : count.value;
80    }
81
82  public Counter<T> clear() {
83    map.clear();
84    return this;
85  }
86
87  public long getTotal() {
88    long count = 0;
89    for (T item : map.keySet()) {
90      count += map.get(item).value;
91    }
92    return count;
93  }
94
95  public int getItemCount() {
96    return size();
97  }
98
99  private static class Entry<T> {
100    RWLong count;
101    T value;
102    int uniqueness;
103    public Entry(RWLong count, T value, int uniqueness) {
104      this.count = count;
105      this.value = value;
106      this.uniqueness = uniqueness;
107    }
108  }
109
110  private static class EntryComparator<T> implements Comparator<Entry<T>>{
111    int countOrdering;
112    Comparator<T> byValue;
113
114    public EntryComparator(boolean ascending, Comparator<T> byValue) {
115      countOrdering = ascending ? 1 : -1;
116      this.byValue = byValue;
117    }
118    public int compare(Entry<T> o1, Entry<T> o2) {
119      if (o1.count.value < o2.count.value) return -countOrdering;
120      if (o1.count.value > o2.count.value) return countOrdering;
121      if (byValue != null) {
122        return byValue.compare(o1.value, o2.value);
123      }
124      return o1.uniqueness - o2.uniqueness;
125    }
126  }
127
128  public Set<T> getKeysetSortedByCount(boolean ascending) {
129    return getKeysetSortedByCount(ascending, null);
130  }
131
132  public Set<T> getKeysetSortedByCount(boolean ascending, Comparator<T> byValue) {
133    Set<Entry<T>> count_key = new TreeSet<Entry<T>>(new EntryComparator<T>(ascending, byValue));
134    int counter = 0;
135    for (T key : map.keySet()) {
136      count_key.add(new Entry<T>(map.get(key), key, counter++));
137    }
138    Set<T> result = new LinkedHashSet<T>();
139    for (Entry<T> entry : count_key) {
140       result.add(entry.value);
141    }
142    return result;
143  }
144
145  public Set<T> getKeysetSortedByKey() {
146    Set<T> s = new TreeSet<T>(comparator);
147    s.addAll(map.keySet());
148    return s;
149  }
150
151//public Map<T,RWInteger> getKeyToKey() {
152//Map<T,RWInteger> result = new HashMap<T,RWInteger>();
153//Iterator<T> it = map.keySet().iterator();
154//while (it.hasNext()) {
155//Object key = it.next();
156//result.put(key, key);
157//}
158//return result;
159//}
160
161  public Set<T> keySet() {
162    return map.keySet();
163  }
164
165  public Iterator<T> iterator() {
166    return map.keySet().iterator();
167  }
168
169  public Map<T, RWLong> getMap() {
170    return map; // older code was protecting map, but not the integer values.
171  }
172
173  public int size() {
174    return map.size();
175  }
176
177  public String toString() {
178    return map.toString();
179  }
180
181  public Counter<T> addAll(Collection<T> keys, int delta) {
182    for (T key : keys) {
183      add(key, delta);
184    }
185    return this;
186  }
187
188  public Counter<T> addAll(Counter<T> keys) {
189    for (T key : keys) {
190      add(key, keys.getCount(key));
191    }
192    return this;
193  }
194
195  public int compareTo(Counter<T> o) {
196    Iterator<T> i = map.keySet().iterator();
197    Iterator<T> j = o.map.keySet().iterator();
198    while (true) {
199      boolean goti = i.hasNext();
200      boolean gotj = j.hasNext();
201      if (!goti || !gotj) {
202        return goti ? 1 : gotj ? -1 : 0;
203      }
204      T ii = i.next();
205      T jj = i.next();
206      int result = ((Comparable<T>)ii).compareTo(jj);
207      if (result != 0) {
208        return result;
209      }
210      final long iv = map.get(ii).value;
211      final long jv = o.map.get(jj).value;
212      if (iv != jv) return iv < jv ? -1 : 0;
213    }
214  }
215
216  public Counter<T> increment(T key) {
217    return add(key, 1);
218  }
219
220public boolean containsKey(T key) {
221    return map.containsKey(key);
222}
223
224public boolean equals(Object o) {
225    return map.equals(o);
226}
227
228public int hashCode() {
229    return map.hashCode();
230}
231
232public boolean isEmpty() {
233    return map.isEmpty();
234}
235
236public Counter<T> remove(T key) {
237    map.remove(key);
238    return this;
239}
240
241//public RWLong put(T key, RWLong value) {
242//    return map.put(key, value);
243//}
244//
245//public void putAll(Map<? extends T, ? extends RWLong> t) {
246//    map.putAll(t);
247//}
248//
249//public Set<java.util.Map.Entry<T, Long>> entrySet() {
250//    return map.entrySet();
251//}
252//
253//public Collection<RWLong> values() {
254//    return map.values();
255//}
256
257}
258