blob: 69b6d1766756fa0467758202cda335d4a2a660da [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with this
* work for additional information regarding copyright ownership. The ASF
* licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package org.apache.bookkeeper.stats;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
/**
* A {@code StatsLogger} that caches the stats objects created by other {@code StatsLogger}.
*/
public class CachingStatsLogger implements StatsLogger {
protected final StatsLogger underlying;
protected final ConcurrentMap<String, Counter> counters;
protected final ConcurrentMap<String, OpStatsLogger> opStatsLoggers;
protected final ConcurrentMap<String, StatsLogger> scopeStatsLoggers;
public CachingStatsLogger(StatsLogger statsLogger) {
this.underlying = statsLogger;
this.counters = new ConcurrentHashMap<String, Counter>();
this.opStatsLoggers = new ConcurrentHashMap<String, OpStatsLogger>();
this.scopeStatsLoggers = new ConcurrentHashMap<String, StatsLogger>();
}
@Override
public int hashCode() {
return underlying.hashCode();
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof CachingStatsLogger)) {
return false;
}
CachingStatsLogger another = (CachingStatsLogger) obj;
return underlying.equals(another.underlying);
}
@Override
public String toString() {
return underlying.toString();
}
@Override
public OpStatsLogger getOpStatsLogger(String name) {
OpStatsLogger opStatsLogger = opStatsLoggers.get(name);
if (null == opStatsLogger) {
OpStatsLogger newOpStatsLogger = underlying.getOpStatsLogger(name);
OpStatsLogger oldOpStatsLogger = opStatsLoggers.putIfAbsent(name, newOpStatsLogger);
opStatsLogger = (null == oldOpStatsLogger) ? newOpStatsLogger : oldOpStatsLogger;
}
return opStatsLogger;
}
@Override
public Counter getCounter(String name) {
Counter counter = counters.get(name);
if (null == counter) {
Counter newCounter = underlying.getCounter(name);
Counter oldCounter = counters.putIfAbsent(name, newCounter);
counter = (null == oldCounter) ? newCounter : oldCounter;
}
return counter;
}
@Override
public <T extends Number> void registerGauge(String name, Gauge<T> gauge) {
underlying.registerGauge(name, gauge);
}
@Override
public <T extends Number> void unregisterGauge(String name, Gauge<T> gauge) {
underlying.unregisterGauge(name, gauge);
}
@Override
public StatsLogger scope(String name) {
StatsLogger statsLogger = scopeStatsLoggers.get(name);
if (null == statsLogger) {
StatsLogger newStatsLogger = new CachingStatsLogger(underlying.scope(name));
StatsLogger oldStatsLogger = scopeStatsLoggers.putIfAbsent(name, newStatsLogger);
statsLogger = (null == oldStatsLogger) ? newStatsLogger : oldStatsLogger;
}
return statsLogger;
}
@Override
public void removeScope(String name, StatsLogger statsLogger) {
scopeStatsLoggers.remove(name, statsLogger);
}
}