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