// 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.io.BufferExposingByteArrayOutputStream;
import com.intellij.util.Processor;
import com.intellij.util.io.AppendablePersistentMap.ValueDataAppender;
import org.jetbrains.annotations.*;

import java.io.*;
import java.io.DataOutputStream;
import java.util.Collection;
import java.util.Objects;

/**
 * A Base interface for custom PersistentHashMap implementations.
 * It is intentionally made not to extend other interfaces.
 * Wrap this class with {@link PersistentHashMap} if you need it to implement other interfaces
 * @see PersistentHashMap
 */
@ApiStatus.Experimental
public interface PersistentHashMapBase<Key, Value> {
  @NotNull
  DataExternalizer<Value> getValuesExternalizer();

  /**
   * Appends value chunk from specified appender to key's value.
   * Important use note: value externalizer used by this map should process all bytes from DataInput during deserialization and make sure
   * that deserialized value is consistent with value chunks appended.
   * E.g. Value can be Set of String and individual Strings can be appended with this method for particular key, when {@link #get(Object)} will
   * be eventually called for the key, deserializer will read all bytes retrieving Strings and collecting them into Set
   */
  default void appendData(Key key, @NotNull ValueDataAppender appender) throws IOException {
    BufferExposingByteArrayOutputStream bos = new BufferExposingByteArrayOutputStream();
    DataOutputStream dos = new DataOutputStream(bos);
    DataExternalizer<Value> dataExternalizer = getValuesExternalizer();

    Value oldValue = get(key);
    if (oldValue != null) {
      dataExternalizer.save(dos, oldValue);
    }
    appender.append(dos);
    dos.close();

    DataInputStream dis = new DataInputStream(bos.toInputStream());
    Value newValue = dataExternalizer.read(dis);
    dis.close();

    put(key, newValue);
  }

  /**
   * Process all keys registered in the map.
   * Note that keys which were removed at some point might be returned as well.
   */
  boolean processKeys(@NotNull Processor<? super Key> processor) throws IOException;

  void remove(Key key) throws IOException;

  boolean containsMapping(Key key) throws IOException;

  boolean isClosed();

  boolean isDirty();

  void markDirty() throws IOException;

  boolean isCorrupted();

  Value get(Key key) throws IOException;

  void put(Key key, Value value) throws IOException;

  void force();

  void close() throws IOException;

  /**
   * Closes the map removing all entries
   */
  void closeAndClean() throws IOException;

  void dropMemoryCaches();

  @NotNull
  Collection<Key> getAllKeysWithExistingMapping() throws IOException;

  boolean processKeysWithExistingMapping(@NotNull Processor<? super Key> processor) throws IOException;
}

@@ -465,34 +465,8 @@
 ion;
-%0Aimport java.util.Objects;
 %0A%0A/*
@@ -714,16 +714,49 @@
 HashMap%0A
+ * @see PersistentHashMapBuilder%0A
  */%0A@Api
@@ -2067,16 +2067,208 @@
 );%0A  %7D%0A%0A
+%0A%0A%0A%0A%0A  @NotNull%0A  Collection%3CKey%3E getAllKeysWithExistingMapping() throws IOException;%0A%0A  boolean processKeysWithExistingMapping(@NotNull Processor%3C? super Key%3E processor) throws IOException;%0A%0A
   /**%0A  
@@ -2486,50 +2486,9 @@
 n;%0A%0A
-  void remove(Key key) throws IOException;
+%0A
 %0A%0A  
@@ -2547,555 +2547,416 @@
 %0A%0A  
-boolean isClosed();%0A%0A  boolean isDirty();%0A%0A  void markDirty() throws IOException;%0A%0A  boolean isCorrupted();%0A%0A  Value get(Key key) throws IOException;%0A%0A  void put(Key key, Value value) throws IOException;%0A%0A  void force();%0A%0A  void close() throws IOException;%0A%0A  /**%0A   * Closes the map removing all entries%0A   */%0A  void closeAndClean() throws IOException;%0A%0A  void dropMemoryCaches();%0A%0A  @NotNull%0A  Collection%3CKey%3E getAllKeysWithExistingMapping() throws IOException;%0A%0A  boolean processKeysWithExistingMapping(@NotNull Processor%3C? super Key%3E processor
+Value get(Key key) throws IOException;%0A%0A  void put(Key key, Value value) throws IOException;%0A%0A  void remove(Key key) throws IOException;%0A%0A%0A%0A  boolean isDirty();%0A%0A  void markDirty() throws IOException;%0A%0A  boolean isCorrupted();%0A%0A%0A  void dropMemoryCaches();%0A%0A  void force();%0A%0A%0A  boolean isClosed();%0A%0A  void close() throws IOException;%0A%0A  /**%0A   * Closes the map removing all entries%0A   */%0A  void closeAndClean(
 ) th

reorder methods for PersistentHashMapBase