/*
 * (c) Copyright 2018 Palantir Technologies Inc. All rights reserved.
 *
 * 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.palantir.atlasdb.cache;

import java.util.function.Supplier;

import javax.annotation.Nullable;

import com.codahale.metrics.MetricRegistry;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.Policy;
import com.google.common.annotations.VisibleForTesting;
import com.palantir.atlasdb.util.AtlasDbMetrics;

public class DefaultTimestampCache implements TimestampCache {
    private final Supplier<Long> size;

    private final Cache<Long, Long> startToCommitTimestampCache;
    private final Policy.Eviction<Long, Long> evictionPolicy;

    @VisibleForTesting
    static Cache<Long, Long> createCache(long size) {
        return Caffeine.newBuilder()
                .maximumSize(size)
                .recordStats()
                .build();
    }

    public DefaultTimestampCache(MetricRegistry metricRegistry, Supplier<Long> size) {
        this.size = size;
        startToCommitTimestampCache = createCache(size.get());
        evictionPolicy = startToCommitTimestampCache.policy().eviction().get();
        AtlasDbMetrics.registerCache(metricRegistry, startToCommitTimestampCache,
                MetricRegistry.name(TimestampCache.class, "startToCommitTimestamp"));
    }

    @Override
    @Nullable
    public Long getCommitTimestampIfPresent(Long startTimestamp) {
        resizeIfNecessary();
        return startToCommitTimestampCache.getIfPresent(startTimestamp);
    }

    private void resizeIfNecessary() {
        if (evictionPolicy.getMaximum() != size.get()) {
            evictionPolicy.setMaximum(size.get());
        }
    }

    @Override
    public void putAlreadyCommittedTransaction(Long startTimestamp, Long commitTimestamp) {
        startToCommitTimestampCache.put(startTimestamp, commitTimestamp);
    }

    @Override
    public void clear() {
        startToCommitTimestampCache.invalidateAll();
    }

    public static TimestampCache createForTests() {
        return new DefaultTimestampCache(new MetricRegistry(), () -> 1000L);
    }
}

@@ -691,16 +691,20 @@
 unction.
+Long
 Supplier
@@ -1049,16 +1049,22 @@
 %0Apublic 
+final 
 class De
@@ -1129,24 +1129,28 @@
 e final 
+Long
 Supplier
 %3CLong%3E s
@@ -1137,30 +1137,24 @@
 LongSupplier
-%3CLong%3E
  size;%0A%0A    
@@ -1554,24 +1554,28 @@
 gistry, 
+Long
 Supplier
 %3CLong%3E s
@@ -1570,14 +1570,8 @@
 lier
-%3CLong%3E
  siz
@@ -1651,32 +1651,38 @@
 teCache(size.get
+AsLong
 ());%0A        evi
@@ -2219,16 +2219,22 @@
 size.get
+AsLong
 ()) %7B%0A  
@@ -2277,16 +2277,22 @@
 size.get
+AsLong
 ());%0A   

Refactor DefaultTimestampCache (#4506)