package com.hwlcn.ldap.util; import java.io.Serializable; import java.util.ArrayList; import java.util.Collections; import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; import com.hwlcn.core.annotation.Mutable; import com.hwlcn.core.annotation.ThreadSafety; import com.hwlcn.ldap.ldap.sdk.ResultCode; @Mutable() @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) public final class ResultCodeCounter implements Serializable { private static final long serialVersionUID = -2280620218815022241L; private final AtomicReference<ConcurrentHashMap<ResultCode,AtomicLong>> rcMap; public ResultCodeCounter() { rcMap = new AtomicReference<ConcurrentHashMap<ResultCode,AtomicLong>>(); rcMap.set(new ConcurrentHashMap<ResultCode,AtomicLong>()); } public void increment(final ResultCode resultCode) { increment(resultCode, 1); } public void increment(final ResultCode resultCode, final int amount) { final ConcurrentHashMap<ResultCode,AtomicLong> m = rcMap.get(); AtomicLong l = m.get(resultCode); if (l == null) { l = new AtomicLong(0L); final AtomicLong l2 = m.putIfAbsent(resultCode, l); if (l2 != null) { l = l2; } } l.addAndGet(amount); } public void reset() { rcMap.set(new ConcurrentHashMap<ResultCode, AtomicLong>()); } public List<ObjectPair<ResultCode,Long>> getCounts(final boolean reset) { final ConcurrentHashMap<ResultCode,AtomicLong> m; if (reset) { m = rcMap.getAndSet(new ConcurrentHashMap<ResultCode,AtomicLong>()); } else { m = new ConcurrentHashMap<ResultCode,AtomicLong>(rcMap.get()); } if (m.isEmpty()) { return Collections.emptyList(); } final TreeMap<Long,TreeMap<Integer,ResultCode>> sortedMap = new TreeMap<Long,TreeMap<Integer,ResultCode>>( new ReverseComparator<Long>()); for (final Map.Entry<ResultCode,AtomicLong> e : m.entrySet()) { final long l = e.getValue().longValue(); TreeMap<Integer,ResultCode> rcByValue = sortedMap.get(l); if (rcByValue == null) { rcByValue = new TreeMap<Integer,ResultCode>(); sortedMap.put(l, rcByValue); } final ResultCode rc = e.getKey(); rcByValue.put(rc.intValue(), rc); } final ArrayList<ObjectPair<ResultCode,Long>> rcCounts = new ArrayList<ObjectPair<ResultCode,Long>>(2*sortedMap.size()); for (final Map.Entry<Long,TreeMap<Integer,ResultCode>> e : sortedMap.entrySet()) { final long count = e.getKey(); for (final ResultCode rc : e.getValue().values()) { rcCounts.add(new ObjectPair<ResultCode,Long>(rc, count)); } } return Collections.unmodifiableList(rcCounts); } }