/* * Copyright 2014 NAVER Corp. * * 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 com.navercorp.pinpoint.collector.util; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.concurrent.atomic.AtomicLong; /** * @author emeroad */ public class AtomicLongUpdateMap<T> { // FIXME consider to save a mapping information at each 30 ~ 50 seconds not to do at each time. // consider to change to LRU due to OOM risk private final ConcurrentMap<T, AtomicLong> cache = new ConcurrentHashMap<>(1024, 0.75f, 32); public boolean update(final T cacheKey, final long time) { if (cacheKey == null) { throw new NullPointerException("cacheKey must not be null"); } final AtomicLong hitSlot = cache.get(cacheKey); if (hitSlot == null ) { final AtomicLong newTime = new AtomicLong(time); final AtomicLong oldTime = cache.putIfAbsent(cacheKey, newTime); if (oldTime == null) { return true; } else { // the cachekey already exists return updateTime(time, oldTime); } } else { // update if the cachekey already exists return updateTime(time, hitSlot); } } private boolean updateTime(final long newTime, final AtomicLong oldTime) { final long oldLong = oldTime.get(); if (newTime > oldLong) { return oldTime.compareAndSet(oldLong, newTime); } return false; } }