/*
 * 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.druid.client.cache;

import com.google.caliper.Param;
import com.google.caliper.Runner;
import com.google.caliper.SimpleBenchmark;
import com.google.common.base.Suppliers;
import net.spy.memcached.AddrUtil;
import net.spy.memcached.ConnectionFactoryBuilder;
import net.spy.memcached.DefaultHashAlgorithm;
import net.spy.memcached.FailureMode;
import net.spy.memcached.MemcachedClient;
import net.spy.memcached.MemcachedClientIF;
import net.spy.memcached.transcoders.SerializingTranscoder;
import org.apache.druid.collections.StupidResourceHolder;
import org.apache.druid.java.util.common.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.concurrent.TimeUnit;

public class MemcachedCacheBenchmark extends SimpleBenchmark
{
  public static final String NAMESPACE = "default";
  private static final String BASE_KEY = "test_2012-11-26T00:00:00.000Z_2012-11-27T00:00:00.000Z_2012-11-27T04:11:25.979Z_";
  private static byte[] randBytes;
  @Param({"localhost:11211"})
  String hosts;
  // object size in kB
  @Param({"1", "5", "10", "40"})
  int objectSize;
  @Param({"100", "1000"})
  int objectCount;
  private MemcachedCache cache;
  private MemcachedClientIF client;

  public static void main(String[] args)
  {
    Runner.main(MemcachedCacheBenchmark.class, args);
  }

  @Override
  protected void setUp() throws Exception
  {
    SerializingTranscoder transcoder = new SerializingTranscoder(
        50 * 1024 * 1024 // 50 MiB
    );
    // disable compression
    transcoder.setCompressionThreshold(Integer.MAX_VALUE);

    client = new MemcachedClient(
        new ConnectionFactoryBuilder().setProtocol(ConnectionFactoryBuilder.Protocol.BINARY)
                                      .setHashAlg(DefaultHashAlgorithm.FNV1A_64_HASH)
                                      .setLocatorType(ConnectionFactoryBuilder.Locator.CONSISTENT)
                                      .setDaemon(true)
                                      .setFailureMode(FailureMode.Retry)
                                      .setTranscoder(transcoder)
                                      .setShouldOptimize(true)
                                      .build(),
        AddrUtil.getAddresses(hosts)
    );


    cache = new MemcachedCache(
        Suppliers.ofInstance(
            StupidResourceHolder.create(client)
        ),
        new MemcachedCacheConfig()
        {
          @Override
          public String getMemcachedPrefix()
          {
            return "druid-memcached-benchmark";
          }

          @Override
          public int getTimeout()
          {
            return 30000;
          }

          @Override
          public int getExpiration()
          {
            return 3600;
          }
        }, MemcachedCacheTest.NOOP_MONITOR
    );

    randBytes = new byte[objectSize * 1024];
    new Random(0).nextBytes(randBytes);
  }

  @Override
  protected void tearDown()
  {
    client.shutdown(1, TimeUnit.MINUTES);
  }

  public void timePutObjects(int reps)
  {
    for (int i = 0; i < reps; ++i) {
      for (int k = 0; k < objectCount; ++k) {
        String key = BASE_KEY + k;
        cache.put(new Cache.NamedKey(NAMESPACE, StringUtils.toUtf8(key)), randBytes);
      }
      // make sure the write queue is empty
      client.waitForQueues(1, TimeUnit.HOURS);
    }
  }

  public long timeGetObject(int reps)
  {
    byte[] bytes;
    long count = 0;
    for (int i = 0; i < reps; i++) {
      for (int k = 0; k < objectCount; ++k) {
        String key = BASE_KEY + k;
        bytes = cache.get(new Cache.NamedKey(NAMESPACE, StringUtils.toUtf8(key)));
        count += bytes.length;
      }
    }
    return count;
  }

  public long timeBulkGetObjects(int reps)
  {
    long count = 0;
    for (int i = 0; i < reps; i++) {
      List<Cache.NamedKey> keys = new ArrayList<>();
      for (int k = 0; k < objectCount; ++k) {
        String key = BASE_KEY + k;
        keys.add(new Cache.NamedKey(NAMESPACE, StringUtils.toUtf8(key)));
      }
      Map<Cache.NamedKey, byte[]> results = cache.getBulk(keys);
      for (Cache.NamedKey key : keys) {
        byte[] bytes = results.get(key);
        count += bytes.length;
      }
    }
    return count;
  }
}
