Perform java static checks in CI (#11221)

Summary:
Integrate pmd on the Java API to catch and report common Java coding problems; fix or suppress a basic set of PMD checks.

Link pmd into java build / CI

Add a pmd dependency to maven
Add a jpmd target to Makefile which runs pmd
Add a workflow to Circle CI which runs pmd
Configure an initial default pmd for CI

Repair lots of very simple PMD reports generated when we apply pmd-rules.xml

Repair or exception for PMD rules in the CloseResource category, which finds unclosed AutoCloseable resources.
We special-case the configuration of CloseResource and use the // NOPMD comment in source the avoid reports where we are the API creating an AutoCloseable, and therefore returning an unclosed resource is correct behaviour.

Pull Request resolved: https://github.com/facebook/rocksdb/pull/11221

Reviewed By: akankshamahajan15

Differential Revision: D50369930

Pulled By: jowlyzhang

fbshipit-source-id: a41c36b44b3bab7644df3e9cc16afbdf33b84f6b
This commit is contained in:
Alan Paxton 2023-10-17 10:04:35 -07:00 committed by Facebook GitHub Bot
parent 84af7cf0bd
commit 2296c624fa
64 changed files with 710 additions and 285 deletions

View File

@ -105,6 +105,15 @@ commands:
path: /tmp/core_dumps
when: on_fail
post-pmd-steps:
steps:
- store_artifacts:
path: /home/circleci/project/java/target/pmd.xml
when: on_fail
- store_artifacts:
path: /home/circleci/project/java/target/site
when: on_fail
upgrade-cmake:
steps:
- run:
@ -127,6 +136,13 @@ commands:
command: |
HOMEBREW_NO_AUTO_UPDATE=1 brew install gflags
install-maven:
steps:
- run:
name: Install maven
command: |
sudo apt-get update -y && sudo apt-get install -y maven
setup-folly:
steps:
- run:
@ -589,6 +605,27 @@ jobs:
command: make V=1 J=8 -j8 jtest
- post-steps
build-linux-java-pmd:
machine:
image: ubuntu-2004:202111-02
resource_class: large
environment:
JAVA_HOME: /usr/lib/jvm/java-8-openjdk-amd64
steps:
- install-maven
- pre-steps
- run:
name: "Set Java Environment"
command: |
echo "JAVA_HOME=${JAVA_HOME}"
echo 'export PATH=$JAVA_HOME/bin:$PATH' >> $BASH_ENV
which java && java -version
which javac && javac -version
- run:
name: "PMD RocksDBJava"
command: make V=1 J=8 -j8 jpmd
- post-pmd-steps
build-linux-java-static:
executor: linux-docker
resource_class: large
@ -853,6 +890,7 @@ workflows:
- build-macos-java
- build-macos-java-static
- build-macos-java-static-universal
- build-linux-java-pmd
jobs-macos:
jobs:
- build-macos

View File

@ -2419,6 +2419,9 @@ jtest_run:
jtest: rocksdbjava
cd java;$(MAKE) sample test
jpmd: rocksdbjava rocksdbjavageneratepom
cd java;$(MAKE) pmd
jdb_bench:
cd java;$(MAKE) db_bench;

View File

@ -267,6 +267,8 @@ JAVADOC_CMD := javadoc
endif
endif
MAVEN_CMD := mvn
# Look for the Java version (1.6->6, 1.7->7, 1.8->8, 11.0->11, 13.0->13, 15.0->15 etc..)
JAVAC_VERSION := $(shell $(JAVAC_CMD) -version 2>&1)
JAVAC_MAJOR_VERSION := $(word 2,$(subst ., ,$(JAVAC_VERSION)))
@ -455,3 +457,6 @@ run_plugin_test:
db_bench: java
$(AM_V_GEN)mkdir -p $(BENCHMARK_MAIN_CLASSES)
$(AM_V_at)$(JAVAC_CMD) $(JAVAC_ARGS) -cp $(MAIN_CLASSES) -d $(BENCHMARK_MAIN_CLASSES) $(BENCHMARK_MAIN_SRC)/org/rocksdb/benchmark/*.java
pmd:
$(MAVEN_CMD) pmd:pmd pmd:cpd pmd:check

62
java/pmd-rules.xml Normal file
View File

@ -0,0 +1,62 @@
<?xml version="1.0"?>
<ruleset name="Custom Rules"
xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
<description>
Custom rules for checking RocksDB
</description>
<!-- Use PMD rules from a few sets, and then make exceptions -->
<rule ref="category/java/codestyle.xml">
<!-- These problems are acceptable in perpertuity -->
<exclude name="AvoidUsingNativeCode"/>
<exclude name="LongVariable"/>
<exclude name="ShortVariable"/>
<exclude name="ShortClassName"/>
<exclude name="OnlyOneReturn"/>
<exclude name="FieldNamingConventions"/>
<exclude name="FormalParameterNamingConventions"/>
<exclude name="LinguisticNaming"/>
<!-- These could be fixed if we take the time to do it -->
<exclude name="CommentDefaultAccessModifier"/>
<exclude name="FieldDeclarationsShouldBeAtStartOfClass"/>
<exclude name="FinalParameterInAbstractMethod"/>
<exclude name="EmptyMethodInAbstractClassShouldBeAbstract"/>
<exclude name="MethodArgumentCouldBeFinal"/>
<exclude name="LocalVariableNamingConventions"/>
<exclude name="LocalVariableCouldBeFinal"/>
<exclude name="ControlStatementBraces"/>
<exclude name="CallSuperInConstructor"/>
<exclude name="ControlStatementBraces"/>
<exclude name="MethodNamingConventions"/>
<exclude name="UselessParentheses"/>
<exclude name="AtLeastOneConstructor"/>
</rule>
<rule ref="category/java/errorprone.xml">
<exclude name="AvoidFieldNameMatchingMethodName"/>
</rule>
<rule ref="category/java/errorprone.xml/AvoidLiteralsInIfCondition">
<properties>
<property name="ignoreMagicNumbers" value="-1,0,1,2,0x0,0x1,0xff" />
<property name="ignoreExpressions" value="true,false" />
</properties>
</rule>
<rule ref="category/java/bestpractices.xml">
<exclude name="UseVarargs"/>
</rule>
<rule ref="category/java/errorprone.xml/CloseResource">
<properties>
<property name="types" value="java.lang.AutoCloseable,java.sql.Connection,java.sql.Statement,java.sql.ResultSet" />
<property name="closeAsDefaultTarget" value="true" />
<!-- we allow these org.rocksdb types as generally our API is opening them for the user. -->
<property name="allowedResourceTypes" value="java.io.ByteArrayOutputStream|java.io.ByteArrayInputStream|java.io.StringWriter|java.io.CharArrayWriter|java.util.stream.Stream|java.util.stream.IntStream|java.util.stream.LongStream|java.util.stream.DoubleStream" />
<property name="closeNotInFinally" value="false" />
</properties>
</rule>
</ruleset>

View File

@ -140,7 +140,44 @@
</execution>
</executions>
</plugin>
</plugins>
<plugin>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs-maven-plugin</artifactId>
<version>4.7.2.1</version>
<configuration>
<excludeFilterFile>spotbugs-exclude.xml</excludeFilterFile>
</configuration>
<dependencies>
<!-- overwrite dependency on spotbugs if you want to specify the version of spotbugs -->
<dependency>
<groupId>com.github.spotbugs</groupId>
<artifactId>spotbugs</artifactId>
<version>4.7.3</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.20.0</version>
<executions>
<execution>
<goals>
<goal>check</goal>
<goal>cpd-check</goal>
</goals>
</execution>
</executions>
<configuration>
<rulesets>
<!-- A rule set, that comes bundled with PMD -->
<ruleset>/pmd-rules.xml</ruleset>
<!-- A rule set, that comes bundled with PMD -->
<!-- <ruleset>/category/java/errorprone.xml</ruleset> -->
</rulesets>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
@ -174,5 +211,15 @@
<version>1.10.19</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencies>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
<version>3.3.0</version>
</plugin>
</plugins>
</reporting>
</project>

151
java/spotbugs-exclude.xml Normal file
View File

@ -0,0 +1,151 @@
<?xml version="1.0" encoding="UTF-8"?>
<FindBugsFilter>
<!-- The set failing checks when spotbugs was set up were added to this file, as a baseline -->
<!-- These exclusions should each be justified or removed and fixed AP (2023-02-09) -->
<Match>
<Class name="org.rocksdb.SstFileWriter"/>
<Bug pattern="UPM_UNCALLED_PRIVATE_METHOD" />
</Match>
<Match>
<Class name="org.rocksdb.AbstractTransactionNotifier"/>
<Bug pattern="UPM_UNCALLED_PRIVATE_METHOD" />
</Match>
<Match>
<Class name="org.rocksdb.Env"/>
<Bug pattern="MS_EXPOSE_REP" />
</Match>
<Match>
<Class name="org.rocksdb.BackupEngineOptions"/>
<Bug pattern="EI_EXPOSE_REP" />
</Match>
<Match>
<Class name="org.rocksdb.BackupEngineOptions"/>
<Bug pattern="EI_EXPOSE_REP" />
</Match>
<Match>
<Class name="org.rocksdb.Transaction$WaitingTransactions"/>
<Bug pattern="EI_EXPOSE_REP" />
</Match>
<Match>
<Class name="org.rocksdb.TransactionDB$KeyLockInfo"/>
<Bug pattern="EI_EXPOSE_REP" />
</Match>
<Match>
<Class name="org.rocksdb.Options"/>
<Bug pattern="EI_EXPOSE_REP" />
</Match>
<Match>
<Class name="org.rocksdb.ColumnFamilyDescriptor"/>
<Bug pattern="EI_EXPOSE_REP" />
</Match>
<Match>
<Class name="org.rocksdb.ColumnFamilyOptions"/>
<Bug pattern="EI_EXPOSE_REP" />
</Match>
<Match>
<Class name="org.rocksdb.DBOptions"/>
<Bug pattern="EI_EXPOSE_REP" />
</Match>
<Match>
<Class name="org.rocksdb.EnvOptions"/>
<Bug pattern="EI_EXPOSE_REP" />
</Match>
<Match>
<Class name="org.rocksdb.LiveFileMetaData"/>
<Bug pattern="EI_EXPOSE_REP" />
</Match>
<Match>
<Class name="org.rocksdb.SstFileMetaData"/>
<Bug pattern="EI_EXPOSE_REP" />
</Match>
<Match>
<Class name="org.rocksdb.StatsCollectorInput"/>
<Bug pattern="EI_EXPOSE_REP" />
</Match>
<Match>
<Class name="org.rocksdb.ThreadStatus"/>
<Bug pattern="EI_EXPOSE_REP" />
</Match>
<Match>
<Class name="org.rocksdb.ColumnFamilyMetaData"/>
<Bug pattern="EI_EXPOSE_REP" />
</Match>
<Match>
<Class name="org.rocksdb.TransactionLogIterator$BatchResult"/>
<Bug pattern="EI_EXPOSE_REP" />
</Match>
<Match>
<Class name="org.rocksdb.WBWIRocksIterator$WriteEntry"/>
<Bug pattern="EI_EXPOSE_REP" />
</Match>
<Match>
<Class name="org.rocksdb.TableProperties"/>
<Bug pattern="EI_EXPOSE_REP" />
</Match>
<Match>
<Class name="org.rocksdb.WBWIRocksIterator$WriteEntry"/>
<Bug pattern="EI_EXPOSE_REP2" />
</Match>
<Match>
<Class name="org.rocksdb.TransactionDB$DeadlockPath"/>
<Bug pattern="EI_EXPOSE_REP2" />
</Match>
<Match>
<Class name="org.rocksdb.StatisticsCollector"/>
<Bug pattern="EI_EXPOSE_REP2" />
</Match>
<Match>
<Class name="org.rocksdb.ReadOptions"/>
<Bug pattern="EI_EXPOSE_REP2" />
</Match>
<Match>
<Class name="org.rocksdb.Range"/>
<Bug pattern="EI_EXPOSE_REP2" />
</Match>
<Match>
<Class name="org.rocksdb.Options"/>
<Bug pattern="EI_EXPOSE_REP2" />
</Match>
<Match>
<Class name="org.rocksdb.StatsCollectorInput"/>
<Bug pattern="EI_EXPOSE_REP2" />
</Match>
<Match>
<Class name="org.rocksdb.EnvOptions"/>
<Bug pattern="EI_EXPOSE_REP2" />
</Match>
<Match>
<Class name="org.rocksdb.DBOptions"/>
<Bug pattern="EI_EXPOSE_REP2" />
</Match>
<Match>
<Class name="org.rocksdb.ColumnFamilyOptions"/>
<Bug pattern="EI_EXPOSE_REP2" />
</Match>
<Match>
<Class name="org.rocksdb.ColumnFamilyDescriptor"/>
<Bug pattern="EI_EXPOSE_REP2" />
</Match>
<Match>
<Class name="org.rocksdb.BackupEngineOptions"/>
<Bug pattern="EI_EXPOSE_REP2" />
</Match>
<!-- comment out a single exclusion to test that CI reports the consequent spotbugs [Error]
<Match>
<Class name="org.rocksdb.TransactionDB$KeyLockInfo"/>
<Bug pattern="EI_EXPOSE_REP2" />
</Match>
-->
<Match>
<Bug pattern="BIT_IOR_OF_SIGNED_BYTE" />
</Match>
<Match>
<Bug pattern="ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD" />
</Match>
<Match>
<Bug pattern="DMI_HARDCODED_ABSOLUTE_FILENAME" />
</Match>
<Match>
<Class name="org.rocksdb.AbstractCompactionFilterFactory" />
</Match>
</FindBugsFilter>

View File

@ -31,8 +31,9 @@ public abstract class AbstractCompactionFilterFactory<T extends AbstractCompacti
*
* @return native handle of the CompactionFilter
*/
private long createCompactionFilter(final boolean fullCompaction,
final boolean manualCompaction) {
@SuppressWarnings({"PMD.UnusedPrivateMethod", "PMD.CloseResource"})
private long createCompactionFilter(
final boolean fullCompaction, final boolean manualCompaction) {
final T filter = createCompactionFilter(
new AbstractCompactionFilter.Context(fullCompaction, manualCompaction));

View File

@ -37,6 +37,7 @@ class AbstractComparatorJniBridge {
*
* @return the result of the comparison
*/
@SuppressWarnings("PMD.UnusedPrivateMethod")
private static int compareInternal(final AbstractComparator comparator, final ByteBuffer a,
final int aLen, final ByteBuffer b, final int bLen) {
if (aLen != -1) {
@ -80,6 +81,7 @@ class AbstractComparatorJniBridge {
* @return either {@code startLen} if the start key is unchanged, otherwise
* the new length of the start key
*/
@SuppressWarnings("PMD.UnusedPrivateMethod")
private static int findShortestSeparatorInternal(final AbstractComparator comparator,
final ByteBuffer start, final int startLen, final ByteBuffer limit, final int limitLen) {
if (startLen != -1) {
@ -108,6 +110,7 @@ class AbstractComparatorJniBridge {
*
* @return either keyLen if the key is unchanged, otherwise the new length of the key
*/
@SuppressWarnings("PMD.UnusedPrivateMethod")
private static int findShortSuccessorInternal(
final AbstractComparator comparator, final ByteBuffer key, final int keyLen) {
if (keyLen != -1) {

View File

@ -10,6 +10,7 @@ import static org.rocksdb.AbstractEventListener.EnabledEventCallback.*;
/**
* Base class for Event Listeners.
*/
@SuppressWarnings("PMD.AvoidDuplicateLiterals")
public abstract class AbstractEventListener extends RocksCallbackObject implements EventListener {
public enum EnabledEventCallback {
ON_FLUSH_COMPLETED((byte) 0x0),
@ -58,7 +59,7 @@ public abstract class AbstractEventListener extends RocksCallbackObject implemen
* @throws IllegalArgumentException if the value is unknown.
*/
static EnabledEventCallback fromValue(final byte value) {
for (final EnabledEventCallback enabledEventCallback : EnabledEventCallback.values()) {
for (final EnabledEventCallback enabledEventCallback : values()) {
if (enabledEventCallback.value == value) {
return enabledEventCallback;
}
@ -124,8 +125,9 @@ public abstract class AbstractEventListener extends RocksCallbackObject implemen
* @param dbHandle native handle of the database
* @param flushJobInfo the flush job info
*/
@SuppressWarnings("PMD.UnusedPrivateMethod")
private void onFlushCompletedProxy(final long dbHandle, final FlushJobInfo flushJobInfo) {
final RocksDB db = new RocksDB(dbHandle);
final RocksDB db = new RocksDB(dbHandle); // NOPMD - CloseResource
db.disOwnNativeHandle(); // we don't own this!
onFlushCompleted(db, flushJobInfo);
}
@ -142,8 +144,9 @@ public abstract class AbstractEventListener extends RocksCallbackObject implemen
* @param dbHandle native handle of the database
* @param flushJobInfo the flush job info
*/
@SuppressWarnings("PMD.UnusedPrivateMethod")
private void onFlushBeginProxy(final long dbHandle, final FlushJobInfo flushJobInfo) {
final RocksDB db = new RocksDB(dbHandle);
final RocksDB db = new RocksDB(dbHandle); // NOPMD - CloseResource
db.disOwnNativeHandle(); // we don't own this!
onFlushBegin(db, flushJobInfo);
}
@ -165,9 +168,10 @@ public abstract class AbstractEventListener extends RocksCallbackObject implemen
* @param dbHandle native handle of the database
* @param compactionJobInfo the flush job info
*/
@SuppressWarnings("PMD.UnusedPrivateMethod")
private void onCompactionBeginProxy(
final long dbHandle, final CompactionJobInfo compactionJobInfo) {
final RocksDB db = new RocksDB(dbHandle);
final RocksDB db = new RocksDB(dbHandle); // NOPMD - CloseResource
db.disOwnNativeHandle(); // we don't own this!
onCompactionBegin(db, compactionJobInfo);
}
@ -184,9 +188,10 @@ public abstract class AbstractEventListener extends RocksCallbackObject implemen
* @param dbHandle native handle of the database
* @param compactionJobInfo the flush job info
*/
@SuppressWarnings("PMD.UnusedPrivateMethod")
private void onCompactionCompletedProxy(
final long dbHandle, final CompactionJobInfo compactionJobInfo) {
final RocksDB db = new RocksDB(dbHandle);
final RocksDB db = new RocksDB(dbHandle); // NOPMD - CloseResource
db.disOwnNativeHandle(); // we don't own this!
onCompactionCompleted(db, compactionJobInfo);
}
@ -225,9 +230,10 @@ public abstract class AbstractEventListener extends RocksCallbackObject implemen
* @param dbHandle native handle of the database
* @param externalFileIngestionInfo the flush job info
*/
@SuppressWarnings("PMD.UnusedPrivateMethod")
private void onExternalFileIngestedProxy(
final long dbHandle, final ExternalFileIngestionInfo externalFileIngestionInfo) {
final RocksDB db = new RocksDB(dbHandle);
final RocksDB db = new RocksDB(dbHandle); // NOPMD - CloseResource
db.disOwnNativeHandle(); // we don't own this!
onExternalFileIngested(db, externalFileIngestionInfo);
}
@ -245,6 +251,7 @@ public abstract class AbstractEventListener extends RocksCallbackObject implemen
* @param reasonByte byte value representing error reason
* @param backgroundError status with error code
*/
@SuppressWarnings("PMD.UnusedPrivateMethod")
private void onBackgroundErrorProxy(final byte reasonByte, final Status backgroundError) {
onBackgroundError(BackgroundErrorReason.fromValue(reasonByte), backgroundError);
}
@ -307,6 +314,7 @@ public abstract class AbstractEventListener extends RocksCallbackObject implemen
* @param reasonByte byte value representing error reason
* @param backgroundError status with error code
*/
@SuppressWarnings("PMD.UnusedPrivateMethod")
private boolean onErrorRecoveryBeginProxy(final byte reasonByte, final Status backgroundError) {
return onErrorRecoveryBegin(BackgroundErrorReason.fromValue(reasonByte), backgroundError);
}

View File

@ -3,12 +3,18 @@ package org.rocksdb;
import java.util.*;
public abstract class AbstractMutableOptions {
/**
* This class is not strictly abstract in Java language terms, so we do not declare it as such.
* The name remains {@code AbstractMutableOptions} to reflect the underlying C++ name.
* The constructor is protected, so it will always be used as a base class.
*/
public class AbstractMutableOptions {
protected static final String KEY_VALUE_PAIR_SEPARATOR = ";";
protected static final char KEY_VALUE_SEPARATOR = '=';
static final String INT_ARRAY_INT_SEPARATOR = ":";
private static final String HAS_NOT_BEEN_SET = " has not been set";
protected final String[] keys;
private final String[] values;
@ -18,15 +24,18 @@ public abstract class AbstractMutableOptions {
* @param keys the keys
* @param values the values
*/
@SuppressWarnings("PMD.ArrayIsStoredDirectly")
protected AbstractMutableOptions(final String[] keys, final String[] values) {
this.keys = keys;
this.values = values;
}
@SuppressWarnings("PMD.MethodReturnsInternalArray")
String[] getKeys() {
return keys;
}
@SuppressWarnings("PMD.MethodReturnsInternalArray")
String[] getValues() {
return values;
}
@ -106,7 +115,7 @@ public abstract class AbstractMutableOptions {
throws NoSuchElementException, NumberFormatException {
final MutableOptionValue<?> value = options.get(key);
if(value == null) {
throw new NoSuchElementException(key.name() + " has not been set");
throw new NoSuchElementException(key.name() + HAS_NOT_BEEN_SET);
}
return value.asDouble();
}
@ -125,7 +134,7 @@ public abstract class AbstractMutableOptions {
throws NoSuchElementException, NumberFormatException {
final MutableOptionValue<?> value = options.get(key);
if(value == null) {
throw new NoSuchElementException(key.name() + " has not been set");
throw new NoSuchElementException(key.name() + HAS_NOT_BEEN_SET);
}
return value.asLong();
}
@ -144,7 +153,7 @@ public abstract class AbstractMutableOptions {
throws NoSuchElementException, NumberFormatException {
final MutableOptionValue<?> value = options.get(key);
if(value == null) {
throw new NoSuchElementException(key.name() + " has not been set");
throw new NoSuchElementException(key.name() + HAS_NOT_BEEN_SET);
}
return value.asInt();
}
@ -163,7 +172,7 @@ public abstract class AbstractMutableOptions {
throws NoSuchElementException, NumberFormatException {
final MutableOptionValue<?> value = options.get(key);
if(value == null) {
throw new NoSuchElementException(key.name() + " has not been set");
throw new NoSuchElementException(key.name() + HAS_NOT_BEEN_SET);
}
return value.asBoolean();
}
@ -182,7 +191,7 @@ public abstract class AbstractMutableOptions {
throws NoSuchElementException, NumberFormatException {
final MutableOptionValue<?> value = options.get(key);
if(value == null) {
throw new NoSuchElementException(key.name() + " has not been set");
throw new NoSuchElementException(key.name() + HAS_NOT_BEEN_SET);
}
return value.asIntArray();
}
@ -202,7 +211,7 @@ public abstract class AbstractMutableOptions {
throws NoSuchElementException, NumberFormatException {
final MutableOptionValue<?> value = options.get(key);
if (value == null) {
throw new NoSuchElementException(key.name() + " has not been set");
throw new NoSuchElementException(key.name() + HAS_NOT_BEEN_SET);
}
if (!(value instanceof MutableOptionValue.MutableOptionEnumValue)) {
@ -225,7 +234,7 @@ public abstract class AbstractMutableOptions {
} catch (final NumberFormatException nfe) {
final double doubleValue = Double.parseDouble(value);
if (doubleValue != Math.round(doubleValue))
throw new IllegalArgumentException("Unable to parse or round " + value + " to long");
throw new IllegalArgumentException("Unable to parse or round " + value + " to long", nfe);
return Math.round(doubleValue);
}
}
@ -243,7 +252,7 @@ public abstract class AbstractMutableOptions {
} catch (final NumberFormatException nfe) {
final double doubleValue = Double.parseDouble(value);
if (doubleValue != Math.round(doubleValue))
throw new IllegalArgumentException("Unable to parse or round " + value + " to int");
throw new IllegalArgumentException("Unable to parse or round " + value + " to int", nfe);
return (int) Math.round(doubleValue);
}
}
@ -287,6 +296,7 @@ public abstract class AbstractMutableOptions {
* @return the same object, after adding options
* @throws IllegalArgumentException if the key is unknown, or a value has the wrong type/form
*/
@SuppressWarnings("PMD.AvoidLiteralsInIfCondition")
private U fromOptionString(final OptionString.Entry option, final boolean ignoreUnknown)
throws IllegalArgumentException {
Objects.requireNonNull(option.key);
@ -340,12 +350,12 @@ public abstract class AbstractMutableOptions {
case ENUM:
final String optionName = key.name();
if (optionName.equals("prepopulate_blob_cache")) {
if ("prepopulate_blob_cache".equals(optionName)) {
final PrepopulateBlobCache prepopulateBlobCache =
PrepopulateBlobCache.getFromInternal(valueStr);
return setEnum(key, prepopulateBlobCache);
} else if (optionName.equals("compression")
|| optionName.equals("blob_compression_type")) {
} else if ("compression".equals(optionName)
|| "blob_compression_type".equals(optionName)) {
final CompressionType compressionType = CompressionType.getFromInternal(valueStr);
return setEnum(key, compressionType);
} else {

View File

@ -119,14 +119,16 @@ public abstract class AbstractSlice<T> extends RocksMutableObject {
*/
public int compare(final AbstractSlice<?> other) {
assert (other != null);
if(!isOwningHandle()) {
return other.isOwningHandle() ? -1 : 0;
if (isOwningHandle() && other.isOwningHandle()) {
return compare0(getNativeHandle(), other.getNativeHandle());
}
if (!isOwningHandle() && !other.isOwningHandle()) {
return 0;
}
if (isOwningHandle()) {
return 1;
} else {
if(!other.isOwningHandle()) {
return 1;
} else {
return compare0(getNativeHandle(), other.getNativeHandle());
}
return -1;
}
}

View File

@ -25,6 +25,7 @@ public abstract class AbstractTraceWriter
* {@link Status.Code#getValue()} and the second byte is the
* {@link Status.SubCode#getValue()}.
*/
@SuppressWarnings("PMD.UnusedPrivateMethod")
private short writeProxy(final long sliceHandle) {
try {
write(new Slice(sliceHandle));
@ -41,6 +42,7 @@ public abstract class AbstractTraceWriter
* {@link Status.Code#getValue()} and the second byte is the
* {@link Status.SubCode#getValue()}.
*/
@SuppressWarnings("PMD.UnusedPrivateMethod")
private short closeWriterProxy() {
try {
closeWriter();

View File

@ -30,9 +30,9 @@ public abstract class AbstractWalFilter
* {@link WalFilter.LogRecordFoundResult#walProcessingOption}
* {@link WalFilter.LogRecordFoundResult#batchChanged}.
*/
private short logRecordFoundProxy(final long logNumber,
final String logFileName, final long batchHandle,
final long newBatchHandle) {
@SuppressWarnings("PMD.UnusedPrivateMethod")
private short logRecordFoundProxy(final long logNumber, final String logFileName,
final long batchHandle, final long newBatchHandle) {
final LogRecordFoundResult logRecordFoundResult = logRecordFound(
logNumber, logFileName, new WriteBatch(batchHandle),
new WriteBatch(newBatchHandle));

View File

@ -228,10 +228,9 @@ public class BackupEngineOptions extends RocksObject {
*
* @return instance of current BackupEngineOptions.
*/
public BackupEngineOptions setBackupRateLimit(long backupRateLimit) {
public BackupEngineOptions setBackupRateLimit(final long backupRateLimit) {
assert(isOwningHandle());
backupRateLimit = (backupRateLimit <= 0) ? 0 : backupRateLimit;
setBackupRateLimit(nativeHandle_, backupRateLimit);
setBackupRateLimit(nativeHandle_, (backupRateLimit <= 0) ? 0 : backupRateLimit);
return this;
}
@ -286,10 +285,9 @@ public class BackupEngineOptions extends RocksObject {
*
* @return instance of current BackupEngineOptions.
*/
public BackupEngineOptions setRestoreRateLimit(long restoreRateLimit) {
public BackupEngineOptions setRestoreRateLimit(final long restoreRateLimit) {
assert(isOwningHandle());
restoreRateLimit = (restoreRateLimit <= 0) ? 0 : restoreRateLimit;
setRestoreRateLimit(nativeHandle_, restoreRateLimit);
setRestoreRateLimit(nativeHandle_, (restoreRateLimit <= 0) ? 0 : restoreRateLimit);
return this;
}

View File

@ -11,7 +11,7 @@ package org.rocksdb;
*/
// TODO(AR) should be renamed BlockBasedTableOptions
public class BlockBasedTableConfig extends TableFormatConfig {
@SuppressWarnings("PMD.NullAssignment")
public BlockBasedTableConfig() {
//TODO(AR) flushBlockPolicyFactory
cacheIndexAndFilterBlocks = false;
@ -87,11 +87,12 @@ public class BlockBasedTableConfig extends TableFormatConfig {
this.enableIndexCompression = enableIndexCompression;
this.blockAlign = blockAlign;
this.indexShortening = IndexShorteningMode.values()[indexShortening];
Filter filterPolicy = FilterPolicyType.values()[filterPolicyType].createFilter(
filterPolicyHandle, filterPolicyConfigValue);
if (filterPolicy != null) {
filterPolicy.disOwnNativeHandle();
this.setFilterPolicy(filterPolicy);
try (Filter filterPolicy = FilterPolicyType.values()[filterPolicyType].createFilter(
filterPolicyHandle, filterPolicyConfigValue)) {
if (filterPolicy != null) {
filterPolicy.disOwnNativeHandle();
this.setFilterPolicy(filterPolicy);
}
}
}

View File

@ -80,18 +80,19 @@ public class BloomFilter extends Filter {
* @param bitsPerKey number of bits to use
* @param IGNORED_useBlockBasedMode obsolete, ignored parameter
*/
@SuppressWarnings("PMD.UnusedFormalParameter")
public BloomFilter(final double bitsPerKey, final boolean IGNORED_useBlockBasedMode) {
this(bitsPerKey);
}
@SuppressWarnings("PMD.")
@Override
public boolean equals(Object o) {
if (this == o)
return true;
if (o == null || getClass() != o.getClass())
return false;
BloomFilter that = (BloomFilter) o;
return bitsPerKey == that.bitsPerKey;
return bitsPerKey == ((BloomFilter) o).bitsPerKey;
}
@Override

View File

@ -42,6 +42,7 @@ public class ByteBufferGetStatus {
*
* @param status the status of the request to fetch into the buffer
*/
@SuppressWarnings("PMD.NullAssignment")
ByteBufferGetStatus(final Status status) {
this.status = status;
this.requiredSize = 0;

View File

@ -37,7 +37,7 @@ public enum ChecksumType {
return value_;
}
private ChecksumType(final byte value) {
ChecksumType(final byte value) {
value_ = value;
}

View File

@ -33,8 +33,9 @@ public class ColumnFamilyDescriptor {
* column family.
* @since 3.10.0
*/
public ColumnFamilyDescriptor(final byte[] columnFamilyName,
final ColumnFamilyOptions columnFamilyOptions) {
@SuppressWarnings("PMD.ArrayIsStoredDirectly")
public ColumnFamilyDescriptor(
final byte[] columnFamilyName, final ColumnFamilyOptions columnFamilyOptions) {
columnFamilyName_ = columnFamilyName;
columnFamilyOptions_ = columnFamilyOptions;
}
@ -45,6 +46,7 @@ public class ColumnFamilyDescriptor {
* @return column family name.
* @since 3.10.0
*/
@SuppressWarnings("PMD.MethodReturnsInternalArray")
public byte[] getName() {
return columnFamilyName_;
}

View File

@ -102,7 +102,7 @@ public class ColumnFamilyHandle extends RocksObject {
return false;
}
final ColumnFamilyHandle that = (ColumnFamilyHandle) o;
@SuppressWarnings("PMD.CloseResource") final ColumnFamilyHandle that = (ColumnFamilyHandle) o;
try {
return rocksDB_.nativeHandle_ == that.rocksDB_.nativeHandle_ &&
getID() == that.getID() &&

View File

@ -11,6 +11,7 @@ import java.util.List;
/**
* The metadata that describes a column family.
*/
@SuppressWarnings("PMD.MissingStaticMethodInNonInstantiatableClass")
public class ColumnFamilyMetaData {
private final long size;
private final long fileCount;
@ -55,6 +56,7 @@ public class ColumnFamilyMetaData {
*
* @return the name
*/
@SuppressWarnings("PMD.MethodReturnsInternalArray")
public byte[] name() {
return name;
}

View File

@ -15,10 +15,9 @@ import java.util.*;
* As a descendant of {@link AbstractNativeReference}, this class is {@link AutoCloseable}
* and will be automatically released if opened in the preamble of a try with resources block.
*/
public class ColumnFamilyOptions extends RocksObject
implements ColumnFamilyOptionsInterface<ColumnFamilyOptions>,
MutableColumnFamilyOptionsInterface<ColumnFamilyOptions> {
public class ColumnFamilyOptions
extends RocksObject implements ColumnFamilyOptionsInterface<ColumnFamilyOptions>,
MutableColumnFamilyOptionsInterface<ColumnFamilyOptions> {
/**
* Construct ColumnFamilyOptions.
* <p>
@ -1013,6 +1012,7 @@ public class ColumnFamilyOptions extends RocksObject
*
* @return true iff blob files are currently enabled
*/
@Override
public boolean enableBlobFiles() {
return enableBlobFiles(nativeHandle_);
}

View File

@ -5,8 +5,6 @@
package org.rocksdb;
import java.util.List;
/**
* Enum CompactionStyle
* <p>
@ -25,7 +23,7 @@ import java.util.List;
* the old data, so it's basically a TTL compaction style.</li>
* <li><strong>NONE</strong> - Disable background compaction.
* Compaction jobs are submitted
* {@link RocksDB#compactFiles(CompactionOptions, ColumnFamilyHandle, List, int, int,
* {@link RocksDB#compactFiles(CompactionOptions, ColumnFamilyHandle, java.util.List, int, int,
* CompactionJobInfo)} ()}.</li>
* </ol>
*

View File

@ -7,7 +7,6 @@
package org.rocksdb;
public class ConfigOptions extends RocksObject {
/**
* Construct with default Options
*/

View File

@ -16,9 +16,7 @@ import java.util.*;
* and will be automatically released if opened in the preamble of a try with resources block.
*/
public class DBOptions extends RocksObject
implements DBOptionsInterface<DBOptions>,
MutableDBOptionsInterface<DBOptions> {
implements DBOptionsInterface<DBOptions>, MutableDBOptionsInterface<DBOptions> {
/**
* Construct DBOptions.
* <p>

View File

@ -47,7 +47,7 @@ public enum EncodingType {
return value_;
}
private EncodingType(final byte value) {
EncodingType(final byte value) {
value_ = value;
}

View File

@ -26,8 +26,9 @@ public abstract class Env extends RocksObject {
*
* @return the default {@link org.rocksdb.RocksEnv} instance.
*/
@SuppressWarnings({"PMD.CloseResource", "PMD.AssignmentInOperand"})
public static Env getDefault() {
RocksEnv defaultEnv = null;
RocksEnv defaultEnv;
RocksEnv newDefaultEnv = null;
while ((defaultEnv = SINGULAR_DEFAULT_ENV.get()) == null) {

View File

@ -5,8 +5,6 @@
package org.rocksdb;
import java.util.List;
/**
* EventListener class contains a set of callback functions that will
* be called when specific RocksDB event happens such as flush. It can
@ -16,14 +14,14 @@ import java.util.List;
* Note that callback functions should not run for an extended period of
* time before the function returns, otherwise RocksDB may be blocked.
* For example, it is not suggested to do
* {@link RocksDB#compactFiles(CompactionOptions, ColumnFamilyHandle, List, int, int,
* {@link RocksDB#compactFiles(CompactionOptions, ColumnFamilyHandle, java.util.List, int, int,
* CompactionJobInfo)} (as it may run for a long while) or issue many of
* {@link RocksDB#put(ColumnFamilyHandle, WriteOptions, byte[], byte[])}
* (as Put may be blocked in certain cases) in the same thread in the
* EventListener callback.
* <p>
* However, doing
* {@link RocksDB#compactFiles(CompactionOptions, ColumnFamilyHandle, List, int, int,
* {@link RocksDB#compactFiles(CompactionOptions, ColumnFamilyHandle, java.util.List, int, int,
* CompactionJobInfo)} and {@link RocksDB#put(ColumnFamilyHandle, WriteOptions, byte[], byte[])} in
* another thread is considered safe.
* <p>

View File

@ -15,7 +15,7 @@ package org.rocksdb;
* and post a warning in the LOG.
*/
public class HashLinkedListMemTableConfig extends MemTableConfig {
public static final long DEFAULT_BUCKET_COUNT = 50000;
public static final long DEFAULT_BUCKET_COUNT = 50_000;
public static final long DEFAULT_HUGE_PAGE_TLB_SIZE = 0;
public static final int DEFAULT_BUCKET_ENTRIES_LOG_THRES = 4096;
public static final boolean

View File

@ -15,7 +15,7 @@ package org.rocksdb;
* and post a warning in the LOG.
*/
public class HashSkipListMemTableConfig extends MemTableConfig {
public static final int DEFAULT_BUCKET_COUNT = 1000000;
public static final int DEFAULT_BUCKET_COUNT = 1_000_000;
public static final int DEFAULT_BRANCHING_FACTOR = 4;
public static final int DEFAULT_HEIGHT = 4;

View File

@ -11,6 +11,7 @@ import java.util.List;
/**
* The metadata that describes a level.
*/
@SuppressWarnings("PMD.MissingStaticMethodInNonInstantiatableClass")
public class LevelMetaData {
private final int level;
private final long size;

View File

@ -8,6 +8,7 @@ package org.rocksdb;
/**
* The full set of metadata associated with each SST file.
*/
@SuppressWarnings("PMD.MissingStaticMethodInNonInstantiatableClass")
public class LiveFileMetaData extends SstFileMetaData {
private final byte[] columnFamilyName;
private final int level;
@ -40,6 +41,7 @@ public class LiveFileMetaData extends SstFileMetaData {
*
* @return the name of the column family
*/
@SuppressWarnings("PMD.MethodReturnsInternalArray")
public byte[] columnFamilyName() {
return columnFamilyName;
}

View File

@ -5,6 +5,7 @@
package org.rocksdb;
@SuppressWarnings("PMD.MissingStaticMethodInNonInstantiatableClass")
public class LogFile {
private final String pathName;
private final long logNumber;

View File

@ -27,7 +27,9 @@ public class MemoryUtil {
* @param caches Set of caches to collect memory usage for.
* @return Map from {@link MemoryUsageType} to memory usage as a {@link Long}.
*/
public static Map<MemoryUsageType, Long> getApproximateMemoryUsageByType(final List<RocksDB> dbs, final Set<Cache> caches) {
@SuppressWarnings("PMD.CloseResource")
public static Map<MemoryUsageType, Long> getApproximateMemoryUsageByType(
final List<RocksDB> dbs, final Set<Cache> caches) {
final int dbCount = (dbs == null) ? 0 : dbs.size();
final int cacheCount = (caches == null) ? 0 : caches.size();
final long[] dbHandles = new long[dbCount];

View File

@ -15,6 +15,8 @@ import java.nio.ByteBuffer;
*/
public abstract class NativeComparatorWrapper
extends AbstractComparator {
static final String NATIVE_CODE_IMPLEMENTATION_SHOULD_NOT_BE_CALLED =
"This should not be called. Implementation is in Native code";
@Override
final ComparatorType getComparatorType() {
@ -23,26 +25,22 @@ public abstract class NativeComparatorWrapper
@Override
public final String name() {
throw new IllegalStateException("This should not be called. " +
"Implementation is in Native code");
throw new IllegalStateException(NATIVE_CODE_IMPLEMENTATION_SHOULD_NOT_BE_CALLED);
}
@Override
public final int compare(final ByteBuffer s1, final ByteBuffer s2) {
throw new IllegalStateException("This should not be called. " +
"Implementation is in Native code");
throw new IllegalStateException(NATIVE_CODE_IMPLEMENTATION_SHOULD_NOT_BE_CALLED);
}
@Override
public final void findShortestSeparator(final ByteBuffer start, final ByteBuffer limit) {
throw new IllegalStateException("This should not be called. " +
"Implementation is in Native code");
throw new IllegalStateException(NATIVE_CODE_IMPLEMENTATION_SHOULD_NOT_BE_CALLED);
}
@Override
public final void findShortSuccessor(final ByteBuffer key) {
throw new IllegalStateException("This should not be called. " +
"Implementation is in Native code");
throw new IllegalStateException(NATIVE_CODE_IMPLEMENTATION_SHOULD_NOT_BE_CALLED);
}
/**

View File

@ -16,13 +16,17 @@ public class NativeLibraryLoader {
private static final NativeLibraryLoader instance = new NativeLibraryLoader();
private static boolean initialized = false;
private static final String sharedLibraryName = Environment.getSharedLibraryName("rocksdb");
private static final String jniLibraryName = Environment.getJniLibraryName("rocksdb");
private static final String ROCKSDB_LIBRARY_NAME = "rocksdb";
private static final String sharedLibraryName =
Environment.getSharedLibraryName(ROCKSDB_LIBRARY_NAME);
private static final String jniLibraryName = Environment.getJniLibraryName(ROCKSDB_LIBRARY_NAME);
private static final /* @Nullable */ String fallbackJniLibraryName =
Environment.getFallbackJniLibraryName("rocksdb");
private static final String jniLibraryFileName = Environment.getJniLibraryFileName("rocksdb");
Environment.getFallbackJniLibraryName(ROCKSDB_LIBRARY_NAME);
private static final String jniLibraryFileName =
Environment.getJniLibraryFileName(ROCKSDB_LIBRARY_NAME);
private static final /* @Nullable */ String fallbackJniLibraryFileName =
Environment.getFallbackJniLibraryFileName("rocksdb");
Environment.getFallbackJniLibraryFileName(ROCKSDB_LIBRARY_NAME);
private static final String tempFilePrefix = "librocksdbjni";
private static final String tempFileSuffix = Environment.getJniLibraryExtension();
@ -51,6 +55,7 @@ public class NativeLibraryLoader {
*
* @throws java.io.IOException if a filesystem operation fails.
*/
@SuppressWarnings("PMD.EmptyCatchBlock")
public synchronized void loadLibrary(final String tmpDir) throws IOException {
try {
// try dynamic library
@ -104,64 +109,58 @@ public class NativeLibraryLoader {
}
}
File loadLibraryFromJarToTemp(final String tmpDir)
throws IOException {
InputStream is = null;
try {
// attempt to look up the static library in the jar file
String libraryFileName = jniLibraryFileName;
is = getClass().getClassLoader().getResourceAsStream(libraryFileName);
if (is == null) {
// is there a fallback we can try
if (fallbackJniLibraryFileName == null) {
throw new RuntimeException(libraryFileName + " was not found inside JAR.");
}
// attempt to look up the fallback static library in the jar file
libraryFileName = fallbackJniLibraryFileName;
is = getClass().getClassLoader().getResourceAsStream(libraryFileName);
if (is == null) {
throw new RuntimeException(libraryFileName + " was not found inside JAR.");
}
private File createTemp(final String tmpDir, final String libraryFileName) throws IOException {
// create a temporary file to copy the library to
final File temp;
if (tmpDir == null || tmpDir.isEmpty()) {
temp = File.createTempFile(tempFilePrefix, tempFileSuffix);
} else {
final File parentDir = new File(tmpDir);
if (!parentDir.exists()) {
throw new RuntimeException(
"Directory: " + parentDir.getAbsolutePath() + " does not exist!");
}
// create a temporary file to copy the library to
final File temp;
if (tmpDir == null || tmpDir.isEmpty()) {
temp = File.createTempFile(tempFilePrefix, tempFileSuffix);
} else {
final File parentDir = new File(tmpDir);
if (!parentDir.exists()) {
throw new RuntimeException(
"Directory: " + parentDir.getAbsolutePath() + " does not exist!");
}
temp = new File(parentDir, libraryFileName);
if (temp.exists() && !temp.delete()) {
throw new RuntimeException(
"File: " + temp.getAbsolutePath() + " already exists and cannot be removed.");
}
if (!temp.createNewFile()) {
throw new RuntimeException("File: " + temp.getAbsolutePath() + " could not be created.");
}
temp = new File(parentDir, libraryFileName);
if (temp.exists() && !temp.delete()) {
throw new RuntimeException(
"File: " + temp.getAbsolutePath() + " already exists and cannot be removed.");
}
if (!temp.exists()) {
throw new RuntimeException("File " + temp.getAbsolutePath() + " does not exist.");
} else {
temp.deleteOnExit();
}
// copy the library from the Jar file to the temp destination
Files.copy(is, temp.toPath(), StandardCopyOption.REPLACE_EXISTING);
// return the temporary library file
return temp;
} finally {
if (is != null) {
is.close();
if (!temp.createNewFile()) {
throw new RuntimeException("File: " + temp.getAbsolutePath() + " could not be created.");
}
}
if (temp.exists()) {
temp.deleteOnExit();
return temp;
} else {
throw new RuntimeException("File " + temp.getAbsolutePath() + " does not exist.");
}
}
@SuppressWarnings({"PMD.UseProperClassLoader", "PMD.UseTryWithResources"})
File loadLibraryFromJarToTemp(final String tmpDir) throws IOException {
try (InputStream is = getClass().getClassLoader().getResourceAsStream(jniLibraryFileName)) {
if (is != null) {
final File temp = createTemp(tmpDir, jniLibraryFileName);
Files.copy(is, temp.toPath(), StandardCopyOption.REPLACE_EXISTING);
return temp;
}
}
if (fallbackJniLibraryFileName == null) {
throw new RuntimeException(fallbackJniLibraryFileName + " was not found inside JAR.");
}
try (InputStream is =
getClass().getClassLoader().getResourceAsStream(fallbackJniLibraryFileName)) {
if (is != null) {
final File temp = createTemp(tmpDir, fallbackJniLibraryFileName);
Files.copy(is, temp.toPath(), StandardCopyOption.REPLACE_EXISTING);
return temp;
}
}
throw new RuntimeException(jniLibraryFileName + " was not found inside JAR.");
}
/**

View File

@ -107,6 +107,7 @@ public class OptimisticTransactionDB extends RocksDB
*
* @throws RocksDBException if an error occurs whilst closing.
*/
@Override
public void closeE() throws RocksDBException {
if (owningHandle_.compareAndSet(true, false)) {
try {
@ -128,6 +129,7 @@ public class OptimisticTransactionDB extends RocksDB
* <p>
* See also {@link #close()}.
*/
@SuppressWarnings("PMD.EmptyCatchBlock")
@Override
public void close() {
if (owningHandle_.compareAndSet(true, false)) {

View File

@ -9,6 +9,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
@SuppressWarnings("PMD.AvoidStringBufferField")
public class OptionString {
private static final char kvPairSeparator = ';';
private static final char kvSeparator = '=';
@ -39,6 +40,7 @@ public class OptionString {
return new Value(null, complex);
}
@Override
public String toString() {
final StringBuilder sb = new StringBuilder();
if (isList()) {
@ -68,6 +70,7 @@ public class OptionString {
this.value = value;
}
@Override
public String toString() {
return "" + key + "=" + value;
}
@ -75,6 +78,8 @@ public class OptionString {
static class Parser {
static class Exception extends RuntimeException {
private static final long serialVersionUID = 752283782841276408L;
public Exception(final String s) {
super(s);
}
@ -122,7 +127,7 @@ public class OptionString {
return (sb.length() > 0);
}
private boolean is(final char c) {
private boolean isChar(final char c) {
return (sb.length() > 0 && sb.charAt(0) == c);
}
@ -151,10 +156,10 @@ public class OptionString {
}
private String parseSimpleValue() {
if (is(wrappedValueBegin)) {
if (isChar(wrappedValueBegin)) {
next();
final String result = parseSimpleValue();
if (!is(wrappedValueEnd)) {
if (!isChar(wrappedValueEnd)) {
exception("Expected to end a wrapped value with " + wrappedValueEnd);
}
next();
@ -172,7 +177,7 @@ public class OptionString {
final List<String> list = new ArrayList<>(1);
while (true) {
list.add(parseSimpleValue());
if (!is(arrayValueSeparator))
if (!isChar(arrayValueSeparator))
break;
next();
@ -188,7 +193,7 @@ public class OptionString {
}
final String key = parseKey();
skipWhite();
if (is(kvSeparator)) {
if (isChar(kvSeparator)) {
next();
} else {
exception("Expected = separating key and value");
@ -200,12 +205,12 @@ public class OptionString {
private Value parseValue() {
skipWhite();
if (is(complexValueBegin)) {
if (isChar(complexValueBegin)) {
next();
skipWhite();
final Value value = Value.fromComplex(parseComplex());
skipWhite();
if (is(complexValueEnd)) {
if (isChar(complexValueEnd)) {
next();
skipWhite();
} else {
@ -214,7 +219,7 @@ public class OptionString {
return value;
} else if (isValueChar()) {
return Value.fromList(parseList());
} else if (is(kvPairSeparator)) {
} else if (isChar(kvPairSeparator)) {
// e.g. empty vector embedded in a struct option looks like
// struct_opt = {vector_opt=;...}
final List<String> entries = new ArrayList<>();
@ -232,7 +237,7 @@ public class OptionString {
if (hasNext()) {
entries.add(parseOption());
skipWhite();
while (is(kvPairSeparator)) {
while (isChar(kvPairSeparator)) {
next();
skipWhite();
if (!isKeyChar()) {

View File

@ -16,11 +16,8 @@ import java.util.*;
* and will be automatically released if opened in the preamble of a try with resources block.
*/
public class Options extends RocksObject
implements DBOptionsInterface<Options>,
MutableDBOptionsInterface<Options>,
ColumnFamilyOptionsInterface<Options>,
MutableColumnFamilyOptionsInterface<Options> {
implements DBOptionsInterface<Options>, MutableDBOptionsInterface<Options>,
ColumnFamilyOptionsInterface<Options>, MutableColumnFamilyOptionsInterface<Options> {
/**
* Converts the input properties into a Options-style formatted string
* @param properties The set of properties to convert

View File

@ -89,6 +89,7 @@ public class OptionsUtil {
private static void loadTableFormatConfig(final List<ColumnFamilyDescriptor> cfDescs) {
for (final ColumnFamilyDescriptor columnFamilyDescriptor : cfDescs) {
@SuppressWarnings("PMD.CloseResource")
final ColumnFamilyOptions columnFamilyOptions = columnFamilyDescriptor.getOptions();
columnFamilyOptions.setFetchedTableFormatConfig(
readTableFormatConfig(columnFamilyOptions.nativeHandle_));

View File

@ -39,7 +39,7 @@ public enum PerfLevel {
*/
@Deprecated OUT_OF_BOUNDS((byte) 6);
private PerfLevel(byte _value) {
PerfLevel(byte _value) {
this._value = _value;
}

View File

@ -573,14 +573,14 @@ public class ReadOptions extends RocksObject {
* @see #iterStartTs()
* @return Reference to timestamp or null if there is no timestamp defined.
*/
@SuppressWarnings("PMD.ConfusingTernary")
public Slice timestamp() {
assert (isOwningHandle());
final long timestampSliceHandle = timestamp(nativeHandle_);
if (timestampSliceHandle != 0) {
return new Slice(timestampSliceHandle);
} else {
if (timestampSliceHandle == 0) {
return null;
}
return new Slice(timestampSliceHandle);
}
/**
@ -623,14 +623,14 @@ public class ReadOptions extends RocksObject {
* @return Reference to lower bound timestamp or null if there is no lower bound timestamp
* defined.
*/
@SuppressWarnings("PMD.ConfusingTernary")
public Slice iterStartTs() {
assert (isOwningHandle());
final long iterStartTsHandle = iterStartTs(nativeHandle_);
if (iterStartTsHandle != 0) {
return new Slice(iterStartTsHandle);
} else {
if (iterStartTsHandle == 0) {
return null;
}
return new Slice(iterStartTsHandle);
}
/**

View File

@ -39,7 +39,7 @@ public abstract class RocksCallbackObject extends
static /* @Nullable */ long[] toNativeHandleList(
/* @Nullable */ final List<? extends RocksCallbackObject> objectList) {
if (objectList == null) {
return null;
return new long[0];
}
final int len = objectList.size();
final long[] handleList = new long[len];

View File

@ -31,6 +31,14 @@ public class RocksDB extends RocksObject {
private static final AtomicReference<LibraryState> libraryLoaded =
new AtomicReference<>(LibraryState.NOT_LOADED);
static {
RocksDB.loadLibrary();
}
static final String PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD =
"Performance optimization for a very specific workload";
private final List<ColumnFamilyHandle> ownedColumnFamilyHandles = new ArrayList<>();
/**
@ -40,6 +48,7 @@ public class RocksDB extends RocksObject {
* java.io.tmpdir, however, you can override this temporary location by
* setting the environment variable ROCKSDB_SHAREDLIB_DIR.
*/
@SuppressWarnings("PMD.EmptyCatchBlock")
public static void loadLibrary() {
if (libraryLoaded.get() == LibraryState.LOADED) {
return;
@ -89,6 +98,7 @@ public class RocksDB extends RocksObject {
* @param paths a list of strings where each describes a directory
* of a library.
*/
@SuppressWarnings("PMD.EmptyCatchBlock")
public static void loadLibrary(final List<String> paths) {
if (libraryLoaded.get() == LibraryState.LOADED) {
return;
@ -171,9 +181,10 @@ public class RocksDB extends RocksObject {
*/
public static RocksDB open(final String path) throws RocksDBException {
RocksDB.loadLibrary();
final Options options = new Options();
options.setCreateIfMissing(true);
return open(options, path);
try (Options options = new Options()) {
options.setCreateIfMissing(true);
return open(options, path);
}
}
/**
@ -209,8 +220,9 @@ public class RocksDB extends RocksObject {
final List<ColumnFamilyDescriptor> columnFamilyDescriptors,
final List<ColumnFamilyHandle> columnFamilyHandles)
throws RocksDBException {
final DBOptions options = new DBOptions();
return open(options, path, columnFamilyDescriptors, columnFamilyHandles);
try (DBOptions options = new DBOptions()) {
return open(options, path, columnFamilyDescriptors, columnFamilyHandles);
}
}
/**
@ -303,7 +315,8 @@ public class RocksDB extends RocksObject {
db.storeOptionsInstance(options);
for (int i = 1; i < handles.length; i++) {
final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(db, handles[i]);
final ColumnFamilyHandle columnFamilyHandle = // NOPMD - CloseResource
new ColumnFamilyHandle(db, handles[i]);
columnFamilyHandles.add(columnFamilyHandle);
}
@ -329,8 +342,9 @@ public class RocksDB extends RocksObject {
RocksDB.loadLibrary();
// This allows to use the rocksjni default Options instead of
// the c++ one.
final Options options = new Options();
return openReadOnly(options, path);
try (Options options = new Options()) {
return openReadOnly(options, path);
}
}
/**
@ -405,8 +419,9 @@ public class RocksDB extends RocksObject {
throws RocksDBException {
// This allows to use the rocksjni default Options instead of
// the c++ one.
final DBOptions options = new DBOptions();
return openReadOnly(options, path, columnFamilyDescriptors, columnFamilyHandles, false);
try (DBOptions options = new DBOptions()) {
return openReadOnly(options, path, columnFamilyDescriptors, columnFamilyHandles, false);
}
}
/**
@ -484,7 +499,8 @@ public class RocksDB extends RocksObject {
db.storeOptionsInstance(options);
for (int i = 1; i < handles.length; i++) {
final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(db, handles[i]);
final ColumnFamilyHandle columnFamilyHandle = // NOPMD - CloseResource
new ColumnFamilyHandle(db, handles[i]);
columnFamilyHandles.add(columnFamilyHandle);
}
@ -580,7 +596,8 @@ public class RocksDB extends RocksObject {
db.storeOptionsInstance(options);
for (int i = 1; i < handles.length; i++) {
final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(db, handles[i]);
final ColumnFamilyHandle columnFamilyHandle = // NOPMD - CloseResource
new ColumnFamilyHandle(db, handles[i]);
columnFamilyHandles.add(columnFamilyHandle);
}
@ -603,7 +620,8 @@ public class RocksDB extends RocksObject {
* @throws RocksDBException if an error occurs whilst closing.
*/
public void closeE() throws RocksDBException {
for (final ColumnFamilyHandle columnFamilyHandle : ownedColumnFamilyHandles) {
for (final ColumnFamilyHandle columnFamilyHandle : // NOPMD - CloseResource
ownedColumnFamilyHandles) {
columnFamilyHandle.close();
}
ownedColumnFamilyHandles.clear();
@ -628,9 +646,11 @@ public class RocksDB extends RocksObject {
* <p>
* See also {@link #close()}.
*/
@SuppressWarnings("PMD.EmptyCatchBlock")
@Override
public void close() {
for (final ColumnFamilyHandle columnFamilyHandle : ownedColumnFamilyHandles) {
for (final ColumnFamilyHandle columnFamilyHandle : // NOPMD - CloseResource
ownedColumnFamilyHandles) {
columnFamilyHandle.close();
}
ownedColumnFamilyHandles.clear();
@ -706,7 +726,7 @@ public class RocksDB extends RocksObject {
final List<ColumnFamilyHandle> columnFamilyHandles =
new ArrayList<>(cfHandles.length);
for (final long cfHandle : cfHandles) {
final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(this, cfHandle);
final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(this, cfHandle); // NOPMD
columnFamilyHandles.add(columnFamilyHandle);
}
ownedColumnFamilyHandles.addAll(columnFamilyHandles);
@ -739,7 +759,7 @@ public class RocksDB extends RocksObject {
final List<ColumnFamilyHandle> columnFamilyHandles =
new ArrayList<>(cfHandles.length);
for (final long cfHandle : cfHandles) {
final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(this, cfHandle);
final ColumnFamilyHandle columnFamilyHandle = new ColumnFamilyHandle(this, cfHandle); // NOPMD
columnFamilyHandles.add(columnFamilyHandle);
}
ownedColumnFamilyHandles.addAll(columnFamilyHandles);
@ -783,7 +803,7 @@ public class RocksDB extends RocksObject {
*/
public void destroyColumnFamilyHandle(final ColumnFamilyHandle columnFamilyHandle) {
for (int i = 0; i < ownedColumnFamilyHandles.size(); ++i) {
final ColumnFamilyHandle ownedHandle = ownedColumnFamilyHandles.get(i);
final ColumnFamilyHandle ownedHandle = ownedColumnFamilyHandles.get(i); // NOPMD
if (ownedHandle.equals(columnFamilyHandle)) {
columnFamilyHandle.close();
ownedColumnFamilyHandles.remove(i);
@ -1273,7 +1293,7 @@ public class RocksDB extends RocksObject {
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
@Experimental("Performance optimization for a very specific workload")
@Experimental(PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD)
public void singleDelete(final byte[] key) throws RocksDBException {
singleDelete(nativeHandle_, key, key.length);
}
@ -1300,9 +1320,9 @@ public class RocksDB extends RocksObject {
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
@Experimental("Performance optimization for a very specific workload")
public void singleDelete(final ColumnFamilyHandle columnFamilyHandle,
final byte[] key) throws RocksDBException {
@Experimental(PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD)
public void singleDelete(final ColumnFamilyHandle columnFamilyHandle, final byte[] key)
throws RocksDBException {
singleDelete(nativeHandle_, key, key.length,
columnFamilyHandle.nativeHandle_);
}
@ -1331,9 +1351,8 @@ public class RocksDB extends RocksObject {
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
@Experimental("Performance optimization for a very specific workload")
public void singleDelete(final WriteOptions writeOpt, final byte[] key)
throws RocksDBException {
@Experimental(PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD)
public void singleDelete(final WriteOptions writeOpt, final byte[] key) throws RocksDBException {
singleDelete(nativeHandle_, writeOpt.nativeHandle_, key, key.length);
}
@ -1362,9 +1381,9 @@ public class RocksDB extends RocksObject {
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
@Experimental("Performance optimization for a very specific workload")
public void singleDelete(final ColumnFamilyHandle columnFamilyHandle,
final WriteOptions writeOpt, final byte[] key) throws RocksDBException {
@Experimental(PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD)
public void singleDelete(final ColumnFamilyHandle columnFamilyHandle, final WriteOptions writeOpt,
final byte[] key) throws RocksDBException {
singleDelete(nativeHandle_, writeOpt.nativeHandle_, key, key.length,
columnFamilyHandle.nativeHandle_);
}
@ -2131,7 +2150,7 @@ public class RocksDB extends RocksObject {
*/
public List<byte[]> multiGetAsList(final List<byte[]> keys)
throws RocksDBException {
assert(keys.size() != 0);
assert (!keys.isEmpty());
final byte[][] keysArray = keys.toArray(new byte[keys.size()][]);
final int[] keyOffsets = new int[keysArray.length];
@ -2167,7 +2186,7 @@ public class RocksDB extends RocksObject {
final List<ColumnFamilyHandle> columnFamilyHandleList,
final List<byte[]> keys) throws RocksDBException,
IllegalArgumentException {
assert(keys.size() != 0);
assert (!keys.isEmpty());
// Check if key size equals cfList size. If not a exception must be
// thrown. If not a Segmentation fault happens.
if (keys.size() != columnFamilyHandleList.size()) {
@ -2204,7 +2223,7 @@ public class RocksDB extends RocksObject {
*/
public List<byte[]> multiGetAsList(final ReadOptions opt,
final List<byte[]> keys) throws RocksDBException {
assert(keys.size() != 0);
assert (!keys.isEmpty());
final byte[][] keysArray = keys.toArray(new byte[keys.size()][]);
final int[] keyOffsets = new int[keysArray.length];
@ -2240,7 +2259,7 @@ public class RocksDB extends RocksObject {
public List<byte[]> multiGetAsList(final ReadOptions opt,
final List<ColumnFamilyHandle> columnFamilyHandleList,
final List<byte[]> keys) throws RocksDBException {
assert(keys.size() != 0);
assert (!keys.isEmpty());
// Check if key size equals cfList size. If not a exception must be
// thrown. If not a Segmentation fault happens.
if (keys.size()!=columnFamilyHandleList.size()){
@ -2277,10 +2296,11 @@ public class RocksDB extends RocksObject {
*/
public List<ByteBufferGetStatus> multiGetByteBuffers(
final List<ByteBuffer> keys, final List<ByteBuffer> values) throws RocksDBException {
final ReadOptions readOptions = new ReadOptions();
final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>(1);
columnFamilyHandleList.add(getDefaultColumnFamily());
return multiGetByteBuffers(readOptions, columnFamilyHandleList, keys, values);
try (ReadOptions readOptions = new ReadOptions()) {
final List<ColumnFamilyHandle> columnFamilyHandleList = new ArrayList<>(1);
columnFamilyHandleList.add(getDefaultColumnFamily());
return multiGetByteBuffers(readOptions, columnFamilyHandleList, keys, values);
}
}
/**
@ -2320,8 +2340,9 @@ public class RocksDB extends RocksObject {
public List<ByteBufferGetStatus> multiGetByteBuffers(
final List<ColumnFamilyHandle> columnFamilyHandleList, final List<ByteBuffer> keys,
final List<ByteBuffer> values) throws RocksDBException {
final ReadOptions readOptions = new ReadOptions();
return multiGetByteBuffers(readOptions, columnFamilyHandleList, keys, values);
try (ReadOptions readOptions = new ReadOptions()) {
return multiGetByteBuffers(readOptions, columnFamilyHandleList, keys, values);
}
}
/**
@ -2344,7 +2365,7 @@ public class RocksDB extends RocksObject {
public List<ByteBufferGetStatus> multiGetByteBuffers(final ReadOptions readOptions,
final List<ColumnFamilyHandle> columnFamilyHandleList, final List<ByteBuffer> keys,
final List<ByteBuffer> values) throws RocksDBException {
assert (keys.size() != 0);
assert (!keys.isEmpty());
// Check if key size equals cfList size. If not a exception must be
// thrown. If not a Segmentation fault happens.
@ -3769,7 +3790,7 @@ public class RocksDB extends RocksObject {
*/
public void flush(final FlushOptions flushOptions)
throws RocksDBException {
flush(flushOptions, (List<ColumnFamilyHandle>) null);
flush(flushOptions, Collections.singletonList(getDefaultColumnFamily()));
}
/**
@ -4295,10 +4316,9 @@ public class RocksDB extends RocksObject {
* @throws RocksDBException thrown if error happens in underlying
* native library.
*/
public void deleteFilesInRanges(final ColumnFamilyHandle columnFamily,
final List<byte[]> ranges, final boolean includeEnd)
throws RocksDBException {
if (ranges.size() == 0) {
public void deleteFilesInRanges(final ColumnFamilyHandle columnFamily, final List<byte[]> ranges,
final boolean includeEnd) throws RocksDBException {
if (ranges.isEmpty()) {
return;
}
if ((ranges.size() % 2) != 0) {
@ -4330,7 +4350,7 @@ public class RocksDB extends RocksObject {
private /* @Nullable */ long[] toNativeHandleList(
/* @Nullable */ final List<? extends RocksObject> objectList) {
if (objectList == null) {
return null;
return new long[0];
}
final int len = objectList.size();
final long[] handleList = new long[len];
@ -4340,6 +4360,7 @@ public class RocksDB extends RocksObject {
return handleList;
}
@SuppressWarnings({"PMD.ForLoopVariableCount", "PMD.AvoidReassigningLoopVariables"})
private static long[] toRangeSliceHandles(final List<Range> ranges) {
final long[] rangeSliceHandles = new long[ranges.size() * 2];
for (int i = 0, j = 0; i < ranges.size(); i++) {
@ -4360,12 +4381,6 @@ public class RocksDB extends RocksObject {
}
}
private static int computeCapacityHint(final int estimatedNumberOfItems) {
// Default load factor for HashMap is 0.75, so N * 1.5 will be at the load
// limit. We add +1 for a buffer.
return (int)Math.ceil(estimatedNumberOfItems * 1.5 + 1.0);
}
// native methods
private static native long open(final long optionsHandle, final String path)
throws RocksDBException;
@ -4711,12 +4726,10 @@ public class RocksDB extends RocksObject {
return getMajor() + "." + getMinor() + "." + getPatch();
}
private static Version fromEncodedVersion(int encodedVersion) {
private static Version fromEncodedVersion(final int encodedVersion) {
final byte patch = (byte) (encodedVersion & 0xff);
encodedVersion >>= 8;
final byte minor = (byte) (encodedVersion & 0xff);
encodedVersion >>= 8;
final byte major = (byte) (encodedVersion & 0xff);
final byte minor = (byte) (encodedVersion >> 8 & 0xff);
final byte major = (byte) (encodedVersion >> 16 & 0xff);
return new Version(major, minor, patch);
}

View File

@ -10,7 +10,7 @@ package org.rocksdb;
* type is used to describe an internal error from the c++ rocksdb library.
*/
public class RocksDBException extends Exception {
private static final long serialVersionUID = -5187634878466267120L;
/* @Nullable */ private final Status status;
/**

View File

@ -36,18 +36,11 @@ public class SstFileMetaData {
* @param numEntries the number of entries
* @param numDeletions the number of deletions
*/
protected SstFileMetaData(
final String fileName,
final String path,
final long size,
final long smallestSeqno,
final long largestSeqno,
final byte[] smallestKey,
final byte[] largestKey,
final long numReadsSampled,
final boolean beingCompacted,
final long numEntries,
final long numDeletions) {
@SuppressWarnings("PMD.ArrayIsStoredDirectly")
protected SstFileMetaData(final String fileName, final String path, final long size,
final long smallestSeqno, final long largestSeqno, final byte[] smallestKey,
final byte[] largestKey, final long numReadsSampled, final boolean beingCompacted,
final long numEntries, final long numDeletions) {
this.fileName = fileName;
this.path = path;
this.size = size;
@ -111,6 +104,7 @@ public class SstFileMetaData {
*
* @return the smallest user defined key
*/
@SuppressWarnings("PMD.MethodReturnsInternalArray")
public byte[] smallestKey() {
return smallestKey;
}
@ -120,6 +114,7 @@ public class SstFileMetaData {
*
* @return the largest user defined key
*/
@SuppressWarnings("PMD.MethodReturnsInternalArray")
public byte[] largestKey() {
return largestKey;
}

View File

@ -6,7 +6,6 @@
package org.rocksdb;
public class SstFileReader extends RocksObject {
public SstFileReader(final Options options) {
super(newSstFileReader(options.nativeHandle_));
}

View File

@ -13,7 +13,6 @@ import java.nio.ByteBuffer;
* sequence number = 0.
*/
public class SstFileWriter extends RocksObject {
/**
* SstFileWriter Constructor.
*
@ -196,6 +195,8 @@ public class SstFileWriter extends RocksObject {
return fileSize(nativeHandle_);
}
@SuppressWarnings("PMD.UnusedPrivateMethod")
// (AP) Should we expose a constructor wrapping this ?
private static native long newSstFileWriter(final long envOptionsHandle, final long optionsHandle,
final long userComparatorHandle, final byte comparatorType);

View File

@ -61,6 +61,7 @@ public class StatisticsCollector {
_executorService.awaitTermination(shutdownTimeout, TimeUnit.MILLISECONDS);
}
@SuppressWarnings("PMD.CloseResource")
private Runnable collectStatistics() {
return () -> {
while (_isRunning) {

View File

@ -5,6 +5,7 @@
package org.rocksdb;
import java.io.Serializable;
import java.util.Objects;
/**
@ -13,7 +14,8 @@ import java.util.Objects;
* Currently only used with {@link RocksDBException} when the
* status is not {@link Code#Ok}
*/
public class Status {
public class Status implements Serializable {
private static final long serialVersionUID = -3794191127754280439L;
private final Code code;
/* @Nullable */ private final SubCode subCode;
/* @Nullable */ private final String state;

View File

@ -46,6 +46,7 @@ public class TableProperties {
* Access is package private as this will only be constructed from
* C++ via JNI and for testing.
*/
@SuppressWarnings("PMD.ArrayIsStoredDirectly")
TableProperties(final long dataSize, final long indexSize, final long indexPartitions,
final long topLevelIndexSize, final long indexKeyIsUserKey,
final long indexValueIsDeltaEncoded, final long filterSize, final long rawKeySize,
@ -116,6 +117,7 @@ public class TableProperties {
*
* @return the total number of index partitions.
*/
@SuppressWarnings("PMD.MethodReturnsInternalArray")
public long getIndexPartitions() {
return indexPartitions;
}
@ -299,6 +301,7 @@ public class TableProperties {
* @return the name of the column family, or null if the
* column family is unknown.
*/
@SuppressWarnings("PMD.MethodReturnsInternalArray")
/*@Nullable*/ public byte[] getColumnFamilyName() {
return columnFamilyName;
}

View File

@ -118,6 +118,7 @@ public class ThreadStatus {
*
* @return the properties
*/
@SuppressWarnings("PMD.MethodReturnsInternalArray")
public long[] getOperationProperties() {
return operationProperties;
}

View File

@ -5,6 +5,8 @@
package org.rocksdb;
import static org.rocksdb.RocksDB.PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@ -26,6 +28,8 @@ import java.util.List;
* examples.
*/
public class Transaction extends RocksObject {
private static final String FOR_EACH_KEY_THERE_MUST_BE_A_COLUMNFAMILYHANDLE =
"For each key there must be a ColumnFamilyHandle.";
private final RocksDB parent;
@ -345,8 +349,7 @@ public class Transaction extends RocksObject {
// Check if key size equals cfList size. If not a exception must be
// thrown. If not a Segmentation fault happens.
if (keys.length != columnFamilyHandles.size()) {
throw new IllegalArgumentException(
"For each key there must be a ColumnFamilyHandle.");
throw new IllegalArgumentException(FOR_EACH_KEY_THERE_MUST_BE_A_COLUMNFAMILYHANDLE);
}
if(keys.length == 0) {
return new byte[0][0];
@ -396,9 +399,9 @@ public class Transaction extends RocksObject {
// Check if key size equals cfList size. If not a exception must be
// thrown. If not a Segmentation fault happens.
if (keys.size() != columnFamilyHandles.size()) {
throw new IllegalArgumentException("For each key there must be a ColumnFamilyHandle.");
throw new IllegalArgumentException(FOR_EACH_KEY_THERE_MUST_BE_A_COLUMNFAMILYHANDLE);
}
if (keys.size() == 0) {
if (keys.isEmpty()) {
return new ArrayList<>(0);
}
final byte[][] keysArray = keys.toArray(new byte[keys.size()][]);
@ -474,7 +477,7 @@ public class Transaction extends RocksObject {
*/
public List<byte[]> multiGetAsList(final ReadOptions readOptions, final List<byte[]> keys)
throws RocksDBException {
if (keys.size() == 0) {
if (keys.isEmpty()) {
return new ArrayList<>(0);
}
final byte[][] keysArray = keys.toArray(new byte[keys.size()][]);
@ -637,8 +640,7 @@ public class Transaction extends RocksObject {
// Check if key size equals cfList size. If not a exception must be
// thrown. If not a Segmentation fault happens.
if (keys.length != columnFamilyHandles.size()){
throw new IllegalArgumentException(
"For each key there must be a ColumnFamilyHandle.");
throw new IllegalArgumentException(FOR_EACH_KEY_THERE_MUST_BE_A_COLUMNFAMILYHANDLE);
}
if(keys.length == 0) {
return new byte[0][0];
@ -673,9 +675,9 @@ public class Transaction extends RocksObject {
// Check if key size equals cfList size. If not a exception must be
// thrown. If not a Segmentation fault happens.
if (keys.size() != columnFamilyHandles.size()) {
throw new IllegalArgumentException("For each key there must be a ColumnFamilyHandle.");
throw new IllegalArgumentException(FOR_EACH_KEY_THERE_MUST_BE_A_COLUMNFAMILYHANDLE);
}
if (keys.size() == 0) {
if (keys.isEmpty()) {
return new ArrayList<>();
}
final byte[][] keysArray = keys.toArray(new byte[keys.size()][]);
@ -727,7 +729,7 @@ public class Transaction extends RocksObject {
public List<byte[]> multiGetForUpdateAsList(
final ReadOptions readOptions, final List<byte[]> keys) throws RocksDBException {
assert (isOwningHandle());
if (keys.size() == 0) {
if (keys.isEmpty()) {
return new ArrayList<>(0);
}
@ -1227,9 +1229,9 @@ public class Transaction extends RocksObject {
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
@Experimental("Performance optimization for a very specific workload")
public void singleDelete(final ColumnFamilyHandle columnFamilyHandle,
final byte[] key, final boolean assumeTracked) throws RocksDBException {
@Experimental(PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD)
public void singleDelete(final ColumnFamilyHandle columnFamilyHandle, final byte[] key,
final boolean assumeTracked) throws RocksDBException {
assert (isOwningHandle());
singleDelete(nativeHandle_, key, key.length,
columnFamilyHandle.nativeHandle_, assumeTracked);
@ -1259,9 +1261,9 @@ public class Transaction extends RocksObject {
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
@Experimental("Performance optimization for a very specific workload")
public void singleDelete(final ColumnFamilyHandle columnFamilyHandle,
final byte[] key) throws RocksDBException {
@Experimental(PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD)
public void singleDelete(final ColumnFamilyHandle columnFamilyHandle, final byte[] key)
throws RocksDBException {
assert(isOwningHandle());
singleDelete(nativeHandle_, key, key.length,
columnFamilyHandle.nativeHandle_, false);
@ -1288,7 +1290,7 @@ public class Transaction extends RocksObject {
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
@Experimental("Performance optimization for a very specific workload")
@Experimental(PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD)
public void singleDelete(final byte[] key) throws RocksDBException {
assert(isOwningHandle());
singleDelete(nativeHandle_, key, key.length);
@ -1311,10 +1313,9 @@ public class Transaction extends RocksObject {
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
@Experimental("Performance optimization for a very specific workload")
public void singleDelete(final ColumnFamilyHandle columnFamilyHandle,
final byte[][] keyParts, final boolean assumeTracked)
throws RocksDBException {
@Experimental(PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD)
public void singleDelete(final ColumnFamilyHandle columnFamilyHandle, final byte[][] keyParts,
final boolean assumeTracked) throws RocksDBException {
assert (isOwningHandle());
singleDelete(nativeHandle_, keyParts, keyParts.length,
columnFamilyHandle.nativeHandle_, assumeTracked);
@ -1333,9 +1334,9 @@ public class Transaction extends RocksObject {
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
@Experimental("Performance optimization for a very specific workload")
public void singleDelete(final ColumnFamilyHandle columnFamilyHandle,
final byte[][] keyParts) throws RocksDBException {
@Experimental(PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD)
public void singleDelete(final ColumnFamilyHandle columnFamilyHandle, final byte[][] keyParts)
throws RocksDBException {
assert(isOwningHandle());
singleDelete(nativeHandle_, keyParts, keyParts.length,
columnFamilyHandle.nativeHandle_, false);
@ -1352,7 +1353,7 @@ public class Transaction extends RocksObject {
* @throws RocksDBException when one of the TransactionalDB conditions
* described above occurs, or in the case of an unexpected error
*/
@Experimental("Performance optimization for a very specific workload")
@Experimental(PERFORMANCE_OPTIMIZATION_FOR_A_VERY_SPECIFIC_WORKLOAD)
public void singleDelete(final byte[][] keyParts) throws RocksDBException {
assert(isOwningHandle());
singleDelete(nativeHandle_, keyParts, keyParts.length);
@ -1980,9 +1981,9 @@ public class Transaction extends RocksObject {
*
* @return The waiting transactions
*/
@SuppressWarnings("PMD.UnusedPrivateMethod")
private WaitingTransactions newWaitingTransactions(
final long columnFamilyId, final String key,
final long[] transactionIds) {
final long columnFamilyId, final String key, final long[] transactionIds) {
return new WaitingTransactions(columnFamilyId, key, transactionIds);
}
@ -2021,6 +2022,7 @@ public class Transaction extends RocksObject {
*
* @return The IDs of the waiting transactions
*/
@SuppressWarnings("PMD.MethodReturnsInternalArray")
public long[] getTransactionIds() {
return transactionIds;
}

View File

@ -14,8 +14,8 @@ import java.util.Map;
*/
public class TransactionDB extends RocksDB
implements TransactionalDB<TransactionOptions> {
private TransactionDBOptions transactionDbOptions_;
// Field is "used" to prevent GC of the
@SuppressWarnings("PMD.UnusedPrivateField") private TransactionDBOptions transactionDbOptions_;
/**
* Private constructor.
@ -116,6 +116,7 @@ public class TransactionDB extends RocksDB
*
* @throws RocksDBException if an error occurs whilst closing.
*/
@Override
public void closeE() throws RocksDBException {
if (owningHandle_.compareAndSet(true, false)) {
try {
@ -137,6 +138,7 @@ public class TransactionDB extends RocksDB
* <p>
* See also {@link #close()}.
*/
@SuppressWarnings("PMD.EmptyCatchBlock")
@Override
public void close() {
if (owningHandle_.compareAndSet(true, false)) {
@ -218,7 +220,7 @@ public class TransactionDB extends RocksDB
final List<Transaction> txns = new ArrayList<>();
for(final long jtxnHandle : jtxnHandles) {
final Transaction txn = new Transaction(this, jtxnHandle);
final Transaction txn = new Transaction(this, jtxnHandle); // NOPMD - CloseResource
// this instance doesn't own the underlying C++ object
txn.disOwnNativeHandle();
@ -233,6 +235,7 @@ public class TransactionDB extends RocksDB
private final long[] transactionIDs;
private final boolean exclusive;
@SuppressWarnings("PMD.ArrayIsStoredDirectly")
public KeyLockInfo(final String key, final long[] transactionIDs, final boolean exclusive) {
this.key = key;
this.transactionIDs = transactionIDs;
@ -253,6 +256,7 @@ public class TransactionDB extends RocksDB
*
* @return the Transaction IDs.
*/
@SuppressWarnings("PMD.MethodReturnsInternalArray")
public long[] getTransactionIDs() {
return transactionIDs;
}
@ -287,8 +291,8 @@ public class TransactionDB extends RocksDB
*
* @return The waiting transactions
*/
private DeadlockInfo newDeadlockInfo(
final long transactionID, final long columnFamilyId,
@SuppressWarnings("PMD.UnusedPrivateMethod")
private DeadlockInfo newDeadlockInfo(final long transactionID, final long columnFamilyId,
final String waitingKey, final boolean exclusive) {
return new DeadlockInfo(transactionID, columnFamilyId,
waitingKey, exclusive);
@ -349,6 +353,7 @@ public class TransactionDB extends RocksDB
final DeadlockInfo[] path;
final boolean limitExceeded;
@SuppressWarnings("PMD.ArrayIsStoredDirectly")
public DeadlockPath(final DeadlockInfo[] path, final boolean limitExceeded) {
this.path = path;
this.limitExceeded = limitExceeded;

View File

@ -154,6 +154,7 @@ public class TtlDB extends RocksDB {
*
* @throws RocksDBException if an error occurs whilst closing.
*/
@Override
public void closeE() throws RocksDBException {
if (owningHandle_.compareAndSet(true, false)) {
try {
@ -175,6 +176,7 @@ public class TtlDB extends RocksDB {
* <p>
* See also {@link #close()}.
*/
@SuppressWarnings("PMD.EmptyCatchBlock")
@Override
public void close() {
if (owningHandle_.compareAndSet(true, false)) {

View File

@ -159,10 +159,10 @@ public class WBWIRocksIterator
* no value
*/
public DirectSlice getValue() {
if(!value.isOwningHandle()) {
return null; //TODO(AR) migrate to JDK8 java.util.Optional#empty()
} else {
if (value.isOwningHandle()) {
return value;
} else {
return null; // TODO(AR) migrate to JDK8 java.util.Optional#empty()
}
}
@ -178,6 +178,7 @@ public class WBWIRocksIterator
return (key == null) ? 0 : key.hashCode();
}
@SuppressWarnings("PMD.CloseResource")
@Override
public boolean equals(final Object other) {
if(other == null) {

View File

@ -9,7 +9,6 @@ package org.rocksdb;
* Java wrapper over native write_buffer_manager class
*/
public class WriteBufferManager extends RocksObject {
/**
* Construct a new instance of WriteBufferManager.
* <p>

View File

@ -52,9 +52,9 @@ public final class BytewiseComparator extends AbstractComparator {
return r;
}
@SuppressWarnings("PMD.EmptyControlStatement")
@Override
public void findShortestSeparator(final ByteBuffer start,
final ByteBuffer limit) {
public void findShortestSeparator(final ByteBuffer start, final ByteBuffer limit) {
// Find length of common prefix
final int minLength = Math.min(start.remaining(), limit.remaining());
int diffIndex = 0;

View File

@ -3,12 +3,20 @@ package org.rocksdb.util;
import java.io.File;
import java.io.IOException;
import java.util.Locale;
public class Environment {
private static String OS = System.getProperty("os.name").toLowerCase();
private static String ARCH = System.getProperty("os.arch").toLowerCase();
@SuppressWarnings("FieldMayBeFinal")
private static String OS = System.getProperty("os.name").toLowerCase(Locale.getDefault());
@SuppressWarnings("FieldMayBeFinal")
private static String ARCH = System.getProperty("os.arch").toLowerCase(Locale.getDefault());
@SuppressWarnings("FieldMayBeFinal")
private static String MUSL_ENVIRONMENT = System.getenv("ROCKSDB_MUSL_LIBC");
private static final String LIBC_MUSL_PREFIX = "libc.musl";
private static final String SPARCV9 = "sparcv9";
/**
* Will be lazily initialised by {@link #isMuslLibc()} instead of the previous static
* initialisation. The lazy initialisation prevents Windows from reporting suspicious behaviour of
@ -70,6 +78,7 @@ public class Environment {
*
* @return true if the environment has a musl libc, false otherwise.
*/
@SuppressWarnings("PMD.EmptyCatchBlock")
static boolean initIsMuslLibc() {
// consider explicit user setting from environment first
if ("true".equalsIgnoreCase(MUSL_ENVIRONMENT)) {
@ -114,7 +123,7 @@ public class Environment {
return false;
}
for (final File f : libFiles) {
if (f.getName().startsWith("libc.musl")) {
if (f.getName().startsWith(LIBC_MUSL_PREFIX)) {
return true;
}
}
@ -132,7 +141,7 @@ public class Environment {
}
public static boolean is64Bit() {
if (ARCH.indexOf("sparcv9") >= 0) {
if (ARCH.contains(SPARCV9)) {
return true;
}
return (ARCH.indexOf("64") > 0);

View File

@ -48,7 +48,7 @@ public final class IntComparator extends AbstractComparator {
*
* @return negative if a &lt; b, 0 if a == b, positive otherwise
*/
private final int compareIntKeys(final ByteBuffer a, final ByteBuffer b) {
private int compareIntKeys(final ByteBuffer a, final ByteBuffer b) {
final int iA = a.getInt();
final int iB = b.getInt();

View File

@ -38,9 +38,9 @@ public final class ReverseBytewiseComparator extends AbstractComparator {
return -BytewiseComparator._compare(a, b);
}
@SuppressWarnings("PMD.EmptyControlStatement")
@Override
public void findShortestSeparator(final ByteBuffer start,
final ByteBuffer limit) {
public void findShortestSeparator(final ByteBuffer start, final ByteBuffer limit) {
// Find length of common prefix
final int minLength = Math.min(start.remaining(), limit.remaining());
int diffIndex = 0;

View File

@ -886,6 +886,8 @@ public class DBOptionsTest {
wasCalled2.set(true);
}
}) {
assertThat(options.setListeners(null)).isEqualTo(options);
assertThat(options.listeners().size()).isEqualTo(0);
assertThat(options.setListeners(Arrays.asList(el1, el2))).isEqualTo(options);
final List<AbstractEventListener> listeners = options.listeners();
assertEquals(el1, listeners.get(0));

View File

@ -1346,6 +1346,25 @@ public class RocksDBTest {
}
}
@Test
public void enableAutoCompactionNull() 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(null);
} finally {
for (final ColumnFamilyHandle cfHandle : cfHandles) {
cfHandle.close();
}
}
}
}
}
@Test
public void numberLevels() throws RocksDBException {
try (final Options options = new Options().setCreateIfMissing(true)) {
@ -1579,9 +1598,43 @@ public class RocksDBTest {
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();
assertThat(range).isNotNull();
} finally {
for (final ColumnFamilyHandle cfHandle : cfHandles) {
cfHandle.close();
}
}
}
}
}
@Test
public void suggestCompactRangeCF() throws RocksDBException {
try (final DBOptions options =
new DBOptions().setCreateIfMissing(true).setCreateMissingColumnFamilies(true)) {
final List<ColumnFamilyDescriptor> cfDescs =
Arrays.asList(new ColumnFamilyDescriptor(RocksDB.DEFAULT_COLUMN_FAMILY),
new ColumnFamilyDescriptor("new_cf".getBytes(), new ColumnFamilyOptions()),
new ColumnFamilyDescriptor("new_cf2".getBytes(), new ColumnFamilyOptions()));
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));
db.put(cfHandles.get(1), "key1_new_cf".getBytes(UTF_8), "value1".getBytes(UTF_8));
db.put(cfHandles.get(1), "key2_new_cf".getBytes(UTF_8), "value2".getBytes(UTF_8));
db.put(cfHandles.get(1), "key3_new_cf".getBytes(UTF_8), "value3".getBytes(UTF_8));
try {
final Range range = db.suggestCompactRange(cfHandles.get(0));
assertThat(range).isNotNull();
final Range rangeCF = db.suggestCompactRange(cfHandles.get(1));
assertThat(rangeCF).isNotNull();
final Range rangeCFEmpty = db.suggestCompactRange(cfHandles.get(2));
assertThat(rangeCFEmpty).isNotNull();
} finally {
for (final ColumnFamilyHandle cfHandle : cfHandles) {
cfHandle.close();

View File

@ -5,7 +5,6 @@
package org.rocksdb.util;
import static org.assertj.core.api.Assertions.assertThat;
import static org.hamcrest.Matchers.is;
import java.lang.reflect.Field;
import org.junit.AfterClass;
@ -13,11 +12,11 @@ import org.junit.BeforeClass;
import org.junit.Test;
public class EnvironmentTest {
private final static String ARCH_FIELD_NAME = "ARCH";
private final static String OS_FIELD_NAME = "OS";
private static final String ARCH_FIELD_NAME = "ARCH";
private static final String OS_FIELD_NAME = "OS";
private final static String MUSL_ENVIRONMENT_FIELD_NAME = "MUSL_ENVIRONMENT";
private final static String MUSL_LIBC_FIELD_NAME = "MUSL_LIBC";
private static final String MUSL_ENVIRONMENT_FIELD_NAME = "MUSL_ENVIRONMENT";
private static final String MUSL_LIBC_FIELD_NAME = "MUSL_LIBC";
private static String INITIAL_OS;
private static String INITIAL_ARCH;
@ -255,8 +254,7 @@ public class EnvironmentTest {
assertThat(Environment.initIsMuslLibc()).isFalse();
}
private void setEnvironmentClassFields(String osName,
String osArch) {
private void setEnvironmentClassFields(final String osName, final String osArch) {
setEnvironmentClassField(OS_FIELD_NAME, osName);
setEnvironmentClassField(ARCH_FIELD_NAME, osArch);
}
@ -270,7 +268,7 @@ public class EnvironmentTest {
}
@SuppressWarnings("unchecked")
private static <T> T getEnvironmentClassField(String fieldName) {
private static <T> T getEnvironmentClassField(final String fieldName) {
final Field field;
try {
field = Environment.class.getDeclaredField(fieldName);
@ -286,7 +284,7 @@ public class EnvironmentTest {
}
}
private static void setEnvironmentClassField(String fieldName, Object value) {
private static void setEnvironmentClassField(final String fieldName, final Object value) {
final Field field;
try {
field = Environment.class.getDeclaredField(fieldName);