// Copyright 2000-2019 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.indexing.impl.forward;

import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.util.io.ByteArraySequence;
import com.intellij.util.io.ByteSequenceDataExternalizer;
import com.intellij.util.io.EnumeratorIntegerDescriptor;
import com.intellij.util.io.PersistentHashMap;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.io.File;
import java.io.IOException;

public class PersistentMapBasedForwardIndex implements ForwardIndex {
  private static final Logger LOG = Logger.getInstance(PersistentMapBasedForwardIndex.class);
  @NotNull
  private volatile PersistentHashMap<Integer, ByteArraySequence> myPersistentMap;
  @NotNull
  private final File myMapFile;

  public PersistentMapBasedForwardIndex(@NotNull File mapFile) throws IOException {
    myPersistentMap = createMap(mapFile);
    myMapFile = mapFile;
  }

  @NotNull
  protected PersistentHashMap<Integer, ByteArraySequence> createMap(File file) throws IOException {
    return new PersistentHashMap<>(file, EnumeratorIntegerDescriptor.INSTANCE, ByteSequenceDataExternalizer.INSTANCE);
  }

  @Nullable
  @Override
  public ByteArraySequence get(@NotNull Integer key) throws IOException {
    return myPersistentMap.get(key);
  }

  @Override
  public void put(@NotNull Integer key, @Nullable ByteArraySequence value) throws IOException {
    if (value == null) {
      myPersistentMap.remove(key);
    }
    else {
      myPersistentMap.put(key, value);
    }
  }

  @Override
  public void force() {
    myPersistentMap.force();
  }

  @Override
  public void clear() throws IOException {
    File baseFile = myPersistentMap.getBaseFile();
    try {
      myPersistentMap.close();
    }
    catch (Exception e) {
      LOG.error(e);
    }
    PersistentHashMap.deleteFilesStartingWith(baseFile);
    myPersistentMap = createMap(myMapFile);
  }

  @Override
  public void close() throws IOException {
    myPersistentMap.close();
  }

  public boolean isBusyReading() {
    return myPersistentMap.isBusyReading();
  }

  public boolean containsMapping(int key) throws IOException {
    return myPersistentMap.containsMapping(key);
  }
}

@@ -448,16 +448,75 @@
 ashMap;%0A
+import com.intellij.util.io.PersistentHashMapValueStorage;%0A
 import o
@@ -549,16 +549,16 @@
 otNull;%0A
-
 import o
@@ -942,16 +942,53 @@
 MapFile;
+%0A  private final boolean myUseChunks;
 %0A%0A  publ
@@ -1057,32 +1057,165 @@
 s IOException %7B%0A
+    this(mapFile, true);%0A  %7D%0A%0A  public PersistentMapBasedForwardIndex(@NotNull File mapFile, boolean useChunks) throws IOException %7B%0A
     myPersistent
@@ -1265,16 +1265,45 @@
 apFile;%0A
+    myUseChunks = useChunks;%0A
   %7D%0A%0A  @
@@ -1418,122 +1418,448 @@
     
-return new PersistentHashMap%3C%3E(file, EnumeratorIntegerDescriptor.INSTANCE, ByteSequenceDataExternalizer.INSTANCE);
+Boolean oldHasNoChunksValue = PersistentHashMapValueStorage.CreationTimeOptions.HAS_NO_CHUNKS.get();%0A    PersistentHashMapValueStorage.CreationTimeOptions.HAS_NO_CHUNKS.set(!myUseChunks);%0A    try %7B%0A      return new PersistentHashMap%3C%3E(file, EnumeratorIntegerDescriptor.INSTANCE, ByteSequenceDataExternalizer.INSTANCE);%0A    %7D%0A    finally %7B%0A      PersistentHashMapValueStorage.CreationTimeOptions.HAS_NO_CHUNKS.set(oldHasNoChunksValue);%0A    %7D
 %0A  %7D

add on option to don't use chunks in persistent map based forward index