package com.revolsys.util.count;
import java.io.StringWriter;
import java.io.Writer;
import java.util.Arrays;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeMap;
import com.revolsys.io.PathNameProxy;
import com.revolsys.logging.Logs;
import com.revolsys.record.io.format.tsv.Tsv;
import com.revolsys.record.io.format.tsv.TsvWriter;
import com.revolsys.util.Counter;
import com.revolsys.util.LongCounter;
public class LabelCountMap {
private final Map<String, Counter> counterByLabel = new TreeMap<>();
private boolean logCounts = true;
private String message;
private int providerCount = 0;
public LabelCountMap() {
this(null);
}
public LabelCountMap(final String message) {
this.message = message;
}
public void addCount(final CharSequence label) {
addCount(label, 1);
}
public synchronized boolean addCount(final CharSequence label, final long count) {
if (label == null) {
return false;
} else {
final String labelString = label.toString();
Counter counter = this.counterByLabel.get(labelString);
if (counter == null) {
counter = new LongCounter(labelString, count);
this.counterByLabel.put(labelString, counter);
return true;
} else {
counter.add(count);
return false;
}
}
}
public void addCount(final PathNameProxy pathNameProxy) {
if (pathNameProxy != null) {
final CharSequence label = pathNameProxy.getPathName();
addCount(label);
}
}
public void addCount(final PathNameProxy pathNameProxy, final long count) {
final CharSequence label = pathNameProxy.getPathName();
addCount(label, count);
}
public void addCounts(final LabelCountMap labelCountMap) {
synchronized (labelCountMap) {
for (final String label : labelCountMap.getLabels()) {
final long count = labelCountMap.getCount(label);
addCount(label, count);
}
}
}
public synchronized void addCountsText(final StringBuilder sb) {
int totalCount = 0;
if (this.message != null) {
sb.append(this.message);
}
sb.append("\n");
for (final Entry<String, Counter> entry : this.counterByLabel.entrySet()) {
sb.append(entry.getKey());
sb.append("\t");
final Counter counter = entry.getValue();
final long count = counter.get();
totalCount += count;
sb.append(count);
sb.append("\n");
}
sb.append("Total");
sb.append("\t");
sb.append(totalCount);
sb.append("\n");
}
public synchronized void clearCounts() {
this.counterByLabel.clear();
}
public synchronized void clearCounts(final String label) {
if (label != null) {
final String labelString = label.toString();
this.counterByLabel.remove(labelString);
}
}
public synchronized void connect() {
this.providerCount++;
}
public synchronized void disconnect() {
this.providerCount--;
if (this.providerCount <= 0) {
logCounts();
}
}
public synchronized Long getCount(final CharSequence label) {
if (label != null) {
final String labelString = label.toString();
final Counter counter = this.counterByLabel.get(labelString);
if (counter != null) {
return counter.get();
}
}
return null;
}
public synchronized Counter getCounter(final CharSequence label) {
if (label == null) {
return null;
} else {
final String labelString = label.toString();
Counter counter = this.counterByLabel.get(labelString);
if (counter == null) {
counter = new LongCounter(labelString);
this.counterByLabel.put(labelString, counter);
}
return counter;
}
}
public synchronized Set<String> getLabels() {
return this.counterByLabel.keySet();
}
public String getMessage() {
return this.message;
}
public boolean isLogCounts() {
return this.logCounts;
}
public synchronized String logCounts() {
final StringBuilder sb = new StringBuilder();
addCountsText(sb);
final String string = sb.toString();
if (isLogCounts() && !this.counterByLabel.isEmpty()) {
Logs.info(this, string);
}
return string;
}
public void setLogCounts(final boolean logCounts) {
this.logCounts = logCounts;
}
public void setMessage(final String message) {
this.message = message;
}
@Override
public String toString() {
return this.message;
}
public String toTsv() {
return toTsv("LABEL", "COUNT");
}
public String toTsv(final String... titles) {
final StringWriter out = new StringWriter();
toTsv(out, titles);
return out.toString();
}
public void toTsv(final Writer out, final String... titles) {
try (
TsvWriter tsv = Tsv.plainWriter(out)) {
long total = 0;
tsv.write(Arrays.asList(titles));
for (final String label : getLabels()) {
final long count = getCount(label);
total += count;
tsv.write(label, count);
}
tsv.write("Total", total);
}
}
}