// Copyright 2000-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.util.io;

import com.intellij.openapi.util.Pair;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.testFramework.PlatformTestUtil;
import com.intellij.testFramework.UsefulTestCase;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.mvstore.MVStore;
import org.jetbrains.mvstore.index.MVStorePersistentMap;

import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public class PersistentMapComparisonPerformanceTest extends UsefulTestCase {
  @Nullable
  private static List<Pair<Integer, String>> ourData;
  @NotNull
  private Path myTempDirectory;

  @Override
  protected void setUp() throws Exception {
    super.setUp();
    getData();
    myTempDirectory = FileUtil.createTempDirectory("persistent-map", "comparison").toPath();
  }

  public synchronized static @NotNull List<Pair<Integer, String>> getData() {
    if (ourData == null) {
      int size = 500_000;
      ourData = new ArrayList<>(size);
      for (int i = 0; i < size; i++) {
        ourData.add(Pair.create(i, PersistentMapTestBase.createRandomString()));
      }
      ourData.sort(Comparator.comparingLong(p -> p.getSecond().length()));
    }
    return ourData;
  }

  public void testMVStoreMap() throws IOException {
    MVStore mvStore = new MVStore
      .Builder()
      .autoCommitDelay(5_000)
      .compressHigh()
      .openOrNewOnIoError(myTempDirectory.resolve("mvstore"), true, e -> LOG.error(e));

    PersistentHashMap<Integer, String> map =
      new PersistentHashMap<>(
        new MVStorePersistentMap<>("test-map",
                                   mvStore,
                                   EnumeratorIntegerDescriptor.INSTANCE,
                                   EnumeratorStringDescriptor.INSTANCE));

    try {
      PlatformTestUtil.startPerformanceTest("put/get MVStore", 2000, () -> {
        doPutGetTest(map);
      }).ioBound().assertTiming();
    }
    finally {
      map.close();
      mvStore.close();
    }
  }

  public void testPersistentHashMap() throws IOException {
    PersistentHashMap<Integer, String> phm = PersistentMapBuilder
      .newBuilder(myTempDirectory.resolve("phm"), EnumeratorIntegerDescriptor.INSTANCE, EnumeratorStringDescriptor.INSTANCE).build();
    try {
      PlatformTestUtil.startPerformanceTest("put/get PHM", 4000, () -> {
        doPutGetTest(phm);
      }).ioBound().assertTiming();
    }
    finally {
      phm.close();
    }
  }

  private static void doPutGetTest(@NotNull PersistentMap<Integer, String> mapBase) throws IOException {
    for (Pair<Integer, String> datum : getData()) {
      mapBase.put(datum.getFirst(), datum.getSecond());
    }

    for (Pair<Integer, String> datum : getData()) {
      assertEquals(datum.getSecond(), mapBase.get(datum.getFirst()));
    }
  }
}

@@ -768,23 +768,16 @@
 private 
-static 
 List%3CPai
@@ -796,19 +796,18 @@
 tring%3E%3E 
-our
+my
 Data;%0A  
@@ -1039,21 +1039,22 @@
   %7D%0A%0A  p
-ublic
+rivate
  synchro
@@ -1059,23 +1059,16 @@
 ronized 
-static 
 @NotNull
@@ -1116,19 +1116,18 @@
     if (
-our
+my
 Data == 
@@ -1162,27 +1162,26 @@
 _000;%0A      
-our
+my
 Data = new A
@@ -1241,27 +1241,26 @@
 ) %7B%0A        
-our
+my
 Data.add(Pai
@@ -1331,19 +1331,18 @@
 %7D%0A      
-our
+my
 Data.sor
@@ -1416,19 +1416,18 @@
  return 
-our
+my
 Data;%0A  
@@ -2678,15 +2678,8 @@
 ate 
-static 
 void

make field non static