text:
// Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
//  This source code is licensed under both the GPLv2 (found in the
//  COPYING file in the root directory) and Apache 2.0 License
//  (found in the LICENSE.Apache file in the root directory).
package org.rocksdb;

import org.junit.*;
import org.junit.rules.ExpectedException;
import org.junit.rules.TemporaryFolder;

import java.nio.ByteBuffer;
import java.util.*;

import static java.nio.charset.StandardCharsets.UTF_8;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.fail;

public class RocksDBTest {

  @ClassRule
  public static final RocksNativeLibraryResource ROCKS_NATIVE_LIBRARY_RESOURCE =
      new RocksNativeLibraryResource();

  @Rule
  public TemporaryFolder dbFolder = new TemporaryFolder();

  public static final Random rand = PlatformRandomHelper.
      getPlatformSpecificRandomFactory();

  @Test
  public void open() throws RocksDBException {
    try (final RocksDB db =
             RocksDB.open(dbFolder.getRoot().getAbsolutePath())) {
      assertThat(db).isNotNull();
    }
  }

  @Test
  public void open_opt() throws RocksDBException {
    try (final Options opt = new Options().setCreateIfMissing(true);
         final RocksDB db = RocksDB.open(opt,
             dbFolder.getRoot().getAbsolutePath())) {
      assertThat(db).isNotNull();
    }
  }

  @Test
  public void openWhenOpen() throws RocksDBException {
    final String dbPath = dbFolder.getRoot().getAbsolutePath();

    try (final RocksDB db1 = RocksDB.open(dbPath)) {
      try (final RocksDB db2 = RocksDB.open(dbPath)) {
        fail("Should have thrown an exception when opening the same db twice");
      } catch (final RocksDBException e) {
        assertThat(e.getStatus().getCode()).isEqualTo(Status.Code.IOError);
        assertThat(e.getStatus().getSubCode()).isEqualTo(Status.SubCode.None);
        assertThat(e.getStatus().getState()).contains("lock ");
      }
    }
  }

  @Test
  public void createColumnFamily() throws RocksDBException {
      final byte[] col1Name = "col1".getBytes(UTF_8);

      try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
           final ColumnFamilyOptions cfOpts = new ColumnFamilyOptions()
      ) {
        try (final ColumnFamilyHandle col1 =
            db.createColumnFamily(new ColumnFamilyDescriptor(col1Name, cfOpts))) {
          assertThat(col1).isNotNull();
          assertThat(col1.getName()).isEqualTo(col1Name);
        }
      }

      final List<ColumnFamilyHandle> cfHandles = new ArrayList<>();
      try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath(),
        Arrays.asList(
            new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
            new ColumnFamilyDescriptor(col1Name)),
            cfHandles)) {
        try {
          assertThat(cfHandles.size()).isEqualTo(2);
          assertThat(cfHandles.get(1)).isNotNull();
          assertThat(cfHandles.get(1).getName()).isEqualTo(col1Name);
        } finally {
          for (final ColumnFamilyHandle cfHandle :
              cfHandles) {
            cfHandle.close();
          }
        }
      }
  }

  @Test
  public void createColumnFamilies() throws RocksDBException {
    final byte[] col1Name = "col1".getBytes(UTF_8);
    final byte[] col2Name = "col2".getBytes(UTF_8);

    List<ColumnFamilyHandle> cfHandles;
    try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
         final ColumnFamilyOptions cfOpts = new ColumnFamilyOptions()
    ) {
      cfHandles =
          db.createColumnFamilies(cfOpts, Arrays.asList(col1Name, col2Name));
      try {
        assertThat(cfHandles).isNotNull();
        assertThat(cfHandles.size()).isEqualTo(2);
        assertThat(cfHandles.get(0).getName()).isEqualTo(col1Name);
        assertThat(cfHandles.get(1).getName()).isEqualTo(col2Name);
      } finally {
        for (final ColumnFamilyHandle cfHandle : cfHandles) {
          cfHandle.close();
        }
      }
    }

    cfHandles = new ArrayList<>();
    try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath(),
        Arrays.asList(
            new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
            new ColumnFamilyDescriptor(col1Name),
            new ColumnFamilyDescriptor(col2Name)),
        cfHandles)) {
      try {
        assertThat(cfHandles.size()).isEqualTo(3);
        assertThat(cfHandles.get(1)).isNotNull();
        assertThat(cfHandles.get(1).getName()).isEqualTo(col1Name);
        assertThat(cfHandles.get(2)).isNotNull();
        assertThat(cfHandles.get(2).getName()).isEqualTo(col2Name);
      } finally {
        for (final ColumnFamilyHandle cfHandle : cfHandles) {
          cfHandle.close();
        }
      }
    }
  }

  @Test
  public void createColumnFamiliesfromDescriptors() throws RocksDBException {
    final byte[] col1Name = "col1".getBytes(UTF_8);
    final byte[] col2Name = "col2".getBytes(UTF_8);

    List<ColumnFamilyHandle> cfHandles;
    try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
         final ColumnFamilyOptions cfOpts = new ColumnFamilyOptions()
    ) {
      cfHandles =
          db.createColumnFamilies(Arrays.asList(
              new ColumnFamilyDescriptor(col1Name, cfOpts),
              new ColumnFamilyDescriptor(col2Name, cfOpts)));
      try {
        assertThat(cfHandles).isNotNull();
        assertThat(cfHandles.size()).isEqualTo(2);
        assertThat(cfHandles.get(0).getName()).isEqualTo(col1Name);
        assertThat(cfHandles.get(1).getName()).isEqualTo(col2Name);
      } finally {
        for (final ColumnFamilyHandle cfHandle : cfHandles) {
          cfHandle.close();
        }
      }
    }

    cfHandles = new ArrayList<>();
    try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath(),
        Arrays.asList(
            new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
            new ColumnFamilyDescriptor(col1Name),
            new ColumnFamilyDescriptor(col2Name)),
        cfHandles)) {
      try {
        assertThat(cfHandles.size()).isEqualTo(3);
        assertThat(cfHandles.get(1)).isNotNull();
        assertThat(cfHandles.get(1).getName()).isEqualTo(col1Name);
        assertThat(cfHandles.get(2)).isNotNull();
        assertThat(cfHandles.get(2).getName()).isEqualTo(col2Name);
      } finally {
        for (final ColumnFamilyHandle cfHandle : cfHandles) {
          cfHandle.close();
        }
      }
    }
  }

  @Test
  public void put() throws RocksDBException {
    try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
         final WriteOptions opt = new WriteOptions(); final ReadOptions optr = new ReadOptions()) {
      db.put("key1".getBytes(), "value".getBytes());
      db.put(opt, "key2".getBytes(), "12345678".getBytes());
      assertThat(db.get("key1".getBytes())).isEqualTo(
          "value".getBytes());
      assertThat(db.get("key2".getBytes())).isEqualTo(
          "12345678".getBytes());

      ByteBuffer key = ByteBuffer.allocateDirect(12);
      ByteBuffer value = ByteBuffer.allocateDirect(12);
      key.position(4);
      key.put("key3".getBytes());
      key.position(4).limit(8);
      value.position(4);
      value.put("val3".getBytes());
      value.position(4).limit(8);

      db.put(opt, key, value);

      assertThat(key.position()).isEqualTo(8);
      assertThat(key.limit()).isEqualTo(8);

      assertThat(value.position()).isEqualTo(8);
      assertThat(value.limit()).isEqualTo(8);

      key.position(4);

      ByteBuffer result = ByteBuffer.allocateDirect(12);
      assertThat(db.get(optr, key, result)).isEqualTo(4);
      assertThat(result.position()).isEqualTo(0);
      assertThat(result.limit()).isEqualTo(4);
      assertThat(key.position()).isEqualTo(8);
      assertThat(key.limit()).isEqualTo(8);

      byte[] tmp = new byte[4];
      result.get(tmp);
      assertThat(tmp).isEqualTo("val3".getBytes());

      key.position(4);

      result.clear().position(9);
      assertThat(db.get(optr, key, result)).isEqualTo(4);
      assertThat(result.position()).isEqualTo(9);
      assertThat(result.limit()).isEqualTo(12);
      assertThat(key.position()).isEqualTo(8);
      assertThat(key.limit()).isEqualTo(8);
      byte[] tmp2 = new byte[3];
      result.get(tmp2);
      assertThat(tmp2).isEqualTo("val".getBytes());

      // put
      Segment key3 = sliceSegment("key3");
      Segment key4 = sliceSegment("key4");
      Segment value0 = sliceSegment("value 0");
      Segment value1 = sliceSegment("value 1");
      db.put(key3.data, key3.offset, key3.len, value0.data, value0.offset, value0.len);
      db.put(opt, key4.data, key4.offset, key4.len, value1.data, value1.offset, value1.len);

      // compare
      Assert.assertTrue(value0.isSamePayload(db.get(key3.data, key3.offset, key3.len)));
      Assert.assertTrue(value1.isSamePayload(db.get(key4.data, key4.offset, key4.len)));
    }
  }

  private static Segment sliceSegment(String key) {
    ByteBuffer rawKey = ByteBuffer.allocate(key.length() + 4);
    rawKey.put((byte)0);
    rawKey.put((byte)0);
    rawKey.put(key.getBytes());

    return new Segment(rawKey.array(), 2, key.length());
  }

  private static class Segment {
    final byte[] data;
    final int offset;
    final int len;

    public boolean isSamePayload(byte[] value) {
      if (value == null) {
        return false;
      }
      if (value.length != len) {
        return false;
      }

      for (int i = 0; i < value.length; i++) {
        if (data[i + offset] != value[i]) {
          return false;
        }
      }

      return true;
    }

    public Segment(byte[] value, int offset, int len) {
      this.data = value;
      this.offset = offset;
      this.len = len;
    }
  }

  @Test
  public void write() throws RocksDBException {
    try (final StringAppendOperator stringAppendOperator = new StringAppendOperator();
         final Options options = new Options()
             .setMergeOperator(stringAppendOperator)
             .setCreateIfMissing(true);
         final RocksDB db = RocksDB.open(options,
             dbFolder.getRoot().getAbsolutePath());
         final WriteOptions opts = new WriteOptions()) {

      try (final WriteBatch wb1 = new WriteBatch()) {
        wb1.put("key1".getBytes(), "aa".getBytes());
        wb1.merge("key1".getBytes(), "bb".getBytes());

        try (final WriteBatch wb2 = new WriteBatch()) {
          wb2.put("key2".getBytes(), "xx".getBytes());
          wb2.merge("key2".getBytes(), "yy".getBytes());
          db.write(opts, wb1);
          db.write(opts, wb2);
        }
      }

      assertThat(db.get("key1".getBytes())).isEqualTo(
          "aa,bb".getBytes());
      assertThat(db.get("key2".getBytes())).isEqualTo(
          "xx,yy".getBytes());
    }
  }

  @Test
  public void getWithOutValue() throws RocksDBException {
    try (final RocksDB db =
             RocksDB.open(dbFolder.getRoot().getAbsolutePath())) {
      db.put("key1".getBytes(), "value".getBytes());
      db.put("key2".getBytes(), "12345678".getBytes());
      byte[] outValue = new byte[5];
      // not found value
      int getResult = db.get("keyNotFound".getBytes(), outValue);
      assertThat(getResult).isEqualTo(RocksDB.NOT_FOUND);
      // found value which fits in outValue
      getResult = db.get("key1".getBytes(), outValue);
      assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND);
      assertThat(outValue).isEqualTo("value".getBytes());
      // found value which fits partially
      getResult = db.get("key2".getBytes(), outValue);
      assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND);
      assertThat(outValue).isEqualTo("12345".getBytes());
    }
  }

  @Test
  public void getWithOutValueReadOptions() throws RocksDBException {
    try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
         final ReadOptions rOpt = new ReadOptions()) {
      db.put("key1".getBytes(), "value".getBytes());
      db.put("key2".getBytes(), "12345678".getBytes());
      byte[] outValue = new byte[5];
      // not found value
      int getResult = db.get(rOpt, "keyNotFound".getBytes(),
          outValue);
      assertThat(getResult).isEqualTo(RocksDB.NOT_FOUND);
      // found value which fits in outValue
      getResult = db.get(rOpt, "key1".getBytes(), outValue);
      assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND);
      assertThat(outValue).isEqualTo("value".getBytes());
      // found value which fits partially
      getResult = db.get(rOpt, "key2".getBytes(), outValue);
      assertThat(getResult).isNotEqualTo(RocksDB.NOT_FOUND);
      assertThat(outValue).isEqualTo("12345".getBytes());
    }
  }

  @Rule
  public ExpectedException thrown = ExpectedException.none();

  @Test
  public void getOutOfArrayMaxSizeValue() throws RocksDBException {
    final int numberOfValueSplits = 10;
    final int splitSize = Integer.MAX_VALUE / numberOfValueSplits;

    Runtime runtime = Runtime.getRuntime();
    long neededMemory = ((long)(splitSize)) * (((long)numberOfValueSplits) + 3);
    boolean isEnoughMemory = runtime.maxMemory() - runtime.totalMemory() > neededMemory;
    Assume.assumeTrue(isEnoughMemory);

    final byte[] valueSplit = new byte[splitSize];
    final byte[] key = "key".getBytes();

    thrown.expect(RocksDBException.class);
    thrown.expectMessage("Requested array size exceeds VM limit");

    // merge (numberOfValueSplits + 1) valueSplit's to get value size exceeding Integer.MAX_VALUE
    try (final StringAppendOperator stringAppendOperator = new StringAppendOperator();
         final Options opt = new Options()
                 .setCreateIfMissing(true)
                 .setMergeOperator(stringAppendOperator);
         final RocksDB db = RocksDB.open(opt, dbFolder.getRoot().getAbsolutePath())) {
      db.put(key, valueSplit);
      for (int i = 0; i < numberOfValueSplits; i++) {
        db.merge(key, valueSplit);
      }
      db.get(key);
    }
  }

  @SuppressWarnings("deprecated")
  @Test
  public void multiGet() throws RocksDBException {
    try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
         final ReadOptions rOpt = new ReadOptions()) {
      db.put("key1".getBytes(), "value".getBytes());
      db.put("key2".getBytes(), "12345678".getBytes());
      List<byte[]> lookupKeys = new ArrayList<>();
      lookupKeys.add("key1".getBytes());
      lookupKeys.add("key2".getBytes());
      Map<byte[], byte[]> results = db.multiGet(lookupKeys);
      assertThat(results).isNotNull();
      assertThat(results.values()).isNotNull();
      assertThat(results.values()).
          contains("value".getBytes(), "12345678".getBytes());
      // test same method with ReadOptions
      results = db.multiGet(rOpt, lookupKeys);
      assertThat(results).isNotNull();
      assertThat(results.values()).isNotNull();
      assertThat(results.values()).
          contains("value".getBytes(), "12345678".getBytes());

      // remove existing key
      lookupKeys.remove("key2".getBytes());
      // add non existing key
      lookupKeys.add("key3".getBytes());
      results = db.multiGet(lookupKeys);
      assertThat(results).isNotNull();
      assertThat(results.values()).isNotNull();
      assertThat(results.values()).
          contains("value".getBytes());
      // test same call with readOptions
      results = db.multiGet(rOpt, lookupKeys);
      assertThat(results).isNotNull();
      assertThat(results.values()).isNotNull();
      assertThat(results.values()).
          contains("value".getBytes());
    }
  }

  @Test
  public void multiGetAsList() throws RocksDBException {
    try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
         final ReadOptions rOpt = new ReadOptions()) {
      db.put("key1".getBytes(), "value".getBytes());
      db.put("key2".getBytes(), "12345678".getBytes());
      List<byte[]> lookupKeys = new ArrayList<>();
      lookupKeys.add("key1".getBytes());
      lookupKeys.add("key2".getBytes());
      List<byte[]> results = db.multiGetAsList(lookupKeys);
      assertThat(results).isNotNull();
      assertThat(results).hasSize(lookupKeys.size());
      assertThat(results).
          containsExactly("value".getBytes(), "12345678".getBytes());
      // test same method with ReadOptions
      results = db.multiGetAsList(rOpt, lookupKeys);
      assertThat(results).isNotNull();
      assertThat(results).
          contains("value".getBytes(), "12345678".getBytes());

      // remove existing key
      lookupKeys.remove(1);
      // add non existing key
      lookupKeys.add("key3".getBytes());
      results = db.multiGetAsList(lookupKeys);
      assertThat(results).isNotNull();
      assertThat(results).
          containsExactly("value".getBytes(), null);
      // test same call with readOptions
      results = db.multiGetAsList(rOpt, lookupKeys);
      assertThat(results).isNotNull();
      assertThat(results).contains("value".getBytes());
    }
  }

  @Test
  public void merge() throws RocksDBException {
    try (final StringAppendOperator stringAppendOperator = new StringAppendOperator();
         final Options opt = new Options()
            .setCreateIfMissing(true)
            .setMergeOperator(stringAppendOperator);
         final WriteOptions wOpt = new WriteOptions();
         final RocksDB db = RocksDB.open(opt,
             dbFolder.getRoot().getAbsolutePath())
    ) {
      db.put("key1".getBytes(), "value".getBytes());
      assertThat(db.get("key1".getBytes())).isEqualTo(
          "value".getBytes());
      // merge key1 with another value portion
      db.merge("key1".getBytes(), "value2".getBytes());
      assertThat(db.get("key1".getBytes())).isEqualTo(
          "value,value2".getBytes());
      // merge key1 with another value portion
      db.merge(wOpt, "key1".getBytes(), "value3".getBytes());
      assertThat(db.get("key1".getBytes())).isEqualTo(
          "value,value2,value3".getBytes());
      // merge on non existent key shall insert the value
      db.merge(wOpt, "key2".getBytes(), "xxxx".getBytes());
      assertThat(db.get("key2".getBytes())).isEqualTo(
          "xxxx".getBytes());

      Segment key3 = sliceSegment("key3");
      Segment key4 = sliceSegment("key4");
      Segment value0 = sliceSegment("value 0");
      Segment value1 = sliceSegment("value 1");

      db.merge(key3.data, key3.offset, key3.len, value0.data, value0.offset, value0.len);
      db.merge(wOpt, key4.data, key4.offset, key4.len, value1.data, value1.offset, value1.len);

      // compare
      Assert.assertTrue(value0.isSamePayload(db.get(key3.data, key3.offset, key3.len)));
      Assert.assertTrue(value1.isSamePayload(db.get(key4.data, key4.offset, key4.len)));
    }
  }

  @Test
  public void delete() throws RocksDBException {
    try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
         final WriteOptions wOpt = new WriteOptions()) {
      db.put("key1".getBytes(), "value".getBytes());
      db.put("key2".getBytes(), "12345678".getBytes());
      db.put("key3".getBytes(), "33".getBytes());
      assertThat(db.get("key1".getBytes())).isEqualTo(
          "value".getBytes());
      assertThat(db.get("key2".getBytes())).isEqualTo(
          "12345678".getBytes());
      assertThat(db.get("key3".getBytes())).isEqualTo("33".getBytes());
      db.delete("key1".getBytes());
      db.delete(wOpt, "key2".getBytes());
      ByteBuffer key = ByteBuffer.allocateDirect(16);
      key.put("key3".getBytes()).flip();
      db.delete(wOpt, key);
      assertThat(key.position()).isEqualTo(4);
      assertThat(key.limit()).isEqualTo(4);

      assertThat(db.get("key1".getBytes())).isNull();
      assertThat(db.get("key2".getBytes())).isNull();

      Segment key3 = sliceSegment("key3");
      Segment key4 = sliceSegment("key4");
      db.put("key3".getBytes(), "key3 value".getBytes());
      db.put("key4".getBytes(), "key4 value".getBytes());

      db.delete(key3.data, key3.offset, key3.len);
      db.delete(wOpt, key4.data, key4.offset, key4.len);

      assertThat(db.get("key3".getBytes())).isNull();
      assertThat(db.get("key4".getBytes())).isNull();
    }
  }

  @Test
  public void singleDelete() throws RocksDBException {
    try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
         final WriteOptions wOpt = new WriteOptions()) {
      db.put("key1".getBytes(), "value".getBytes());
      db.put("key2".getBytes(), "12345678".getBytes());
      assertThat(db.get("key1".getBytes())).isEqualTo(
          "value".getBytes());
      assertThat(db.get("key2".getBytes())).isEqualTo(
          "12345678".getBytes());
      db.singleDelete("key1".getBytes());
      db.singleDelete(wOpt, "key2".getBytes());
      assertThat(db.get("key1".getBytes())).isNull();
      assertThat(db.get("key2".getBytes())).isNull();
    }
  }

  @Test
  public void singleDelete_nonExisting() throws RocksDBException {
    try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath());
         final WriteOptions wOpt = new WriteOptions()) {
      db.singleDelete("key1".getBytes());
      db.singleDelete(wOpt, "key2".getBytes());
      assertThat(db.get("key1".getBytes())).isNull();
      assertThat(db.get("key2".getBytes())).isNull();
    }
  }

  @Test
  public void deleteRange() throws RocksDBException {
    try (final RocksDB db = RocksDB.open(dbFolder.getRoot().getAbsolutePath())) {
      db.put("key1".getBytes(), "value".getBytes());
      db.put("key2".getBytes(), "12345678".getBytes());
      db.put("key3".getBytes(), "abcdefg".getBytes());
      db.put("key4".getBytes(), "xyz".getBytes());
      assertThat(db.get("key1".getBytes())).isEqualTo("value".getBytes());
      assertThat(db.get("key2".getBytes())).isEqualTo("12345678".getBytes());
      assertThat(db.get("key3".getBytes())).isEqualTo("abcdefg".getBytes());
      assertThat(db.get("key4".getBytes())).isEqualTo("xyz".getBytes());
      db.deleteRange("key2".getBytes(), "key4".getBytes());
      assertThat(db.get("key1".getBytes())).isEqualTo("value".getBytes());
      assertThat(db.get("key2".getBytes())).isNull();
      assertThat(db.get("key3".getBytes())).isNull();
      assertThat(db.get("key4".getBytes())).isEqualTo("xyz".getBytes());
    }
  }

  @Test
  public void getIntProperty() throws RocksDBException {
    try (
        final Options options = new Options()
            .setCreateIfMissing(true)
            .setMaxWriteBufferNumber(10)
            .setMinWriteBufferNumberToMerge(10);
        final RocksDB db = RocksDB.open(options,
            dbFolder.getRoot().getAbsolutePath());
        final WriteOptions wOpt = new WriteOptions().setDisableWAL(true)
    ) {
      db.put(wOpt, "key1".getBytes(), "value1".getBytes());
      db.put(wOpt, "key2".getBytes(), "value2".getBytes());
      db.put(wOpt, "key3".getBytes(), "value3".getBytes());
      db.put(wOpt, "key4".getBytes(), "value4".getBytes());
      assertThat(db.getLongProperty("rocksdb.num-entries-active-mem-table"))
          .isGreaterThan(0);
      assertThat(db.getLongProperty("rocksdb.cur-size-active-mem-table"))
          .isGreaterThan(0);
    }
  }

  @Test
  public void fullCompactRange() throws RocksDBException {
    try (final Options opt = new Options().
        setCreateIfMissing(true).
        setDisableAutoCompactions(true).
        setCompactionStyle(CompactionStyle.LEVEL).
        setNumLevels(4).
        setWriteBufferSize(100 << 10).
        setLevelZeroFileNumCompactionTrigger(3).
        setTargetFileSizeBase(200 << 10).
        setTargetFileSizeMultiplier(1).
        setMaxBytesForLevelBase(500 << 10).
        setMaxBytesForLevelMultiplier(1).
        setDisableAutoCompactions(false);
         final RocksDB db = RocksDB.open(opt,
             dbFolder.getRoot().getAbsolutePath())) {
      // fill database with key/value pairs
      byte[] b = new byte[10000];
      for (int i = 0; i < 200; i++) {
        rand.nextBytes(b);
        db.put((String.valueOf(i)).getBytes(), b);
      }
      db.compactRange();
    }
  }

  @Test
  public void fullCompactRangeColumnFamily()
      throws RocksDBException {
    try (
        final DBOptions opt = new DBOptions().
            setCreateIfMissing(true).
            setCreateMissingColumnFamilies(true);
        final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions().
            setDisableAutoCompactions(true).
            setCompactionStyle(CompactionStyle.LEVEL).
            setNumLevels(4).
            setWriteBufferSize(100 << 10).
            setLevelZeroFileNumCompactionTrigger(3).
            setTargetFileSizeBase(200 << 10).
            setTargetFileSizeMultiplier(1).
            setMaxBytesForLevelBase(500 << 10).
            setMaxBytesForLevelMultiplier(1).
            setDisableAutoCompactions(false)
    ) {
      final List<ColumnFamilyDescriptor> columnFamilyDescriptors =
          Arrays.asList(
              new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
              new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts));

      // open database
      final List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>();
      try (final RocksDB db = RocksDB.open(opt,
          dbFolder.getRoot().getAbsolutePath(),
          columnFamilyDescriptors,
          columnFamilyHandles)) {
        try {
          // fill database with key/value pairs
          byte[] b = new byte[10000];
          for (int i = 0; i < 200; i++) {
            rand.nextBytes(b);
            db.put(columnFamilyHandles.get(1),
                String.valueOf(i).getBytes(), b);
          }
          db.compactRange(columnFamilyHandles.get(1));
        } finally {
          for (final ColumnFamilyHandle handle : columnFamilyHandles) {
            handle.close();
          }
        }
      }
    }
  }

  @Test
  public void compactRangeWithKeys()
      throws RocksDBException {
    try (final Options opt = new Options().
        setCreateIfMissing(true).
        setDisableAutoCompactions(true).
        setCompactionStyle(CompactionStyle.LEVEL).
        setNumLevels(4).
        setWriteBufferSize(100 << 10).
        setLevelZeroFileNumCompactionTrigger(3).
        setTargetFileSizeBase(200 << 10).
        setTargetFileSizeMultiplier(1).
        setMaxBytesForLevelBase(500 << 10).
        setMaxBytesForLevelMultiplier(1).
        setDisableAutoCompactions(false);
         final RocksDB db = RocksDB.open(opt,
             dbFolder.getRoot().getAbsolutePath())) {
      // fill database with key/value pairs
      byte[] b = new byte[10000];
      for (int i = 0; i < 200; i++) {
        rand.nextBytes(b);
        db.put((String.valueOf(i)).getBytes(), b);
      }
      db.compactRange("0".getBytes(), "201".getBytes());
    }
  }

  @Test
  public void compactRangeWithKeysReduce()
      throws RocksDBException {
    try (
        final Options opt = new Options().
            setCreateIfMissing(true).
            setDisableAutoCompactions(true).
            setCompactionStyle(CompactionStyle.LEVEL).
            setNumLevels(4).
            setWriteBufferSize(100 << 10).
            setLevelZeroFileNumCompactionTrigger(3).
            setTargetFileSizeBase(200 << 10).
            setTargetFileSizeMultiplier(1).
            setMaxBytesForLevelBase(500 << 10).
            setMaxBytesForLevelMultiplier(1).
            setDisableAutoCompactions(false);
        final RocksDB db = RocksDB.open(opt,
            dbFolder.getRoot().getAbsolutePath())) {
      // fill database with key/value pairs
      byte[] b = new byte[10000];
      for (int i = 0; i < 200; i++) {
        rand.nextBytes(b);
        db.put((String.valueOf(i)).getBytes(), b);
      }
      db.flush(new FlushOptions().setWaitForFlush(true));
      try (final CompactRangeOptions compactRangeOpts = new CompactRangeOptions()
            .setChangeLevel(true)
            .setTargetLevel(-1)
            .setTargetPathId(0)) {
        db.compactRange(null, "0".getBytes(), "201".getBytes(),
            compactRangeOpts);
      }
    }
  }

  @Test
  public void compactRangeWithKeysColumnFamily()
      throws RocksDBException {
    try (final DBOptions opt = new DBOptions().
        setCreateIfMissing(true).
        setCreateMissingColumnFamilies(true);
         final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions().
             setDisableAutoCompactions(true).
             setCompactionStyle(CompactionStyle.LEVEL).
             setNumLevels(4).
             setWriteBufferSize(100 << 10).
             setLevelZeroFileNumCompactionTrigger(3).
             setTargetFileSizeBase(200 << 10).
             setTargetFileSizeMultiplier(1).
             setMaxBytesForLevelBase(500 << 10).
             setMaxBytesForLevelMultiplier(1).
             setDisableAutoCompactions(false)
    ) {
      final List<ColumnFamilyDescriptor> columnFamilyDescriptors =
          Arrays.asList(
              new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
              new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts)
          );

      // open database
      final List<ColumnFamilyHandle> columnFamilyHandles =
          new ArrayList<>();
      try (final RocksDB db = RocksDB.open(opt,
          dbFolder.getRoot().getAbsolutePath(),
          columnFamilyDescriptors,
          columnFamilyHandles)) {
        try {
          // fill database with key/value pairs
          byte[] b = new byte[10000];
          for (int i = 0; i < 200; i++) {
            rand.nextBytes(b);
            db.put(columnFamilyHandles.get(1),
                String.valueOf(i).getBytes(), b);
          }
          db.compactRange(columnFamilyHandles.get(1),
              "0".getBytes(), "201".getBytes());
        } finally {
          for (final ColumnFamilyHandle handle : columnFamilyHandles) {
            handle.close();
          }
        }
      }
    }
  }

  @Test
  public void compactRangeWithKeysReduceColumnFamily()
      throws RocksDBException {
    try (final DBOptions opt = new DBOptions().
        setCreateIfMissing(true).
        setCreateMissingColumnFamilies(true);
         final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions().
             setDisableAutoCompactions(true).
             setCompactionStyle(CompactionStyle.LEVEL).
             setNumLevels(4).
             setWriteBufferSize(100 << 10).
             setLevelZeroFileNumCompactionTrigger(3).
             setTargetFileSizeBase(200 << 10).
             setTargetFileSizeMultiplier(1).
             setMaxBytesForLevelBase(500 << 10).
             setMaxBytesForLevelMultiplier(1).
             setDisableAutoCompactions(false)
    ) {
      final List<ColumnFamilyDescriptor> columnFamilyDescriptors =
          Arrays.asList(
              new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
              new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts)
          );

      final List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>();
      // open database
      try (final RocksDB db = RocksDB.open(opt,
          dbFolder.getRoot().getAbsolutePath(),
          columnFamilyDescriptors,
          columnFamilyHandles)) {
        try (final CompactRangeOptions compactRangeOpts = new CompactRangeOptions()
            .setChangeLevel(true)
            .setTargetLevel(-1)
            .setTargetPathId(0)) {
          // fill database with key/value pairs
          byte[] b = new byte[10000];
          for (int i = 0; i < 200; i++) {
            rand.nextBytes(b);
            db.put(columnFamilyHandles.get(1),
                String.valueOf(i).getBytes(), b);
          }
          db.compactRange(columnFamilyHandles.get(1), "0".getBytes(),
              "201".getBytes(), compactRangeOpts);
        } finally {
          for (final ColumnFamilyHandle handle : columnFamilyHandles) {
            handle.close();
          }
        }
      }
    }
  }

  @Test
  public void compactRangeToLevel()
      throws RocksDBException, InterruptedException {
    final int NUM_KEYS_PER_L0_FILE = 100;
    final int KEY_SIZE = 20;
    final int VALUE_SIZE = 300;
    final int L0_FILE_SIZE =
        NUM_KEYS_PER_L0_FILE * (KEY_SIZE + VALUE_SIZE);
    final int NUM_L0_FILES = 10;
    final int TEST_SCALE = 5;
    final int KEY_INTERVAL = 100;
    try (final Options opt = new Options().
        setCreateIfMissing(true).
        setCompactionStyle(CompactionStyle.LEVEL).
        setNumLevels(5).
        // a slightly bigger write buffer than L0 file
        // so that we can ensure manual flush always
        // go before background flush happens.
            setWriteBufferSize(L0_FILE_SIZE * 2).
        // Disable auto L0 -> L1 compaction
            setLevelZeroFileNumCompactionTrigger(20).
            setTargetFileSizeBase(L0_FILE_SIZE * 100).
            setTargetFileSizeMultiplier(1).
        // To disable auto compaction
            setMaxBytesForLevelBase(NUM_L0_FILES * L0_FILE_SIZE * 100).
            setMaxBytesForLevelMultiplier(2).
            setDisableAutoCompactions(true);
         final RocksDB db = RocksDB.open(opt,
             dbFolder.getRoot().getAbsolutePath())
    ) {
      // fill database with key/value pairs
      byte[] value = new byte[VALUE_SIZE];
      int int_key = 0;
      for (int round = 0; round < 5; ++round) {
        int initial_key = int_key;
        for (int f = 1; f <= NUM_L0_FILES; ++f) {
          for (int i = 0; i < NUM_KEYS_PER_L0_FILE; ++i) {
            int_key += KEY_INTERVAL;
            rand.nextBytes(value);

            db.put(String.format("%020d", int_key).getBytes(),
                value);
          }
          db.flush(new FlushOptions().setWaitForFlush(true));
          // Make sure we do create one more L0 files.
          assertThat(
              db.getProperty("rocksdb.num-files-at-level0")).
              isEqualTo("" + f);
        }

        // Compact all L0 files we just created
        db.compactRange(
            String.format("%020d", initial_key).getBytes(),
            String.format("%020d", int_key - 1).getBytes());
        // Making sure there isn't any L0 files.
        assertThat(
            db.getProperty("rocksdb.num-files-at-level0")).
            isEqualTo("0");
        // Making sure there are some L1 files.
        // Here we only use != 0 instead of a specific number
        // as we don't want the test make any assumption on
        // how compaction works.
        assertThat(
            db.getProperty("rocksdb.num-files-at-level1")).
            isNotEqualTo("0");
        // Because we only compacted those keys we issued
        // in this round, there shouldn't be any L1 -> L2
        // compaction.  So we expect zero L2 files here.
        assertThat(
            db.getProperty("rocksdb.num-files-at-level2")).
            isEqualTo("0");
      }
    }
  }

  @Test
  public void deleteFilesInRange() throws RocksDBException, InterruptedException {
    final int KEY_SIZE = 20;
    final int VALUE_SIZE = 1000;
    final int FILE_SIZE = 64000;
    final int NUM_FILES = 10;

    final int KEY_INTERVAL = 10000;
    /*
     * Intention of these options is to end up reliably with 10 files
     * we will be deleting using deleteFilesInRange.
     * It is writing roughly number of keys that will fit in 10 files (target size)
     * It is writing interleaved so that files from memory on L0 will overlap
     * Then compaction cleans everything and we should end up with 10 files
     */
    try (final Options opt = new Options()
                                 .setCreateIfMissing(true)
                                 .setCompressionType(CompressionType.NO_COMPRESSION)
                                 .setTargetFileSizeBase(FILE_SIZE)
                                 .setWriteBufferSize(FILE_SIZE / 2)
                                 .setDisableAutoCompactions(true);
         final RocksDB db = RocksDB.open(opt, dbFolder.getRoot().getAbsolutePath())) {
      int records = FILE_SIZE / (KEY_SIZE + VALUE_SIZE);

      // fill database with key/value pairs
      byte[] value = new byte[VALUE_SIZE];
      int key_init = 0;
      for (int o = 0; o < NUM_FILES; ++o) {
        int int_key = key_init++;
        for (int i = 0; i < records; ++i) {
          int_key += KEY_INTERVAL;
          rand.nextBytes(value);

          db.put(String.format("%020d", int_key).getBytes(), value);
        }
      }
      db.flush(new FlushOptions().setWaitForFlush(true));
      db.compactRange();
      // Make sure we do create one more L0 files.
      assertThat(db.getProperty("rocksdb.num-files-at-level0")).isEqualTo("0");

      // Should be 10, but we are OK with asserting +- 2
      int files = Integer.parseInt(db.getProperty("rocksdb.num-files-at-level1"));
      assertThat(files).isBetween(8, 12);

      // Delete lower 60% (roughly). Result should be 5, but we are OK with asserting +- 2
      // Important is that we know something was deleted (JNI call did something)
      // Exact assertions are done in C++ unit tests
      db.deleteFilesInRanges(null,
          Arrays.asList(null, String.format("%020d", records * KEY_INTERVAL * 6 / 10).getBytes()),
          false);
      files = Integer.parseInt(db.getProperty("rocksdb.num-files-at-level1"));
      assertThat(files).isBetween(3, 7);
    }
  }

  @Test
  public void compactRangeToLevelColumnFamily()
      throws RocksDBException {
    final int NUM_KEYS_PER_L0_FILE = 100;
    final int KEY_SIZE = 20;
    final int VALUE_SIZE = 300;
    final int L0_FILE_SIZE =
        NUM_KEYS_PER_L0_FILE * (KEY_SIZE + VALUE_SIZE);
    final int NUM_L0_FILES = 10;
    final int TEST_SCALE = 5;
    final int KEY_INTERVAL = 100;

    try (final DBOptions opt = new DBOptions().
        setCreateIfMissing(true).
        setCreateMissingColumnFamilies(true);
         final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions().
             setCompactionStyle(CompactionStyle.LEVEL).
             setNumLevels(5).
             // a slightly bigger write buffer than L0 file
             // so that we can ensure manual flush always
             // go before background flush happens.
                 setWriteBufferSize(L0_FILE_SIZE * 2).
             // Disable auto L0 -> L1 compaction
                 setLevelZeroFileNumCompactionTrigger(20).
                 setTargetFileSizeBase(L0_FILE_SIZE * 100).
                 setTargetFileSizeMultiplier(1).
             // To disable auto compaction
                 setMaxBytesForLevelBase(NUM_L0_FILES * L0_FILE_SIZE * 100).
                 setMaxBytesForLevelMultiplier(2).
                 setDisableAutoCompactions(true)
    ) {
      final List<ColumnFamilyDescriptor> columnFamilyDescriptors =
          Arrays.asList(
              new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
              new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts)
          );

      final List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>();
      // open database
      try (final RocksDB db = RocksDB.open(opt,
          dbFolder.getRoot().getAbsolutePath(),
          columnFamilyDescriptors,
          columnFamilyHandles)) {
        try {
          // fill database with key/value pairs
          byte[] value = new byte[VALUE_SIZE];
          int int_key = 0;
          for (int round = 0; round < 5; ++round) {
            int initial_key = int_key;
            for (int f = 1; f <= NUM_L0_FILES; ++f) {
              for (int i = 0; i < NUM_KEYS_PER_L0_FILE; ++i) {
                int_key += KEY_INTERVAL;
                rand.nextBytes(value);

                db.put(columnFamilyHandles.get(1),
                    String.format("%020d", int_key).getBytes(),
                    value);
              }
              db.flush(new FlushOptions().setWaitForFlush(true),
                  columnFamilyHandles.get(1));
              // Make sure we do create one more L0 files.
              assertThat(
                  db.getProperty(columnFamilyHandles.get(1),
                      "rocksdb.num-files-at-level0")).
                  isEqualTo("" + f);
            }

            // Compact all L0 files we just created
            db.compactRange(
                columnFamilyHandles.get(1),
                String.format("%020d", initial_key).getBytes(),
                String.format("%020d", int_key - 1).getBytes());
            // Making sure there isn't any L0 files.
            assertThat(
                db.getProperty(columnFamilyHandles.get(1),
                    "rocksdb.num-files-at-level0")).
                isEqualTo("0");
            // Making sure there are some L1 files.
            // Here we only use != 0 instead of a specific number
            // as we don't want the test make any assumption on
            // how compaction works.
            assertThat(
                db.getProperty(columnFamilyHandles.get(1),
                    "rocksdb.num-files-at-level1")).
                isNotEqualTo("0");
            // Because we only compacted those keys we issued
            // in this round, there shouldn't be any L1 -> L2
            // compaction.  So we expect zero L2 files here.
            assertThat(
                db.getProperty(columnFamilyHandles.get(1),
                    "rocksdb.num-files-at-level2")).
                isEqualTo("0");
          }
        } finally {
          for (final ColumnFamilyHandle handle : columnFamilyHandles) {
            handle.close();
          }
        }
      }
    }
  }

  @Test
  public void pauseContinueBackgroundWork() throws RocksDBException {
    try (final Options options = new Options().setCreateIfMissing(true);
         final RocksDB db = RocksDB.open(options,
             dbFolder.getRoot().getAbsolutePath())
    ) {
      db.pauseBackgroundWork();
      db.continueBackgroundWork();
      db.pauseBackgroundWork();
      db.continueBackgroundWork();
    }
  }

  @Test
  public void enableDisableFileDeletions() throws RocksDBException {
    try (final Options options = new Options().setCreateIfMissing(true);
         final RocksDB db = RocksDB.open(options,
             dbFolder.getRoot().getAbsolutePath())
    ) {
      db.disableFileDeletions();
      db.enableFileDeletions(false);
      db.disableFileDeletions();
      db.enableFileDeletions(true);
    }
  }

  @Test
  public void setOptions() throws RocksDBException {
    try (final DBOptions options = new DBOptions()
             .setCreateIfMissing(true)
             .setCreateMissingColumnFamilies(true);
         final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions()
             .setWriteBufferSize(4096)) {

      final List<ColumnFamilyDescriptor> columnFamilyDescriptors =
          Arrays.asList(
              new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
              new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts));

      // open database
      final List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>();
      try (final RocksDB db = RocksDB.open(options,
          dbFolder.getRoot().getAbsolutePath(), columnFamilyDescriptors, columnFamilyHandles)) {
        try {
          final MutableColumnFamilyOptions mutableOptions =
              MutableColumnFamilyOptions.builder()
                  .setWriteBufferSize(2048)
                  .build();

          db.setOptions(columnFamilyHandles.get(1), mutableOptions);

        } finally {
          for (final ColumnFamilyHandle handle : columnFamilyHandles) {
            handle.close();
          }
        }
      }
    }
  }

  @Test
  public void destroyDB() throws RocksDBException {
    try (final Options options = new Options().setCreateIfMissing(true)) {
      String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath)) {
        db.put("key1".getBytes(), "value".getBytes());
      }
      assertThat(dbFolder.getRoot().exists() && dbFolder.getRoot().listFiles().length != 0)
          .isTrue();
      RocksDB.destroyDB(dbPath, options);
      assertThat(dbFolder.getRoot().exists() && dbFolder.getRoot().listFiles().length != 0)
          .isFalse();
    }
  }

  @Test(expected = RocksDBException.class)
  public void destroyDBFailIfOpen() throws RocksDBException {
    try (final Options options = new Options().setCreateIfMissing(true)) {
      String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath)) {
        // Fails as the db is open and locked.
        RocksDB.destroyDB(dbPath, options);
      }
    }
  }

  @Ignore("This test crashes. Re-enable after fixing.")
  @Test
  public void getApproximateSizes() throws RocksDBException {
    final byte key1[] = "key1".getBytes(UTF_8);
    final byte key2[] = "key2".getBytes(UTF_8);
    final byte key3[] = "key3".getBytes(UTF_8);
    try (final Options options = new Options().setCreateIfMissing(true)) {
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath)) {
        db.put(key1, key1);
        db.put(key2, key2);
        db.put(key3, key3);

        final long[] sizes = db.getApproximateSizes(
            Arrays.asList(
                new Range(new Slice(key1), new Slice(key2)),
                new Range(new Slice(key2), new Slice(key3))
            ),
            SizeApproximationFlag.INCLUDE_FILES,
            SizeApproximationFlag.INCLUDE_MEMTABLES);

        assertThat(sizes.length).isEqualTo(2);
        assertThat(sizes[0]).isEqualTo(0);
        assertThat(sizes[1]).isGreaterThanOrEqualTo(1);
      }
    }
  }

  @Test
  public void getApproximateMemTableStats() throws RocksDBException {
    final byte key1[] = "key1".getBytes(UTF_8);
    final byte key2[] = "key2".getBytes(UTF_8);
    final byte key3[] = "key3".getBytes(UTF_8);
    try (final Options options = new Options().setCreateIfMissing(true)) {
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath)) {
        db.put(key1, key1);
        db.put(key2, key2);
        db.put(key3, key3);

        final RocksDB.CountAndSize stats =
            db.getApproximateMemTableStats(
                new Range(new Slice(key1), new Slice(key3)));

        assertThat(stats).isNotNull();
        assertThat(stats.count).isGreaterThan(1);
        assertThat(stats.size).isGreaterThan(1);
      }
    }
  }

  @Ignore("TODO(AR) re-enable when ready!")
  @Test
  public void compactFiles() throws RocksDBException {
    final int kTestKeySize = 16;
    final int kTestValueSize = 984;
    final int kEntrySize = kTestKeySize + kTestValueSize;
    final int kEntriesPerBuffer = 100;
    final int writeBufferSize = kEntrySize * kEntriesPerBuffer;
    final byte[] cfName = "pikachu".getBytes(UTF_8);

    try (final Options options = new Options()
        .setCreateIfMissing(true)
        .setWriteBufferSize(writeBufferSize)
        .setCompactionStyle(CompactionStyle.LEVEL)
        .setTargetFileSizeBase(writeBufferSize)
        .setMaxBytesForLevelBase(writeBufferSize * 2)
        .setLevel0StopWritesTrigger(2)
        .setMaxBytesForLevelMultiplier(2)
        .setCompressionType(CompressionType.NO_COMPRESSION)
        .setMaxSubcompactions(4)) {
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath);
           final ColumnFamilyOptions cfOptions = new ColumnFamilyOptions(options)) {
        db.createColumnFamily(new ColumnFamilyDescriptor(cfName,
            cfOptions)).close();
      }

      try (final ColumnFamilyOptions cfOptions = new ColumnFamilyOptions(options)) {
        final List<ColumnFamilyDescriptor> cfDescriptors = Arrays.asList(
            new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY, cfOptions),
            new ColumnFamilyDescriptor(cfName, cfOptions)
        );
        final List<ColumnFamilyHandle> cfHandles = new ArrayList<>();
        try (final DBOptions dbOptions = new DBOptions(options);
            final RocksDB db = RocksDB.open(dbOptions, dbPath, cfDescriptors,
                cfHandles);
        ) {
          try (final FlushOptions flushOptions = new FlushOptions()
                .setWaitForFlush(true)
                .setAllowWriteStall(true);
               final CompactionOptions compactionOptions = new CompactionOptions()) {
            final Random rnd = new Random(301);
            for (int key = 64 * kEntriesPerBuffer; key >= 0; --key) {
              final byte[] value = new byte[kTestValueSize];
              rnd.nextBytes(value);
              db.put(cfHandles.get(1), Integer.toString(key).getBytes(UTF_8),
                  value);
            }
            db.flush(flushOptions, cfHandles);

            final RocksDB.LiveFiles liveFiles = db.getLiveFiles();
            final List<String> compactedFiles =
                db.compactFiles(compactionOptions, cfHandles.get(1),
                    liveFiles.files, 1, -1, null);
            assertThat(compactedFiles).isNotEmpty();
          } finally {
            for (final ColumnFamilyHandle cfHandle : cfHandles) {
              cfHandle.close();
            }
          }
        }
      }
    }
  }

  @Test
  public void enableAutoCompaction() throws RocksDBException {
    try (final DBOptions options = new DBOptions()
        .setCreateIfMissing(true)) {
      final List<ColumnFamilyDescriptor> cfDescs = Arrays.asList(
          new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY)
      );
      final List<ColumnFamilyHandle> cfHandles = new ArrayList<>();
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath, cfDescs, cfHandles)) {
        try {
          db.enableAutoCompaction(cfHandles);
        } finally {
          for (final ColumnFamilyHandle cfHandle : cfHandles) {
            cfHandle.close();
          }
        }
      }
    }
  }

  @Test
  public void numberLevels() throws RocksDBException {
    try (final Options options = new Options().setCreateIfMissing(true)) {
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath)) {
        assertThat(db.numberLevels()).isEqualTo(7);
      }
    }
  }

  @Test
  public void maxMemCompactionLevel() throws RocksDBException {
    try (final Options options = new Options().setCreateIfMissing(true)) {
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath)) {
        assertThat(db.maxMemCompactionLevel()).isEqualTo(0);
      }
    }
  }

  @Test
  public void level0StopWriteTrigger() throws RocksDBException {
    try (final Options options = new Options().setCreateIfMissing(true)) {
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath)) {
        assertThat(db.level0StopWriteTrigger()).isEqualTo(36);
      }
    }
  }

  @Test
  public void getName() throws RocksDBException {
    try (final Options options = new Options().setCreateIfMissing(true)) {
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath)) {
        assertThat(db.getName()).isEqualTo(dbPath);
      }
    }
  }

  @Test
  public void getEnv() throws RocksDBException {
    try (final Options options = new Options().setCreateIfMissing(true)) {
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath)) {
        assertThat(db.getEnv()).isEqualTo(Env.getDefault());
      }
    }
  }

  @Test
  public void flush() throws RocksDBException {
    try (final Options options = new Options().setCreateIfMissing(true)) {
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath);
        final FlushOptions flushOptions = new FlushOptions()) {
        db.flush(flushOptions);
      }
    }
  }

  @Test
  public void flushWal() throws RocksDBException {
    try (final Options options = new Options().setCreateIfMissing(true)) {
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath)) {
        db.flushWal(true);
      }
    }
  }

  @Test
  public void syncWal() throws RocksDBException {
    try (final Options options = new Options().setCreateIfMissing(true)) {
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath)) {
        db.syncWal();
      }
    }
  }

  @Test
  public void setPreserveDeletesSequenceNumber() throws RocksDBException {
    try (final Options options = new Options().setCreateIfMissing(true)) {
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath)) {
        assertThat(db.setPreserveDeletesSequenceNumber(db.getLatestSequenceNumber()))
            .isFalse();
      }
    }
  }

  @Test
  public void getLiveFiles() throws RocksDBException {
    try (final Options options = new Options().setCreateIfMissing(true)) {
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath)) {
        final RocksDB.LiveFiles livefiles = db.getLiveFiles(true);
        assertThat(livefiles).isNotNull();
        assertThat(livefiles.manifestFileSize).isEqualTo(13);
        assertThat(livefiles.files.size()).isEqualTo(3);
        assertThat(livefiles.files.get(0)).isEqualTo("/CURRENT");
        assertThat(livefiles.files.get(1)).isEqualTo("/MANIFEST-000001");
        assertThat(livefiles.files.get(2)).isEqualTo("/OPTIONS-000005");
      }
    }
  }

  @Test
  public void getSortedWalFiles() throws RocksDBException {
    try (final Options options = new Options().setCreateIfMissing(true)) {
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath)) {
        db.put("key1".getBytes(UTF_8), "value1".getBytes(UTF_8));
        final List<LogFile> logFiles = db.getSortedWalFiles();
        assertThat(logFiles).isNotNull();
        assertThat(logFiles.size()).isEqualTo(1);
        assertThat(logFiles.get(0).type())
            .isEqualTo(WalFileType.kAliveLogFile);
      }
    }
  }

  @Test
  public void deleteFile() throws RocksDBException {
    try (final Options options = new Options().setCreateIfMissing(true)) {
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath)) {
        db.deleteFile("unknown");
      }
    }
  }

  @Test
  public void getLiveFilesMetaData() throws RocksDBException {
    try (final Options options = new Options().setCreateIfMissing(true)) {
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath)) {
        db.put("key1".getBytes(UTF_8), "value1".getBytes(UTF_8));
        final List<LiveFileMetaData> liveFilesMetaData
            = db.getLiveFilesMetaData();
        assertThat(liveFilesMetaData).isEmpty();
      }
    }
  }

  @Test
  public void getColumnFamilyMetaData() throws RocksDBException {
    try (final DBOptions options = new DBOptions()
        .setCreateIfMissing(true)) {
      final List<ColumnFamilyDescriptor> cfDescs = Arrays.asList(
          new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY)
      );
      final List<ColumnFamilyHandle> cfHandles = new ArrayList<>();
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath, cfDescs, cfHandles)) {
        db.put(cfHandles.get(0), "key1".getBytes(UTF_8), "value1".getBytes(UTF_8));
        try {
          final ColumnFamilyMetaData cfMetadata =
              db.getColumnFamilyMetaData(cfHandles.get(0));
          assertThat(cfMetadata).isNotNull();
          assertThat(cfMetadata.name()).isEqualTo(RocksDB.DEFAULT_COLUMN_FAMILY);
          assertThat(cfMetadata.levels().size()).isEqualTo(7);
        } finally {
          for (final ColumnFamilyHandle cfHandle : cfHandles) {
            cfHandle.close();
          }
        }
      }
    }
  }

  @Test
  public void verifyChecksum() throws RocksDBException {
    try (final Options options = new Options().setCreateIfMissing(true)) {
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath)) {
        db.verifyChecksum();
      }
    }
  }

  @Test
  public void getPropertiesOfAllTables() throws RocksDBException {
    try (final DBOptions options = new DBOptions()
        .setCreateIfMissing(true)) {
      final List<ColumnFamilyDescriptor> cfDescs = Arrays.asList(
          new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY)
      );
      final List<ColumnFamilyHandle> cfHandles = new ArrayList<>();
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath, cfDescs, cfHandles)) {
        db.put(cfHandles.get(0), "key1".getBytes(UTF_8), "value1".getBytes(UTF_8));
        try {
          final Map<String, TableProperties> properties =
              db.getPropertiesOfAllTables(cfHandles.get(0));
          assertThat(properties).isNotNull();
        } finally {
          for (final ColumnFamilyHandle cfHandle : cfHandles) {
            cfHandle.close();
          }
        }
      }
    }
  }

  @Test
  public void getPropertiesOfTablesInRange() throws RocksDBException {
    try (final DBOptions options = new DBOptions()
        .setCreateIfMissing(true)) {
      final List<ColumnFamilyDescriptor> cfDescs = Arrays.asList(
          new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY)
      );
      final List<ColumnFamilyHandle> cfHandles = new ArrayList<>();
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath, cfDescs, cfHandles)) {
        db.put(cfHandles.get(0), "key1".getBytes(UTF_8), "value1".getBytes(UTF_8));
        db.put(cfHandles.get(0), "key2".getBytes(UTF_8), "value2".getBytes(UTF_8));
        db.put(cfHandles.get(0), "key3".getBytes(UTF_8), "value3".getBytes(UTF_8));
        try {
          final Range range = new Range(
              new Slice("key1".getBytes(UTF_8)),
              new Slice("key3".getBytes(UTF_8)));
          final Map<String, TableProperties> properties =
              db.getPropertiesOfTablesInRange(
                  cfHandles.get(0), Arrays.asList(range));
          assertThat(properties).isNotNull();
        } finally {
          for (final ColumnFamilyHandle cfHandle : cfHandles) {
            cfHandle.close();
          }
        }
      }
    }
  }

  @Test
  public void suggestCompactRange() throws RocksDBException {
    try (final DBOptions options = new DBOptions()
        .setCreateIfMissing(true)) {
      final List<ColumnFamilyDescriptor> cfDescs = Arrays.asList(
          new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY)
      );
      final List<ColumnFamilyHandle> cfHandles = new ArrayList<>();
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath, cfDescs, cfHandles)) {
        db.put(cfHandles.get(0), "key1".getBytes(UTF_8), "value1".getBytes(UTF_8));
        db.put(cfHandles.get(0), "key2".getBytes(UTF_8), "value2".getBytes(UTF_8));
        db.put(cfHandles.get(0), "key3".getBytes(UTF_8), "value3".getBytes(UTF_8));
        try {
          final Range range =  db.suggestCompactRange(cfHandles.get(0));
          assertThat(range).isNotNull();
        } finally {
          for (final ColumnFamilyHandle cfHandle : cfHandles) {
            cfHandle.close();
          }
        }
      }
    }
  }

  @Test
  public void promoteL0() throws RocksDBException {
    try (final Options options = new Options().setCreateIfMissing(true)) {
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath)) {
        db.promoteL0(2);
      }
    }
  }

  @Test
  public void startTrace() throws RocksDBException {
    try (final Options options = new Options().setCreateIfMissing(true)) {
      final String dbPath = dbFolder.getRoot().getAbsolutePath();
      try (final RocksDB db = RocksDB.open(options, dbPath)) {
        final TraceOptions traceOptions = new TraceOptions();

        try (final InMemoryTraceWriter traceWriter = new InMemoryTraceWriter()) {
          db.startTrace(traceOptions, traceWriter);

          db.put("key1".getBytes(UTF_8), "value1".getBytes(UTF_8));

          db.endTrace();

          final List<byte[]> writes = traceWriter.getWrites();
          assertThat(writes.size()).isGreaterThan(0);
        }
      }
    }
  }

  @Test
  public void setDBOptions() throws RocksDBException {
    try (final DBOptions options = new DBOptions()
        .setCreateIfMissing(true)
        .setCreateMissingColumnFamilies(true);
         final ColumnFamilyOptions new_cf_opts = new ColumnFamilyOptions()
             .setWriteBufferSize(4096)) {

      final List<ColumnFamilyDescriptor> columnFamilyDescriptors =
          Arrays.asList(
              new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
              new ColumnFamilyDescriptor("new_cf".getBytes(), new_cf_opts));

      // open database
      final List<ColumnFamilyHandle> columnFamilyHandles = new ArrayList<>();
      try (final RocksDB db = RocksDB.open(options,
          dbFolder.getRoot().getAbsolutePath(), columnFamilyDescriptors, columnFamilyHandles)) {
        try {
          final MutableDBOptions mutableOptions =
              MutableDBOptions.builder()
                  .setBytesPerSync(1024 * 1027 * 7)
                  .setAvoidFlushDuringShutdown(false)
                  .build();

          db.setDBOptions(mutableOptions);
        } finally {
          for (final ColumnFamilyHandle handle : columnFamilyHandles) {
            handle.close();
          }
        }
      }
    }
  }

  private static class InMemoryTraceWriter extends AbstractTraceWriter {
    private final List<byte[]> writes = new ArrayList<>();
    private volatile boolean closed = false;

    @Override
    public void write(final Slice slice) {
      if (closed) {
        return;
      }
      final byte[] data = slice.data();
      final byte[] dataCopy = new byte[data.length];
      System.arraycopy(data, 0, dataCopy, 0, data.length);
      writes.add(dataCopy);
    }

    @Override
    public void closeWriter() {
      closed = true;
    }

    @Override
    public long getFileSize() {
      long size = 0;
      for (int i = 0; i < writes.size(); i++) {
        size += writes.get(i).length;
      }
      return size;
    }

    public List<byte[]> getWrites() {
      return writes;
    }
  }
}


text:
ACCEPTED

#### According to
Index Fungorum

#### Published in
Sydowia 7(1-4): 228 (1953)

#### Original name
Inocybe cerasphora Singer

### Remarks
null

redpajama_set_name: RedPajamaGithub


text:
package org.apache.pinot.core.segment.creator.impl.stats;

import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
import java.util.Arrays;
import java.util.Set;
import org.apache.pinot.core.segment.creator.StatsCollectorConfig;
import org.apache.pinot.spi.utils.ByteArray;

/**
 * Extension of {@link AbstractColumnStatisticsCollector} for byte[] column type.
 */
public class BytesColumnPredIndexStatsCollector extends AbstractColumnStatisticsCollector {
  private final Set<ByteArray> _values = new ObjectOpenHashSet<>(INITIAL_HASH_SET_SIZE);

  private int _minLength = Integer.MAX_VALUE;
  private int _maxLength = 0;
  private ByteArray[] _sortedValues;
  private boolean _sealed = false;

  public BytesColumnPredIndexStatsCollector(String column, StatsCollectorConfig statsCollectorConfig) {
    super(column, statsCollectorConfig);
  }

  @Override
  public void collect(Object entry) {
    ByteArray value = new ByteArray((byte[]) entry);
    addressSorted(value);
    updatePartition(value);
    _values.add(value);

    int length = value.length();
    _minLength = Math.min(_minLength, length);
    _maxLength = Math.max(_maxLength, length);

    totalNumberOfEntries++;
  }

  @Override
  public ByteArray getMinValue() {
    if (_sealed) {
      return _sortedValues[0];
    }
    throw new IllegalStateException("you must seal the collector first before asking for min value");
  }

  @Override
  public ByteArray getMaxValue() {
    if (_sealed) {
      return _sortedValues[_sortedValues.length - 1];
    }
    throw new IllegalStateException("you must seal the collector first before asking for max value");
  }

  @Override
  public ByteArray[] getUniqueValuesSet() {
    if (_sealed) {
      return _sortedValues;
    }
    throw new IllegalStateException("you must seal the collector first before asking for unique values set");
  }

  @Override
  public int getLengthOfShortestElement() {
    return _minLength;
  }

  @Override
  public int getLengthOfLargestElement() {
    if (_sealed) {
      return _maxLength;
    }
    throw new IllegalStateException("you must seal the collector first before asking for longest value");
  }

  @Override
  public int getCardinality() {
    if (_sealed) {
      return _sortedValues.length;
    }
    throw new IllegalStateException("you must seal the collector first before asking for cardinality");
  }

  @Override
  public boolean hasNull() {
    return false;
  }

  @Override
  public void seal() {
    _sortedValues = _values.toArray(new ByteArray[_values.size()]);
    Arrays.sort(_sortedValues);
    _sealed = true;
  }
}


text:
# jsonParser.py
#
# Copyright (c) 2006, Paul McGuire
#

test1 = """
{
        "glossary": {
            "title": "example glossary",
                "GlossDiv": {
                        "title": "S",
                        "GlossList": [{
                "ID": "SGML",
                "SortAs": "SGML",
                "GlossTerm": "Standard Generalized Markup Language",
                "Acronym": "SGML",
                "LargestPrimeLessThan100": 97,
                "AvogadroNumber": 6.02E23,
                "EvenPrimesGreaterThan2": null,
                "PrimesLessThan10" : [2,3,5,7],
                "WMDsFound" : false,
                "IraqAlQaedaConnections" : null,
                "Abbrev": "ISO 8879:1986",
                "GlossDef":
"A meta-markup language, used to create markup languages such as DocBook.",
                "GlossSeeAlso": ["GML", "XML", "markup"],
                "EmptyDict" : {},
                "EmptyList" : []
            }]
        }
    }
}
"""

test2 = """
{"menu": {
  "id": "file",
  "value": "File:",
  "popup": {
    "menuitem": [
      {"value": "New", "onclick": "CreateNewDoc()"},
      {"value": "Open", "onclick": "OpenDoc()"},
      {"value": "Close", "onclick": "CloseDoc()"}
    ]
  }
}}
"""
test3 = """
{"widget": {
    "debug": "on",
    "window": {
        "title": "Sample Konfabulator Widget",        "name": "main_window",        "width": 500,        "height": 500
    },    "image": {
        "src": "Images/Sun.png",
        "name": "sun1",        "hOffset": 250,        "vOffset": 250,        "alignment": "center"
    },    "text": {
        "data": "Click Here",
        "size": 36,
        "style": "bold",        "name": "text1",        "hOffset": 250,        "vOffset": 100,        "alignment": "center",
        "onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
    }
}}
"""
test4 = """
{"web-app": {
  "servlet": [    // Defines the CDSServlet
    {
      "servlet-name": "cofaxCDS",
      "servlet-class": "org.cofax.cds.CDSServlet",
/*
    Defines glossary variables that template designers
    can use across the site.  You can add new
    variables to this set by creating a new init-param, with
    the param-name prefixed with "configGlossary:".
*/
      "init-param": {
        "configGlossary:installationAt": "Philadelphia, PA",
        "configGlossary:adminEmail": "ksm@pobox.com",
        "configGlossary:poweredBy": "Cofax",
        "configGlossary:poweredByIcon": "/images/cofax.gif",
        "configGlossary:staticPath": "/content/static",
/*
    Defines the template loader and template processor
    classes.  These are implementations of org.cofax.TemplateProcessor
    and org.cofax.TemplateLoader respectively.  Simply create new
    implementation of these classes and set them here if the default
    implementations do not suit your needs.  Leave these alone
    for the defaults.
*/
        "templateProcessorClass": "org.cofax.WysiwygTemplate",
        "templateLoaderClass": "org.cofax.FilesTemplateLoader",
        "templatePath": "templates",
        "templateOverridePath": "",
/*
    Defines the names of the default templates to look for
    when acquiring WYSIWYG templates.  Leave these at their
    defaults for most usage.
*/
        "defaultListTemplate": "listTemplate.htm",
        "defaultFileTemplate": "articleTemplate.htm",
/*
    New! useJSP switches on JSP template processing.
    jspListTemplate and jspFileTemplate are the names
    of the default templates to look for when aquiring JSP
    templates.  Cofax currently in production at KR has useJSP
    set to false, since our sites currently use WYSIWYG
    templating exclusively.
*/
        "useJSP": false,
        "jspListTemplate": "listTemplate.jsp",
        "jspFileTemplate": "articleTemplate.jsp",
/*
    Defines the packageTag cache.  This cache keeps
    Cofax from needing to interact with the database
    to look up packageTag commands.
*/
        "cachePackageTagsTrack": 200,
        "cachePackageTagsStore": 200,
        "cachePackageTagsRefresh": 60,
/*
    Defines the template cache.  Keeps Cofax from needing
    to go to the file system to load a raw template from
    the file system.
*/
        "cacheTemplatesTrack": 100,
        "cacheTemplatesStore": 50,
        "cacheTemplatesRefresh": 15,
/*
    Defines the page cache.  Keeps Cofax from processing
    templates to deliver to users.
*/
        "cachePagesTrack": 200,
        "cachePagesStore": 100,
        "cachePagesRefresh": 10,
        "cachePagesDirtyRead": 10,
/*
    Defines the templates Cofax will use when
    being browsed by a search engine identified in
    searchEngineRobotsDb
*/
        "searchEngineListTemplate": "forSearchEnginesList.htm",
        "searchEngineFileTemplate": "forSearchEngines.htm",
        "searchEngineRobotsDb": "WEB-INF/robots.db",
/*
    New!  useDataStore enables/disables the Cofax database pool
*/
        "useDataStore": true,
/*
    Defines the implementation of org.cofax.DataStore that Cofax
    will use.  If this DataStore class does not suit your needs
    simply implement a new DataStore class and set here.
*/
        "dataStoreClass": "org.cofax.SqlDataStore",
/*
    Defines the implementation of org.cofax.Redirection that
    Cofax will use.  If this Redirection class does not suit
    your needs simply implenet a new Redirection class
    and set here.
*/
        "redirectionClass": "org.cofax.SqlRedirection",
/*
    Defines the data store name.   Keep this at the default
*/
        "dataStoreName": "cofax",
/*
    Defines the JDBC driver that Cofax's database pool will use
*/
        "dataStoreDriver": "com.microsoft.jdbc.sqlserver.SQLServerDriver",
/*
    Defines the JDBC connection URL to connect to the database
*/
        "dataStoreUrl": "jdbc:microsoft:sqlserver://LOCALHOST:1433;DatabaseName=goon",
/*
    Defines the user name to connect to the database
*/
        "dataStoreUser": "sa",
/*
    Defines the password to connect to the database
*/
        "dataStorePassword": "dataStoreTestQuery",
/*
    A query that will run to test the validity of the
    connection in the pool.
*/
        "dataStoreTestQuery": "SET NOCOUNT ON;select test='test';",
/*
    A log file to print out database information
*/
        "dataStoreLogFile": "/usr/local/tomcat/logs/datastore.log",
/*
    The number of connection to initialize on startup
*/
        "dataStoreInitConns": 10,
/*
    The maximum number of connection to use in the pool
*/
        "dataStoreMaxConns": 100,
/*
    The number of times a connection will be utilized from the
    pool before disconnect
*/
        "dataStoreConnUsageLimit": 100,
/*
    The level of information to print to the log
*/
        "dataStoreLogLevel": "debug",
/*
    The maximum URL length allowable by the CDS Servlet
    Helps to prevent hacking
*/
        "maxUrlLength": 500}},
/*
    Defines the Email Servlet
*/
    {
      "servlet-name": "cofaxEmail",
      "servlet-class": "org.cofax.cds.EmailServlet",
      "init-param": {
/*
    The mail host to be used by the mail servlet
*/
        "mailHost": "mail1",
/*
    An override
*/
        "mailHostOverride": "mail2"}},
/*
    Defines the Admin Servlet - used to refresh cache on
    demand and see statistics
*/
    {
      "servlet-name": "cofaxAdmin",
      "servlet-class": "org.cofax.cds.AdminServlet"},
/*
    Defines the File Servlet - used to display files like Apache
*/
    {
      "servlet-name": "fileServlet",
      "servlet-class": "org.cofax.cds.FileServlet"},
    {
      "servlet-name": "cofaxTools",
      "servlet-class": "org.cofax.cms.CofaxToolsServlet",
      "init-param": {
/*
    Path to the template folder relative to the tools tomcat installation.
*/
        "templatePath": "toolstemplates/",
/*
    Logging boolean 1 = on, 0 = off
*/
        "log": 1,
/*
    Location of log. If empty, log will be written System.out
*/
        "logLocation": "/usr/local/tomcat/logs/CofaxTools.log",
/*
    Max size of log in BITS. If size is empty, no limit to log.
    If size is defined, log will be overwritten upon reaching defined size.
*/
        "logMaxSize": "",
/*
    DataStore logging boolean 1 = on, 0 = off
*/
        "dataLog": 1,
/*
    DataStore location of log. If empty, log will be written System.out
*/
        "dataLogLocation": "/usr/local/tomcat/logs/dataLog.log",
/*
    Max size of log in BITS. If size is empty, no limit to log.
    If size is defined, log will be overwritten upon reaching defined size.
*/
        "dataLogMaxSize": "",
/*
    Http string relative to server root to call for page cache
    removal to Cofax Servlet.
*/
        "removePageCache": "/content/admin/remove?cache=pages&id=",
/*
    Http string relative to server root to call for template
    cache removal to Cofax Servlet.
*/
        "removeTemplateCache": "/content/admin/remove?cache=templates&id=",
/*
    Location of folder from root of drive that will be used for
    ftp transfer from beta server or user hard drive to live servers.
    Note that Edit Article will not function without this variable
    set correctly. MultiPart request relies upon access to this folder.
*/
        "fileTransferFolder": "/usr/local/tomcat/webapps/content/fileTransferFolder",
/*
    Defines whether the Server should look in another path for
    config files or variables.
*/
        "lookInContext": 1,
/*
    Number of the ID of the top level administration group in tblPermGroups.
*/
        "adminGroupID": 4,
/*
    Is the tools app running on  the 'beta server'.
*/
        "betaServer": true}}],
  "servlet-mapping": {
/*
    URL mapping for the CDS Servlet
*/
     "cofaxCDS": "/",
/*
    URL mapping for the Email Servlet
*/
     "cofaxEmail": "/cofaxutil/aemail/*",
/*
    URL mapping for the Admin servlet
*/
     "cofaxAdmin": "/admin/*",
/*
    URL mapping for the Files servlet
*/
     "fileServlet": "/static/*",
     "cofaxTools": "/tools/*"},
/*
    New! The cofax taglib descriptor file
*/
  "taglib": {
    "taglib-uri": "cofax.tld",
    "taglib-location": "/WEB-INF/tlds/cofax.tld"}}}

"""

test5 = """
{"menu": {
    "header": "SVG Viewer",
    "items": [
        {"id": "Open"},
        {"id": "OpenNew", "label": "Open New"},
        null,
        {"id": "ZoomIn", "label": "Zoom In"},
        {"id": "ZoomOut", "label": "Zoom Out"},
        {"id": "OriginalView", "label": "Original View"},
        null,
        {"id": "Quality"},
        {"id": "Pause"},
        {"id": "Mute"},
        null,
        {"id": "Find", "label": "Find..."},
        {"id": "FindAgain", "label": "Find Again"},
        {"id": "Copy"},
        {"id": "CopyAgain", "label": "Copy Again"},
        {"id": "CopySVG", "label": "Copy SVG"},
        {"id": "ViewSVG", "label": "View SVG"},
        {"id": "ViewSource", "label": "View Source"},
        {"id": "SaveAs", "label": "Save As"},
        null,
        {"id": "Help"},
        {"id": "About", "label": "About Adobe CVG Viewer..."}
    ]
}}
"""


text:
<?php

/**
 * The DataExport Process Cron task
 *
 * @package  Nails\Admin
 * @category Task
 */

namespace Nails\Admin\Cron\Task\DataExport;

use Nails\Cron\Task\Base;

/**
 * Class Process
 *
 * @package Nails\Admin\Cron\Task
 */
class Process extends Base
{
    /**
     * The cron expression of when to run
     *
     * @var string
     */
    const CRON_EXPRESSION = '* * * * *';

    /**
     * The console command to execute
     *
     * @var string
     */
    const CONSOLE_COMMAND = 'admin:dataexport:process';
}


text:
from __future__ import absolute_import

import itertools
import six

from celery import current_app

COUNTER_TASKS = set([
    'sentry.tasks.process_buffer.process_pending',
    'sentry.tasks.process_buffer.process_incr',
])

TRIGGER_TASKS = set([
    'sentry.tasks.post_process.post_process_group',
    'sentry.tasks.post_process.plugin_post_process_group',
    'sentry.tasks.post_process.record_affected_user',
    'sentry.tasks.post_process.record_affected_code',
])

class SplitQueueRouter(object):
    def __init__(self):
        queues = current_app.conf['CELERY_QUEUES']
        self.counter_queues = itertools.cycle([
            q.name for q in queues
            if q.name.startswith('counters-')
        ])

        self.trigger_queues = itertools.cycle([
            q.name for q in queues
            if q.name.startswith('triggers-')
        ])

    def route_for_task(self, task, *args, **kwargs):
        if task in COUNTER_TASKS:
            return {'queue': six.next(self.counter_queues)}
        if task in TRIGGER_TASKS:
            return {'queue': six.next(self.trigger_queues)}
        return None


text:
@interface ASFFeedly : NSObject

+ (BOOL)openURL:(NSURL *)URL;

- (instancetype)initWithClientID:(NSString *)clientID
                    clientSecret:(NSString *)clientSecret NS_DESIGNATED_INITIALIZER;

- (BOOL)isAuthorized;

- (void)subscriptions:(void(^)(NSArray *subscriptions, NSError *error))completion;
- (void)stream:(NSString *)streamID completion:(void(^)(ASFStream *stream, NSError *error))completion;

- (void)getMarkersReads;
- (void)getMarkersReadsNewerThan:(long long)newerThan;

- (void)updateCategory:(NSString *)ID withLabel:(NSString *)label;
- (void)updateSubscription:(NSString *)ID withTitle:(NSString *)title categories:(NSArray *)categories;

- (void)markEntry:(NSString *)ID read:(BOOL)read;
- (void)markEntries:(NSArray *)IDs read:(BOOL)read;
- (void)markCategory:(NSString *)ID read:(BOOL)read;
- (void)markCategories:(NSArray *)IDs read:(BOOL)read;
- (void)markSubscription:(NSString *)ID read:(BOOL)read;
- (void)markSubscriptions:(NSArray *)IDs read:(BOOL)read;

@end


text:
var assert = require('assert'),
    math = require('../../../index'),
    bignumber = math.bignumber,
    complex = math.complex,
    matrix = math.matrix,
    sparse = math.sparse,
    unit = math.unit,
    smallerEq = math.smallerEq;

describe('smallerEq', function() {

  it('should compare two numbers correctly', function() {
    assert.equal(smallerEq(2, 3), true);
    assert.equal(smallerEq(2, 2), true);
    assert.equal(smallerEq(2, 1), false);
    assert.equal(smallerEq(0, 0), true);
    assert.equal(smallerEq(-2, 2), true);
    assert.equal(smallerEq(-2, -3), false);
    assert.equal(smallerEq(-2, -2), true);
    assert.equal(smallerEq(-3, -2), true);
  });

  it('should compare two floating point numbers correctly', function() {
    // Infinity
    assert.equal(smallerEq(Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY), true);
    assert.equal(smallerEq(Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY), true);
    assert.equal(smallerEq(Number.POSITIVE_INFINITY, Number.NEGATIVE_INFINITY), false);
    assert.equal(smallerEq(Number.NEGATIVE_INFINITY, Number.POSITIVE_INFINITY), true);
    assert.equal(smallerEq(Number.POSITIVE_INFINITY, 2.0), false);
    assert.equal(smallerEq(2.0, Number.POSITIVE_INFINITY), true);
    assert.equal(smallerEq(Number.NEGATIVE_INFINITY, 2.0), true);
    assert.equal(smallerEq(2.0, Number.NEGATIVE_INFINITY), false);
    // floating point numbers
    assert.equal(smallerEq(0.3 - 0.2, 0.1), true);
  });

  it('should compare two booleans', function() {
    assert.equal(smallerEq(true, true), true);
    assert.equal(smallerEq(true, false), false);
    assert.equal(smallerEq(false, true), true);
    assert.equal(smallerEq(false, false), true);
  });

  it('should compare mixed numbers and booleans', function() {
    assert.equal(smallerEq(2, true), false);
    assert.equal(smallerEq(1, true), true);
    assert.equal(smallerEq(0, true), true);
    assert.equal(smallerEq(true, 2), true);
    assert.equal(smallerEq(true, 1), true);
    assert.equal(smallerEq(false, 2), true);
  });

  it('should compare mixed numbers and null', function() {
    assert.equal(smallerEq(1, null), false);
    assert.equal(smallerEq(0, null), true);
    assert.equal(smallerEq(null, 1), true);
    assert.equal(smallerEq(null, 0), true);
  });

  it('should compare bignumbers', function() {
    assert.deepEqual(smallerEq(bignumber(2), bignumber(3)), true);
    assert.deepEqual(smallerEq(bignumber(2), bignumber(2)), true);
    assert.deepEqual(smallerEq(bignumber(3), bignumber(2)), false);
    assert.deepEqual(smallerEq(bignumber(0), bignumber(0)), true);
    assert.deepEqual(smallerEq(bignumber(-2), bignumber(2)), true);
  });

  it('should compare mixed numbers and bignumbers', function() {
    assert.deepEqual(smallerEq(bignumber(2), 3), true);
    assert.deepEqual(smallerEq(2, bignumber(2)), true);

    assert.throws(function () {smallerEq(1/3, bignumber(1).div(3));}, /TypeError: Cannot implicitly convert a number with >15 significant digits to BigNumber/);
    assert.throws(function () {smallerEq(bignumber(1).div(3), 1/3);}, /TypeError: Cannot implicitly convert a number with >15 significant digits to BigNumber/);
  });

  it('should compare mixed booleans and bignumbers', function() {
    assert.deepEqual(smallerEq(bignumber(0.1), true), true);
    assert.deepEqual(smallerEq(bignumber(1), true), true);
    assert.deepEqual(smallerEq(bignumber(1), false), false);
    assert.deepEqual(smallerEq(bignumber(0), false), true);
    assert.deepEqual(smallerEq(false, bignumber(0)), true);
    assert.deepEqual(smallerEq(true, bignumber(0)), false);
    assert.deepEqual(smallerEq(true, bignumber(1)), true);
  });

  it('should compare two fractions', function() {
    assert.strictEqual(smallerEq(math.fraction(3), math.fraction(2)).valueOf(), false);
    assert.strictEqual(smallerEq(math.fraction(2), math.fraction(3)).valueOf(), true);
    assert.strictEqual(smallerEq(math.fraction(3), math.fraction(3)).valueOf(), true);
  });

  it('should compare mixed fractions and numbers', function() {
    assert.strictEqual(smallerEq(1, math.fraction(1,3)), false);
    assert.strictEqual(smallerEq(math.fraction(2), 2), true);
  });

  it('should compare two measures of the same unit correctly', function() {
    assert.equal(smallerEq(unit('100cm'), unit('10inch')), false);
    assert.equal(smallerEq(unit('99cm'), unit('1m')), true);
    //assert.equal(smallerEq(unit('100cm'), unit('1m')), true); // dangerous, round-off errors
    assert.equal(smallerEq(unit('101cm'), unit('1m')), false);
  });

  it('should apply configuration option epsilon', function() {
    var mymath = math.create();
    assert.equal(mymath.smallerEq(1.01, 1), false);
    assert.equal(mymath.smallerEq(math.bignumber(1.01), math.bignumber(1)), false);

    mymath.config({epsilon: 1e-2});
    assert.equal(mymath.smallerEq(1.01, 1), true);
    assert.equal(mymath.smallerEq(math.bignumber(1.01), math.bignumber(1)), true);
  });

  it('should throw an error if comparing a unit with a number', function() {
    assert.throws(function () {smallerEq(unit('100cm'), 22);});
    assert.throws(function () {smallerEq(22, unit('100cm'));});
  });

  it('should throw an error for two measures of different units', function() {
    assert.throws(function () {smallerEq(math.unit(5, 'km'), math.unit(100, 'gram'));});
  });

  it('should throw an error if comparing a unit with a bignumber', function() {
    assert.throws(function () {smallerEq(unit('100cm'), bignumber(22));});
    assert.throws(function () {smallerEq(bignumber(22), unit('100cm'));});
  });

  it('should perform lexical comparison of two strings', function() {
    assert.equal(smallerEq('0', 0), true);
    assert.equal(smallerEq('abd', 'abc'), false);
    assert.equal(smallerEq('abc', 'abc'), true);
    assert.equal(smallerEq('abc', 'abd'), true);
  });

  describe('Array', function () {

    it('should compare array - scalar', function () {
      assert.deepEqual(smallerEq('B', ['A', 'B', 'C']), [false, true, true]);
      assert.deepEqual(smallerEq(['A', 'B', 'C'], 'B'), [true, true, false]);
    });

    it('should compare array - array', function () {
      assert.deepEqual(smallerEq([[1, 2, 0], [-1, 0, 2]], [[1, -1, 0], [-1, 1, 0]]), [[true, false, true], [true, true, false]]);
    });

    it('should compare array - dense matrix', function () {
      assert.deepEqual(smallerEq([[1, 2, 0], [-1, 0, 2]], matrix([[1, -1, 0], [-1, 1, 0]])), matrix([[true, false, true], [true, true, false]]));
    });

    it('should compare array - sparse matrix', function () {
      assert.deepEqual(smallerEq([[1, 2, 0], [-1, 0, 2]], sparse([[1, -1, 0], [-1, 1, 0]])), matrix([[true, false, true], [true, true, false]]));
    });

    it('should throw an error if arrays have different sizes', function() {
      assert.throws(function () {smallerEq([1,4,5], [3,4]);});
    });
  });

  describe('DenseMatrix', function () {

    it('should compare dense matrix - scalar', function () {
      assert.deepEqual(smallerEq('B', matrix(['A', 'B', 'C'])), matrix([false, true, true]));
      assert.deepEqual(smallerEq(matrix(['A', 'B', 'C']), 'B'), matrix([true, true, false]));
    });

    it('should compare dense matrix - array', function () {
      assert.deepEqual(smallerEq(matrix([[1, 2, 0], [-1, 0, 2]]), [[1, -1, 0], [-1, 1, 0]]), matrix([[true, false, true], [true, true, false]]));
    });

    it('should compare dense matrix - dense matrix', function () {
      assert.deepEqual(smallerEq(matrix([[1, 2, 0], [-1, 0, 2]]), matrix([[1, -1, 0], [-1, 1, 0]])), matrix([[true, false, true], [true, true, false]]));
    });

    it('should compare dense matrix - sparse matrix', function () {
      assert.deepEqual(smallerEq(matrix([[1, 2, 0], [-1, 0, 2]]), sparse([[1, -1, 0], [-1, 1, 0]])), matrix([[true, false, true], [true, true, false]]));
    });
  });

  describe('SparseMatrix', function () {

    it('should compare sparse matrix - scalar', function () {
      assert.deepEqual(smallerEq('B', sparse([['A', 'B'], ['C', 'D']])), matrix([[false, true], [true, true]]));
      assert.deepEqual(smallerEq(sparse([['A', 'B'], ['C', 'D']]), 'B'), matrix([[true, true], [false, false]]));
    });

    it('should compare sparse matrix - array', function () {
      assert.deepEqual(smallerEq(sparse([[1, 2, 0], [-1, 0, 2]]), [[1, -1, 0], [-1, 1, 0]]), matrix([[true, false, true], [true, true, false]]));
    });

    it('should compare sparse matrix - dense matrix', function () {
      assert.deepEqual(smallerEq(sparse([[1, 2, 0], [-1, 0, 2]]), matrix([[1, -1, 0], [-1, 1, 0]])), matrix([[true, false, true], [true, true, false]]));
    });

    it('should compare sparse matrix - sparse matrix', function () {
      assert.deepEqual(smallerEq(sparse([[1, 2, 0], [-1, 0, 2]]), sparse([[1, -1, 0], [-1, 1, 0]])), matrix([[true, false, true], [true, true, false]]));
    });
  });

  it('should throw an error when comparing complex numbers', function() {
    assert.throws(function () {smallerEq(complex(1,1), complex(1,2));}, TypeError);
    assert.throws(function () {smallerEq(complex(2,1), 3);}, TypeError);
    assert.throws(function () {smallerEq(3, complex(2,4));}, TypeError);
    assert.throws(function () {smallerEq(math.bignumber(3), complex(2,4));}, TypeError);
    assert.throws(function () {smallerEq(complex(2,4), math.bignumber(3));}, TypeError);
  });

  it('should throw an error with two matrices of different sizes', function () {
    assert.throws(function () {smallerEq([1,4,6], [3,4]);});
  });

  it('should throw an error in case of invalid number of arguments', function() {
    assert.throws(function () {smallerEq(1);}, /TypeError: Too few arguments/);
    assert.throws(function () {smallerEq(1, 2, 3);}, /TypeError: Too many arguments/);
  });

  it('should LaTeX smallerEq', function () {
    var expression = math.parse('smallerEq(1,2)');
    assert.equal(expression.toTex(), '\\left(1\\leq2\\right)');
  });

});


text:
using System;

namespace Sodium
{
    [Obsolete("Use SecretAeadChaCha20Poly1305 instead")]
    public static class SecretAead
    {
        [Obsolete("Use SecretAeadChaCha20Poly1305.GenerateNonce instead")]
        public static byte[] GenerateNonce() => SecretAeadChaCha20Poly1305.GenerateNonce();

        [Obsolete("Use SecretAeadChaCha20Poly1305.Encrypt instead")]
        public static byte[] Encrypt(byte[] message, byte[] nonce, byte[] key, byte[]? additionalData = null) => SecretAeadChaCha20Poly1305.Encrypt(message, nonce, key, additionalData);

        [Obsolete("Use SecretAeadChaCha20Poly1305.Decrypt instead")]
        public static byte[] Decrypt(byte[] cipher, byte[] nonce, byte[] key, byte[]? additionalData = null) => SecretAeadChaCha20Poly1305.Decrypt(cipher, nonce, key, additionalData);
    }
}


text:
import warnings

import numpy as np
from numpy.testing import TestCase, assert_array_almost_equal, \
        assert_array_equal, assert_raises, assert_

from scipy.signal import tf2zpk, zpk2tf, bessel, BadCoefficients

class TestTf2zpk(TestCase):

    def test_simple(self):
        z_r = np.array([0.5, -0.5])
        p_r = np.array([1.j / np.sqrt(2), -1.j / np.sqrt(2)])
        # Sort the zeros/poles so that we don't fail the test if the order
        # changes
        z_r.sort()
        p_r.sort()
        b = np.poly(z_r)
        a = np.poly(p_r)

        z, p, k = tf2zpk(b, a)
        z.sort()
        p.sort()
        assert_array_almost_equal(z, z_r)
        assert_array_almost_equal(p, p_r)

    def test_bad_filter(self):
        """Regression test for #651: better handling of badly conditioned
        filter coefficients."""
        warnings.simplefilter("error", BadCoefficients)
        try:
            assert_raises(BadCoefficients, tf2zpk, [1e-15], [1.0, 1.0])
        finally:
            warnings.simplefilter("always", BadCoefficients)

class TestZpk2Tf(TestCase):

    def test_identity(self):
        """Test the identity transfer function."""
        z = []
        p = []
        k = 1.
        b, a = zpk2tf(z, p, k)
        b_r = np.array([1.])  # desired result
        a_r = np.array([1.])  # desired result
        # The test for the *type* of the return values is a regression
        # test for ticket #1095.  In the case p=[], zpk2tf used to
        # return the scalar 1.0 instead of array([1.0]).
        assert_array_equal(b, b_r)
        assert_(isinstance(b, np.ndarray))
        assert_array_equal(a, a_r)
        assert_(isinstance(a, np.ndarray))


text:
@implementation FxBaseCell

- (void)initCell
{
}

- (void)setCellData:(BaseInfo *)info
{
    self.cellInfo = info;
    _titleLabel.text = info.name;
}

@end


text:
package org.springframework.context.annotation;

import io.interface21.web.servlet.app.basic.BasicAuthenticationConfiguration;
import io.interface21.web.servlet.app.basic.EnableBasicAuthentication;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;

/**
 * A BasicAuthenticationImportSelector.
 *
 * @author Heiko Scherrer
 * @version 1.0
 * @since 1.0
 */
public class BasicAuthenticationImportSelector implements ImportSelector {

    /**
     * {@inheritDoc}
     */
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        Class<?> annoType = EnableBasicAuthentication.class;
        AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType);
        if (attributes == null) {
            throw new IllegalArgumentException(String.format(
                    "@%s is not present on importing class '%s' as expected",
                    annoType.getSimpleName(), importingClassMetadata.getClassName()));
        }
        BasicAuthenticationConfiguration.authenticationProviderBean = attributes.getString("authenticationProviderBean");
        return new String[]{BasicAuthenticationConfiguration.class.getName()};
    }
}


text:
<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLog
        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd
        http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
    <changeSet author="brianfreeman" id="changelog-23">

        <createTable tableName="cohort_annotation_enum_value">
            <column name="cohort_annotation_enum_value_id" type="bigint" autoIncrement="true">
                <constraints primaryKey="true" nullable="false"/>
            </column>
            <column name="cohort_annotation_definition_id" type="bigint">
                <constraints nullable="false"/>
            </column>
            <column name="name" type="VARCHAR(255)">
                <constraints nullable="false"/>
            </column>
            <column name="enum_order" type="bigint">
                <constraints nullable="false"/>
            </column>
        </createTable>

        <addForeignKeyConstraint baseColumnNames="cohort_annotation_definition_id"
                                 baseTableName="cohort_annotation_enum_value"
                                 constraintName="fk_enum_cohort_annotation_definition_id"
                                 referencedColumnNames="cohort_annotation_definition_id"
                                 referencedTableName="cohort_annotation_definition"/>

        <dropColumn columnName="annotation_value_timestamp" tableName="participant_cohort_annotations"/>
        <addColumn tableName="participant_cohort_annotations">
            <column name="annotation_value_date" type="date"/>
        </addColumn>
        <addColumn tableName="participant_cohort_annotations">
            <column name="cohort_annotation_enum_value_id" type="bigint"/>
        </addColumn>
        <addColumn tableName="participant_cohort_annotations">
            <column name="annotation_value_boolean" type="tinyint"/>
        </addColumn>

        <addForeignKeyConstraint baseColumnNames="cohort_annotation_enum_value_id"
                                 baseTableName="participant_cohort_annotations"
                                 constraintName="fk_enum_cohort_annotation_enum_value_id"
                                 referencedColumnNames="cohort_annotation_enum_value_id"
                                 referencedTableName="cohort_annotation_enum_value"/>

    </changeSet>
</databaseChangeLog>


text:
package com.navercorp.pinpoint.plugin.spring.r2dbc.interceptor;

import com.navercorp.pinpoint.bootstrap.context.Trace;
import com.navercorp.pinpoint.bootstrap.context.TraceContext;
import com.navercorp.pinpoint.bootstrap.interceptor.AroundInterceptor;
import com.navercorp.pinpoint.bootstrap.logging.PLogger;
import com.navercorp.pinpoint.bootstrap.logging.PLoggerFactory;
import com.navercorp.pinpoint.bootstrap.plugin.jdbc.BindValueAccessor;
import com.navercorp.pinpoint.common.util.ArrayArgumentUtils;

import java.util.HashMap;
import java.util.Map;

public class StatementBindInterceptor implements AroundInterceptor {
    private final PLogger logger = PLoggerFactory.getLogger(getClass());
    private final boolean isDebug = logger.isDebugEnabled();

    private final TraceContext traceContext;

    public StatementBindInterceptor(TraceContext traceContext) {
        this.traceContext = traceContext;
    }

    @Override
    public void before(Object target, Object[] args) {
    }

    @Override
    public void after(Object target, Object[] args, Object result, Throwable throwable) {
        if (isDebug) {
            logger.afterInterceptor(target, args, result, throwable);
        }

        if (throwable != null) {
            return;
        }

        final Trace trace = traceContext.currentTraceObject();
        if (trace == null) {
            return;
        }

        if (!(target instanceof BindValueAccessor)) {
            return;
        }

        final Integer index = ArrayArgumentUtils.getArgument(args, 0, Integer.class);
        if (index == null) {
            return;
        }
        // nullable
        final Object object = ArrayArgumentUtils.getArgument(args, 1, Object.class);

        Map<Integer, String> bindList = ((BindValueAccessor) target)._$PINPOINT$_getBindValue();
        if (bindList == null) {
            bindList = new HashMap<>();
            ((BindValueAccessor) target)._$PINPOINT$_setBindValue(bindList);
        }

        try {
            final String value = traceContext.getJdbcContext().getBindVariableService().formatBindVariable(object);
            bindList.put(index + 1, value);
        } catch (Throwable th) {
            if (logger.isWarnEnabled()) {
                logger.warn("AFTER error. Caused:{}", th.getMessage(), th);
            }
        }
    }
}