/*
 * 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.kafka.jmh.cache;

import org.apache.kafka.common.cache.LRUCache;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;

/**
 * This is a simple example of a JMH benchmark.
 *
 * The sample code provided by the JMH project is a great place to start learning how to write correct benchmarks:
 * http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/
 */
@State(Scope.Thread)
public class LRUCacheBenchmark {

    private LRUCache<String, String> lruCache;

    private final String key = "the_key_to_use";
    private final String value = "the quick brown fox jumped over the lazy dog the olympics are about to start";
    int counter;


    @Setup(Level.Trial)
    public void setUpCaches() {
        lruCache = new LRUCache<>(100);
    }

    @Benchmark
    public String testCachePerformance() {
        counter++;
        lruCache.put(key + counter, value + counter);
        return lruCache.get(key + counter);
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(LRUCacheBenchmark.class.getSimpleName())
                .forks(2)
                .build();

        new Runner(opt).run();
    }

}

@@ -830,16 +830,54 @@
 cache;%0A%0A
+import java.util.concurrent.TimeUnit;%0A
 import o
@@ -1003,16 +1003,67 @@
 .Level;%0A
+import org.openjdk.jmh.annotations.OutputTimeUnit;%0A
 import o
@@ -1667,16 +1667,55 @@
 Thread)%0A
+@OutputTimeUnit(TimeUnit.MILLISECONDS)%0A
 public c
@@ -1756,41 +1756,47 @@
 ate 
-LRUCache%3CString, String%3E lruCache
+static final int DISTINCT_KEYS = 10_000
 ;%0A%0A 
@@ -1798,32 +1798,39 @@
 0;%0A%0A    private 
+static 
 final String key
@@ -1826,19 +1826,19 @@
  String 
-key
+KEY
  = %22the_
@@ -1850,16 +1850,17 @@
 o_use%22;%0A
+%0A
     priv
@@ -1863,16 +1863,23 @@
 private 
+static 
 final St
@@ -1883,21 +1883,21 @@
  String 
-value
+VALUE
  = %22the 
@@ -1971,16 +1971,191 @@
 start%22;%0A
+%0A    private final String%5B%5D keys = new String%5BDISTINCT_KEYS%5D;%0A%0A    private final String%5B%5D values = new String%5BDISTINCT_KEYS%5D;%0A%0A    private LRUCache%3CString, String%3E lruCache;%0A%0A
     int 
@@ -2164,17 +2164,16 @@
 unter;%0A%0A
-%0A
     @Set
@@ -2213,18 +2213,138 @@
 etUp
-Caches() %7B
+() %7B%0A        for (int i = 0; i %3C DISTINCT_KEYS; ++i) %7B%0A            keys%5Bi%5D = KEY + i;%0A            values%5Bi%5D = VALUE + i;%0A        %7D
 %0A   
@@ -2476,51 +2476,126 @@
     
-lruCache.put(key + counter, value + counter
+int index = counter %25 DISTINCT_KEYS;%0A        String hashkey = keys%5Bindex%5D;%0A        lruCache.put(hashkey, values%5Bindex%5D
 );%0A 
@@ -2625,21 +2625,15 @@
 get(
-key + counter
+hashkey
 );%0A 

Fix needless GC + Result time unit in JMH