2 *******************************************************************************
3 * Copyright (C) 1996-2010, International Business Machines Corporation and *
4 * others. All Rights Reserved. *
5 *******************************************************************************
7 * $Date: 2009-08-07 15:01:31 -0700 (Fri, 07 Aug 2009) $
10 *******************************************************************************
13 package com.ibm.icu.dev.test.collator;
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;
23 import java.util.TreeMap;
24 import java.util.TreeSet;
26 public class Counter<T> implements Iterable<T>, Comparable<Counter<T>> {
28 Comparator<T> comparator;
34 public Counter(Comparator<T> comparator) {
35 if (comparator != null) {
36 this.comparator = comparator;
37 map = new TreeMap<T, RWLong>(comparator);
39 map = new LinkedHashMap<T, RWLong>();
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;
47 private final int forceUnique;
49 synchronized (RWLong.class) { // make thread-safe
50 forceUnique = uniqueCount++;
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;
61 return 1; // the forceUnique values must be different, so this is the only remaining case
63 public String toString() {
64 return String.valueOf(value);
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;
75 public long getCount(T obj) {
79 public long get(T obj) {
80 RWLong count = map.get(obj);
81 return count == null ? 0 : count.value;
84 public Counter<T> clear() {
89 public long getTotal() {
91 for (T item : map.keySet()) {
92 count += map.get(item).value;
97 public int getItemCount() {
101 private static class Entry<T> {
105 public Entry(RWLong count, T value, int uniqueness) {
108 this.uniqueness = uniqueness;
112 private static class EntryComparator<T> implements Comparator<Entry<T>>{
114 Comparator<T> byValue;
116 public EntryComparator(boolean ascending, Comparator<T> byValue) {
117 countOrdering = ascending ? 1 : -1;
118 this.byValue = byValue;
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);
126 return o1.uniqueness - o2.uniqueness;
130 public Set<T> getKeysetSortedByCount(boolean ascending) {
131 return getKeysetSortedByCount(ascending, null);
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));
137 for (T key : map.keySet()) {
138 count_key.add(new Entry<T>(map.get(key), key, counter++));
140 Set<T> result = new LinkedHashSet<T>();
141 for (Entry<T> entry : count_key) {
142 result.add(entry.value);
147 public Set<T> getKeysetSortedByKey() {
148 Set<T> s = new TreeSet<T>(comparator);
149 s.addAll(map.keySet());
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);
163 public Set<T> keySet() {
167 public Iterator<T> iterator() {
168 return map.keySet().iterator();
171 public Map<T, RWLong> getMap() {
172 return map; // older code was protecting map, but not the integer values.
179 public String toString() {
180 return map.toString();
183 public Counter<T> addAll(Collection<T> keys, int delta) {
190 public Counter<T> addAll(Counter<T> keys) {
192 add(key, keys.getCount(key));
197 public int compareTo(Counter<T> o) {
198 Iterator<T> i = map.keySet().iterator();
199 Iterator<T> j = o.map.keySet().iterator();
201 boolean goti = i.hasNext();
202 boolean gotj = j.hasNext();
203 if (!goti || !gotj) {
204 return goti ? 1 : gotj ? -1 : 0;
208 int result = ((Comparable<T>)ii).compareTo(jj);
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;
218 public Counter<T> increment(T key) {
222 public boolean containsKey(T key) {
223 return map.containsKey(key);
226 public boolean equals(Object o) {
227 return map.equals(o);
230 public int hashCode() {
231 return map.hashCode();
234 public boolean isEmpty() {
235 return map.isEmpty();
238 public Counter<T> remove(T key) {
243 //public RWLong put(T key, RWLong value) {
244 // return map.put(key, value);
247 //public void putAll(Map<? extends T, ? extends RWLong> t) {
251 //public Set<java.util.Map.Entry<T, Long>> entrySet() {
252 // return map.entrySet();
255 //public Collection<RWLong> values() {
256 // return map.values();