io.datarouter.instrumentation.count.AtomicCounter Maven / Gradle / Ivy
/**
* Copyright © 2009 HotPads ([email protected])
*
* Licensed 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 io.datarouter.instrumentation.count;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.atomic.AtomicLong;
public class AtomicCounter implements CountCollectorPeriod{
public static final Integer INITIAL_CAPACITY = 512;//try to set higher than est num counters
private final long startTimeMs;
private final long lengthMs;
private final ConcurrentMap countByKey;
private final String createdByThreadId;
public AtomicCounter(long startTimeMs, long lengthMs){
this.startTimeMs = startTimeMs;
this.lengthMs = lengthMs;
this.countByKey = new ConcurrentHashMap<>(INITIAL_CAPACITY);
Thread createdByThread = Thread.currentThread();
this.createdByThreadId = createdByThread.getId() + "-" + createdByThread.getName();
}
@Override
public String toString(){
LocalDateTime time = LocalDateTime.ofInstant(Instant.ofEpochMilli(startTimeMs), ZoneId.systemDefault());
String formattedTime = time.format(DateTimeFormatter.ofPattern("yyyy-MM-dd_HH:mm:ss.SSS"));
return getClass().getSimpleName() + "[" + formattedTime + "," + Counters.getSuffix(lengthMs)
+ "," + System.identityHashCode(this) + "," + createdByThreadId + "]";
}
@Override
public long getPeriodMs(){
return lengthMs;
}
@Override
public long getStartTimeMs(){
return startTimeMs;
}
@Override
public long getNextStartTimeMs(){
return startTimeMs + lengthMs;
}
@Override
public Map getCountByKey(){
return countByKey;
}
@Override
public long increment(String key){
return getOrCreate(key).getAndAdd(1);
}
@Override
public long increment(String key, long delta){
return getOrCreate(key).getAndAdd(delta);
}
public void merge(CountCollector other){
for(Entry otherEntry : other.getCountByKey().entrySet()){
AtomicLong existingValue = countByKey.get(otherEntry.getKey());
if(existingValue != null){
existingValue.addAndGet(otherEntry.getValue().longValue());
}else{
countByKey.put(otherEntry.getKey(), new AtomicLong(otherEntry.getValue().longValue()));
}
}
}
private AtomicLong getOrCreate(String key){
AtomicLong count = countByKey.get(key);
if(count != null){
return count;
}
AtomicLong newVal = new AtomicLong(0L);// could be wasted
AtomicLong existingVal = countByKey.putIfAbsent(key, newVal);
return existingVal == null ? newVal : existingVal;
}
@Override
public AtomicCounter getCounter(){
return this;
}
@Override
public void stopAndFlushAll(){
//no-op
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy