Compare commits

..

1 Commits

Author SHA1 Message Date
Peter Dillinger 59852b5e71 TESTING ppc build based on known good base revision
This commit is actually a cherry-pick of #6643 but for testing purposes
only (see Issue #6653)
2020-04-06 14:36:41 -07:00
564 changed files with 10963 additions and 41437 deletions
-54
View File
@@ -1,54 +0,0 @@
#! /bin/bash
# Work around issue with parallel make output causing random error, as in
# make[1]: write error: stdout
# Probably due to a kernel bug:
# https://bugs.launchpad.net/ubuntu/+source/linux-signed/+bug/1814393
# Seems to affect image ubuntu-1604:201903-01 and ubuntu-1604:202004-01
cd "$(dirname $0)"
if [ ! -x cat_ignore_eagain.out ]; then
cc -x c -o cat_ignore_eagain.out - << EOF
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
int main() {
int n, m, p;
char buf[1024];
for (;;) {
n = read(STDIN_FILENO, buf, 1024);
if (n > 0 && n <= 1024) {
for (m = 0; m < n;) {
p = write(STDOUT_FILENO, buf + m, n - m);
if (p < 0) {
if (errno == EAGAIN) {
// ignore but pause a bit
usleep(100);
} else {
perror("write failed");
return 42;
}
} else {
m += p;
}
}
} else if (n < 0) {
if (errno == EAGAIN) {
// ignore but pause a bit
usleep(100);
} else {
// Some non-ignorable error
perror("read failed");
return 43;
}
} else {
// EOF
return 0;
}
}
}
EOF
fi
exec ./cat_ignore_eagain.out
+6 -267
View File
@@ -6,191 +6,25 @@ orbs:
executors:
windows-2xlarge:
machine:
image: 'windows-server-2019-vs2019:201908-06'
image: 'windows-server-2019-vs2019:stable'
resource_class: windows.2xlarge
shell: bash.exe
jobs:
build-linux:
machine:
image: ubuntu-1604:201903-01
resource_class: 2xlarge
steps:
- checkout # check out the code in the project directory
- run: pyenv global 3.5.2
- run: sudo apt-get update -y && sudo apt-get install -y libgflags-dev
- run: SKIP_FORMAT_BUCK_CHECKS=1 PRINT_PARALLEL_OUTPUTS=1 GTEST_THROW_ON_FAILURE=0 GTEST_OUTPUT="xml:/tmp/test-results/" make V=1 J=32 -j32 check | .circleci/cat_ignore_eagain
- store_test_results:
path: /tmp/test-results
build-linux-shared_lib-alt_namespace-status_checked:
machine:
image: ubuntu-1604:201903-01
resource_class: 2xlarge
steps:
- checkout # check out the code in the project directory
- run: pyenv global 3.5.2
- run: sudo apt-get update -y && sudo apt-get install -y libgflags-dev
- run: SKIP_FORMAT_BUCK_CHECKS=1 PRINT_PARALLEL_OUTPUTS=1 ASSERT_STATUS_CHECKED=1 LIB_MODE=shared OPT="-DROCKSDB_NAMESPACE=alternative_rocksdb_ns" GTEST_THROW_ON_FAILURE=0 GTEST_OUTPUT="xml:/tmp/test-results/" make V=1 -j32 all check_some | .circleci/cat_ignore_eagain
- store_test_results:
path: /tmp/test-results
build-linux-release:
machine:
image: ubuntu-1604:201903-01
resource_class: 2xlarge
steps:
- checkout # check out the code in the project directory
- run: make V=1 -j32 release | .circleci/cat_ignore_eagain
- run: if ./db_stress --version; then false; else true; fi # ensure without gflags
- run: sudo apt-get update -y && sudo apt-get install -y libgflags-dev
- run: make V=1 -j32 release | .circleci/cat_ignore_eagain
- run: ./db_stress --version # ensure with gflags
build-linux-lite:
machine:
image: ubuntu-1604:201903-01
resource_class: 2xlarge
steps:
- checkout # check out the code in the project directory
- run: pyenv global 3.5.2
- run: sudo apt-get update -y && sudo apt-get install -y libgflags-dev
- run: SKIP_FORMAT_BUCK_CHECKS=1 PRINT_PARALLEL_OUTPUTS=1 LITE=1 GTEST_THROW_ON_FAILURE=0 GTEST_OUTPUT="xml:/tmp/test-results/" make V=1 J=32 -j32 check | .circleci/cat_ignore_eagain
- store_test_results:
path: /tmp/test-results
build-linux-lite-release:
machine:
image: ubuntu-1604:201903-01
resource_class: large
steps:
- checkout # check out the code in the project directory
- run: LITE=1 make V=1 -j32 release | .circleci/cat_ignore_eagain
- run: if ./db_stress --version; then false; else true; fi # ensure without gflags
- run: sudo apt-get update -y && sudo apt-get install -y libgflags-dev
- run: LITE=1 make V=1 -j32 release | .circleci/cat_ignore_eagain
- run: ./db_stress --version # ensure with gflags
build-linux-clang-no-test:
machine:
image: ubuntu-1604:201903-01
resource_class: 2xlarge
steps:
- checkout # check out the code in the project directory
- run: sudo apt-get update -y && sudo apt-get install -y clang libgflags-dev
- run: CC=clang CXX=clang++ USE_CLANG=1 PORTABLE=1 make V=1 -j32 all | .circleci/cat_ignore_eagain
build-linux-clang10-no-test:
machine:
image: ubuntu-1604:201903-01
resource_class: 2xlarge
steps:
- checkout # check out the code in the project directory
- run: echo "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main" | sudo tee -a /etc/apt/sources.list
- run: echo "deb-src http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main" | sudo tee -a /etc/apt/sources.list
- run: sudo apt-get update -y && sudo apt-get install -y clang-10 libgflags-dev
- run: CC=clang-10 CXX=clang++-10 ROCKSDB_DISABLE_ALIGNED_NEW=1 USE_CLANG=1 make V=1 -j32 all | .circleci/cat_ignore_eagain # aligned new doesn't work for reason we haven't figured out
build-linux-clang10-asan:
machine:
image: ubuntu-1604:201903-01
resource_class: 2xlarge
steps:
- checkout # check out the code in the project directory
- run: pyenv global 3.5.2
- run: echo "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main" | sudo tee -a /etc/apt/sources.list
- run: echo "deb-src http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main" | sudo tee -a /etc/apt/sources.list
- run: sudo apt-get update -y && sudo apt-get install -y clang-10 libgflags-dev
- run: SKIP_FORMAT_BUCK_CHECKS=1 COMPILE_WITH_ASAN=1 CC=clang-10 CXX=clang++-10 ROCKSDB_DISABLE_ALIGNED_NEW=1 USE_CLANG=1 PRINT_PARALLEL_OUTPUTS=1 GTEST_THROW_ON_FAILURE=0 GTEST_OUTPUT="xml:/tmp/test-results/" make V=1 -j32 check | .circleci/cat_ignore_eagain # aligned new doesn't work for reason we haven't figured out
- store_test_results:
path: /tmp/test-results
build-linux-clang10-mini-tsan:
machine:
image: ubuntu-1604:201903-01
resource_class: 2xlarge
steps:
- checkout # check out the code in the project directory
- run: pyenv global 3.5.2
- run: echo "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main" | sudo tee -a /etc/apt/sources.list
- run: echo "deb-src http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main" | sudo tee -a /etc/apt/sources.list
- run: sudo apt-get update -y && sudo apt-get install -y clang-10 libgflags-dev
- run: SKIP_FORMAT_BUCK_CHECKS=1 COMPILE_WITH_TSAN=1 CC=clang-10 CXX=clang++-10 ROCKSDB_DISABLE_ALIGNED_NEW=1 USE_CLANG=1 PRINT_PARALLEL_OUTPUTS=1 EXCLUDE_TESTS_REGEX="TransactionStressTest|SnapshotConcurrentAccess|SeqAdvanceConcurrent|DeadlockStress|MultiThreadedDBTest.MultiThreaded|WriteUnpreparedStressTest.ReadYourOwnWriteStress|DBAsBaseDB/TransactionStressTest|FlushCloseWALFiles|BackgroundPurgeCFDropTest" GTEST_THROW_ON_FAILURE=0 GTEST_OUTPUT="xml:/tmp/test-results/" make V=1 -j32 check | .circleci/cat_ignore_eagain # aligned new doesn't work for reason we haven't figured out. Exclude FlushCloseWALFiles and BackgroundPurgeCFDropTest for occasional failures.
- store_test_results:
path: /tmp/test-results
build-linux-clang10-ubsan:
machine:
image: ubuntu-1604:201903-01
resource_class: 2xlarge
steps:
- checkout # check out the code in the project directory
- run: pyenv global 3.5.2
- run: echo "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main" | sudo tee -a /etc/apt/sources.list
- run: echo "deb-src http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main" | sudo tee -a /etc/apt/sources.list
- run: sudo apt-get update -y && sudo apt-get install -y clang-10 libgflags-dev
- run: SKIP_FORMAT_BUCK_CHECKS=1 COMPILE_WITH_UBSAN=1 OPT="-fsanitize-blacklist=.circleci/ubsan_suppression_list.txt" CC=clang-10 CXX=clang++-10 ROCKSDB_DISABLE_ALIGNED_NEW=1 USE_CLANG=1 PRINT_PARALLEL_OUTPUTS=1 make V=1 -j32 ubsan_check | .circleci/cat_ignore_eagain # aligned new doesn't work for reason we haven't figured out
build-linux-clang10-clang-analyze:
machine:
image: ubuntu-1604:201903-01
resource_class: 2xlarge
steps:
- checkout # check out the code in the project directory
- run: pyenv global 3.5.2
- run: echo "deb http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main" | sudo tee -a /etc/apt/sources.list
- run: echo "deb-src http://apt.llvm.org/xenial/ llvm-toolchain-xenial-10 main" | sudo tee -a /etc/apt/sources.list
- run: sudo apt-get update -y && sudo apt-get install -y clang-10 libgflags-dev clang-tools-10
- run: SKIP_FORMAT_BUCK_CHECKS=1 CC=clang-10 CXX=clang++-10 ROCKSDB_DISABLE_ALIGNED_NEW=1 CLANG_ANALYZER="/usr/bin/clang++-10" CLANG_SCAN_BUILD=scan-build-10 USE_CLANG=1 PRINT_PARALLEL_OUTPUTS=1 make V=1 -j32 analyze | .circleci/cat_ignore_eagain # aligned new doesn't work for reason we haven't figured out. For unknown, reason passing "clang++-10" as CLANG_ANALYZER doesn't work, and we need a full path.
build-linux-cmake:
machine:
image: ubuntu-1604:201903-01
resource_class: 2xlarge
steps:
- checkout # check out the code in the project directory
- run: (mkdir build && cd build && cmake -DWITH_GFLAGS=0 .. && make V=1 -j32) | .circleci/cat_ignore_eagain
build-linux-unity:
docker: # executor type
- image: gcc:latest
resource_class: xlarge
steps:
- checkout # check out the code in the project directory
- run: apt-get update -y && apt-get install -y libgflags-dev
- run: TEST_TMPDIR=/dev/shm && make V=1 -j16 unity_test | .circleci/cat_ignore_eagain
build-windows:
build:
executor: windows-2xlarge
parameters:
extra_cmake_opt:
default: ""
type: string
vs_year:
default: "2019"
type: string
cmake_generator:
default: "Visual Studio 16 2019"
type: string
environment:
THIRDPARTY_HOME: C:/Users/circleci/thirdparty
CMAKE_HOME: C:/Users/circleci/thirdparty/cmake-3.16.4-win64-x64
CMAKE_BIN: C:/Users/circleci/thirdparty/cmake-3.16.4-win64-x64/bin/cmake.exe
CMAKE_GENERATOR: Visual Studio 16 2019
SNAPPY_HOME: C:/Users/circleci/thirdparty/snappy-1.1.7
SNAPPY_INCLUDE: C:/Users/circleci/thirdparty/snappy-1.1.7;C:/Users/circleci/thirdparty/snappy-1.1.7/build
SNAPPY_LIB_DEBUG: C:/Users/circleci/thirdparty/snappy-1.1.7/build/Debug/snappy.lib
VS_YEAR: <<parameters.vs_year>>
CMAKE_GENERATOR: <<parameters.cmake_generator>>
steps:
- checkout
- run:
name: "Setup VS"
command: |
if [[ "${VS_YEAR}" == "2017" ]]; then
powershell .circleci/vs2017_install.ps1
elif [[ "${VS_YEAR}" == "2015" ]]; then
powershell .circleci/vs2015_install.ps1
fi
- run:
name: "Install thirdparty dependencies"
command: |
@@ -212,7 +46,7 @@ jobs:
command: |
mkdir build
cd build
${CMAKE_BIN} -G "${CMAKE_GENERATOR}" -DCMAKE_BUILD_TYPE=Debug -DOPTDBG=1 -DPORTABLE=1 -DSNAPPY=1 -DJNI=1 << parameters.extra_cmake_opt >> ..
${CMAKE_BIN} -G "${CMAKE_GENERATOR}" -DCMAKE_BUILD_TYPE=Debug -DOPTDBG=1 -DPORTABLE=1 -DSNAPPY=1 -DJNI=1 ..
cd ..
msbuild.exe build/rocksdb.sln -maxCpuCount -property:Configuration=Debug -property:Platform=x64
- run:
@@ -220,98 +54,3 @@ jobs:
shell: powershell.exe
command: |
build_tools\run_ci_db_test.ps1 -SuiteRun db_basic_test,db_test,db_test2,env_basic_test,env_test,db_merge_operand_test -Concurrency 16
build-linux-java:
machine:
image: ubuntu-1604:201903-01
resource_class: 2xlarge
steps:
- checkout
- run: pyenv global 3.5.2
- run: sudo apt-get update -y && sudo apt-get install -y libgflags-dev
- run:
name: "Build RocksDBJava"
command: |
export JAVA_HOME=/usr/lib/jvm/jdk1.8.0
export PATH=$JAVA_HOME/bin:$PATH
echo "JAVA_HOME=${JAVA_HOME}"
which java && java -version
which javac && javac -version
SKIP_FORMAT_BUCK_CHECKS=1 PRINT_PARALLEL_OUTPUTS=1 make V=1 J=32 -j32 rocksdbjava jtest | .circleci/cat_ignore_eagain
build-examples:
machine:
image: ubuntu-1604:201903-01
resource_class: medium
steps:
- checkout # check out the code in the project directory
- run: pyenv global 3.5.2
- run: sudo apt-get update -y && sudo apt-get install -y libgflags-dev
- run:
name: "Build examples"
command: |
OPT=-DTRAVIS V=1 make -j4 static_lib && cd examples && make -j4 | ../.circleci/cat_ignore_eagain
workflows:
build-linux:
jobs:
- build-linux
build-linux-shared_lib-alt_namespace-status_checked:
jobs:
- build-linux-shared_lib-alt_namespace-status_checked
build-linux-lite:
jobs:
- build-linux-lite
build-linux-release:
jobs:
- build-linux-release
build-linux-lite-release:
jobs:
- build-linux-lite-release
build-linux-clang-no-test:
jobs:
- build-linux-clang-no-test
build-linux-clang10-no-test:
jobs:
- build-linux-clang10-no-test
build-linux-clang10-asan:
jobs:
- build-linux-clang10-asan
build-linux-clang10-mini-tsan:
jobs:
- build-linux-clang10-mini-tsan
build-linux-clang10-ubsan:
jobs:
- build-linux-clang10-ubsan
build-linux-clang10-clang-analyze:
jobs:
- build-linux-clang10-clang-analyze
build-linux-cmake:
jobs:
- build-linux-cmake
build-linux-unity:
jobs:
- build-linux-unity
build-windows:
jobs:
- build-windows
build-windows-vs2017:
jobs:
- build-windows:
vs_year: "2017"
cmake_generator: "Visual Studio 15 Win64"
build-windows-vs2015:
jobs:
- build-windows:
vs_year: "2015"
cmake_generator: "Visual Studio 14 Win64"
build-windows-cxx20:
jobs:
- build-windows:
extra_cmake_opt: -DCMAKE_CXX_STANDARD=20
build-java:
jobs:
- build-linux-java
build-examples:
jobs:
- build-examples
-6
View File
@@ -1,6 +0,0 @@
# Supress UBSAN warnings related to stl_tree.h, e.g.
# UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_tree.h:1505:43 in
# /usr/bin/../lib/gcc/x86_64-linux-gnu/5.4.0/../../../../include/c++/5.4.0/bits/stl_tree.h:1505:43:
# runtime error: upcast of address 0x000001fa8820 with insufficient space for an object of type
# 'std::_Rb_tree_node<std::pair<const std::__cxx11::basic_string<char>, rocksdb::(anonymous namespace)::LockHoldingInfo> >'
src:*bits/stl_tree.h
-23
View File
@@ -1,23 +0,0 @@
$VS_DOWNLOAD_LINK = "https://go.microsoft.com/fwlink/?LinkId=691126"
$COLLECT_DOWNLOAD_LINK = "https://aka.ms/vscollect.exe"
curl.exe --retry 3 -kL $VS_DOWNLOAD_LINK --output vs_installer.exe
if ($LASTEXITCODE -ne 0) {
echo "Download of the VS 2015 installer failed"
exit 1
}
$VS_INSTALL_ARGS = @("/Quiet", "/NoRestart")
$process = Start-Process "${PWD}\vs_installer.exe" -ArgumentList $VS_INSTALL_ARGS -NoNewWindow -Wait -PassThru
Remove-Item -Path vs_installer.exe -Force
$exitCode = $process.ExitCode
if (($exitCode -ne 0) -and ($exitCode -ne 3010)) {
echo "VS 2017 installer exited with code $exitCode, which should be one of [0, 3010]."
curl.exe --retry 3 -kL $COLLECT_DOWNLOAD_LINK --output Collect.exe
if ($LASTEXITCODE -ne 0) {
echo "Download of the VS Collect tool failed."
exit 1
}
Start-Process "${PWD}\Collect.exe" -NoNewWindow -Wait -PassThru
New-Item -Path "C:\w\build-results" -ItemType "directory" -Force
Copy-Item -Path "C:\Users\circleci\AppData\Local\Temp\vslogs.zip" -Destination "C:\w\build-results\"
exit 1
}
-34
View File
@@ -1,34 +0,0 @@
$VS_DOWNLOAD_LINK = "https://aka.ms/vs/15/release/vs_buildtools.exe"
$COLLECT_DOWNLOAD_LINK = "https://aka.ms/vscollect.exe"
$VS_INSTALL_ARGS = @("--nocache","--quiet","--wait", "--add Microsoft.VisualStudio.Workload.VCTools",
"--add Microsoft.VisualStudio.Component.VC.Tools.14.13",
"--add Microsoft.Component.MSBuild",
"--add Microsoft.VisualStudio.Component.Roslyn.Compiler",
"--add Microsoft.VisualStudio.Component.TextTemplating",
"--add Microsoft.VisualStudio.Component.VC.CoreIde",
"--add Microsoft.VisualStudio.Component.VC.Redist.14.Latest",
"--add Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Core",
"--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64",
"--add Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Win81")
curl.exe --retry 3 -kL $VS_DOWNLOAD_LINK --output vs_installer.exe
if ($LASTEXITCODE -ne 0) {
echo "Download of the VS 2017 installer failed"
exit 1
}
$process = Start-Process "${PWD}\vs_installer.exe" -ArgumentList $VS_INSTALL_ARGS -NoNewWindow -Wait -PassThru
Remove-Item -Path vs_installer.exe -Force
$exitCode = $process.ExitCode
if (($exitCode -ne 0) -and ($exitCode -ne 3010)) {
echo "VS 2017 installer exited with code $exitCode, which should be one of [0, 3010]."
curl.exe --retry 3 -kL $COLLECT_DOWNLOAD_LINK --output Collect.exe
if ($LASTEXITCODE -ne 0) {
echo "Download of the VS Collect tool failed."
exit 1
}
Start-Process "${PWD}\Collect.exe" -NoNewWindow -Wait -PassThru
New-Item -Path "C:\w\build-results" -ItemType "directory" -Force
Copy-Item -Path "C:\Users\circleci\AppData\Local\Temp\vslogs.zip" -Destination "C:\w\build-results\"
exit 1
}
-41
View File
@@ -1,41 +0,0 @@
name: Check buck targets and code format
on: [push, pull_request]
jobs:
check:
name: Check TARGETS file and code format
runs-on: ubuntu-latest
steps:
- name: Checkout feature branch
uses: actions/checkout@v2
with:
fetch-depth: 0
- name: Fetch from upstream
run: |
git remote add upstream https://github.com/facebook/rocksdb.git && git fetch upstream
- name: Where am I
run: |
echo git status && git status
echo "git remote -v" && git remote -v
echo git branch && git branch
- name: Setup Python
uses: actions/setup-python@v1
- name: Install Dependencies
run: python -m pip install --upgrade pip
- name: Install argparse
run: pip install argparse
- name: Download clang-format-diff.py
uses: wei/wget@v1
with:
args: https://raw.githubusercontent.com/llvm-mirror/clang/master/tools/clang-format/clang-format-diff.py
- name: Check format
run: VERBOSE_CHECK=1 make check-format
- name: Compare buckify output
run: make check-buck-targets
-2
View File
@@ -85,5 +85,3 @@ buckifier/*.pyc
buckifier/__pycache__
compile_commands.json
clang-format-diff.py
.py3/
+34 -120
View File
@@ -50,24 +50,14 @@ env:
- JOB_NAME=examples # 5-7 minutes
- JOB_NAME=cmake # 3-5 minutes
- JOB_NAME=cmake-gcc8 # 3-5 minutes
- JOB_NAME=cmake-gcc9 # 3-5 minutes
- JOB_NAME=cmake-gcc9-c++20 # 3-5 minutes
- JOB_NAME=cmake-mingw # 3 minutes
- JOB_NAME=make-gcc4.8
- JOB_NAME=status_checked
matrix:
exclude:
- os: osx
env: JOB_NAME=cmake-gcc8
- os: osx
env: JOB_NAME=cmake-gcc9
- os: osx
env: JOB_NAME=cmake-gcc9-c++20
- os: osx
env: JOB_NAME=cmake-mingw
- os: osx
env: JOB_NAME=make-gcc4.8
- os: osx
arch: ppc64le
- os: osx
@@ -75,149 +65,88 @@ matrix:
- os : linux
arch: arm64
env: JOB_NAME=cmake-mingw
- os : linux
arch: arm64
env: JOB_NAME=make-gcc4.8
- os: linux
arch: ppc64le
env: JOB_NAME=cmake-mingw
- os: linux
arch: ppc64le
env: JOB_NAME=make-gcc4.8
- os: linux
compiler: clang
# Exclude all but most unique cmake variants for pull requests, but build all in branches
- if: type = pull_request
os : linux
arch: amd64
env: JOB_NAME=cmake
- if: type = pull_request
os : linux
arch: amd64
env: JOB_NAME=cmake-gcc8
- if: type = pull_request
os : linux
arch: amd64
env: JOB_NAME=cmake-gcc9
# Exclude most osx, arm64 and ppc64le tests for pull requests, but build in branches
# Temporarily disable ppc64le unit tests in PRs until Travis gets its act together (#6653)
- if: type = pull_request
os: linux
arch: ppc64le
env: TEST_GROUP=platform_dependent
# NB: the cmake build is a partial java test
- if: type = pull_request
- if: type != pull_request
os: osx
env: TEST_GROUP=1
- if: type = pull_request
- if: type != pull_request
os : linux
arch: arm64
env: TEST_GROUP=1
- if: type = pull_request
- if: type != pull_request
os: linux
arch: ppc64le
env: TEST_GROUP=1
- if: type = pull_request
- if: type != pull_request
os: osx
env: TEST_GROUP=2
- if: type = pull_request
- if: type != pull_request
os : linux
arch: arm64
env: TEST_GROUP=2
- if: type = pull_request
- if: type != pull_request
os: linux
arch: ppc64le
env: TEST_GROUP=2
- if: type = pull_request
- if: type != pull_request
os: osx
env: TEST_GROUP=3
- if: type = pull_request
- if: type != pull_request
os : linux
arch: arm64
env: TEST_GROUP=3
- if: type = pull_request
- if: type != pull_request
os: linux
arch: ppc64le
env: TEST_GROUP=3
- if: type = pull_request
- if: type != pull_request
os: osx
env: TEST_GROUP=4
- if: type = pull_request
- if: type != pull_request
os : linux
arch: arm64
env: TEST_GROUP=4
- if: type = pull_request
- if: type != pull_request
os: linux
arch: ppc64le
env: TEST_GROUP=4
- if: type = pull_request AND commit_message !~ /java/
os : osx
env: JOB_NAME=java_test
- if: type = pull_request AND commit_message !~ /java/
- if: type != pull_request
os : linux
arch: arm64
env: JOB_NAME=java_test
- if: type = pull_request AND commit_message !~ /java/
env: JOB_NAME=java-test
- if: type != pull_request
os: linux
arch: ppc64le
env: JOB_NAME=java_test
- if: type = pull_request
os : osx
env: JOB_NAME=lite_build
- if: type = pull_request
env: JOB_NAME=java-test
- if: type != pull_request
os : linux
arch: arm64
env: JOB_NAME=lite_build
- if: type = pull_request
env: JOB_NAME=lite-build
- if: type != pull_request
os: linux
arch: ppc64le
env: JOB_NAME=lite_build
- if: type = pull_request
os : osx
env: JOB_NAME=examples
- if: type = pull_request
env: JOB_NAME=lite-build
- if: type != pull_request
os : linux
arch: arm64
env: JOB_NAME=examples
- if: type = pull_request
- if: type != pull_request
os: linux
arch: ppc64le
env: JOB_NAME=examples
- if: type = pull_request
- if: type != pull_request
os : linux
arch: arm64
env: JOB_NAME=cmake-gcc8
- if: type = pull_request
- if: type != pull_request
os: linux
arch: ppc64le
env: JOB_NAME=cmake-gcc8
- if: type = pull_request
os : linux
arch: arm64
env: JOB_NAME=cmake-gcc9
- if: type = pull_request
os: linux
arch: ppc64le
env: JOB_NAME=cmake-gcc9
- if: type = pull_request
os : linux
arch: arm64
env: JOB_NAME=cmake-gcc9-c++20
- if: type = pull_request
os: linux
arch: ppc64le
env: JOB_NAME=cmake-gcc9-c++20
- if: type = pull_request
os : osx
env: JOB_NAME=status_checked
- if: type = pull_request
os : linux
arch: arm64
env: JOB_NAME=status_checked
- if: type = pull_request
os: linux
arch: ppc64le
env: JOB_NAME=status_checked
install:
- if [ "${TRAVIS_OS_NAME}" == osx ]; then
@@ -227,20 +156,17 @@ install:
sudo apt-get install -y g++-8;
CC=gcc-8 && CXX=g++-8;
fi
- if [ "${JOB_NAME}" == cmake-gcc9 ] || [ "${JOB_NAME}" == cmake-gcc9-c++20 ]; then
sudo apt-get install -y g++-9;
CC=gcc-9 && CXX=g++-9;
fi
- if [ "${JOB_NAME}" == cmake-mingw ]; then
sudo apt-get install -y mingw-w64 ;
fi
- if [ "${JOB_NAME}" == make-gcc4.8 ]; then
sudo apt-get install -y g++-4.8 ;
CC=gcc-4.8 && CXX=g++-4.8;
fi
- if [[ "${JOB_NAME}" == cmake* ]] && [ "${TRAVIS_OS_NAME}" == linux ]; then
sudo snap install cmake --beta --classic;
export PATH=/snap/bin:$PATH;
CMAKE_DIST_URL="https://rocksdb-deps.s3-us-west-2.amazonaws.com/cmake/cmake-3.14.5-Linux-$(uname -m).tar.bz2";
TAR_OPT="--strip-components=1 -xj";
if [ "aarch64" == "$(uname -m)" ]; then
sudo apt-get install -y libuv1 librhash0;
sudo apt-get upgrade -y libstdc++6;
fi;
mkdir cmake-dist && curl --silent --fail --show-error --location "${CMAKE_DIST_URL}" | tar -C cmake-dist ${TAR_OPT} && export PATH=$PWD/cmake-dist/bin:$PATH;
fi
- |
if [[ "${JOB_NAME}" == java_test || "${JOB_NAME}" == cmake* ]]; then
@@ -278,7 +204,7 @@ script:
OPT="-DTRAVIS -DROCKSDB_NAMESPACE=alternative_rocksdb_ns" V=1 make -j4 tools && OPT="-DTRAVIS -DROCKSDB_NAMESPACE=alternative_rocksdb_ns" V=1 ROCKSDBTESTS_START=db_iter_test ROCKSDBTESTS_END=options_file_test make -j4 check_some
;;
3)
OPT=-DTRAVIS LIB_MODE=shared V=1 ROCKSDBTESTS_START=options_file_test ROCKSDBTESTS_END=write_prepared_transaction_test make -j4 check_some
OPT=-DTRAVIS V=1 ROCKSDBTESTS_START=options_file_test ROCKSDBTESTS_END=write_prepared_transaction_test make -j4 check_some
;;
4)
OPT=-DTRAVIS V=1 ROCKSDBTESTS_START=write_prepared_transaction_test make -j4 check_some
@@ -289,7 +215,7 @@ script:
OPT=-DTRAVIS V=1 make rocksdbjava jtest
;;
lite_build)
OPT='-DTRAVIS -DROCKSDB_LITE' V=1 make -j4 all
OPT='-DTRAVIS -DROCKSDB_LITE' V=1 make -j4 static_lib tools
;;
examples)
OPT=-DTRAVIS V=1 make -j4 static_lib && cd examples && make -j4
@@ -299,19 +225,7 @@ script:
mkdir build && cd build && cmake -DJNI=1 -DWITH_GFLAGS=OFF .. -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++ -DCMAKE_SYSTEM_NAME=Windows && make -j4 rocksdb rocksdbjni
;;
cmake*)
case $JOB_NAME in
*-c++20)
OPT=-DCMAKE_CXX_STANDARD=20
;;
esac
mkdir build && cd build && cmake -DCMAKE_BUILD_TYPE=Release -DWITH_TESTS=0 -DWITH_GFLAGS=0 -DWITH_BENCHMARK_TOOLS=0 -DWITH_TOOLS=0 -DWITH_CORE_TOOLS=1 .. && make -j4 && cd .. && rm -rf build && mkdir build && cd build && cmake -DJNI=1 .. -DCMAKE_BUILD_TYPE=Release $OPT && make -j4 rocksdb rocksdbjni
;;
make-gcc4.8)
OPT=-DTRAVIS V=1 SKIP_LINK=1 make -j4 all && [ "Linking broken because libgflags compiled with newer ABI" ]
;;
status_checked)
OPT=-DTRAVIS V=1 ASSERT_STATUS_CHECKED=1 make -j4 check_some
mkdir build && cd build && cmake -DJNI=1 .. -DCMAKE_BUILD_TYPE=Release && make -j4 rocksdb rocksdbjni
;;
esac
notifications:
+44 -118
View File
@@ -83,10 +83,6 @@ else()
option(WITH_FOLLY_DISTRIBUTED_MUTEX "build with folly::DistributedMutex" OFF)
endif()
if( NOT DEFINED CMAKE_CXX_STANDARD )
set(CMAKE_CXX_STANDARD 11)
endif()
include(CMakeDependentOption)
CMAKE_DEPENDENT_OPTION(WITH_GFLAGS "build with GFlags" ON
"NOT MSVC;NOT MINGW" OFF)
@@ -95,7 +91,7 @@ if(MSVC)
option(WITH_XPRESS "build with windows built in compression" OFF)
include(${CMAKE_CURRENT_SOURCE_DIR}/thirdparty.inc)
else()
if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD" AND NOT CMAKE_SYSTEM_NAME MATCHES "kFreeBSD")
if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
# FreeBSD has jemalloc as default malloc
# but it does not have all the jemalloc files in include/...
set(WITH_JEMALLOC ON)
@@ -107,35 +103,18 @@ else()
endif()
endif()
set(GFLAGS_LIB)
# No config file for this
if(WITH_GFLAGS)
# Config with namespace available since gflags 2.2.2
option(GFLAGS_USE_TARGET_NAMESPACE "Use gflags import target with namespace." ON)
find_package(gflags CONFIG)
if(gflags_FOUND)
if(TARGET ${GFLAGS_TARGET})
# Config with GFLAGS_TARGET available since gflags 2.2.0
set(GFLAGS_LIB ${GFLAGS_TARGET})
else()
# Config with GFLAGS_LIBRARIES available since gflags 2.1.0
set(GFLAGS_LIB ${GFLAGS_LIBRARIES})
endif()
else()
find_package(gflags REQUIRED)
set(GFLAGS_LIB gflags::gflags)
endif()
include_directories(${GFLAGS_INCLUDE_DIR})
list(APPEND THIRDPARTY_LIBS ${GFLAGS_LIB})
find_package(gflags REQUIRED)
add_definitions(-DGFLAGS=1)
include_directories(${gflags_INCLUDE_DIR})
list(APPEND THIRDPARTY_LIBS gflags::gflags)
endif()
if(WITH_SNAPPY)
find_package(Snappy CONFIG)
if(NOT Snappy_FOUND)
find_package(Snappy REQUIRED)
endif()
find_package(snappy REQUIRED)
add_definitions(-DSNAPPY)
list(APPEND THIRDPARTY_LIBS Snappy::snappy)
list(APPEND THIRDPARTY_LIBS snappy::snappy)
endif()
if(WITH_ZLIB)
@@ -212,6 +191,7 @@ else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-format -fno-asynchronous-unwind-tables")
add_definitions(-D_POSIX_C_SOURCE=1)
endif()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-omit-frame-pointer")
include(CheckCXXCompilerFlag)
@@ -274,7 +254,6 @@ include(CheckCXXSourceCompiles)
if(NOT MSVC)
set(CMAKE_REQUIRED_FLAGS "-msse4.2 -mpclmul")
endif()
CHECK_CXX_SOURCE_COMPILES("
#include <cstdint>
#include <nmmintrin.h>
@@ -407,15 +386,7 @@ if(MSVC)
message(STATUS "Debug optimization is enabled")
set(CMAKE_CXX_FLAGS_DEBUG "/Oxt")
else()
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /RTC1")
# Minimal Build is deprecated after MSVC 2015
if( MSVC_VERSION GREATER 1900 )
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Gm-")
else()
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Gm")
endif()
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /Od /RTC1 /Gm")
endif()
if(WITH_RUNTIME_DEBUG)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /${RUNTIME_LIBRARY}d")
@@ -451,8 +422,6 @@ elseif(CMAKE_SYSTEM_NAME MATCHES "Linux")
add_definitions(-DOS_LINUX)
elseif(CMAKE_SYSTEM_NAME MATCHES "SunOS")
add_definitions(-DOS_SOLARIS)
elseif(CMAKE_SYSTEM_NAME MATCHES "kFreeBSD")
add_definitions(-DOS_GNU_KFREEBSD)
elseif(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
add_definitions(-DOS_FREEBSD)
elseif(CMAKE_SYSTEM_NAME MATCHES "NetBSD")
@@ -511,11 +480,7 @@ if(HAVE_PTHREAD_MUTEX_ADAPTIVE_NP)
endif()
include(CheckCXXSymbolExists)
if(CMAKE_SYSTEM_NAME MATCHES "^FreeBSD")
check_cxx_symbol_exists(malloc_usable_size malloc_np.h HAVE_MALLOC_USABLE_SIZE)
else()
check_cxx_symbol_exists(malloc_usable_size malloc.h HAVE_MALLOC_USABLE_SIZE)
endif()
check_cxx_symbol_exists(malloc_usable_size malloc.h HAVE_MALLOC_USABLE_SIZE)
if(HAVE_MALLOC_USABLE_SIZE)
add_definitions(-DROCKSDB_MALLOC_USABLE_SIZE)
endif()
@@ -532,6 +497,7 @@ endif()
include_directories(${PROJECT_SOURCE_DIR})
include_directories(${PROJECT_SOURCE_DIR}/include)
include_directories(SYSTEM ${PROJECT_SOURCE_DIR}/third-party/gtest-1.8.1/fused-src)
if(WITH_FOLLY_DISTRIBUTED_MUTEX)
include_directories(${PROJECT_SOURCE_DIR}/third-party/folly)
endif()
@@ -540,17 +506,12 @@ find_package(Threads REQUIRED)
# Main library source code
set(SOURCES
cache/cache.cc
cache/clock_cache.cc
cache/lru_cache.cc
cache/sharded_cache.cc
db/arena_wrapped_db_iter.cc
db/blob/blob_file_addition.cc
db/blob/blob_file_garbage.cc
db/blob/blob_file_meta.cc
db/blob/blob_log_format.cc
db/blob/blob_log_reader.cc
db/blob/blob_log_writer.cc
db/builder.cc
db/c.cc
db/column_family.cc
@@ -562,7 +523,6 @@ set(SOURCES
db/compaction/compaction_picker_fifo.cc
db/compaction/compaction_picker_level.cc
db/compaction/compaction_picker_universal.cc
db/compaction/sst_partitioner.cc
db/convenience.cc
db/db_filesnapshot.cc
db/db_impl/db_impl.cc
@@ -605,7 +565,6 @@ set(SOURCES
db/trim_history_scheduler.cc
db/version_builder.cc
db/version_edit.cc
db/version_edit_handler.cc
db/version_set.cc
db/wal_manager.cc
db/write_batch.cc
@@ -634,7 +593,6 @@ set(SOURCES
memory/arena.cc
memory/concurrent_arena.cc
memory/jemalloc_nodump_allocator.cc
memory/memkind_kmem_allocator.cc
memtable/alloc_tracker.cc
memtable/hash_linklist_rep.cc
memtable/hash_skiplist_rep.cc
@@ -659,6 +617,7 @@ set(SOURCES
options/options.cc
options/options_helper.cc
options/options_parser.cc
options/options_sanity_check.cc
port/stack_trace.cc
table/adaptive/adaptive_table_factory.cc
table/block_based/binary_search_index_reader.cc
@@ -702,7 +661,6 @@ set(SOURCES
table/plain/plain_table_index.cc
table/plain/plain_table_key_coding.cc
table/plain/plain_table_reader.cc
table/sst_file_dumper.cc
table/sst_file_reader.cc
table/sst_file_writer.cc
table/table_properties.cc
@@ -744,6 +702,9 @@ set(SOURCES
utilities/blob_db/blob_db_impl_filesnapshot.cc
utilities/blob_db/blob_dump_tool.cc
utilities/blob_db/blob_file.cc
utilities/blob_db/blob_log_reader.cc
utilities/blob_db/blob_log_writer.cc
utilities/blob_db/blob_log_format.cc
utilities/cassandra/cassandra_compaction_filter.cc
utilities/cassandra/format.cc
utilities/cassandra/merge_operator.cc
@@ -752,8 +713,6 @@ set(SOURCES
utilities/debug.cc
utilities/env_mirror.cc
utilities/env_timed.cc
utilities/fault_injection_env.cc
utilities/fault_injection_fs.cc
utilities/leveldb_options/leveldb_options.cc
utilities/memory/memory_util.cc
utilities/merge_operators/bytesxor.cc
@@ -816,13 +775,9 @@ if(WIN32)
port/win/env_win.cc
port/win/env_default.cc
port/win/port_win.cc
port/win/win_logger.cc)
if(NOT MINGW)
# Mingw only supports std::thread when using
# posix threads.
list(APPEND SOURCES
port/win/win_thread.cc)
endif()
port/win/win_logger.cc
port/win/win_thread.cc)
if(WITH_XPRESS)
list(APPEND SOURCES
port/win/xpress_win.cc)
@@ -869,12 +824,12 @@ else()
endif()
add_library(${ROCKSDB_STATIC_LIB} STATIC ${SOURCES})
target_link_libraries(${ROCKSDB_STATIC_LIB} PRIVATE
target_link_libraries(${ROCKSDB_STATIC_LIB}
${THIRDPARTY_LIBS} ${SYSTEM_LIBS})
if(ROCKSDB_BUILD_SHARED)
add_library(${ROCKSDB_SHARED_LIB} SHARED ${SOURCES})
target_link_libraries(${ROCKSDB_SHARED_LIB} PRIVATE
target_link_libraries(${ROCKSDB_SHARED_LIB}
${THIRDPARTY_LIBS} ${SYSTEM_LIBS})
if(WIN32)
@@ -891,6 +846,7 @@ if(ROCKSDB_BUILD_SHARED)
LINKER_LANGUAGE CXX
VERSION ${rocksdb_VERSION}
SOVERSION ${rocksdb_VERSION_MAJOR}
CXX_STANDARD 11
OUTPUT_NAME "rocksdb")
endif()
endif()
@@ -902,16 +858,6 @@ else()
endif()
option(WITH_JNI "build with JNI" OFF)
# Tests are excluded from Release builds
CMAKE_DEPENDENT_OPTION(WITH_TESTS "build with tests" ON
"CMAKE_BUILD_TYPE STREQUAL Debug" OFF)
option(WITH_BENCHMARK_TOOLS "build with benchmarks" ON)
option(WITH_CORE_TOOLS "build with ldb and sst_dump" ON)
option(WITH_TOOLS "build with tools" ON)
if(WITH_TESTS OR WITH_BENCHMARK_TOOLS OR WITH_TOOLS OR WITH_JNI OR JNI)
include_directories(SYSTEM ${PROJECT_SOURCE_DIR}/third-party/gtest-1.8.1/fused-src)
endif()
if(WITH_JNI OR JNI)
message(STATUS "JNI library is enabled")
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/java)
@@ -949,8 +895,6 @@ if(NOT WIN32 OR ROCKSDB_INSTALL_ON_WINDOWS)
install(DIRECTORY include/rocksdb COMPONENT devel DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}")
install(DIRECTORY "${PROJECT_SOURCE_DIR}/cmake/modules" COMPONENT devel DESTINATION ${package_config_destination})
install(
TARGETS ${ROCKSDB_STATIC_LIB}
EXPORT RocksDBTargets
@@ -987,22 +931,16 @@ if(NOT WIN32 OR ROCKSDB_INSTALL_ON_WINDOWS)
)
endif()
option(WITH_ALL_TESTS "Build all test, rather than a small subset" ON)
if(WITH_TESTS OR WITH_BENCHMARK_TOOLS)
# Tests are excluded from Release builds
CMAKE_DEPENDENT_OPTION(WITH_TESTS "build with tests" ON
"CMAKE_BUILD_TYPE STREQUAL Debug" OFF)
if(WITH_TESTS)
add_subdirectory(third-party/gtest-1.8.1/fused-src/gtest)
add_library(testharness STATIC
test_util/testharness.cc)
target_link_libraries(testharness gtest)
endif()
if(WITH_TESTS)
set(TESTS
db/db_basic_test.cc
env/env_basic_test.cc
)
if(WITH_ALL_TESTS)
list(APPEND TESTS
cache/cache_test.cc
cache/lru_cache_test.cc
db/blob/blob_file_addition_test.cc
@@ -1017,6 +955,7 @@ if(WITH_TESTS)
db/comparator_db_test.cc
db/corruption_test.cc
db/cuckoo_table_db_test.cc
db/db_basic_test.cc
db/db_with_timestamp_basic_test.cc
db/db_block_cache_test.cc
db/db_bloom_filter_test.cc
@@ -1046,7 +985,6 @@ if(WITH_TESTS)
db/db_logical_block_size_cache_test.cc
db/db_universal_compaction_test.cc
db/db_wal_test.cc
db/db_with_timestamp_compaction_test.cc
db/db_write_test.cc
db/dbformat_test.cc
db/deletefile_test.cc
@@ -1079,16 +1017,15 @@ if(WITH_TESTS)
db/write_batch_test.cc
db/write_callback_test.cc
db/write_controller_test.cc
env/env_basic_test.cc
env/env_test.cc
env/io_posix_test.cc
env/mock_env_test.cc
file/delete_scheduler_test.cc
file/random_access_file_reader_test.cc
logging/auto_roll_logger_test.cc
logging/env_logger_test.cc
logging/event_logger_test.cc
memory/arena_test.cc
memory/memkind_kmem_allocator_test.cc
memtable/inlineskiplist_test.cc
memtable/skiplist_test.cc
memtable/write_buffer_manager_test.cc
@@ -1099,7 +1036,6 @@ if(WITH_TESTS)
options/options_settable_test.cc
options/options_test.cc
table/block_based/block_based_filter_block_test.cc
table/block_based/block_based_table_reader_test.cc
table/block_based/block_test.cc
table/block_based/data_block_hash_index_test.cc
table/block_based/full_filter_block_test.cc
@@ -1110,8 +1046,6 @@ if(WITH_TESTS)
table/merger_test.cc
table/sst_file_reader_test.cc
table/table_test.cc
table/block_fetcher_test.cc
test_util/testutil_test.cc
tools/block_cache_analyzer/block_cache_trace_analyzer_test.cc
tools/ldb_cmd_test.cc
tools/reduce_levels_test.cc
@@ -1133,10 +1067,8 @@ if(WITH_TESTS)
util/slice_test.cc
util/slice_transform_test.cc
util/timer_queue_test.cc
util/timer_test.cc
util/thread_list_test.cc
util/thread_local_test.cc
util/work_queue_test.cc
utilities/backupable/backupable_db_test.cc
utilities/blob_db/blob_db_test.cc
utilities/cassandra/cassandra_functional_test.cc
@@ -1156,13 +1088,11 @@ if(WITH_TESTS)
utilities/table_properties_collectors/compact_on_deletion_collector_test.cc
utilities/transactions/optimistic_transaction_test.cc
utilities/transactions/transaction_test.cc
utilities/transactions/transaction_lock_mgr_test.cc
utilities/transactions/write_prepared_transaction_test.cc
utilities/transactions/write_unprepared_transaction_test.cc
utilities/ttl/ttl_test.cc
utilities/write_batch_with_index/write_batch_with_index_test.cc
)
endif()
)
if(WITH_LIBRADOS)
list(APPEND TESTS utilities/env_librados_test.cc)
endif()
@@ -1175,6 +1105,8 @@ if(WITH_TESTS)
db/db_test_util.cc
monitoring/thread_status_updater_debug.cc
table/mock_table.cc
test_util/fault_injection_test_env.cc
test_util/fault_injection_test_fs.cc
utilities/cassandra/test_utils.cc
)
enable_testing()
@@ -1189,7 +1121,7 @@ if(WITH_TESTS)
PROPERTIES EXCLUDE_FROM_DEFAULT_BUILD_RELEASE 1
EXCLUDE_FROM_DEFAULT_BUILD_MINRELEASE 1
EXCLUDE_FROM_DEFAULT_BUILD_RELWITHDEBINFO 1
)
)
foreach(sourcefile ${TESTS})
get_filename_component(exename ${sourcefile} NAME_WE)
@@ -1199,16 +1131,12 @@ if(WITH_TESTS)
EXCLUDE_FROM_DEFAULT_BUILD_MINRELEASE 1
EXCLUDE_FROM_DEFAULT_BUILD_RELWITHDEBINFO 1
OUTPUT_NAME ${exename}${ARTIFACT_SUFFIX}
)
target_link_libraries(${CMAKE_PROJECT_NAME}_${exename}${ARTIFACT_SUFFIX} testutillib${ARTIFACT_SUFFIX} testharness gtest ${GFLAGS_LIB} ${ROCKSDB_LIB})
)
target_link_libraries(${CMAKE_PROJECT_NAME}_${exename}${ARTIFACT_SUFFIX} testutillib${ARTIFACT_SUFFIX} testharness gtest ${ROCKSDB_LIB})
if(NOT "${exename}" MATCHES "db_sanity_test")
add_test(NAME ${exename} COMMAND ${exename}${ARTIFACT_SUFFIX})
add_dependencies(check ${CMAKE_PROJECT_NAME}_${exename}${ARTIFACT_SUFFIX})
endif()
if("${exename}" MATCHES "env_librados_test")
# env_librados_test.cc uses librados directly
target_link_libraries(${CMAKE_PROJECT_NAME}_${exename}${ARTIFACT_SUFFIX} rados)
endif()
endforeach(sourcefile ${TESTS})
if(WIN32)
@@ -1232,44 +1160,47 @@ if(WITH_TESTS)
endif()
endif()
option(WITH_BENCHMARK_TOOLS "build with benchmarks" ON)
if(WITH_BENCHMARK_TOOLS)
add_executable(db_bench
tools/db_bench.cc
tools/db_bench_tool.cc)
target_link_libraries(db_bench
${ROCKSDB_LIB} ${GFLAGS_LIB})
${ROCKSDB_LIB})
add_executable(cache_bench
cache/cache_bench.cc)
target_link_libraries(cache_bench
${ROCKSDB_LIB} ${GFLAGS_LIB})
${ROCKSDB_LIB})
add_executable(memtablerep_bench
memtable/memtablerep_bench.cc)
target_link_libraries(memtablerep_bench
${ROCKSDB_LIB} ${GFLAGS_LIB})
${ROCKSDB_LIB})
add_executable(range_del_aggregator_bench
db/range_del_aggregator_bench.cc)
target_link_libraries(range_del_aggregator_bench
${ROCKSDB_LIB} ${GFLAGS_LIB})
${ROCKSDB_LIB})
add_executable(table_reader_bench
table/table_reader_bench.cc)
target_link_libraries(table_reader_bench
${ROCKSDB_LIB} testharness ${GFLAGS_LIB})
${ROCKSDB_LIB} testharness)
add_executable(filter_bench
util/filter_bench.cc)
target_link_libraries(filter_bench
${ROCKSDB_LIB} ${GFLAGS_LIB})
${ROCKSDB_LIB})
add_executable(hash_table_bench
utilities/persistent_cache/hash_table_bench.cc)
target_link_libraries(hash_table_bench
${ROCKSDB_LIB} ${GFLAGS_LIB})
${ROCKSDB_LIB})
endif()
option(WITH_CORE_TOOLS "build with ldb and sst_dump" ON)
option(WITH_TOOLS "build with tools" ON)
if(WITH_CORE_TOOLS OR WITH_TOOLS)
add_subdirectory(tools)
add_custom_target(core_tools
@@ -1281,8 +1212,3 @@ if(WITH_TOOLS)
add_custom_target(tools
DEPENDS ${tool_deps})
endif()
option(WITH_EXAMPLES "build with examples" OFF)
if(WITH_EXAMPLES)
add_subdirectory(examples)
endif()
+1 -154
View File
@@ -1,171 +1,18 @@
# Rocksdb Change Log
## 6.12.8 (2020-11-15)
### Bug Fixes
* Fix a bug of encoding and parsing BlockBasedTableOptions::read_amp_bytes_per_bit as a 64-bit integer.
* Fixed the logic of populating native data structure for `read_amp_bytes_per_bit` during OPTIONS file parsing on big-endian architecture. Without this fix, original code introduced in PR7659, when running on big-endian machine, can mistakenly store read_amp_bytes_per_bit (an uint32) in little endian format. Future access to `read_amp_bytes_per_bit` will give wrong values. Little endian architecture is not affected.
## 6.12.7 (2020-10-14)
### Other
Fix build issue to enable RocksJava release for ppc64le
## 6.12.6 (2020-10-13)
### Bug Fixes
* Fix false positive flush/compaction `Status::Corruption` failure when `paranoid_file_checks == true` and range tombstones were written to the compaction output files.
## 6.12.5 (2020-10-12)
### Bug Fixes
* Since 6.12, memtable lookup should report unrecognized value_type as corruption (#7121).
* Fixed a bug in the following combination of features: indexes with user keys (`format_version >= 3`), indexes are partitioned (`index_type == kTwoLevelIndexSearch`), and some index partitions are pinned in memory (`BlockBasedTableOptions::pin_l0_filter_and_index_blocks_in_cache`). The bug could cause keys to be truncated when read from the index leading to wrong read results or other unexpected behavior.
* Fixed a bug when indexes are partitioned (`index_type == kTwoLevelIndexSearch`), some index partitions are pinned in memory (`BlockBasedTableOptions::pin_l0_filter_and_index_blocks_in_cache`), and partitions reads could be mixed between block cache and directly from the file (e.g., with `enable_index_compression == 1` and `mmap_read == 1`, partitions that were stored uncompressed due to poor compression ratio would be read directly from the file via mmap, while partitions that were stored compressed would be read from block cache). The bug could cause index partitions to be mistakenly considered empty during reads leading to wrong read results.
## 6.12.4 (2020-09-18)
### Public API Change
* Reworked `BackupableDBOptions::share_files_with_checksum_naming` (new in 6.12) with some minor improvements and to better support those who were extracting files sizes from backup file names.
## 6.12.3 (2020-09-16)
### Bug fixes
* Fixed a bug in size-amp-triggered and periodic-triggered universal compaction, where the compression settings for the first input level were used rather than the compression settings for the output (bottom) level.
## 6.12.2 (2020-09-14)
### Public API Change
* BlobDB now exposes the start of the expiration range of TTL blob files via the `GetLiveFilesMetaData` API.
## 6.12.1 (2020-08-20)
### Bug fixes
* BackupEngine::CreateNewBackup could fail intermittently with non-OK status when backing up a read-write DB configured with a DBOptions::file_checksum_gen_factory. This issue has been worked-around such that CreateNewBackup should succeed, but (until fully fixed) BackupEngine might not see all checksums available in the DB.
## 6.12 (2020-07-28)
### Public API Change
* Encryption file classes now exposed for inheritance in env_encryption.h
* File I/O listener is extended to cover more I/O operations. Now class `EventListener` in listener.h contains new callback functions: `OnFileFlushFinish()`, `OnFileSyncFinish()`, `OnFileRangeSyncFinish()`, `OnFileTruncateFinish()`, and ``OnFileCloseFinish()``.
* `FileOperationInfo` now reports `duration` measured by `std::chrono::steady_clock` and `start_ts` measured by `std::chrono::system_clock` instead of start and finish timestamps measured by `system_clock`. Note that `system_clock` is called before `steady_clock` in program order at operation starts.
* `DB::GetDbSessionId(std::string& session_id)` is added. `session_id` stores a unique identifier that gets reset every time the DB is opened. This DB session ID should be unique among all open DB instances on all hosts, and should be unique among re-openings of the same or other DBs. This identifier is recorded in the LOG file on the line starting with "DB Session ID:".
* `DB::OpenForReadOnly()` now returns `Status::NotFound` when the specified DB directory does not exist. Previously the error returned depended on the underlying `Env`. This change is available in all 6.11 releases as well.
* A parameter `verify_with_checksum` is added to `BackupEngine::VerifyBackup`, which is false by default. If it is ture, `BackupEngine::VerifyBackup` verifies checksums and file sizes of backup files. Pass `false` for `verify_with_checksum` to maintain the previous behavior and performance of `BackupEngine::VerifyBackup`, by only verifying sizes of backup files.
### Behavior Changes
* Best-efforts recovery ignores CURRENT file completely. If CURRENT file is missing during recovery, best-efforts recovery still proceeds with MANIFEST file(s).
* In best-efforts recovery, an error that is not Corruption or IOError::kNotFound or IOError::kPathNotFound will be overwritten silently. Fix this by checking all non-ok cases and return early.
* When `file_checksum_gen_factory` is set to `GetFileChecksumGenCrc32cFactory()`, BackupEngine will compare the crc32c checksums of table files computed when creating a backup to the expected checksums stored in the DB manifest, and will fail `CreateNewBackup()` on mismatch (corruption). If the `file_checksum_gen_factory` is not set or set to any other customized factory, there is no checksum verification to detect if SST files in a DB are corrupt when read, copied, and independently checksummed by BackupEngine.
* When a DB sets `stats_dump_period_sec > 0`, either as the initial value for DB open or as a dynamic option change, the first stats dump is staggered in the following X seconds, where X is an integer in `[0, stats_dump_period_sec)`. Subsequent stats dumps are still spaced `stats_dump_period_sec` seconds apart.
* When the paranoid_file_checks option is true, a hash is generated of all keys and values are generated when the SST file is written, and then the values are read back in to validate the file. A corruption is signaled if the two hashes do not match.
### Bug fixes
* Compressed block cache was automatically disabled with read-only DBs by mistake. Now it is fixed: compressed block cache will be in effective with read-only DB too.
* Fix a bug of wrong iterator result if another thread finishes an update and a DB flush between two statement.
* Disable file deletion after MANIFEST write/sync failure until db re-open or Resume() so that subsequent re-open will not see MANIFEST referencing deleted SSTs.
* Fix a bug when index_type == kTwoLevelIndexSearch in PartitionedIndexBuilder to update FlushPolicy to point to internal key partitioner when it changes from user-key mode to internal-key mode in index partition.
* Make compaction report InternalKey corruption while iterating over the input.
* Fix a bug which may cause MultiGet to be slow because it may read more data than requested, but this won't affect correctness. The bug was introduced in 6.10 release.
* Fail recovery and report once hitting a physical log record checksum mismatch, while reading MANIFEST. RocksDB should not continue processing the MANIFEST any further.
### New Features
* DB identity (`db_id`) and DB session identity (`db_session_id`) are added to table properties and stored in SST files. SST files generated from SstFileWriter and Repairer have DB identity “SST Writer” and “DB Repairer”, respectively. Their DB session IDs are generated in the same way as `DB::GetDbSessionId`. The session ID for SstFileWriter (resp., Repairer) resets every time `SstFileWriter::Open` (resp., `Repairer::Run`) is called.
* Added experimental option BlockBasedTableOptions::optimize_filters_for_memory for reducing allocated memory size of Bloom filters (~10% savings with Jemalloc) while preserving the same general accuracy. To have an effect, the option requires format_version=5 and malloc_usable_size. Enabling this option is forward and backward compatible with existing format_version=5.
* `BackupableDBOptions::share_files_with_checksum_naming` is added with new default behavior for naming backup files with `share_files_with_checksum`, to address performance and backup integrity issues. See API comments for details.
* Added auto resume function to automatically recover the DB from background Retryable IO Error. When retryable IOError happens during flush and WAL write, the error is mapped to Hard Error and DB will be in read mode. When retryable IO Error happens during compaction, the error will be mapped to Soft Error. DB is still in write/read mode. Autoresume function will create a thread for a DB to call DB->ResumeImpl() to try the recover for Retryable IO Error during flush and WAL write. Compaction will be rescheduled by itself if retryable IO Error happens. Auto resume may also cause other Retryable IO Error during the recovery, so the recovery will fail. Retry the auto resume may solve the issue, so we use max_bgerror_resume_count to decide how many resume cycles will be tried in total. If it is <=0, auto resume retryable IO Error is disabled. Default is INT_MAX, which will lead to a infinit auto resume. bgerror_resume_retry_interval decides the time interval between two auto resumes.
* Option `max_subcompactions` can be set dynamically using DB::SetDBOptions().
* Added experimental ColumnFamilyOptions::sst_partitioner_factory to define determine the partitioning of sst files. This helps compaction to split the files on interesting boundaries (key prefixes) to make propagation of sst files less write amplifying (covering the whole key space).
### Performance Improvements
* Eliminate key copies for internal comparisons while accessing ingested block-based tables.
* Reduce key comparisons during random access in all block-based tables.
* BackupEngine avoids unnecessary repeated checksum computation for backing up a table file to the `shared_checksum` directory when using `share_files_with_checksum_naming = kUseDbSessionId` (new default), except on SST files generated before this version of RocksDB, which fall back on using `kLegacyCrc32cAndFileSize`.
## 6.11 (6/12/2020)
### Bug Fixes
* Fix consistency checking error swallowing in some cases when options.force_consistency_checks = true.
* Fix possible false NotFound status from batched MultiGet using index type kHashSearch.
* Fix corruption caused by enabling delete triggered compaction (NewCompactOnDeletionCollectorFactory) in universal compaction mode, along with parallel compactions. The bug can result in two parallel compactions picking the same input files, resulting in the DB resurrecting older and deleted versions of some keys.
* Fix a use-after-free bug in best-efforts recovery. column_family_memtables_ needs to point to valid ColumnFamilySet.
* Let best-efforts recovery ignore corrupted files during table loading.
* Fix corrupt key read from ingested file when iterator direction switches from reverse to forward at a key that is a prefix of another key in the same file. It is only possible in files with a non-zero global seqno.
* Fix abnormally large estimate from GetApproximateSizes when a range starts near the end of one SST file and near the beginning of another. Now GetApproximateSizes consistently and fairly includes the size of SST metadata in addition to data blocks, attributing metadata proportionally among the data blocks based on their size.
* Fix potential file descriptor leakage in PosixEnv's IsDirectory() and NewRandomAccessFile().
* Fix false negative from the VerifyChecksum() API when there is a checksum mismatch in an index partition block in a BlockBasedTable format table file (index_type is kTwoLevelIndexSearch).
* Fix sst_dump to return non-zero exit code if the specified file is not a recognized SST file or fails requested checks.
* Fix incorrect results from batched MultiGet for duplicate keys, when the duplicate key matches the largest key of an SST file and the value type for the key in the file is a merge value.
### Public API Change
* Flush(..., column_family) may return Status::ColumnFamilyDropped() instead of Status::InvalidArgument() if column_family is dropped while processing the flush request.
* BlobDB now explicitly disallows using the default column family's storage directories as blob directory.
* DeleteRange now returns `Status::InvalidArgument` if the range's end key comes before its start key according to the user comparator. Previously the behavior was undefined.
* ldb now uses options.force_consistency_checks = true by default and "--disable_consistency_checks" is added to disable it.
* DB::OpenForReadOnly no longer creates files or directories if the named DB does not exist, unless create_if_missing is set to true.
* The consistency checks that validate LSM state changes (table file additions/deletions during flushes and compactions) are now stricter, more efficient, and no longer optional, i.e. they are performed even if `force_consistency_checks` is `false`.
* Disable delete triggered compaction (NewCompactOnDeletionCollectorFactory) in universal compaction mode and num_levels = 1 in order to avoid a corruption bug.
* `pin_l0_filter_and_index_blocks_in_cache` no longer applies to L0 files larger than `1.5 * write_buffer_size` to give more predictable memory usage. Such L0 files may exist due to intra-L0 compaction, external file ingestion, or user dynamically changing `write_buffer_size` (note, however, that files that are already pinned will continue being pinned, even after such a dynamic change).
* In point-in-time wal recovery mode, fail database recovery in case of IOError while reading the WAL to avoid data loss.
* A new method `Env::LowerThreadPoolCPUPriority(Priority, CpuPriority)` is added to `Env` to be able to lower to a specific priority such as `CpuPriority::kIdle`.
### New Features
* sst_dump to add a new --readahead_size argument. Users can specify read size when scanning the data. Sst_dump also tries to prefetch tail part of the SST files so usually some number of I/Os are saved there too.
* Generate file checksum in SstFileWriter if Options.file_checksum_gen_factory is set. The checksum and checksum function name are stored in ExternalSstFileInfo after the sst file write is finished.
* Add a value_size_soft_limit in read options which limits the cumulative value size of keys read in batches in MultiGet. Once the cumulative value size of found keys exceeds read_options.value_size_soft_limit, all the remaining keys are returned with status Abort without further finding their values. By default the value_size_soft_limit is std::numeric_limits<uint64_t>::max().
* Enable SST file ingestion with file checksum information when calling IngestExternalFiles(const std::vector<IngestExternalFileArg>& args). Added files_checksums and files_checksum_func_names to IngestExternalFileArg such that user can ingest the sst files with their file checksum information. Added verify_file_checksum to IngestExternalFileOptions (default is True). To be backward compatible, if DB does not enable file checksum or user does not provide checksum information (vectors of files_checksums and files_checksum_func_names are both empty), verification of file checksum is always sucessful. If DB enables file checksum, DB will always generate the checksum for each ingested SST file during Prepare stage of ingestion and store the checksum in Manifest, unless verify_file_checksum is False and checksum information is provided by the application. In this case, we only verify the checksum function name and directly store the ingested checksum in Manifest. If verify_file_checksum is set to True, DB will verify the ingested checksum and function name with the genrated ones. Any mismatch will fail the ingestion. Note that, if IngestExternalFileOptions::write_global_seqno is True, the seqno will be changed in the ingested file. Therefore, the checksum of the file will be changed. In this case, a new checksum will be generated after the seqno is updated and be stored in the Manifest.
### Performance Improvements
* Eliminate redundant key comparisons during random access in block-based tables.
## 6.10 (5/2/2020)
### Bug Fixes
* Fix wrong result being read from ingested file. May happen when a key in the file happen to be prefix of another key also in the file. The issue can further cause more data corruption. The issue exists with rocksdb >= 5.0.0 since DB::IngestExternalFile() was introduced.
* Finish implementation of BlockBasedTableOptions::IndexType::kBinarySearchWithFirstKey. It's now ready for use. Significantly reduces read amplification in some setups, especially for iterator seeks.
* Fix a bug by updating CURRENT file so that it points to the correct MANIFEST file after best-efforts recovery.
* Fixed a bug where ColumnFamilyHandle objects were not cleaned up in case an error happened during BlobDB's open after the base DB had been opened.
* Fix a potential undefined behavior caused by trying to dereference nullable pointer (timestamp argument) in DB::MultiGet.
* Fix a bug caused by not including user timestamp in MultiGet LookupKey construction. This can lead to wrong query result since the trailing bytes of a user key, if not shorter than timestamp, will be mistaken for user timestamp.
* Fix a bug caused by using wrong compare function when sorting the input keys of MultiGet with timestamps.
* Upgraded version of bzip library (1.0.6 -> 1.0.8) used with RocksJava to address potential vulnerabilities if an attacker can manipulate compressed data saved and loaded by RocksDB (not normal). See issue #6703.
### Public API Change
* Add a ConfigOptions argument to the APIs dealing with converting options to and from strings and files. The ConfigOptions is meant to replace some of the options (such as input_strings_escaped and ignore_unknown_options) and allow for more parameters to be passed in the future without changing the function signature.
* Add NewFileChecksumGenCrc32cFactory to the file checksum public API, such that the builtin Crc32c based file checksum generator factory can be used by applications.
* Add IsDirectory to Env and FS to indicate if a path is a directory.
### New Features
* Added support for pipelined & parallel compression optimization for `BlockBasedTableBuilder`. This optimization makes block building, block compression and block appending a pipeline, and uses multiple threads to accelerate block compression. Users can set `CompressionOptions::parallel_threads` greater than 1 to enable compression parallelism. This feature is experimental for now.
* Provide an allocator for memkind to be used with block cache. This is to work with memory technologies (Intel DCPMM is one such technology currently available) that require different libraries for allocation and management (such as PMDK and memkind). The high capacities available make it possible to provision large caches (up to several TBs in size) beyond what is achievable with DRAM.
* Option `max_background_flushes` can be set dynamically using DB::SetDBOptions().
* Added functionality in sst_dump tool to check the compressed file size for different compression levels and print the time spent on compressing files with each compression type. Added arguments `--compression_level_from` and `--compression_level_to` to report size of all compression levels and one compression_type must be specified with it so that it will report compressed sizes of one compression type with different levels.
* Added statistics for redundant insertions into block cache: rocksdb.block.cache.*add.redundant. (There is currently no coordination to ensure that only one thread loads a table block when many threads are trying to access that same table block.)
### Bug Fixes
* Fix a bug when making options.bottommost_compression, options.compression_opts and options.bottommost_compression_opts dynamically changeable: the modified values are not written to option files or returned back to users when being queried.
* Fix a bug where index key comparisons were unaccounted in `PerfContext::user_key_comparison_count` for lookups in files written with `format_version >= 3`.
* Fix many bloom.filter statistics not being updated in batch MultiGet.
### Performance Improvements
* Improve performance of batch MultiGet with partitioned filters, by sharing block cache lookups to applicable filter blocks.
* Reduced memory copies when fetching and uncompressing compressed blocks from sst files.
## 6.9.0 (03/29/2020)
### Behavior changes
* Since RocksDB 6.8, ttl-based FIFO compaction can drop a file whose oldest key becomes older than options.ttl while others have not. This fix reverts this and makes ttl-based FIFO compaction use the file's flush time as the criterion. This fix also requires that max_open_files = -1 and compaction_options_fifo.allow_compaction = false to function properly.
## Unreleased
### Public API Change
* Fix spelling so that API now has correctly spelled transaction state name `COMMITTED`, while the old misspelled `COMMITED` is still available as an alias.
* Updated default format_version in BlockBasedTableOptions from 2 to 4. SST files generated with the new default can be read by RocksDB versions 5.16 and newer, and use more efficient encoding of keys in index blocks.
* A new parameter `CreateBackupOptions` is added to both `BackupEngine::CreateNewBackup` and `BackupEngine::CreateNewBackupWithMetadata`, you can decrease CPU priority of `BackupEngine`'s background threads by setting `decrease_background_thread_cpu_priority` and `background_thread_cpu_priority` in `CreateBackupOptions`.
* Updated the public API of SST file checksum. Introduce the FileChecksumGenFactory to create the FileChecksumGenerator for each SST file, such that the FileChecksumGenerator is not shared and it can be more general for checksum implementations. Changed the FileChecksumGenerator interface from Value, Extend, and GetChecksum to Update, Finalize, and GetChecksum. Finalize should be only called once after all data is processed to generate the final checksum. Temproal data should be maintained by the FileChecksumGenerator object itself and finally it can return the checksum string.
### Bug Fixes
* Fix a bug where range tombstone blocks in ingested files were cached incorrectly during ingestion. If range tombstones were read from those incorrectly cached blocks, the keys they covered would be exposed.
* Fix a data race that might cause crash when calling DB::GetCreationTimeOfOldestFile() by a small chance. The bug was introduced in 6.6 Release.
* Fix a bug where a boolean value optimize_filters_for_hits was for max threads when calling load table handles after a flush or compaction. The value is correct to 1. The bug should not cause user visible problems.
* Fix a bug which might crash the service when write buffer manager fails to insert the dummy handle to the block cache.
### Performance Improvements
* In CompactRange, for levels starting from 0, if the level does not have any file with any key falling in the specified range, the level is skipped. So instead of always compacting from level 0, the compaction starts from the first level with keys in the specified range until the last such level.
* Reduced memory copy when reading sst footer and blobdb in direct IO mode.
* When restarting a database with large numbers of sst files, large amount of CPU time is spent on getting logical block size of the sst files, which slows down the starting progress, this inefficiency is optimized away with an internal cache for the logical block sizes.
### New Features
* Basic support for user timestamp in iterator. Seek/SeekToFirst/Next and lower/upper bounds are supported. Reverse iteration is not supported. Merge is not considered.
* When file lock failure when the lock is held by the current process, return acquiring time and thread ID in the error message.
* Added a new option, best_efforts_recovery (default: false), to allow database to open in a db dir with missing table files. During best efforts recovery, missing table files are ignored, and database recovers to the most recent state without missing table file. Cross-column-family consistency is not guaranteed even if WAL is enabled.
* options.bottommost_compression, options.compression_opts and options.bottommost_compression_opts are now dynamically changeable.
## 6.8.0 (02/24/2020)
### Java API Changes
+1 -3
View File
@@ -10,9 +10,7 @@ This is the list of all known third-party language bindings for RocksDB. If some
* Ruby - http://rubygems.org/gems/rocksdb-ruby
* Haskell - https://hackage.haskell.org/package/rocksdb-haskell
* PHP - https://github.com/Photonios/rocksdb-php
* C#
* https://github.com/warrenfalk/rocksdb-sharp
* https://github.com/curiosity-ai/rocksdb-sharp
* C# - https://github.com/warrenfalk/rocksdb-sharp
* Rust
* https://github.com/pingcap/rust-rocksdb (used in production fork of https://github.com/spacejam/rust-rocksdb)
* https://github.com/spacejam/rust-rocksdb
+578 -601
View File
File diff suppressed because it is too large Load Diff
+3 -4
View File
@@ -1,8 +1,7 @@
## RocksDB: A Persistent Key-Value Store for Flash and RAM Storage
[![CircleCI Status](https://circleci.com/gh/facebook/rocksdb.svg?style=svg)](https://circleci.com/gh/facebook/rocksdb)
[![TravisCI Status](https://travis-ci.org/facebook/rocksdb.svg?branch=master)](https://travis-ci.org/facebook/rocksdb)
[![Appveyor Build status](https://ci.appveyor.com/api/projects/status/fbgfu0so3afcno78/branch/master?svg=true)](https://ci.appveyor.com/project/Facebook/rocksdb/branch/master)
[![Linux/Mac Build Status](https://travis-ci.org/facebook/rocksdb.svg?branch=master)](https://travis-ci.org/facebook/rocksdb)
[![Windows Build status](https://ci.appveyor.com/api/projects/status/fbgfu0so3afcno78/branch/master?svg=true)](https://ci.appveyor.com/project/Facebook/rocksdb/branch/master)
[![PPC64le Build Status](http://140.211.168.68:8080/buildStatus/icon?job=Rocksdb)](http://140.211.168.68:8080/job/Rocksdb)
RocksDB is developed and maintained by Facebook Database Engineering Team.
@@ -25,7 +24,7 @@ The public interface is in `include/`. Callers should not include or
rely on the details of any other header files in this package. Those
internal APIs may be changed without warning.
Design discussions are conducted in https://www.facebook.com/groups/rocksdb.dev/ and https://rocksdb.slack.com/
Design discussions are conducted in https://www.facebook.com/groups/rocksdb.dev/
## License
+31 -127
View File
@@ -1,4 +1,4 @@
# This file @generated by `python3 buckifier/buckify_rocksdb.py`
# This file @generated by `python buckifier/buckify_rocksdb.py`
# --> DO NOT EDIT MANUALLY <--
# This file is a Facebook-specific integration for buck builds, so can
# only be validated by Facebook employees.
@@ -26,6 +26,7 @@ ROCKSDB_EXTERNAL_DEPS = [
("lz4", None, "lz4"),
("zstd", None),
("tbb", None),
("googletest", None, "gtest"),
]
ROCKSDB_OS_DEPS = [
@@ -108,25 +109,15 @@ ROCKSDB_OS_DEPS += ([(
["third-party//jemalloc:headers"],
)] if sanitizer == "" else [])
ROCKSDB_LIB_DEPS = [
":rocksdb_lib",
":rocksdb_test_lib",
] if not is_opt_mode else [":rocksdb_lib"]
cpp_library(
name = "rocksdb_lib",
srcs = [
"cache/cache.cc",
"cache/clock_cache.cc",
"cache/lru_cache.cc",
"cache/sharded_cache.cc",
"db/arena_wrapped_db_iter.cc",
"db/blob/blob_file_addition.cc",
"db/blob/blob_file_garbage.cc",
"db/blob/blob_file_meta.cc",
"db/blob/blob_log_format.cc",
"db/blob/blob_log_reader.cc",
"db/blob/blob_log_writer.cc",
"db/builder.cc",
"db/c.cc",
"db/column_family.cc",
@@ -138,7 +129,6 @@ cpp_library(
"db/compaction/compaction_picker_fifo.cc",
"db/compaction/compaction_picker_level.cc",
"db/compaction/compaction_picker_universal.cc",
"db/compaction/sst_partitioner.cc",
"db/convenience.cc",
"db/db_filesnapshot.cc",
"db/db_impl/db_impl.cc",
@@ -181,7 +171,6 @@ cpp_library(
"db/trim_history_scheduler.cc",
"db/version_builder.cc",
"db/version_edit.cc",
"db/version_edit_handler.cc",
"db/version_set.cc",
"db/wal_manager.cc",
"db/write_batch.cc",
@@ -194,7 +183,6 @@ cpp_library(
"env/env_hdfs.cc",
"env/env_posix.cc",
"env/file_system.cc",
"env/file_system_tracer.cc",
"env/fs_posix.cc",
"env/io_posix.cc",
"env/mock_env.cc",
@@ -214,7 +202,6 @@ cpp_library(
"memory/arena.cc",
"memory/concurrent_arena.cc",
"memory/jemalloc_nodump_allocator.cc",
"memory/memkind_kmem_allocator.cc",
"memtable/alloc_tracker.cc",
"memtable/hash_linklist_rep.cc",
"memtable/hash_skiplist_rep.cc",
@@ -240,6 +227,7 @@ cpp_library(
"options/options.cc",
"options/options_helper.cc",
"options/options_parser.cc",
"options/options_sanity_check.cc",
"port/port_posix.cc",
"port/stack_trace.cc",
"table/adaptive/adaptive_table_factory.cc",
@@ -284,7 +272,6 @@ cpp_library(
"table/plain/plain_table_index.cc",
"table/plain/plain_table_key_coding.cc",
"table/plain/plain_table_reader.cc",
"table/sst_file_dumper.cc",
"table/sst_file_reader.cc",
"table/sst_file_writer.cc",
"table/table_properties.cc",
@@ -297,7 +284,6 @@ cpp_library(
"tools/ldb_tool.cc",
"tools/sst_dump_tool.cc",
"trace_replay/block_cache_tracer.cc",
"trace_replay/io_tracer.cc",
"trace_replay/trace_replay.cc",
"util/build_version.cc",
"util/coding.cc",
@@ -325,6 +311,9 @@ cpp_library(
"utilities/blob_db/blob_db_impl_filesnapshot.cc",
"utilities/blob_db/blob_dump_tool.cc",
"utilities/blob_db/blob_file.cc",
"utilities/blob_db/blob_log_format.cc",
"utilities/blob_db/blob_log_reader.cc",
"utilities/blob_db/blob_log_writer.cc",
"utilities/cassandra/cassandra_compaction_filter.cc",
"utilities/cassandra/format.cc",
"utilities/cassandra/merge_operator.cc",
@@ -334,8 +323,6 @@ cpp_library(
"utilities/debug.cc",
"utilities/env_mirror.cc",
"utilities/env_timed.cc",
"utilities/fault_injection_env.cc",
"utilities/fault_injection_fs.cc",
"utilities/leveldb_options/leveldb_options.cc",
"utilities/memory/memory_util.cc",
"utilities/merge_operators/bytesxor.cc",
@@ -389,6 +376,8 @@ cpp_library(
srcs = [
"db/db_test_util.cc",
"table/mock_table.cc",
"test_util/fault_injection_test_env.cc",
"test_util/fault_injection_test_fs.cc",
"test_util/testharness.cc",
"test_util/testutil.cc",
"tools/block_cache_analyzer/block_cache_trace_analyzer.cc",
@@ -402,9 +391,7 @@ cpp_library(
os_preprocessor_flags = ROCKSDB_OS_PREPROCESSOR_FLAGS,
preprocessor_flags = ROCKSDB_PREPROCESSOR_FLAGS,
deps = [":rocksdb_lib"],
external_deps = ROCKSDB_EXTERNAL_DEPS + [
("googletest", None, "gtest"),
],
external_deps = ROCKSDB_EXTERNAL_DEPS,
)
cpp_library(
@@ -447,31 +434,10 @@ cpp_library(
os_deps = ROCKSDB_OS_DEPS,
os_preprocessor_flags = ROCKSDB_OS_PREPROCESSOR_FLAGS,
preprocessor_flags = ROCKSDB_PREPROCESSOR_FLAGS,
deps = ROCKSDB_LIB_DEPS,
deps = [":rocksdb_lib"],
external_deps = ROCKSDB_EXTERNAL_DEPS,
)
if not is_opt_mode:
cpp_binary(
name = "c_test_bin",
srcs = ["db/c_test.c"],
arch_preprocessor_flags = ROCKSDB_ARCH_PREPROCESSOR_FLAGS,
os_preprocessor_flags = ROCKSDB_OS_PREPROCESSOR_FLAGS,
compiler_flags = ROCKSDB_COMPILER_FLAGS,
preprocessor_flags = ROCKSDB_PREPROCESSOR_FLAGS,
deps = [":rocksdb_test_lib"],
)
if not is_opt_mode:
custom_unittest(
"c_test",
command = [
native.package_name() + "/buckifier/rocks_test_runner.sh",
"$(location :{})".format("c_test_bin"),
],
type = "simple",
)
cpp_library(
name = "env_basic_test_lib",
srcs = ["env/env_basic_test.cc"],
@@ -543,13 +509,6 @@ ROCKS_TESTS = [
[],
[],
],
[
"block_based_table_reader_test",
"table/block_based/block_based_table_reader_test.cc",
"serial",
[],
[],
],
[
"block_cache_trace_analyzer_test",
"tools/block_cache_analyzer/block_cache_trace_analyzer_test.cc",
@@ -564,13 +523,6 @@ ROCKS_TESTS = [
[],
[],
],
[
"block_fetcher_test",
"table/block_fetcher_test.cc",
"serial",
[],
[],
],
[
"block_test",
"table/block_based/block_test.cc",
@@ -585,6 +537,13 @@ ROCKS_TESTS = [
[],
[],
],
[
"c_test",
"db/c_test.c",
"serial",
[],
[],
],
[
"cache_simulator_test",
"utilities/simulator_cache/cache_simulator_test.cc",
@@ -651,7 +610,7 @@ ROCKS_TESTS = [
[
"column_family_test",
"db/column_family_test.cc",
"parallel",
"serial",
[],
[],
],
@@ -945,7 +904,7 @@ ROCKS_TESTS = [
[
"db_test2",
"db/db_test2.cc",
"parallel",
"serial",
[],
[],
],
@@ -970,13 +929,6 @@ ROCKS_TESTS = [
[],
[],
],
[
"db_with_timestamp_compaction_test",
"db/db_with_timestamp_compaction_test.cc",
"serial",
[],
[],
],
[
"db_write_test",
"db/db_write_test.cc",
@@ -1173,13 +1125,6 @@ ROCKS_TESTS = [
[],
[],
],
[
"io_tracer_test",
"trace_replay/io_tracer_test.cc",
"serial",
[],
[],
],
[
"iostats_context_test",
"monitoring/iostats_context_test.cc",
@@ -1222,13 +1167,6 @@ ROCKS_TESTS = [
[],
[],
],
[
"memkind_kmem_allocator_test",
"memory/memkind_kmem_allocator_test.cc",
"serial",
[],
[],
],
[
"memory_test",
"utilities/memory/memory_test.cc",
@@ -1362,13 +1300,6 @@ ROCKS_TESTS = [
[],
[],
],
[
"random_access_file_reader_test",
"file/random_access_file_reader_test.cc",
"serial",
[],
[],
],
[
"random_test",
"util/random_test.cc",
@@ -1495,13 +1426,6 @@ ROCKS_TESTS = [
[],
[],
],
[
"testutil_test",
"test_util/testutil_test.cc",
"serial",
[],
[],
],
[
"thread_list_test",
"util/thread_list_test.cc",
@@ -1523,13 +1447,6 @@ ROCKS_TESTS = [
[],
[],
],
[
"timer_test",
"util/timer_test.cc",
"serial",
[],
[],
],
[
"trace_analyzer_test",
"tools/trace_analyzer_test.cc",
@@ -1537,13 +1454,6 @@ ROCKS_TESTS = [
[],
[],
],
[
"transaction_lock_mgr_test",
"utilities/transactions/transaction_lock_mgr_test.cc",
"parallel",
[],
[],
],
[
"transaction_test",
"utilities/transactions/transaction_test.cc",
@@ -1593,13 +1503,6 @@ ROCKS_TESTS = [
[],
[],
],
[
"work_queue_test",
"util/work_queue_test.cc",
"serial",
[],
[],
],
[
"write_batch_test",
"db/write_batch_test.cc",
@@ -1655,17 +1558,18 @@ ROCKS_TESTS = [
# Do not build the tests in opt mode, since SyncPoint and other test code
# will not be included.
[
cpp_unittest(
name = test_name,
srcs = [test_cc],
arch_preprocessor_flags = ROCKSDB_ARCH_PREPROCESSOR_FLAGS,
os_preprocessor_flags = ROCKSDB_OS_PREPROCESSOR_FLAGS,
compiler_flags = ROCKSDB_COMPILER_FLAGS,
preprocessor_flags = ROCKSDB_PREPROCESSOR_FLAGS,
deps = [":rocksdb_test_lib"] + extra_deps,
external_deps = ROCKSDB_EXTERNAL_DEPS + [
("googletest", None, "gtest"),
],
test_binary(
extra_compiler_flags = extra_compiler_flags,
extra_deps = extra_deps,
parallelism = parallelism,
rocksdb_arch_preprocessor_flags = ROCKSDB_ARCH_PREPROCESSOR_FLAGS,
rocksdb_compiler_flags = ROCKSDB_COMPILER_FLAGS,
rocksdb_external_deps = ROCKSDB_EXTERNAL_DEPS,
rocksdb_os_deps = ROCKSDB_OS_DEPS,
rocksdb_os_preprocessor_flags = ROCKSDB_OS_PREPROCESSOR_FLAGS,
rocksdb_preprocessor_flags = ROCKSDB_PREPROCESSOR_FLAGS,
test_cc = test_cc,
test_name = test_name,
)
for test_name, test_cc, parallelism, extra_deps, extra_compiler_flags in ROCKS_TESTS
if not is_opt_mode
-3
View File
@@ -106,6 +106,3 @@ LzLabs is using RocksDB as a storage engine in their multi-database distributed
## Nebula Graph
[Nebula Graph](https://github.com/vesoft-inc/nebula) is a distributed, scalable, lightning-fast, open source graph database capable of hosting super large scale graphs with dozens of billions of vertices (nodes) and trillions of edges, with milliseconds of latency.
## YugabyteDB
[YugabyteDB](https://www.yugabyte.com/) is an open source, high performance, distributed SQL database that uses RocksDB as its storage layer. For more information, please see https://github.com/yugabyte/yugabyte-db/.
+4 -6
View File
@@ -1,6 +1,6 @@
version: 1.0.{build}
image: Visual Studio 2019
image: Visual Studio 2017
environment:
JAVA_HOME: C:\Program Files\Java\jdk1.8.0
@@ -34,8 +34,7 @@ install:
- cd snappy-1.1.7
- mkdir build
- cd build
- if DEFINED CMAKE_PLATEFORM_NAME (set "PLATEFORM_OPT=-A %CMAKE_PLATEFORM_NAME%")
- cmake .. -G "%CMAKE_GENERATOR%" %PLATEFORM_OPT%
- cmake -G "%CMAKE_GENERATOR%" ..
- msbuild Snappy.sln /p:Configuration=Debug /p:Platform=x64
- msbuild Snappy.sln /p:Configuration=Release /p:Platform=x64
- echo "Building LZ4 dependency..."
@@ -58,8 +57,7 @@ install:
before_build:
- md %APPVEYOR_BUILD_FOLDER%\build
- cd %APPVEYOR_BUILD_FOLDER%\build
- if DEFINED CMAKE_PLATEFORM_NAME (set "PLATEFORM_OPT=-A %CMAKE_PLATEFORM_NAME%")
- cmake .. -G "%CMAKE_GENERATOR%" %PLATEFORM_OPT% %CMAKE_OPT% -DCMAKE_BUILD_TYPE=Debug -DOPTDBG=1 -DPORTABLE=1 -DSNAPPY=1 -DLZ4=1 -DZSTD=1 -DXPRESS=1 -DJNI=1 -DWITH_ALL_TESTS=0
- cmake -G "%CMAKE_GENERATOR%" -DCMAKE_BUILD_TYPE=Debug -DOPTDBG=1 -DPORTABLE=1 -DSNAPPY=1 -DLZ4=1 -DZSTD=1 -DXPRESS=1 -DJNI=1 ..
- cd ..
build:
@@ -70,7 +68,7 @@ build:
test:
test_script:
- ps: build_tools\run_ci_db_test.ps1 -SuiteRun db_basic_test,env_basic_test -Concurrency 8
- ps: build_tools\run_ci_db_test.ps1 -SuiteRun db_basic_test,db_with_timestamp_basic_test,db_test2,db_test,env_basic_test,env_test,db_merge_operand_test -Concurrency 8
on_failure:
- cmd: 7z a build-failed.zip %APPVEYOR_BUILD_FOLDER%\build\ && appveyor PushArtifact build-failed.zip
+50 -48
View File
@@ -20,10 +20,10 @@ from util import ColorString
# User can pass extra dependencies as a JSON object via command line, and this
# script can include these dependencies in the generate TARGETS file.
# Usage:
# $python3 buckifier/buckify_rocksdb.py
# $python buckifier/buckify_rocksdb.py
# (This generates a TARGET file without user-specified dependency for unit
# tests.)
# $python3 buckifier/buckify_rocksdb.py \
# $python buckifier/buckify_rocksdb.py \
# '{"fake": { \
# "extra_deps": [":test_dep", "//fakes/module:mock1"], \
# "extra_compiler_flags": ["-DROCKSDB_LITE", "-Os"], \
@@ -48,8 +48,8 @@ def parse_src_mk(repo_path):
if '=' in line:
current_src = line.split('=')[0].strip()
src_files[current_src] = []
elif '.c' in line:
src_path = line.split('\\')[0].strip()
elif '.cc' in line:
src_path = line.split('.cc')[0].strip() + '.cc'
src_files[current_src].append(src_path)
return src_files
@@ -69,11 +69,27 @@ def get_cc_files(repo_path):
return cc_files
# Get parallel tests from Makefile
def get_parallel_tests(repo_path):
# Get tests from Makefile
def get_tests(repo_path):
Makefile = repo_path + "/Makefile"
s = set({})
# Dictionary TEST_NAME => IS_PARALLEL
tests = {}
found_tests = False
for line in open(Makefile):
line = line.strip()
if line.startswith("TESTS ="):
found_tests = True
elif found_tests:
if line.endswith("\\"):
# remove the trailing \
line = line[:-1]
line = line.strip()
tests[line] = False
else:
# we consumed all the tests
break
found_parallel_tests = False
for line in open(Makefile):
@@ -85,12 +101,13 @@ def get_parallel_tests(repo_path):
# remove the trailing \
line = line[:-1]
line = line.strip()
s.add(line)
tests[line] = True
else:
# we consumed all the parallel tests
break
return s
return tests
# Parse extra dependencies passed by user from command line
def get_dependencies():
@@ -123,14 +140,13 @@ def generate_targets(repo_path, deps_map):
src_mk = parse_src_mk(repo_path)
# get all .cc files
cc_files = get_cc_files(repo_path)
# get parallel tests from Makefile
parallel_tests = get_parallel_tests(repo_path)
# get tests from Makefile
tests = get_tests(repo_path)
if src_mk is None or cc_files is None or parallel_tests is None:
if src_mk is None or cc_files is None or tests is None:
return False
TARGETS = TARGETSBuilder("%s/TARGETS" % repo_path)
# rocksdb_lib
TARGETS.add_library(
"rocksdb_lib",
@@ -143,10 +159,7 @@ def generate_targets(repo_path, deps_map):
src_mk.get("TEST_LIB_SOURCES", []) +
src_mk.get("EXP_LIB_SOURCES", []) +
src_mk.get("ANALYZER_LIB_SOURCES", []),
[":rocksdb_lib"],
extra_external_deps=""" + [
("googletest", None, "gtest"),
]""")
[":rocksdb_lib"])
# rocksdb_tools_lib
TARGETS.add_library(
"rocksdb_tools_lib",
@@ -155,50 +168,40 @@ def generate_targets(repo_path, deps_map):
["test_util/testutil.cc"],
[":rocksdb_lib"])
# rocksdb_stress_lib
TARGETS.add_rocksdb_library(
TARGETS.add_library(
"rocksdb_stress_lib",
src_mk.get("ANALYZER_LIB_SOURCES", [])
+ src_mk.get('STRESS_LIB_SOURCES', [])
+ ["test_util/testutil.cc"])
print("Extra dependencies:\n{0}".format(json.dumps(deps_map)))
# Dictionary test executable name -> relative source file path
test_source_map = {}
print(src_mk)
# c_test.c is added through TARGETS.add_c_test(). If there
# are more than one .c test file, we need to extend
# TARGETS.add_c_test() to include other C tests too.
for test_src in src_mk.get("TEST_MAIN_SOURCES_C", []):
if test_src != 'db/c_test.c':
print("Don't know how to deal with " + test_src)
return False
TARGETS.add_c_test()
for test_src in src_mk.get("TEST_MAIN_SOURCES", []):
test = test_src.split('.c')[0].strip().split('/')[-1].strip()
test_source_map[test] = test_src
print("" + test + " " + test_src)
+ ["test_util/testutil.cc"],
[":rocksdb_lib"])
print("Extra dependencies:\n{0}".format(str(deps_map)))
# test for every test we found in the Makefile
for target_alias, deps in deps_map.items():
for test, test_src in sorted(test_source_map.items()):
if len(test) == 0:
print(ColorString.warning("Failed to get test name for %s" % test_src))
for test in sorted(tests):
match_src = [src for src in cc_files if ("/%s.c" % test) in src]
if len(match_src) == 0:
print(ColorString.warning("Cannot find .cc file for %s" % test))
continue
elif len(match_src) > 1:
print(ColorString.warning("Found more than one .cc for %s" % test))
print(match_src)
continue
assert(len(match_src) == 1)
is_parallel = tests[test]
test_target_name = \
test if not target_alias else test + "_" + target_alias
TARGETS.register_test(
test_target_name,
test_src,
test in parallel_tests,
json.dumps(deps['extra_deps']),
json.dumps(deps['extra_compiler_flags']))
match_src[0],
is_parallel,
deps['extra_deps'],
deps['extra_compiler_flags'])
if test in _EXPORTED_TEST_LIBS:
test_library = "%s_lib" % test_target_name
TARGETS.add_library(test_library, [test_src], [":rocksdb_test_lib"])
TARGETS.add_library(test_library, match_src, [":rocksdb_test_lib"])
TARGETS.flush_tests()
print(ColorString.info("Generated TARGETS Summary:"))
@@ -217,7 +220,6 @@ def get_rocksdb_path():
return rocksdb_path
def exit_with_error(msg):
print(ColorString.error(msg))
sys.exit(1)
-32
View File
@@ -1,32 +0,0 @@
#!/usr/bin/env bash
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
# If clang_format_diff.py command is not specfied, we assume we are able to
# access directly without any path.
TGT_DIFF=`git diff TARGETS | head -n 1`
if [ ! -z "$TGT_DIFF" ]
then
echo "TARGETS file has uncommitted changes. Skip this check."
exit 0
fi
echo Backup original TARGETS file.
cp TARGETS TARGETS.bkp
${PYTHON:-python3} buckifier/buckify_rocksdb.py
TGT_DIFF=`git diff TARGETS | head -n 1`
if [ -z "$TGT_DIFF" ]
then
mv TARGETS.bkp TARGETS
exit 0
else
echo "Please run '${PYTHON:-python3} buckifier/buckify_rocksdb.py' to update TARGETS file."
echo "Do not manually update TARGETS file."
${PYTHON:-python3} --version
mv TARGETS.bkp TARGETS
exit 1
fi
+3 -46
View File
@@ -28,8 +28,7 @@ class TARGETSBuilder(object):
def __init__(self, path):
self.path = path
self.targets_file = open(path, 'w')
header = targets_cfg.rocksdb_target_header_template
self.targets_file.write(header)
self.targets_file.write(targets_cfg.rocksdb_target_header)
self.total_lib = 0
self.total_bin = 0
self.total_test = 0
@@ -38,35 +37,17 @@ class TARGETSBuilder(object):
def __del__(self):
self.targets_file.close()
def add_library(self, name, srcs, deps=None, headers=None,
extra_external_deps=""):
def add_library(self, name, srcs, deps=None, headers=None):
headers_attr_prefix = ""
if headers is None:
headers_attr_prefix = "auto_"
headers = "AutoHeaders.RECURSIVE_GLOB"
else:
headers = "[" + pretty_list(headers) + "]"
self.targets_file.write(targets_cfg.library_template.format(
name=name,
srcs=pretty_list(srcs),
headers_attr_prefix=headers_attr_prefix,
headers=headers,
deps=pretty_list(deps),
extra_external_deps=extra_external_deps))
self.total_lib = self.total_lib + 1
def add_rocksdb_library(self, name, srcs, headers=None):
headers_attr_prefix = ""
if headers is None:
headers_attr_prefix = "auto_"
headers = "AutoHeaders.RECURSIVE_GLOB"
else:
headers = "[" + pretty_list(headers) + "]"
self.targets_file.write(targets_cfg.rocksdb_library_template.format(
name=name,
srcs=pretty_list(srcs),
headers_attr_prefix=headers_attr_prefix,
headers=headers))
deps=pretty_list(deps)))
self.total_lib = self.total_lib + 1
def add_binary(self, name, srcs, deps=None):
@@ -76,30 +57,6 @@ class TARGETSBuilder(object):
pretty_list(deps)))
self.total_bin = self.total_bin + 1
def add_c_test(self):
self.targets_file.write("""
if not is_opt_mode:
cpp_binary(
name = "c_test_bin",
srcs = ["db/c_test.c"],
arch_preprocessor_flags = ROCKSDB_ARCH_PREPROCESSOR_FLAGS,
os_preprocessor_flags = ROCKSDB_OS_PREPROCESSOR_FLAGS,
compiler_flags = ROCKSDB_COMPILER_FLAGS,
preprocessor_flags = ROCKSDB_PREPROCESSOR_FLAGS,
deps = [":rocksdb_test_lib"],
)
if not is_opt_mode:
custom_unittest(
"c_test",
command = [
native.package_name() + "/buckifier/rocks_test_runner.sh",
"$(location :{})".format("c_test_bin"),
],
type = "simple",
)
""")
def register_test(self,
test_name,
src,
+14 -33
View File
@@ -4,8 +4,7 @@ from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
rocksdb_target_header_template = \
"""# This file \100generated by `python3 buckifier/buckify_rocksdb.py`
rocksdb_target_header = """# This file \100generated by `python buckifier/buckify_rocksdb.py`
# --> DO NOT EDIT MANUALLY <--
# This file is a Facebook-specific integration for buck builds, so can
# only be validated by Facebook employees.
@@ -33,6 +32,7 @@ ROCKSDB_EXTERNAL_DEPS = [
("lz4", None, "lz4"),
("zstd", None),
("tbb", None),
("googletest", None, "gtest"),
]
ROCKSDB_OS_DEPS = [
@@ -114,11 +114,6 @@ ROCKSDB_OS_DEPS += ([(
"linux",
["third-party//jemalloc:headers"],
)] if sanitizer == "" else [])
ROCKSDB_LIB_DEPS = [
":rocksdb_lib",
":rocksdb_test_lib",
] if not is_opt_mode else [":rocksdb_lib"]
"""
@@ -133,21 +128,6 @@ cpp_library(
os_preprocessor_flags = ROCKSDB_OS_PREPROCESSOR_FLAGS,
preprocessor_flags = ROCKSDB_PREPROCESSOR_FLAGS,
deps = [{deps}],
external_deps = ROCKSDB_EXTERNAL_DEPS{extra_external_deps},
)
"""
rocksdb_library_template = """
cpp_library(
name = "{name}",
srcs = [{srcs}],
{headers_attr_prefix}headers = {headers},
arch_preprocessor_flags = ROCKSDB_ARCH_PREPROCESSOR_FLAGS,
compiler_flags = ROCKSDB_COMPILER_FLAGS,
os_deps = ROCKSDB_OS_DEPS,
os_preprocessor_flags = ROCKSDB_OS_PREPROCESSOR_FLAGS,
preprocessor_flags = ROCKSDB_PREPROCESSOR_FLAGS,
deps = ROCKSDB_LIB_DEPS,
external_deps = ROCKSDB_EXTERNAL_DEPS,
)
"""
@@ -182,17 +162,18 @@ ROCKS_TESTS = [
# Do not build the tests in opt mode, since SyncPoint and other test code
# will not be included.
[
cpp_unittest(
name = test_name,
srcs = [test_cc],
arch_preprocessor_flags = ROCKSDB_ARCH_PREPROCESSOR_FLAGS,
os_preprocessor_flags = ROCKSDB_OS_PREPROCESSOR_FLAGS,
compiler_flags = ROCKSDB_COMPILER_FLAGS,
preprocessor_flags = ROCKSDB_PREPROCESSOR_FLAGS,
deps = [":rocksdb_test_lib"] + extra_deps,
external_deps = ROCKSDB_EXTERNAL_DEPS + [
("googletest", None, "gtest"),
],
test_binary(
extra_compiler_flags = extra_compiler_flags,
extra_deps = extra_deps,
parallelism = parallelism,
rocksdb_arch_preprocessor_flags = ROCKSDB_ARCH_PREPROCESSOR_FLAGS,
rocksdb_compiler_flags = ROCKSDB_COMPILER_FLAGS,
rocksdb_external_deps = ROCKSDB_EXTERNAL_DEPS,
rocksdb_os_deps = ROCKSDB_OS_DEPS,
rocksdb_os_preprocessor_flags = ROCKSDB_OS_PREPROCESSOR_FLAGS,
rocksdb_preprocessor_flags = ROCKSDB_PREPROCESSOR_FLAGS,
test_cc = test_cc,
test_name = test_name,
)
for test_name, test_cc, parallelism, extra_deps, extra_compiler_flags in ROCKS_TESTS
if not is_opt_mode
+12 -71
View File
@@ -28,7 +28,6 @@
# -DZSTD if the ZSTD library is present
# -DNUMA if the NUMA library is present
# -DTBB if the TBB library is present
# -DMEMKIND if the memkind library is present
#
# Using gflags in rocksdb:
# Our project depends on gflags, which requires users to take some extra steps
@@ -89,16 +88,6 @@ if test -z "$CXX"; then
fi
fi
if test -z "$AR"; then
if [ -x "$(command -v gcc-ar)" ]; then
AR=gcc-ar
elif [ -x "$(command -v llvm-ar)" ]; then
AR=llvm-ar
else
AR=ar
fi
fi
# Detect OS
if test -z "$TARGET_OS"; then
TARGET_OS=`uname -s`
@@ -161,7 +150,7 @@ case "$TARGET_OS" in
else
PLATFORM_LDFLAGS="$PLATFORM_LDFLAGS -latomic"
fi
PLATFORM_LDFLAGS="$PLATFORM_LDFLAGS -lpthread -lrt -ldl"
PLATFORM_LDFLAGS="$PLATFORM_LDFLAGS -lpthread -lrt"
if test $ROCKSDB_USE_IO_URING; then
# check for liburing
$CXX $CFLAGS -x c++ - -luring -o /dev/null 2>/dev/null <<EOF
@@ -202,17 +191,6 @@ EOF
PLATFORM_LDFLAGS="$PLATFORM_LDFLAGS -lpthread"
# PORT_FILES=port/freebsd/freebsd_specific.cc
;;
GNU/kFreeBSD)
PLATFORM=OS_GNU_KFREEBSD
COMMON_FLAGS="$COMMON_FLAGS -DOS_GNU_KFREEBSD"
if [ -z "$USE_CLANG" ]; then
COMMON_FLAGS="$COMMON_FLAGS -fno-builtin-memcmp"
else
PLATFORM_LDFLAGS="$PLATFORM_LDFLAGS -latomic"
fi
PLATFORM_LDFLAGS="$PLATFORM_LDFLAGS -lpthread -lrt"
# PORT_FILES=port/gnu_kfreebsd/gnu_kfreebsd_specific.cc
;;
NetBSD)
PLATFORM=OS_NETBSD
COMMON_FLAGS="$COMMON_FLAGS -fno-builtin-memcmp -D_REENTRANT -DOS_NETBSD"
@@ -267,10 +245,6 @@ JAVAC_ARGS="-source 7"
if [ "$CROSS_COMPILE" = "true" -o "$FBCODE_BUILD" = "true" ]; then
# Cross-compiling; do not try any compilation tests.
# Also don't need any compilation tests if compiling on fbcode
if [ "$FBCODE_BUILD" = "true" ]; then
# Enable backtrace on fbcode since the necessary libraries are present
COMMON_FLAGS="$COMMON_FLAGS -DROCKSDB_BACKTRACE"
fi
true
else
if ! test $ROCKSDB_DISABLE_FALLOCATE; then
@@ -306,32 +280,24 @@ EOF
# Test whether gflags library is installed
# http://gflags.github.io/gflags/
# check if the namespace is gflags
if $CXX $CFLAGS -x c++ - -o /dev/null 2>/dev/null << EOF
$CXX $CFLAGS -x c++ - -o /dev/null 2>/dev/null << EOF
#include <gflags/gflags.h>
using namespace GFLAGS_NAMESPACE;
int main() {}
EOF
then
COMMON_FLAGS="$COMMON_FLAGS -DGFLAGS=1"
PLATFORM_LDFLAGS="$PLATFORM_LDFLAGS -lgflags"
# check if namespace is gflags
elif $CXX $CFLAGS -x c++ - -o /dev/null 2>/dev/null << EOF
#include <gflags/gflags.h>
using namespace gflags;
int main() {}
EOF
then
COMMON_FLAGS="$COMMON_FLAGS -DGFLAGS=1 -DGFLAGS_NAMESPACE=gflags"
PLATFORM_LDFLAGS="$PLATFORM_LDFLAGS -lgflags"
# check if namespace is google
elif $CXX $CFLAGS -x c++ - -o /dev/null 2>/dev/null << EOF
if [ "$?" = 0 ]; then
COMMON_FLAGS="$COMMON_FLAGS -DGFLAGS=1"
PLATFORM_LDFLAGS="$PLATFORM_LDFLAGS -lgflags"
else
# check if namespace is google
$CXX $CFLAGS -x c++ - -o /dev/null 2>/dev/null << EOF
#include <gflags/gflags.h>
using namespace google;
int main() {}
EOF
then
COMMON_FLAGS="$COMMON_FLAGS -DGFLAGS=1 -DGFLAGS_NAMESPACE=google"
PLATFORM_LDFLAGS="$PLATFORM_LDFLAGS -lgflags"
if [ "$?" = 0 ]; then
COMMON_FLAGS="$COMMON_FLAGS -DGFLAGS=google"
PLATFORM_LDFLAGS="$PLATFORM_LDFLAGS -lgflags"
fi
fi
fi
@@ -460,22 +426,6 @@ EOF
fi
fi
if ! test $ROCKSDB_DISABLE_MEMKIND; then
# Test whether memkind library is installed
$CXX $CFLAGS $COMMON_FLAGS -lmemkind -x c++ - -o /dev/null 2>/dev/null <<EOF
#include <memkind.h>
int main() {
memkind_malloc(MEMKIND_DAX_KMEM, 1024);
return 0;
}
EOF
if [ "$?" = 0 ]; then
COMMON_FLAGS="$COMMON_FLAGS -DMEMKIND"
PLATFORM_LDFLAGS="$PLATFORM_LDFLAGS -lmemkind"
JAVA_LDFLAGS="$JAVA_LDFLAGS -lmemkind"
fi
fi
if ! test $ROCKSDB_DISABLE_PTHREAD_MUTEX_ADAPTIVE_NP; then
# Test whether PTHREAD_MUTEX_ADAPTIVE_NP mutex type is available
$CXX $CFLAGS -x c++ - -o /dev/null 2>/dev/null <<EOF
@@ -641,13 +591,6 @@ else
if test "$USE_SSE"; then
TRY_SSE_ETC="1"
fi
if [[ "${PLATFORM}" == "OS_MACOSX" ]]; then
# For portability compile for macOS 10.12 (2016) or newer
COMMON_FLAGS="$COMMON_FLAGS -mmacosx-version-min=10.12"
PLATFORM_LDFLAGS="$PLATFORM_LDFLAGS -mmacosx-version-min=10.12"
PLATFORM_SHARED_LDFLAGS="$PLATFORM_SHARED_LDFLAGS -mmacosx-version-min=10.12"
fi
fi
if test "$TRY_SSE_ETC"; then
@@ -741,7 +684,6 @@ EOF
fi
fi
if [ "$FBCODE_BUILD" != "true" -a "$PLATFORM" = OS_LINUX ]; then
$CXX $COMMON_FLAGS $PLATFORM_SHARED_CFLAGS -x c++ -c - -o test_dl.o 2>/dev/null <<EOF
void dummy_func() {}
@@ -766,7 +708,6 @@ ROCKSDB_PATCH=`build_tools/version.sh patch`
echo "CC=$CC" >> "$OUTPUT"
echo "CXX=$CXX" >> "$OUTPUT"
echo "AR=$AR" >> "$OUTPUT"
echo "PLATFORM=$PLATFORM" >> "$OUTPUT"
echo "PLATFORM_LDFLAGS=$PLATFORM_LDFLAGS" >> "$OUTPUT"
echo "JAVA_LDFLAGS=$JAVA_LDFLAGS" >> "$OUTPUT"
-2
View File
@@ -109,7 +109,6 @@ if [ -z "$USE_CLANG" ]; then
# gcc
CC="$GCC_BASE/bin/gcc"
CXX="$GCC_BASE/bin/g++"
AR="$GCC_BASE/bin/gcc-ar"
CFLAGS+=" -B$BINUTILS/gold"
CFLAGS+=" -isystem $GLIBC_INCLUDE"
@@ -120,7 +119,6 @@ else
CLANG_INCLUDE="$CLANG_LIB/clang/stable/include"
CC="$CLANG_BIN/clang"
CXX="$CLANG_BIN/clang++"
AR="$CLANG_BIN/llvm-ar"
KERNEL_HEADERS_INCLUDE="$KERNEL_HEADERS_BASE/include"
-2
View File
@@ -69,7 +69,6 @@ if [ -z "$USE_CLANG" ]; then
# gcc
CC="$GCC_BASE/bin/gcc"
CXX="$GCC_BASE/bin/g++"
CXX="$GCC_BASE/bin/gcc-ar"
CFLAGS="-B$BINUTILS/gold -m64 -mtune=generic"
CFLAGS+=" -isystem $GLIBC_INCLUDE"
@@ -82,7 +81,6 @@ else
CLANG_INCLUDE="$CLANG_LIB/clang/*/include"
CC="$CLANG_BIN/clang"
CXX="$CLANG_BIN/clang++"
AR="$CLANG_BIN/llvm-ar"
KERNEL_HEADERS_INCLUDE="$KERNEL_HEADERS_BASE/include/"
-2
View File
@@ -118,7 +118,6 @@ if [ -z "$USE_CLANG" ]; then
# gcc
CC="$GCC_BASE/bin/gcc"
CXX="$GCC_BASE/bin/g++"
AR="$GCC_BASE/bin/gcc-ar"
CFLAGS+=" -B$BINUTILS/gold"
CFLAGS+=" -isystem $LIBGCC_INCLUDE"
@@ -129,7 +128,6 @@ else
CLANG_INCLUDE="$CLANG_LIB/clang/stable/include"
CC="$CLANG_BIN/clang"
CXX="$CLANG_BIN/clang++"
AR="$CLANG_BIN/llvm-ar"
KERNEL_HEADERS_INCLUDE="$KERNEL_HEADERS_BASE/include"
+33 -99
View File
@@ -2,99 +2,41 @@
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
# If clang_format_diff.py command is not specfied, we assume we are able to
# access directly without any path.
if [ -z $CLANG_FORMAT_DIFF ]
then
CLANG_FORMAT_DIFF="clang-format-diff.py"
fi
print_usage () {
echo "Usage:"
echo "format-diff.sh [OPTIONS]"
echo "-c: check only."
echo "-h: print this message."
}
# Check clang-format-diff.py
if ! which $CLANG_FORMAT_DIFF &> /dev/null
then
echo "You didn't have clang-format-diff.py and/or clang-format available in your computer!"
echo "You can download clang-format-diff.py by running: "
echo " curl --location http://goo.gl/iUW1u2 -o ${CLANG_FORMAT_DIFF}"
echo "You can download clang-format by running:"
echo " brew install clang-format"
echo " Or"
echo " apt install clang-format"
echo " This might work too:"
echo " yum install git-clang-format"
echo "Then, move both files (i.e. ${CLANG_FORMAT_DIFF} and clang-format) to some directory within PATH=${PATH}"
echo "and make sure ${CLANG_FORMAT_DIFF} is executable."
exit 128
fi
while getopts ':ch' OPTION; do
case "$OPTION" in
c)
CHECK_ONLY=1
;;
h)
print_usage
exit 1
;;
?)
print_usage
exit 1
;;
esac
done
# Check argparse, a library that clang-format-diff.py requires.
python 2>/dev/null << EOF
import argparse
EOF
REPO_ROOT="$(git rev-parse --show-toplevel)"
if [ "$CLANG_FORMAT_DIFF" ]; then
echo "Note: CLANG_FORMAT_DIFF='$CLANG_FORMAT_DIFF'"
# Dry run to confirm dependencies like argparse
if $CLANG_FORMAT_DIFF --help >/dev/null < /dev/null; then
true #Good
else
exit 128
fi
else
# First try directly executing the possibilities
if clang-format-diff.py --help &> /dev/null < /dev/null; then
CLANG_FORMAT_DIFF=clang-format-diff.py
elif $REPO_ROOT/clang-format-diff.py --help &> /dev/null < /dev/null; then
CLANG_FORMAT_DIFF=$REPO_ROOT/clang-format-diff.py
else
# This probably means we need to directly invoke the interpreter.
# But first find clang-format-diff.py
if [ -f "$REPO_ROOT/clang-format-diff.py" ]; then
CFD_PATH="$REPO_ROOT/clang-format-diff.py"
elif which clang-format-diff.py &> /dev/null; then
CFD_PATH="$(which clang-format-diff.py)"
else
echo "You didn't have clang-format-diff.py and/or clang-format available in your computer!"
echo "You can download clang-format-diff.py by running: "
echo " curl --location http://goo.gl/iUW1u2 -o ${CLANG_FORMAT_DIFF}"
echo "You can download clang-format by running:"
echo " brew install clang-format"
echo " Or"
echo " apt install clang-format"
echo " This might work too:"
echo " yum install git-clang-format"
echo "Then, move both files (i.e. ${CLANG_FORMAT_DIFF} and clang-format) to some directory within PATH=${PATH}"
echo "and make sure ${CLANG_FORMAT_DIFF} is executable."
exit 128
fi
# Check argparse pre-req on interpreter, or it will fail
if echo import argparse | ${PYTHON:-python3}; then
true # Good
else
echo "To run clang-format-diff.py, we'll need the library "argparse" to be"
echo "installed. You can try either of the follow ways to install it:"
echo " 1. Manually download argparse: https://pypi.python.org/pypi/argparse"
echo " 2. easy_install argparse (if you have easy_install)"
echo " 3. pip install argparse (if you have pip)"
exit 129
fi
# Unfortunately, some machines have a Python2 clang-format-diff.py
# installed but only a Python3 interpreter installed. Rather than trying
# different Python versions that might be installed, we can try migrating
# the code to Python3 if it looks like Python2
if grep -q "print '" "$CFD_PATH" && \
${PYTHON:-python3} --version | grep -q 'ython 3'; then
if [ ! -f "$REPO_ROOT/.py3/clang-format-diff.py" ]; then
echo "Migrating $CFD_PATH to Python3 in a hidden file"
mkdir -p "$REPO_ROOT/.py3"
${PYTHON:-python3} -m lib2to3 -w -n -o "$REPO_ROOT/.py3" "$CFD_PATH" > /dev/null || exit 128
fi
CFD_PATH="$REPO_ROOT/.py3/clang-format-diff.py"
fi
CLANG_FORMAT_DIFF="${PYTHON:-python3} $CFD_PATH"
# This had better work after all those checks
if $CLANG_FORMAT_DIFF --help >/dev/null < /dev/null; then
true #Good
else
exit 128
fi
fi
if [ "$?" != 0 ]
then
echo "To run clang-format-diff.py, we'll need the library "argparse" to be"
echo "installed. You can try either of the follow ways to install it:"
echo " 1. Manually download argparse: https://pypi.python.org/pypi/argparse"
echo " 2. easy_install argparse (if you have easy_install)"
echo " 3. pip install argparse (if you have pip)"
exit 129
fi
# TODO(kailiu) following work is not complete since we still need to figure
@@ -145,14 +87,6 @@ if [ -z "$diffs" ]
then
echo "Nothing needs to be reformatted!"
exit 0
elif [ $CHECK_ONLY ]
then
echo "Your change has unformatted code. Please run make format!"
if [ $VERBOSE_CHECK ]; then
clang-format --version
echo "$diffs"
fi
exit 1
fi
# Highlight the insertion/deletion from the clang-format-diff.py's output
@@ -187,7 +121,7 @@ if [ -z "$uncommitted_code" ]
then
git diff -U0 "$FORMAT_UPSTREAM_MERGE_BASE" | $CLANG_FORMAT_DIFF -i -p 1
else
git diff -U0 HEAD | $CLANG_FORMAT_DIFF -i -p 1
git diff -U0 HEAD^ | $CLANG_FORMAT_DIFF -i -p 1
fi
echo "Files reformatted!"
+1 -231
View File
@@ -421,66 +421,6 @@ STRESS_CRASH_TEST_COMMANDS="[
}
]"
#
# RocksDB blackbox stress/crash test
#
BLACKBOX_STRESS_CRASH_TEST_COMMANDS="[
{
'name':'Rocksdb Blackbox Stress and Crash Test',
'oncall':'$ONCALL',
'executeLocal': 'true',
'timeout': 86400,
'steps': [
$CLEANUP_ENV,
{
'name':'Build and run RocksDB debug stress tests',
'shell':'$SHM $DEBUG $NON_TSAN_CRASH make J=1 db_stress || $CONTRUN_NAME=db_stress $TASK_CREATION_TOOL',
'user':'root',
$PARSER
},
{
'name':'Build and run RocksDB debug blackbox crash tests',
'timeout': 86400,
'shell':'$SHM $DEBUG $NON_TSAN_CRASH make J=1 blackbox_crash_test || $CONTRUN_NAME=blackbox_crash_test $TASK_CREATION_TOOL',
'user':'root',
$PARSER
},
$UPLOAD_DB_DIR,
],
$REPORT
}
]"
#
# RocksDB whitebox stress/crash test
#
WHITEBOX_STRESS_CRASH_TEST_COMMANDS="[
{
'name':'Rocksdb Whitebox Stress and Crash Test',
'oncall':'$ONCALL',
'executeLocal': 'true',
'timeout': 86400,
'steps': [
$CLEANUP_ENV,
{
'name':'Build and run RocksDB debug stress tests',
'shell':'$SHM $DEBUG $NON_TSAN_CRASH make J=1 db_stress || $CONTRUN_NAME=db_stress $TASK_CREATION_TOOL',
'user':'root',
$PARSER
},
{
'name':'Build and run RocksDB debug whitebox crash tests',
'timeout': 86400,
'shell':'$SHM $DEBUG $NON_TSAN_CRASH make J=1 whitebox_crash_test || $CONTRUN_NAME=whitebox_crash_test $TASK_CREATION_TOOL',
'user':'root',
$PARSER
},
$UPLOAD_DB_DIR,
],
$REPORT
}
]"
#
# RocksDB stress/crash test with atomic flush
#
@@ -609,54 +549,6 @@ ASAN_CRASH_TEST_COMMANDS="[
}
]"
#
# RocksDB blackbox crash testing under address sanitizer
#
ASAN_BLACKBOX_CRASH_TEST_COMMANDS="[
{
'name':'Rocksdb blackbox crash test under ASAN',
'oncall':'$ONCALL',
'executeLocal': 'true',
'timeout': 86400,
'steps': [
$CLEANUP_ENV,
{
'name':'Build and run RocksDB debug blackbox asan_crash_test',
'timeout': 86400,
'shell':'$SHM $DEBUG $NON_TSAN_CRASH make J=1 blackbox_asan_crash_test || $CONTRUN_NAME=blackbox_asan_crash_test $TASK_CREATION_TOOL',
'user':'root',
$PARSER
},
$UPLOAD_DB_DIR,
],
$REPORT
}
]"
#
# RocksDB whitebox crash testing under address sanitizer
#
ASAN_WHITEBOX_CRASH_TEST_COMMANDS="[
{
'name':'Rocksdb whitebox crash test under ASAN',
'oncall':'$ONCALL',
'executeLocal': 'true',
'timeout': 86400,
'steps': [
$CLEANUP_ENV,
{
'name':'Build and run RocksDB debug whitebox asan_crash_test',
'timeout': 86400,
'shell':'$SHM $DEBUG $NON_TSAN_CRASH make J=1 whitebox_asan_crash_test || $CONTRUN_NAME=whitebox_asan_crash_test $TASK_CREATION_TOOL',
'user':'root',
$PARSER
},
$UPLOAD_DB_DIR,
],
$REPORT
}
]"
#
# RocksDB crash testing with atomic flush under address sanitizer
#
@@ -727,7 +619,7 @@ UBSAN_TEST_COMMANDS="[
]"
#
# RocksDB crash testing under undefined behavior sanitizer
# RocksDB crash testing under udnefined behavior sanitizer
#
UBSAN_CRASH_TEST_COMMANDS="[
{
@@ -750,54 +642,6 @@ UBSAN_CRASH_TEST_COMMANDS="[
}
]"
#
# RocksDB crash testing under undefined behavior sanitizer
#
UBSAN_BLACKBOX_CRASH_TEST_COMMANDS="[
{
'name':'Rocksdb blackbox crash test under UBSAN',
'oncall':'$ONCALL',
'executeLocal': 'true',
'timeout': 86400,
'steps': [
$CLEANUP_ENV,
{
'name':'Build and run RocksDB debug blackbox ubsan_crash_test',
'timeout': 86400,
'shell':'$SHM $DEBUG $NON_TSAN_CRASH $CLANG make J=1 blackbox_ubsan_crash_test || $CONTRUN_NAME=blackbox_ubsan_crash_test $TASK_CREATION_TOOL',
'user':'root',
$PARSER
},
$UPLOAD_DB_DIR,
],
$REPORT
}
]"
#
# RocksDB crash testing under undefined behavior sanitizer
#
UBSAN_WHITEBOX_CRASH_TEST_COMMANDS="[
{
'name':'Rocksdb whitebox crash test under UBSAN',
'oncall':'$ONCALL',
'executeLocal': 'true',
'timeout': 86400,
'steps': [
$CLEANUP_ENV,
{
'name':'Build and run RocksDB debug whitebox ubsan_crash_test',
'timeout': 86400,
'shell':'$SHM $DEBUG $NON_TSAN_CRASH $CLANG make J=1 whitebox_ubsan_crash_test || $CONTRUN_NAME=whitebox_ubsan_crash_test $TASK_CREATION_TOOL',
'user':'root',
$PARSER
},
$UPLOAD_DB_DIR,
],
$REPORT
}
]"
#
# RocksDB crash testing with atomic flush under undefined behavior sanitizer
#
@@ -916,54 +760,6 @@ TSAN_CRASH_TEST_COMMANDS="[
}
]"
#
# RocksDB blackbox crash test under TSAN
#
TSAN_BLACKBOX_CRASH_TEST_COMMANDS="[
{
'name':'Rocksdb Blackbox Crash Test under TSAN',
'oncall':'$ONCALL',
'executeLocal': 'true',
'timeout': 86400,
'steps': [
$CLEANUP_ENV,
{
'name':'Compile and run',
'timeout': 86400,
'shell':'set -o pipefail && $SHM $DEBUG $TSAN $TSAN_CRASH CRASH_TEST_KILL_ODD=1887 make J=1 blackbox_crash_test || $CONTRUN_NAME=tsan_blackbox_crash_test $TASK_CREATION_TOOL',
'user':'root',
$PARSER
},
$UPLOAD_DB_DIR,
],
$REPORT
}
]"
#
# RocksDB whitebox crash test under TSAN
#
TSAN_WHITEBOX_CRASH_TEST_COMMANDS="[
{
'name':'Rocksdb Whitebox Crash Test under TSAN',
'oncall':'$ONCALL',
'executeLocal': 'true',
'timeout': 86400,
'steps': [
$CLEANUP_ENV,
{
'name':'Compile and run',
'timeout': 86400,
'shell':'set -o pipefail && $SHM $DEBUG $TSAN $TSAN_CRASH CRASH_TEST_KILL_ODD=1887 make J=1 whitebox_crash_test || $CONTRUN_NAME=tsan_whitebox_crash_test $TASK_CREATION_TOOL',
'user':'root',
$PARSER
},
$UPLOAD_DB_DIR,
],
$REPORT
}
]"
#
# RocksDB crash test with atomic flush under TSAN
#
@@ -1022,8 +818,6 @@ run_format_compatible()
rm -rf /dev/shm/rocksdb
mkdir /dev/shm/rocksdb
export https_proxy="fwdproxy:8080"
tools/check_format_compatible.sh
}
@@ -1198,12 +992,6 @@ case $1 in
stress_crash)
echo $STRESS_CRASH_TEST_COMMANDS
;;
blackbox_stress_crash)
echo $BLACKBOX_STRESS_CRASH_TEST_COMMANDS
;;
whitebox_stress_crash)
echo $WHITEBOX_STRESS_CRASH_TEST_COMMANDS
;;
stress_crash_with_atomic_flush)
echo $STRESS_CRASH_TEST_WITH_ATOMIC_FLUSH_COMMANDS
;;
@@ -1219,12 +1007,6 @@ case $1 in
asan_crash)
echo $ASAN_CRASH_TEST_COMMANDS
;;
blackbox_asan_crash)
echo $ASAN_BLACKBOX_CRASH_TEST_COMMANDS
;;
whitebox_asan_crash)
echo $ASAN_WHITEBOX_CRASH_TEST_COMMANDS
;;
asan_crash_with_atomic_flush)
echo $ASAN_CRASH_TEST_WITH_ATOMIC_FLUSH_COMMANDS
;;
@@ -1237,12 +1019,6 @@ case $1 in
ubsan_crash)
echo $UBSAN_CRASH_TEST_COMMANDS
;;
blackbox_ubsan_crash)
echo $UBSAN_BLACKBOX_CRASH_TEST_COMMANDS
;;
whitebox_ubsan_crash)
echo $UBSAN_WHITEBOX_CRASH_TEST_COMMANDS
;;
ubsan_crash_with_atomic_flush)
echo $UBSAN_CRASH_TEST_WITH_ATOMIC_FLUSH_COMMANDS
;;
@@ -1258,12 +1034,6 @@ case $1 in
tsan_crash)
echo $TSAN_CRASH_TEST_COMMANDS
;;
blackbox_tsan_crash)
echo $TSAN_BLACKBOX_CRASH_TEST_COMMANDS
;;
whitebox_tsan_crash)
echo $TSAN_WHITEBOX_CRASH_TEST_COMMANDS
;;
tsan_crash_with_atomic_flush)
echo $TSAN_CRASH_TEST_WITH_ATOMIC_FLUSH_COMMANDS
;;
+5 -6
View File
@@ -1,9 +1,9 @@
#!/bin/bash
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
set -ex
set -e
ROCKSDB_VERSION="6.7.3"
ZSTD_VERSION="1.4.4"
ROCKSDB_VERSION="5.10.3"
ZSTD_VERSION="1.1.3"
echo "This script configures CentOS with everything needed to build and run RocksDB"
@@ -40,6 +40,5 @@ cd /usr/local/rocksdb
chown -R vagrant:vagrant /usr/local/rocksdb/
sudo -u vagrant make static_lib
cd examples/
sudo -u vagrant LD_LIBRARY_PATH=/usr/local/lib/ make all
sudo -u vagrant LD_LIBRARY_PATH=/usr/local/lib/ ./c_simple_example
sudo -u vagrant make all
sudo -u vagrant ./c_simple_example
-66
View File
@@ -1,66 +0,0 @@
// 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).
//
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "rocksdb/cache.h"
#include "cache/lru_cache.h"
#include "options/options_helper.h"
#include "util/string_util.h"
namespace ROCKSDB_NAMESPACE {
#ifndef ROCKSDB_LITE
static std::unordered_map<std::string, OptionTypeInfo>
lru_cache_options_type_info = {
{"capacity",
{offsetof(struct LRUCacheOptions, capacity), OptionType::kSizeT,
OptionVerificationType::kNormal, OptionTypeFlags::kMutable,
offsetof(struct LRUCacheOptions, capacity)}},
{"num_shard_bits",
{offsetof(struct LRUCacheOptions, num_shard_bits), OptionType::kInt,
OptionVerificationType::kNormal, OptionTypeFlags::kMutable,
offsetof(struct LRUCacheOptions, num_shard_bits)}},
{"strict_capacity_limit",
{offsetof(struct LRUCacheOptions, strict_capacity_limit),
OptionType::kBoolean, OptionVerificationType::kNormal,
OptionTypeFlags::kMutable,
offsetof(struct LRUCacheOptions, strict_capacity_limit)}},
{"high_pri_pool_ratio",
{offsetof(struct LRUCacheOptions, high_pri_pool_ratio),
OptionType::kDouble, OptionVerificationType::kNormal,
OptionTypeFlags::kMutable,
offsetof(struct LRUCacheOptions, high_pri_pool_ratio)}}};
#endif // ROCKSDB_LITE
Status Cache::CreateFromString(const ConfigOptions& config_options,
const std::string& value,
std::shared_ptr<Cache>* result) {
Status status;
std::shared_ptr<Cache> cache;
if (value.find('=') == std::string::npos) {
cache = NewLRUCache(ParseSizeT(value));
} else {
#ifndef ROCKSDB_LITE
LRUCacheOptions cache_opts;
status = OptionTypeInfo::ParseStruct(
config_options, "", &lru_cache_options_type_info, "", value,
reinterpret_cast<char*>(&cache_opts));
if (status.ok()) {
cache = NewLRUCache(cache_opts);
}
#else
(void)config_options;
status = Status::NotSupported("Cannot load cache in LITE mode ", value);
#endif //! ROCKSDB_LITE
}
if (status.ok()) {
result->swap(cache);
}
return status;
}
} // namespace ROCKSDB_NAMESPACE
+62 -162
View File
@@ -14,47 +14,34 @@ int main() {
#include <stdio.h>
#include <sys/types.h>
#include <cinttypes>
#include <limits>
#include "port/port.h"
#include "rocksdb/cache.h"
#include "rocksdb/db.h"
#include "rocksdb/env.h"
#include "util/coding.h"
#include "util/gflags_compat.h"
#include "util/hash.h"
#include "util/mutexlock.h"
#include "util/random.h"
using GFLAGS_NAMESPACE::ParseCommandLineFlags;
static constexpr uint32_t KiB = uint32_t{1} << 10;
static constexpr uint32_t MiB = KiB << 10;
static constexpr uint64_t GiB = MiB << 10;
static const uint32_t KB = 1024;
DEFINE_uint32(threads, 16, "Number of concurrent threads to run.");
DEFINE_uint64(cache_size, 1 * GiB,
"Number of bytes to use as a cache of uncompressed data.");
DEFINE_uint32(num_shard_bits, 6, "shard_bits.");
DEFINE_int32(threads, 16, "Number of concurrent threads to run.");
DEFINE_int64(cache_size, 8 * KB * KB,
"Number of bytes to use as a cache of uncompressed data.");
DEFINE_int32(num_shard_bits, 4, "shard_bits.");
DEFINE_double(resident_ratio, 0.25,
"Ratio of keys fitting in cache to keyspace.");
DEFINE_uint64(ops_per_thread, 0,
"Number of operations per thread. (Default: 5 * keyspace size)");
DEFINE_uint32(value_bytes, 8 * KiB, "Size of each value added.");
DEFINE_int64(max_key, 1 * KB * KB * KB, "Max number of key to place in cache");
DEFINE_uint64(ops_per_thread, 1200000, "Number of operations per thread.");
DEFINE_uint32(skew, 5, "Degree of skew in key selection");
DEFINE_bool(populate_cache, true, "Populate cache before operations");
DEFINE_uint32(lookup_insert_percent, 87,
"Ratio of lookup (+ insert on not found) to total workload "
"(expressed as a percentage)");
DEFINE_uint32(insert_percent, 2,
"Ratio of insert to total workload (expressed as a percentage)");
DEFINE_uint32(lookup_percent, 10,
"Ratio of lookup to total workload (expressed as a percentage)");
DEFINE_uint32(erase_percent, 1,
"Ratio of erase to total workload (expressed as a percentage)");
DEFINE_bool(populate_cache, false, "Populate cache before operations");
DEFINE_int32(insert_percent, 40,
"Ratio of insert to total workload (expressed as a percentage)");
DEFINE_int32(lookup_percent, 50,
"Ratio of lookup to total workload (expressed as a percentage)");
DEFINE_int32(erase_percent, 10,
"Ratio of erase to total workload (expressed as a percentage)");
DEFINE_bool(use_clock_cache, false, "");
@@ -62,15 +49,21 @@ namespace ROCKSDB_NAMESPACE {
class CacheBench;
namespace {
void deleter(const Slice& /*key*/, void* value) {
delete reinterpret_cast<char *>(value);
}
// State shared by all concurrent executions of the same benchmark.
class SharedState {
public:
explicit SharedState(CacheBench* cache_bench)
: cv_(&mu_),
num_threads_(FLAGS_threads),
num_initialized_(0),
start_(false),
num_done_(0),
cache_bench_(cache_bench) {}
cache_bench_(cache_bench) {
}
~SharedState() {}
@@ -94,9 +87,13 @@ class SharedState {
num_done_++;
}
bool AllInitialized() const { return num_initialized_ >= FLAGS_threads; }
bool AllInitialized() const {
return num_initialized_ >= num_threads_;
}
bool AllDone() const { return num_done_ >= FLAGS_threads; }
bool AllDone() const {
return num_done_ >= num_threads_;
}
void SetStart() {
start_ = true;
@@ -110,6 +107,7 @@ class SharedState {
port::Mutex mu_;
port::CondVar cv_;
const uint64_t num_threads_;
uint64_t num_initialized_;
bool start_;
uint64_t num_done_;
@@ -120,69 +118,17 @@ class SharedState {
// Per-thread state for concurrent executions of the same benchmark.
struct ThreadState {
uint32_t tid;
Random64 rnd;
Random rnd;
SharedState* shared;
ThreadState(uint32_t index, SharedState* _shared)
: tid(index), rnd(1000 + index), shared(_shared) {}
};
struct KeyGen {
char key_data[27];
Slice GetRand(Random64& rnd, uint64_t max_key) {
uint64_t raw = rnd.Next();
// Skew according to setting
for (uint32_t i = 0; i < FLAGS_skew; ++i) {
raw = std::min(raw, rnd.Next());
}
uint64_t key = fastrange64(raw, max_key);
// Variable size and alignment
size_t off = key % 8;
key_data[0] = char{42};
EncodeFixed64(key_data + 1, key);
key_data[9] = char{11};
EncodeFixed64(key_data + 10, key);
key_data[18] = char{4};
EncodeFixed64(key_data + 19, key);
return Slice(&key_data[off], sizeof(key_data) - off);
}
};
char* createValue(Random64& rnd) {
char* rv = new char[FLAGS_value_bytes];
// Fill with some filler data, and take some CPU time
for (uint32_t i = 0; i < FLAGS_value_bytes; i += 8) {
EncodeFixed64(rv + i, rnd.Next());
}
return rv;
}
void deleter(const Slice& /*key*/, void* value) {
delete[] static_cast<char*>(value);
}
} // namespace
class CacheBench {
static constexpr uint64_t kHundredthUint64 =
std::numeric_limits<uint64_t>::max() / 100U;
public:
CacheBench()
: max_key_(static_cast<uint64_t>(FLAGS_cache_size / FLAGS_resident_ratio /
FLAGS_value_bytes)),
lookup_insert_threshold_(kHundredthUint64 *
FLAGS_lookup_insert_percent),
insert_threshold_(lookup_insert_threshold_ +
kHundredthUint64 * FLAGS_insert_percent),
lookup_threshold_(insert_threshold_ +
kHundredthUint64 * FLAGS_lookup_percent),
erase_threshold_(lookup_threshold_ +
kHundredthUint64 * FLAGS_erase_percent) {
if (erase_threshold_ != 100U * kHundredthUint64) {
fprintf(stderr, "Percentages must add to 100.\n");
exit(1);
}
CacheBench() : num_threads_(FLAGS_threads) {
if (FLAGS_use_clock_cache) {
cache_ = NewClockCache(FLAGS_cache_size, FLAGS_num_shard_bits);
if (!cache_) {
@@ -192,19 +138,18 @@ class CacheBench {
} else {
cache_ = NewLRUCache(FLAGS_cache_size, FLAGS_num_shard_bits);
}
if (FLAGS_ops_per_thread == 0) {
FLAGS_ops_per_thread = 5 * max_key_;
}
}
~CacheBench() {}
void PopulateCache() {
Random64 rnd(1);
KeyGen keygen;
for (uint64_t i = 0; i < 2 * FLAGS_cache_size; i += FLAGS_value_bytes) {
cache_->Insert(keygen.GetRand(rnd, max_key_), createValue(rnd),
FLAGS_value_bytes, &deleter);
Random rnd(1);
for (int64_t i = 0; i < FLAGS_cache_size; i++) {
uint64_t rand_key = rnd.Next() % FLAGS_max_key;
// Cast uint64* to be char*, data would be copied to cache
Slice key(reinterpret_cast<char*>(&rand_key), 8);
// do insert
cache_->Insert(key, new char[10], 1, &deleter);
}
}
@@ -213,10 +158,10 @@ class CacheBench {
PrintEnv();
SharedState shared(this);
std::vector<std::unique_ptr<ThreadState> > threads(FLAGS_threads);
for (uint32_t i = 0; i < FLAGS_threads; i++) {
threads[i].reset(new ThreadState(i, &shared));
env->StartThread(ThreadBody, threads[i].get());
std::vector<ThreadState*> threads(num_threads_);
for (uint32_t i = 0; i < num_threads_; i++) {
threads[i] = new ThreadState(i, &shared);
env->StartThread(ThreadBody, threads[i]);
}
{
MutexLock l(shared.GetMutex());
@@ -247,15 +192,10 @@ class CacheBench {
private:
std::shared_ptr<Cache> cache_;
const uint64_t max_key_;
// Cumulative thresholds in the space of a random uint64_t
const uint64_t lookup_insert_threshold_;
const uint64_t insert_threshold_;
const uint64_t lookup_threshold_;
const uint64_t erase_threshold_;
uint32_t num_threads_;
static void ThreadBody(void* v) {
ThreadState* thread = static_cast<ThreadState*>(v);
ThreadState* thread = reinterpret_cast<ThreadState*>(v);
SharedState* shared = thread->shared;
{
@@ -280,78 +220,40 @@ class CacheBench {
}
void OperateCache(ThreadState* thread) {
// To use looked-up values
uint64_t result = 0;
// To hold handles for a non-trivial amount of time
Cache::Handle* handle = nullptr;
KeyGen gen;
for (uint64_t i = 0; i < FLAGS_ops_per_thread; i++) {
Slice key = gen.GetRand(thread->rnd, max_key_);
uint64_t random_op = thread->rnd.Next();
if (random_op < lookup_insert_threshold_) {
if (handle) {
cache_->Release(handle);
handle = nullptr;
}
// do lookup
handle = cache_->Lookup(key);
if (handle) {
// do something with the data
result += NPHash64(static_cast<char*>(cache_->Value(handle)),
FLAGS_value_bytes);
} else {
// do insert
cache_->Insert(key, createValue(thread->rnd), FLAGS_value_bytes,
&deleter, &handle);
}
} else if (random_op < insert_threshold_) {
if (handle) {
cache_->Release(handle);
handle = nullptr;
}
uint64_t rand_key = thread->rnd.Next() % FLAGS_max_key;
// Cast uint64* to be char*, data would be copied to cache
Slice key(reinterpret_cast<char*>(&rand_key), 8);
int32_t prob_op = thread->rnd.Uniform(100);
if (prob_op >= 0 && prob_op < FLAGS_insert_percent) {
// do insert
cache_->Insert(key, createValue(thread->rnd), FLAGS_value_bytes,
&deleter, &handle);
} else if (random_op < lookup_threshold_) {
cache_->Insert(key, new char[10], 1, &deleter);
} else if (prob_op -= FLAGS_insert_percent &&
prob_op < FLAGS_lookup_percent) {
// do lookup
auto handle = cache_->Lookup(key);
if (handle) {
cache_->Release(handle);
handle = nullptr;
}
// do lookup
handle = cache_->Lookup(key);
if (handle) {
// do something with the data
result += NPHash64(static_cast<char*>(cache_->Value(handle)),
FLAGS_value_bytes);
}
} else if (random_op < erase_threshold_) {
} else if (prob_op -= FLAGS_lookup_percent &&
prob_op < FLAGS_erase_percent) {
// do erase
cache_->Erase(key);
} else {
// Should be extremely unlikely (noop)
assert(random_op >= kHundredthUint64 * 100U);
}
}
if (handle) {
cache_->Release(handle);
handle = nullptr;
}
}
void PrintEnv() const {
printf("RocksDB version : %d.%d\n", kMajorVersion, kMinorVersion);
printf("Number of threads : %u\n", FLAGS_threads);
printf("Number of threads : %d\n", FLAGS_threads);
printf("Ops per thread : %" PRIu64 "\n", FLAGS_ops_per_thread);
printf("Cache size : %" PRIu64 "\n", FLAGS_cache_size);
printf("Num shard bits : %u\n", FLAGS_num_shard_bits);
printf("Max key : %" PRIu64 "\n", max_key_);
printf("Resident ratio : %g\n", FLAGS_resident_ratio);
printf("Skew degree : %u\n", FLAGS_skew);
printf("Populate cache : %d\n", int{FLAGS_populate_cache});
printf("Lookup+Insert pct : %u%%\n", FLAGS_lookup_insert_percent);
printf("Insert percentage : %u%%\n", FLAGS_insert_percent);
printf("Lookup percentage : %u%%\n", FLAGS_lookup_percent);
printf("Erase percentage : %u%%\n", FLAGS_erase_percent);
printf("Num shard bits : %d\n", FLAGS_num_shard_bits);
printf("Max key : %" PRIu64 "\n", FLAGS_max_key);
printf("Populate cache : %d\n", FLAGS_populate_cache);
printf("Insert percentage : %d%%\n", FLAGS_insert_percent);
printf("Lookup percentage : %d%%\n", FLAGS_lookup_percent);
printf("Erase percentage : %d%%\n", FLAGS_erase_percent);
printf("----------------------------\n");
}
};
@@ -368,8 +270,6 @@ int main(int argc, char** argv) {
ROCKSDB_NAMESPACE::CacheBench bench;
if (FLAGS_populate_cache) {
bench.PopulateCache();
printf("Population complete\n");
printf("----------------------------\n");
}
if (bench.Run()) {
return 0;
+4 -12
View File
@@ -182,7 +182,7 @@ struct CacheHandle {
void (*deleter)(const Slice&, void* value);
// Flags and counters associated with the cache handle:
// lowest bit: in-cache bit
// lowest bit: n-cache bit
// second lowest bit: usage bit
// the rest bits: reference count
// The handle is unused when flags equals to 0. The thread decreases the count
@@ -341,8 +341,7 @@ class ClockCacheShard final : public CacheShard {
CacheHandle* Insert(const Slice& key, uint32_t hash, void* value,
size_t change,
void (*deleter)(const Slice& key, void* value),
bool hold_reference, CleanupContext* context,
bool* overwritten);
bool hold_reference, CleanupContext* context);
// Guards list_, head_, and recycle_. In addition, updating table_ also has
// to hold the mutex, to avoid the cache being in inconsistent state.
@@ -565,8 +564,7 @@ void ClockCacheShard::SetStrictCapacityLimit(bool strict_capacity_limit) {
CacheHandle* ClockCacheShard::Insert(
const Slice& key, uint32_t hash, void* value, size_t charge,
void (*deleter)(const Slice& key, void* value), bool hold_reference,
CleanupContext* context, bool* overwritten) {
assert(overwritten != nullptr && *overwritten == false);
CleanupContext* context) {
size_t total_charge =
CacheHandle::CalcTotalCharge(key, charge, metadata_charge_policy_);
MutexLock l(&mutex_);
@@ -599,7 +597,6 @@ CacheHandle* ClockCacheShard::Insert(
handle->flags.store(flags, std::memory_order_relaxed);
HashTable::accessor accessor;
if (table_.find(accessor, CacheKey(key, hash))) {
*overwritten = true;
CacheHandle* existing_handle = accessor->second;
table_.erase(accessor);
UnsetInCache(existing_handle, context);
@@ -622,9 +619,8 @@ Status ClockCacheShard::Insert(const Slice& key, uint32_t hash, void* value,
char* key_data = new char[key.size()];
memcpy(key_data, key.data(), key.size());
Slice key_copy(key_data, key.size());
bool overwritten = false;
CacheHandle* handle = Insert(key_copy, hash, value, charge, deleter,
out_handle != nullptr, &context, &overwritten);
out_handle != nullptr, &context);
Status s;
if (out_handle != nullptr) {
if (handle == nullptr) {
@@ -633,10 +629,6 @@ Status ClockCacheShard::Insert(const Slice& key, uint32_t hash, void* value,
*out_handle = reinterpret_cast<Cache::Handle*>(handle);
}
}
if (overwritten) {
assert(s.ok());
s = Status::OkOverwritten();
}
Cleanup(context);
return s;
}
-1
View File
@@ -386,7 +386,6 @@ Status LRUCacheShard::Insert(const Slice& key, uint32_t hash, void* value,
LRUHandle* old = table_.Insert(e);
usage_ += total_charge;
if (old != nullptr) {
s = Status::OkOverwritten();
assert(old->InCache());
old->SetInCache(false);
if (!old->HasRefs()) {
-51
View File
@@ -1,54 +1,3 @@
@PACKAGE_INIT@
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/modules")
include(CMakeFindDependencyMacro)
set(GFLAGS_USE_TARGET_NAMESPACE @GFLAGS_USE_TARGET_NAMESPACE@)
if(@WITH_JEMALLOC@)
find_dependency(JeMalloc)
endif()
if(@WITH_GFLAGS@)
find_dependency(gflags CONFIG)
if(NOT gflags_FOUND)
find_dependency(gflags)
endif()
endif()
if(@WITH_SNAPPY@)
find_dependency(Snappy CONFIG)
if(NOT Snappy_FOUND)
find_dependency(Snappy)
endif()
endif()
if(@WITH_ZLIB@)
find_dependency(ZLIB)
endif()
if(@WITH_BZ2@)
find_dependency(BZip2)
endif()
if(@WITH_LZ4@)
find_dependency(lz4)
endif()
if(@WITH_ZSTD@)
find_dependency(zstd)
endif()
if(@WITH_NUMA@)
find_dependency(NUMA)
endif()
if(@WITH_TBB@)
find_dependency(TBB)
endif()
find_dependency(Threads)
include("${CMAKE_CURRENT_LIST_DIR}/RocksDBTargets.cmake")
check_required_components(RocksDB)
-7
View File
@@ -1,7 +0,0 @@
macro(get_cxx_std_flags FLAGS_VARIABLE)
if( CMAKE_CXX_STANDARD_REQUIRED )
set(${FLAGS_VARIABLE} ${CMAKE_CXX${CMAKE_CXX_STANDARD}_STANDARD_COMPILE_OPTION})
else()
set(${FLAGS_VARIABLE} ${CMAKE_CXX${CMAKE_CXX_STANDARD}_EXTENSION_COMPILE_OPTION})
endif()
endmacro()
-29
View File
@@ -1,29 +0,0 @@
# - Find Snappy
# Find the snappy compression library and includes
#
# Snappy_INCLUDE_DIRS - where to find snappy.h, etc.
# Snappy_LIBRARIES - List of libraries when using snappy.
# Snappy_FOUND - True if snappy found.
find_path(Snappy_INCLUDE_DIRS
NAMES snappy.h
HINTS ${snappy_ROOT_DIR}/include)
find_library(Snappy_LIBRARIES
NAMES snappy
HINTS ${snappy_ROOT_DIR}/lib)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(Snappy DEFAULT_MSG Snappy_LIBRARIES Snappy_INCLUDE_DIRS)
mark_as_advanced(
Snappy_LIBRARIES
Snappy_INCLUDE_DIRS)
if(Snappy_FOUND AND NOT (TARGET Snappy::snappy))
add_library (Snappy::snappy UNKNOWN IMPORTED)
set_target_properties(Snappy::snappy
PROPERTIES
IMPORTED_LOCATION ${Snappy_LIBRARIES}
INTERFACE_INCLUDE_DIRECTORIES ${Snappy_INCLUDE_DIRS})
endif()
+2 -2
View File
@@ -1,8 +1,8 @@
# - Find gflags library
# Find the gflags includes and library
#
# GFLAGS_INCLUDE_DIR - where to find gflags.h.
# GFLAGS_LIBRARIES - List of libraries when using gflags.
# gflags_INCLUDE_DIR - where to find gflags.h.
# gflags_LIBRARIES - List of libraries when using gflags.
# gflags_FOUND - True if gflags found.
find_path(GFLAGS_INCLUDE_DIR
+29
View File
@@ -0,0 +1,29 @@
# - Find Snappy
# Find the snappy compression library and includes
#
# snappy_INCLUDE_DIRS - where to find snappy.h, etc.
# snappy_LIBRARIES - List of libraries when using snappy.
# snappy_FOUND - True if snappy found.
find_path(snappy_INCLUDE_DIRS
NAMES snappy.h
HINTS ${snappy_ROOT_DIR}/include)
find_library(snappy_LIBRARIES
NAMES snappy
HINTS ${snappy_ROOT_DIR}/lib)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(snappy DEFAULT_MSG snappy_LIBRARIES snappy_INCLUDE_DIRS)
mark_as_advanced(
snappy_LIBRARIES
snappy_INCLUDE_DIRS)
if(snappy_FOUND AND NOT (TARGET snappy::snappy))
add_library (snappy::snappy UNKNOWN IMPORTED)
set_target_properties(snappy::snappy
PROPERTIES
IMPORTED_LOCATION ${snappy_LIBRARIES}
INTERFACE_INCLUDE_DIRECTORIES ${snappy_INCLUDE_DIRS})
endif()
+3 -6
View File
@@ -12,24 +12,21 @@ fi
ROOT=".."
# Fetch right version of gcov
if [ -d /mnt/gvfs/third-party -a -z "$CXX" ]; then
source $ROOT/build_tools/fbcode_config_platform007.sh
source $ROOT/build_tools/fbcode_config.sh
GCOV=$GCC_BASE/bin/gcov
else
GCOV=$(which gcov)
fi
echo -e "Using $GCOV"
COVERAGE_DIR="$PWD/COVERAGE_REPORT"
mkdir -p $COVERAGE_DIR
# Find all gcno files to generate the coverage report
PYTHON=${1:-`which python`}
echo -e "Using $PYTHON"
GCNO_FILES=`find $ROOT -name "*.gcno"`
$GCOV --preserve-paths --relative-only --no-output $GCNO_FILES 2>/dev/null |
# Parse the raw gcov report to more human readable form.
$PYTHON $ROOT/coverage/parse_gcov_output.py |
python $ROOT/coverage/parse_gcov_output.py |
# Write the output to both stdout and report file.
tee $COVERAGE_DIR/coverage_report_all.txt &&
echo -e "Generated coverage report for all files: $COVERAGE_DIR/coverage_report_all.txt\n"
@@ -44,7 +41,7 @@ RECENT_REPORT=$COVERAGE_DIR/coverage_report_recent.txt
echo -e "Recently updated files: $LATEST_FILES\n" > $RECENT_REPORT
$GCOV --preserve-paths --relative-only --no-output $GCNO_FILES 2>/dev/null |
$PYTHON $ROOT/coverage/parse_gcov_output.py -interested-files $LATEST_FILES |
python $ROOT/coverage/parse_gcov_output.py -interested-files $LATEST_FILES |
tee -a $RECENT_REPORT &&
echo -e "Generated coverage report for recently updated files: $RECENT_REPORT\n"
+10 -12
View File
@@ -1,12 +1,10 @@
#!/usr/bin/env python
#!/usr/bin/env python2
# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
from __future__ import print_function
import optparse
import re
import sys
from optparse import OptionParser
# the gcov report follows certain pattern. Each file will have two lines
# of report, from which we can extract the file name, total lines and coverage
# percentage.
@@ -50,7 +48,7 @@ def parse_gcov_report(gcov_input):
def get_option_parser():
usage = "Parse the gcov output and generate more human-readable code " +\
"coverage report."
parser = optparse.OptionParser(usage)
parser = OptionParser(usage)
parser.add_option(
"--interested-files", "-i",
@@ -75,8 +73,8 @@ def display_file_coverage(per_file_coverage, total_coverage):
header_template = \
"%" + str(max_file_name_length) + "s\t%s\t%s"
separator = "-" * (max_file_name_length + 10 + 20)
print(header_template % ("Filename", "Coverage", "Lines")) # noqa: E999 T25377293 Grandfathered in
print(separator)
print header_template % ("Filename", "Coverage", "Lines") # noqa: E999 T25377293 Grandfathered in
print separator
# -- Print body
# template for printing coverage report for each file.
@@ -84,12 +82,12 @@ def display_file_coverage(per_file_coverage, total_coverage):
for fname, coverage_info in per_file_coverage.items():
coverage, lines = coverage_info
print(record_template % (fname, coverage, lines))
print record_template % (fname, coverage, lines)
# -- Print footer
if total_coverage:
print(separator)
print(record_template % ("Total", total_coverage[0], total_coverage[1]))
print separator
print record_template % ("Total", total_coverage[0], total_coverage[1])
def report_coverage():
parser = get_option_parser()
@@ -113,7 +111,7 @@ def report_coverage():
total_coverage = None
if not len(per_file_coverage):
print("Cannot find coverage info for the given files.", file=sys.stderr)
print >> sys.stderr, "Cannot find coverage info for the given files."
return
display_file_coverage(per_file_coverage, total_coverage)
+3 -5
View File
@@ -56,9 +56,8 @@ Status ArenaWrappedDBIter::Refresh() {
// TODO(yiwu): For last_seq_same_as_publish_seq_==false, this is not the
// correct behavior. Will be corrected automatically when we take a snapshot
// here for the case of WritePreparedTxnDB.
SequenceNumber latest_seq = db_impl_->GetLatestSequenceNumber();
uint64_t cur_sv_number = cfd_->GetSuperVersionNumber();
TEST_SYNC_POINT("ArenaWrappedDBIter::Refresh:1");
TEST_SYNC_POINT("ArenaWrappedDBIter::Refresh:2");
if (sv_number_ != cur_sv_number) {
Env* env = db_iter_->env();
db_iter_->~DBIter();
@@ -66,7 +65,6 @@ Status ArenaWrappedDBIter::Refresh() {
new (&arena_) Arena();
SuperVersion* sv = cfd_->GetReferencedSuperVersion(db_impl_);
SequenceNumber latest_seq = db_impl_->GetLatestSequenceNumber();
if (read_callback_) {
read_callback_->Refresh(latest_seq);
}
@@ -77,10 +75,10 @@ Status ArenaWrappedDBIter::Refresh() {
InternalIterator* internal_iter = db_impl_->NewInternalIterator(
read_options_, cfd_, sv, &arena_, db_iter_->GetRangeDelAggregator(),
latest_seq, /* allow_unprepared_value */ true);
latest_seq);
SetIterUnderDBIter(internal_iter);
} else {
db_iter_->set_sequence(db_impl_->GetLatestSequenceNumber());
db_iter_->set_sequence(latest_seq);
db_iter_->set_valid(false);
}
return Status::OK();
-55
View File
@@ -1,55 +0,0 @@
// 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).
#include "db/blob/blob_file_meta.h"
#include <ostream>
#include <sstream>
namespace ROCKSDB_NAMESPACE {
std::string SharedBlobFileMetaData::DebugString() const {
std::ostringstream oss;
oss << (*this);
return oss.str();
}
std::ostream& operator<<(std::ostream& os,
const SharedBlobFileMetaData& shared_meta) {
os << "blob_file_number: " << shared_meta.GetBlobFileNumber()
<< " total_blob_count: " << shared_meta.GetTotalBlobCount()
<< " total_blob_bytes: " << shared_meta.GetTotalBlobBytes()
<< " checksum_method: " << shared_meta.GetChecksumMethod()
<< " checksum_value: " << shared_meta.GetChecksumValue();
return os;
}
std::string BlobFileMetaData::DebugString() const {
std::ostringstream oss;
oss << (*this);
return oss.str();
}
std::ostream& operator<<(std::ostream& os, const BlobFileMetaData& meta) {
const auto& shared_meta = meta.GetSharedMeta();
assert(shared_meta);
os << (*shared_meta);
os << " linked_ssts: {";
for (uint64_t file_number : meta.GetLinkedSsts()) {
os << ' ' << file_number;
}
os << " }";
os << " garbage_blob_count: " << meta.GetGarbageBlobCount()
<< " garbage_blob_bytes: " << meta.GetGarbageBlobBytes();
return os;
}
} // namespace ROCKSDB_NAMESPACE
-164
View File
@@ -1,164 +0,0 @@
// 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).
#pragma once
#include <cassert>
#include <iosfwd>
#include <memory>
#include <string>
#include <unordered_set>
#include "rocksdb/rocksdb_namespace.h"
namespace ROCKSDB_NAMESPACE {
// SharedBlobFileMetaData represents the immutable part of blob files' metadata,
// like the blob file number, total number and size of blobs, or checksum
// method and value. There is supposed to be one object of this class per blob
// file (shared across all versions that include the blob file in question);
// hence, the type is neither copyable nor movable. A blob file can be marked
// obsolete when the corresponding SharedBlobFileMetaData object is destroyed.
class SharedBlobFileMetaData {
public:
static std::shared_ptr<SharedBlobFileMetaData> Create(
uint64_t blob_file_number, uint64_t total_blob_count,
uint64_t total_blob_bytes, std::string checksum_method,
std::string checksum_value) {
return std::shared_ptr<SharedBlobFileMetaData>(new SharedBlobFileMetaData(
blob_file_number, total_blob_count, total_blob_bytes,
std::move(checksum_method), std::move(checksum_value)));
}
template <typename Deleter>
static std::shared_ptr<SharedBlobFileMetaData> Create(
uint64_t blob_file_number, uint64_t total_blob_count,
uint64_t total_blob_bytes, std::string checksum_method,
std::string checksum_value, Deleter deleter) {
return std::shared_ptr<SharedBlobFileMetaData>(
new SharedBlobFileMetaData(blob_file_number, total_blob_count,
total_blob_bytes, std::move(checksum_method),
std::move(checksum_value)),
deleter);
}
SharedBlobFileMetaData(const SharedBlobFileMetaData&) = delete;
SharedBlobFileMetaData& operator=(const SharedBlobFileMetaData&) = delete;
SharedBlobFileMetaData(SharedBlobFileMetaData&&) = delete;
SharedBlobFileMetaData& operator=(SharedBlobFileMetaData&&) = delete;
uint64_t GetBlobFileNumber() const { return blob_file_number_; }
uint64_t GetTotalBlobCount() const { return total_blob_count_; }
uint64_t GetTotalBlobBytes() const { return total_blob_bytes_; }
const std::string& GetChecksumMethod() const { return checksum_method_; }
const std::string& GetChecksumValue() const { return checksum_value_; }
std::string DebugString() const;
private:
SharedBlobFileMetaData(uint64_t blob_file_number, uint64_t total_blob_count,
uint64_t total_blob_bytes, std::string checksum_method,
std::string checksum_value)
: blob_file_number_(blob_file_number),
total_blob_count_(total_blob_count),
total_blob_bytes_(total_blob_bytes),
checksum_method_(std::move(checksum_method)),
checksum_value_(std::move(checksum_value)) {
assert(checksum_method_.empty() == checksum_value_.empty());
}
uint64_t blob_file_number_;
uint64_t total_blob_count_;
uint64_t total_blob_bytes_;
std::string checksum_method_;
std::string checksum_value_;
};
std::ostream& operator<<(std::ostream& os,
const SharedBlobFileMetaData& shared_meta);
// BlobFileMetaData contains the part of the metadata for blob files that can
// vary across versions, like the amount of garbage in the blob file. In
// addition, BlobFileMetaData objects point to and share the ownership of the
// SharedBlobFileMetaData object for the corresponding blob file. Similarly to
// SharedBlobFileMetaData, BlobFileMetaData are not copyable or movable. They
// are meant to be jointly owned by the versions in which the blob file has the
// same (immutable *and* mutable) state.
class BlobFileMetaData {
public:
using LinkedSsts = std::unordered_set<uint64_t>;
static std::shared_ptr<BlobFileMetaData> Create(
std::shared_ptr<SharedBlobFileMetaData> shared_meta,
LinkedSsts linked_ssts, uint64_t garbage_blob_count,
uint64_t garbage_blob_bytes) {
return std::shared_ptr<BlobFileMetaData>(
new BlobFileMetaData(std::move(shared_meta), std::move(linked_ssts),
garbage_blob_count, garbage_blob_bytes));
}
BlobFileMetaData(const BlobFileMetaData&) = delete;
BlobFileMetaData& operator=(const BlobFileMetaData&) = delete;
BlobFileMetaData(BlobFileMetaData&&) = delete;
BlobFileMetaData& operator=(BlobFileMetaData&&) = delete;
const std::shared_ptr<SharedBlobFileMetaData>& GetSharedMeta() const {
return shared_meta_;
}
uint64_t GetBlobFileNumber() const {
assert(shared_meta_);
return shared_meta_->GetBlobFileNumber();
}
uint64_t GetTotalBlobCount() const {
assert(shared_meta_);
return shared_meta_->GetTotalBlobCount();
}
uint64_t GetTotalBlobBytes() const {
assert(shared_meta_);
return shared_meta_->GetTotalBlobBytes();
}
const std::string& GetChecksumMethod() const {
assert(shared_meta_);
return shared_meta_->GetChecksumMethod();
}
const std::string& GetChecksumValue() const {
assert(shared_meta_);
return shared_meta_->GetChecksumValue();
}
const LinkedSsts& GetLinkedSsts() const { return linked_ssts_; }
uint64_t GetGarbageBlobCount() const { return garbage_blob_count_; }
uint64_t GetGarbageBlobBytes() const { return garbage_blob_bytes_; }
std::string DebugString() const;
private:
BlobFileMetaData(std::shared_ptr<SharedBlobFileMetaData> shared_meta,
LinkedSsts linked_ssts, uint64_t garbage_blob_count,
uint64_t garbage_blob_bytes)
: shared_meta_(std::move(shared_meta)),
linked_ssts_(std::move(linked_ssts)),
garbage_blob_count_(garbage_blob_count),
garbage_blob_bytes_(garbage_blob_bytes) {
assert(shared_meta_);
assert(garbage_blob_count_ <= shared_meta_->GetTotalBlobCount());
assert(garbage_blob_bytes_ <= shared_meta_->GetTotalBlobBytes());
}
std::shared_ptr<SharedBlobFileMetaData> shared_meta_;
LinkedSsts linked_ssts_;
uint64_t garbage_blob_count_;
uint64_t garbage_blob_bytes_;
};
std::ostream& operator<<(std::ostream& os, const BlobFileMetaData& meta);
} // namespace ROCKSDB_NAMESPACE
+1 -1
View File
@@ -46,7 +46,7 @@ class DBBlobIndexTest : public DBTestBase {
ColumnFamilyHandle* cfh() { return dbfull()->DefaultColumnFamily(); }
ColumnFamilyData* cfd() {
return static_cast_with_check<ColumnFamilyHandleImpl>(cfh())->cfd();
return reinterpret_cast<ColumnFamilyHandleImpl*>(cfh())->cfd();
}
Status PutBlobIndex(WriteBatch* batch, const Slice& key,
+20 -56
View File
@@ -51,8 +51,7 @@ TableBuilder* NewTableBuilder(
uint64_t sample_for_compression, const CompressionOptions& compression_opts,
int level, const bool skip_filters, const uint64_t creation_time,
const uint64_t oldest_key_time, const uint64_t target_file_size,
const uint64_t file_creation_time, const std::string& db_id,
const std::string& db_session_id) {
const uint64_t file_creation_time) {
assert((column_family_id ==
TablePropertiesCollectorFactory::Context::kUnknownColumnFamily) ==
column_family_name.empty());
@@ -62,7 +61,7 @@ TableBuilder* NewTableBuilder(
sample_for_compression, compression_opts,
skip_filters, column_family_name, level,
creation_time, oldest_key_time, target_file_size,
file_creation_time, db_id, db_session_id),
file_creation_time),
column_family_id, file);
}
@@ -82,20 +81,16 @@ Status BuildTable(
SnapshotChecker* snapshot_checker, const CompressionType compression,
uint64_t sample_for_compression, const CompressionOptions& compression_opts,
bool paranoid_file_checks, InternalStats* internal_stats,
TableFileCreationReason reason, IOStatus* io_status,
EventLogger* event_logger, int job_id, const Env::IOPriority io_priority,
TableProperties* table_properties, int level, const uint64_t creation_time,
const uint64_t oldest_key_time, Env::WriteLifeTimeHint write_hint,
const uint64_t file_creation_time, const std::string& db_id,
const std::string& db_session_id) {
TableFileCreationReason reason, EventLogger* event_logger, int job_id,
const Env::IOPriority io_priority, TableProperties* table_properties,
int level, const uint64_t creation_time, const uint64_t oldest_key_time,
Env::WriteLifeTimeHint write_hint, const uint64_t file_creation_time) {
assert((column_family_id ==
TablePropertiesCollectorFactory::Context::kUnknownColumnFamily) ==
column_family_name.empty());
// Reports the IOStats for flush for every following bytes.
const size_t kReportFlushIOStatsEvery = 1048576;
uint64_t paranoid_hash = 0;
Status s;
IOStatus io_s;
meta->fd.file_size = 0;
iter->SeekToFirst();
std::unique_ptr<CompactionRangeDelAggregator> range_del_agg(
@@ -111,6 +106,7 @@ Status BuildTable(
ioptions.listeners, dbname, column_family_name, fname, job_id, reason);
#endif // !ROCKSDB_LITE
TableProperties tp;
if (iter->Valid() || !range_del_agg->IsEmpty()) {
TableBuilder* builder;
std::unique_ptr<WritableFileWriter> file_writer;
@@ -125,11 +121,7 @@ Status BuildTable(
bool use_direct_writes = file_options.use_direct_writes;
TEST_SYNC_POINT_CALLBACK("BuildTable:create_file", &use_direct_writes);
#endif // !NDEBUG
io_s = NewWritableFile(fs, fname, &file, file_options);
s = io_s;
if (io_status->ok()) {
*io_status = io_s;
}
s = NewWritableFile(fs, fname, &file, file_options);
if (!s.ok()) {
EventHelpers::LogAndNotifyTableFileCreationFinished(
event_logger, ioptions.listeners, dbname, column_family_name, fname,
@@ -141,7 +133,7 @@ Status BuildTable(
file_writer.reset(new WritableFileWriter(
std::move(file), fname, file_options, env, ioptions.statistics,
ioptions.listeners, ioptions.file_checksum_gen_factory));
ioptions.listeners, ioptions.sst_file_checksum_func));
builder = NewTableBuilder(
ioptions, mutable_cf_options, internal_comparator,
@@ -149,7 +141,7 @@ Status BuildTable(
column_family_name, file_writer.get(), compression,
sample_for_compression, compression_opts_for_flush, level,
false /* skip_filters */, creation_time, oldest_key_time,
0 /*target_file_size*/, file_creation_time, db_id, db_session_id);
0 /*target_file_size*/, file_creation_time);
}
MergeHelper merge(env, internal_comparator.user_comparator(),
@@ -168,11 +160,6 @@ Status BuildTable(
const Slice& key = c_iter.key();
const Slice& value = c_iter.value();
const ParsedInternalKey& ikey = c_iter.ikey();
if (paranoid_file_checks) {
// Generate a rolling 64-bit hash of the key and values
paranoid_hash = Hash64(key.data(), key.size(), paranoid_hash);
paranoid_hash = Hash64(value.data(), value.size(), paranoid_hash);
}
builder->Add(key, value);
meta->UpdateBoundaries(key, value, ikey.sequence, ikey.type);
@@ -195,18 +182,14 @@ Status BuildTable(
}
// Finish and check for builder errors
bool empty = builder->IsEmpty();
tp = builder->GetTableProperties();
bool empty = builder->NumEntries() == 0 && tp.num_range_deletions == 0;
s = c_iter.status();
TEST_SYNC_POINT("BuildTable:BeforeFinishBuildTable");
if (!s.ok() || empty) {
builder->Abandon();
} else {
s = builder->Finish();
}
io_s = builder->io_status();
if (io_status->ok()) {
*io_status = io_s;
}
if (s.ok() && !empty) {
uint64_t file_size = builder->FileSize();
@@ -217,28 +200,20 @@ Status BuildTable(
if (table_properties) {
*table_properties = tp;
}
// Add the checksum information to file metadata.
meta->file_checksum = builder->GetFileChecksum();
meta->file_checksum_func_name = builder->GetFileChecksumFuncName();
}
delete builder;
// Finish and check for file errors
if (s.ok() && !empty) {
StopWatch sw(env, ioptions.statistics, TABLE_SYNC_MICROS);
*io_status = file_writer->Sync(ioptions.use_fsync);
s = file_writer->Sync(ioptions.use_fsync);
}
if (s.ok() && io_status->ok() && !empty) {
*io_status = file_writer->Close();
if (s.ok() && !empty) {
s = file_writer->Close();
}
if (s.ok() && io_status->ok() && !empty) {
// Add the checksum information to file metadata.
meta->file_checksum = file_writer->GetFileChecksum();
meta->file_checksum_func_name = file_writer->GetFileChecksumFuncName();
}
if (s.ok()) {
s = *io_status;
}
// TODO Also check the IO status when create the Iterator.
if (s.ok() && !empty) {
// Verify that the table is usable
@@ -254,24 +229,13 @@ Status BuildTable(
(internal_stats == nullptr) ? nullptr
: internal_stats->GetFileReadHist(0),
TableReaderCaller::kFlush, /*arena=*/nullptr,
/*skip_filter=*/false, level,
MaxFileSizeForL0MetaPin(mutable_cf_options),
/*smallest_compaction_key=*/nullptr,
/*largest_compaction_key*/ nullptr,
/*allow_unprepared_value*/ false));
/*skip_filter=*/false, level, /*smallest_compaction_key=*/nullptr,
/*largest_compaction_key*/ nullptr));
s = it->status();
if (s.ok() && paranoid_file_checks) {
uint64_t check_hash = 0;
for (it->SeekToFirst(); it->Valid(); it->Next()) {
// Generate a rolling 64-bit hash of the key and values
check_hash = Hash64(it->key().data(), it->key().size(), check_hash);
check_hash =
Hash64(it->value().data(), it->value().size(), check_hash);
}
s = it->status();
if (s.ok() && check_hash != paranoid_hash) {
s = Status::Corruption("Paraniod checksums do not match");
}
}
}
}
+3 -5
View File
@@ -51,8 +51,7 @@ TableBuilder* NewTableBuilder(
const CompressionOptions& compression_opts, int level,
const bool skip_filters = false, const uint64_t creation_time = 0,
const uint64_t oldest_key_time = 0, const uint64_t target_file_size = 0,
const uint64_t file_creation_time = 0, const std::string& db_id = "",
const std::string& db_session_id = "");
const uint64_t file_creation_time = 0);
// Build a Table file from the contents of *iter. The generated file
// will be named according to number specified in meta. On success, the rest of
@@ -79,12 +78,11 @@ extern Status BuildTable(
const uint64_t sample_for_compression,
const CompressionOptions& compression_opts, bool paranoid_file_checks,
InternalStats* internal_stats, TableFileCreationReason reason,
IOStatus* io_status, EventLogger* event_logger = nullptr, int job_id = 0,
EventLogger* event_logger = nullptr, int job_id = 0,
const Env::IOPriority io_priority = Env::IO_HIGH,
TableProperties* table_properties = nullptr, int level = -1,
const uint64_t creation_time = 0, const uint64_t oldest_key_time = 0,
Env::WriteLifeTimeHint write_hint = Env::WLTH_NOT_SET,
const uint64_t file_creation_time = 0, const std::string& db_id = "",
const std::string& db_session_id = "");
const uint64_t file_creation_time = 0);
} // namespace ROCKSDB_NAMESPACE
+2 -479
View File
@@ -595,15 +595,6 @@ void rocksdb_backup_engine_restore_db_from_latest_backup(
restore_options->rep));
}
void rocksdb_backup_engine_restore_db_from_backup(
rocksdb_backup_engine_t* be, const char* db_dir, const char* wal_dir,
const rocksdb_restore_options_t* restore_options, const uint32_t backup_id,
char** errptr) {
SaveError(errptr, be->rep->RestoreDBFromBackup(backup_id, std::string(db_dir),
std::string(wal_dir),
restore_options->rep));
}
const rocksdb_backup_engine_info_t* rocksdb_backup_engine_get_backup_info(
rocksdb_backup_engine_t* be) {
rocksdb_backup_engine_info_t* result = new rocksdb_backup_engine_info_t;
@@ -1005,55 +996,6 @@ void rocksdb_multi_get_cf(
}
}
unsigned char rocksdb_key_may_exist(rocksdb_t* db,
const rocksdb_readoptions_t* options,
const char* key, size_t key_len,
char** value, size_t* val_len,
const char* timestamp, size_t timestamp_len,
unsigned char* value_found) {
std::string tmp;
std::string time;
if (timestamp) {
time.assign(timestamp, timestamp_len);
}
bool found = false;
const bool result = db->rep->KeyMayExist(options->rep, Slice(key, key_len),
&tmp, timestamp ? &time : nullptr,
value_found ? &found : nullptr);
if (value_found) {
*value_found = found;
if (found) {
*val_len = tmp.size();
*value = CopyString(tmp);
}
}
return result;
}
unsigned char rocksdb_key_may_exist_cf(
rocksdb_t* db, const rocksdb_readoptions_t* options,
rocksdb_column_family_handle_t* column_family, const char* key,
size_t key_len, char** value, size_t* val_len, const char* timestamp,
size_t timestamp_len, unsigned char* value_found) {
std::string tmp;
std::string time;
if (timestamp) {
time.assign(timestamp, timestamp_len);
}
bool found = false;
const bool result = db->rep->KeyMayExist(
options->rep, column_family->rep, Slice(key, key_len), &tmp,
timestamp ? &time : nullptr, value_found ? &found : nullptr);
if (value_found) {
*value_found = found;
if (found) {
*val_len = tmp.size();
*value = CopyString(tmp);
}
}
return result;
}
rocksdb_iterator_t* rocksdb_create_iterator(
rocksdb_t* db,
const rocksdb_readoptions_t* options) {
@@ -1524,11 +1466,6 @@ void rocksdb_writebatch_delete(
b->rep.Delete(Slice(key, klen));
}
void rocksdb_writebatch_singledelete(rocksdb_writebatch_t* b, const char* key,
size_t klen) {
b->rep.SingleDelete(Slice(key, klen));
}
void rocksdb_writebatch_delete_cf(
rocksdb_writebatch_t* b,
rocksdb_column_family_handle_t* column_family,
@@ -1536,12 +1473,6 @@ void rocksdb_writebatch_delete_cf(
b->rep.Delete(column_family->rep, Slice(key, klen));
}
void rocksdb_writebatch_singledelete_cf(
rocksdb_writebatch_t* b, rocksdb_column_family_handle_t* column_family,
const char* key, size_t klen) {
b->rep.SingleDelete(column_family->rep, Slice(key, klen));
}
void rocksdb_writebatch_deletev(
rocksdb_writebatch_t* b,
int num_keys, const char* const* keys_list,
@@ -1792,11 +1723,6 @@ void rocksdb_writebatch_wi_delete(
b->rep->Delete(Slice(key, klen));
}
void rocksdb_writebatch_wi_singledelete(rocksdb_writebatch_wi_t* b,
const char* key, size_t klen) {
b->rep->SingleDelete(Slice(key, klen));
}
void rocksdb_writebatch_wi_delete_cf(
rocksdb_writebatch_wi_t* b,
rocksdb_column_family_handle_t* column_family,
@@ -1804,12 +1730,6 @@ void rocksdb_writebatch_wi_delete_cf(
b->rep->Delete(column_family->rep, Slice(key, klen));
}
void rocksdb_writebatch_wi_singledelete_cf(
rocksdb_writebatch_wi_t* b, rocksdb_column_family_handle_t* column_family,
const char* key, size_t klen) {
b->rep->SingleDelete(column_family->rep, Slice(key, klen));
}
void rocksdb_writebatch_wi_deletev(
rocksdb_writebatch_wi_t* b,
int num_keys, const char* const* keys_list,
@@ -2234,10 +2154,6 @@ void rocksdb_options_destroy(rocksdb_options_t* options) {
delete options;
}
rocksdb_options_t* rocksdb_options_create_copy(rocksdb_options_t* options) {
return new rocksdb_options_t(*options);
}
void rocksdb_options_increase_parallelism(
rocksdb_options_t* opt, int total_threads) {
opt->rep.IncreaseParallelism(total_threads);
@@ -2263,10 +2179,6 @@ void rocksdb_options_set_allow_ingest_behind(
opt->rep.allow_ingest_behind = v;
}
unsigned char rocksdb_options_get_allow_ingest_behind(rocksdb_options_t* opt) {
return opt->rep.allow_ingest_behind;
}
void rocksdb_options_set_compaction_filter(
rocksdb_options_t* opt,
rocksdb_compactionfilter_t* filter) {
@@ -2284,10 +2196,6 @@ void rocksdb_options_compaction_readahead_size(
opt->rep.compaction_readahead_size = s;
}
size_t rocksdb_options_get_compaction_readahead_size(rocksdb_options_t* opt) {
return opt->rep.compaction_readahead_size;
}
void rocksdb_options_set_comparator(
rocksdb_options_t* opt,
rocksdb_comparator_t* cmp) {
@@ -2300,43 +2208,27 @@ void rocksdb_options_set_merge_operator(
opt->rep.merge_operator = std::shared_ptr<MergeOperator>(merge_operator);
}
void rocksdb_options_set_create_if_missing(
rocksdb_options_t* opt, unsigned char v) {
opt->rep.create_if_missing = v;
}
unsigned char rocksdb_options_get_create_if_missing(rocksdb_options_t* opt) {
return opt->rep.create_if_missing;
}
void rocksdb_options_set_create_missing_column_families(
rocksdb_options_t* opt, unsigned char v) {
opt->rep.create_missing_column_families = v;
}
unsigned char rocksdb_options_get_create_missing_column_families(
rocksdb_options_t* opt) {
return opt->rep.create_missing_column_families;
}
void rocksdb_options_set_error_if_exists(
rocksdb_options_t* opt, unsigned char v) {
opt->rep.error_if_exists = v;
}
unsigned char rocksdb_options_get_error_if_exists(rocksdb_options_t* opt) {
return opt->rep.error_if_exists;
}
void rocksdb_options_set_paranoid_checks(
rocksdb_options_t* opt, unsigned char v) {
opt->rep.paranoid_checks = v;
}
unsigned char rocksdb_options_get_paranoid_checks(rocksdb_options_t* opt) {
return opt->rep.paranoid_checks;
}
void rocksdb_options_set_db_paths(rocksdb_options_t* opt,
const rocksdb_dbpath_t** dbpath_values,
size_t num_paths) {
@@ -2362,107 +2254,57 @@ void rocksdb_options_set_info_log_level(
opt->rep.info_log_level = static_cast<InfoLogLevel>(v);
}
int rocksdb_options_get_info_log_level(rocksdb_options_t* opt) {
return static_cast<int>(opt->rep.info_log_level);
}
void rocksdb_options_set_db_write_buffer_size(rocksdb_options_t* opt,
size_t s) {
opt->rep.db_write_buffer_size = s;
}
size_t rocksdb_options_get_db_write_buffer_size(rocksdb_options_t* opt) {
return opt->rep.db_write_buffer_size;
}
void rocksdb_options_set_write_buffer_size(rocksdb_options_t* opt, size_t s) {
opt->rep.write_buffer_size = s;
}
size_t rocksdb_options_get_write_buffer_size(rocksdb_options_t* opt) {
return opt->rep.write_buffer_size;
}
void rocksdb_options_set_max_open_files(rocksdb_options_t* opt, int n) {
opt->rep.max_open_files = n;
}
int rocksdb_options_get_max_open_files(rocksdb_options_t* opt) {
return opt->rep.max_open_files;
}
void rocksdb_options_set_max_file_opening_threads(rocksdb_options_t* opt, int n) {
opt->rep.max_file_opening_threads = n;
}
int rocksdb_options_get_max_file_opening_threads(rocksdb_options_t* opt) {
return opt->rep.max_file_opening_threads;
}
void rocksdb_options_set_max_total_wal_size(rocksdb_options_t* opt, uint64_t n) {
opt->rep.max_total_wal_size = n;
}
uint64_t rocksdb_options_get_max_total_wal_size(rocksdb_options_t* opt) {
return opt->rep.max_total_wal_size;
}
void rocksdb_options_set_target_file_size_base(
rocksdb_options_t* opt, uint64_t n) {
opt->rep.target_file_size_base = n;
}
uint64_t rocksdb_options_get_target_file_size_base(rocksdb_options_t* opt) {
return opt->rep.target_file_size_base;
}
void rocksdb_options_set_target_file_size_multiplier(
rocksdb_options_t* opt, int n) {
opt->rep.target_file_size_multiplier = n;
}
int rocksdb_options_get_target_file_size_multiplier(rocksdb_options_t* opt) {
return opt->rep.target_file_size_multiplier;
}
void rocksdb_options_set_max_bytes_for_level_base(
rocksdb_options_t* opt, uint64_t n) {
opt->rep.max_bytes_for_level_base = n;
}
uint64_t rocksdb_options_get_max_bytes_for_level_base(rocksdb_options_t* opt) {
return opt->rep.max_bytes_for_level_base;
}
void rocksdb_options_set_level_compaction_dynamic_level_bytes(
rocksdb_options_t* opt, unsigned char v) {
opt->rep.level_compaction_dynamic_level_bytes = v;
}
unsigned char rocksdb_options_get_level_compaction_dynamic_level_bytes(
rocksdb_options_t* opt) {
return opt->rep.level_compaction_dynamic_level_bytes;
}
void rocksdb_options_set_max_bytes_for_level_multiplier(rocksdb_options_t* opt,
double n) {
opt->rep.max_bytes_for_level_multiplier = n;
}
double rocksdb_options_get_max_bytes_for_level_multiplier(
rocksdb_options_t* opt) {
return opt->rep.max_bytes_for_level_multiplier;
}
void rocksdb_options_set_max_compaction_bytes(rocksdb_options_t* opt,
uint64_t n) {
opt->rep.max_compaction_bytes = n;
}
uint64_t rocksdb_options_get_max_compaction_bytes(rocksdb_options_t* opt) {
return opt->rep.max_compaction_bytes;
}
void rocksdb_options_set_max_bytes_for_level_multiplier_additional(
rocksdb_options_t* opt, int* level_values, size_t num_levels) {
opt->rep.max_bytes_for_level_multiplier_additional.resize(num_levels);
@@ -2480,57 +2322,30 @@ void rocksdb_options_set_skip_stats_update_on_db_open(rocksdb_options_t* opt,
opt->rep.skip_stats_update_on_db_open = val;
}
unsigned char rocksdb_options_get_skip_stats_update_on_db_open(
rocksdb_options_t* opt) {
return opt->rep.skip_stats_update_on_db_open;
}
void rocksdb_options_set_skip_checking_sst_file_sizes_on_db_open(
rocksdb_options_t* opt, unsigned char val) {
opt->rep.skip_checking_sst_file_sizes_on_db_open = val;
}
unsigned char rocksdb_options_get_skip_checking_sst_file_sizes_on_db_open(
rocksdb_options_t* opt) {
return opt->rep.skip_checking_sst_file_sizes_on_db_open;
}
void rocksdb_options_set_num_levels(rocksdb_options_t* opt, int n) {
opt->rep.num_levels = n;
}
int rocksdb_options_get_num_levels(rocksdb_options_t* opt) {
return opt->rep.num_levels;
}
void rocksdb_options_set_level0_file_num_compaction_trigger(
rocksdb_options_t* opt, int n) {
opt->rep.level0_file_num_compaction_trigger = n;
}
int rocksdb_options_get_level0_file_num_compaction_trigger(
rocksdb_options_t* opt) {
return opt->rep.level0_file_num_compaction_trigger;
}
void rocksdb_options_set_level0_slowdown_writes_trigger(
rocksdb_options_t* opt, int n) {
opt->rep.level0_slowdown_writes_trigger = n;
}
int rocksdb_options_get_level0_slowdown_writes_trigger(rocksdb_options_t* opt) {
return opt->rep.level0_slowdown_writes_trigger;
}
void rocksdb_options_set_level0_stop_writes_trigger(
rocksdb_options_t* opt, int n) {
opt->rep.level0_stop_writes_trigger = n;
}
int rocksdb_options_get_level0_stop_writes_trigger(rocksdb_options_t* opt) {
return opt->rep.level0_stop_writes_trigger;
}
void rocksdb_options_set_max_mem_compaction_level(rocksdb_options_t* /*opt*/,
int /*n*/) {}
@@ -2538,26 +2353,10 @@ void rocksdb_options_set_wal_recovery_mode(rocksdb_options_t* opt,int mode) {
opt->rep.wal_recovery_mode = static_cast<WALRecoveryMode>(mode);
}
int rocksdb_options_get_wal_recovery_mode(rocksdb_options_t* opt) {
return static_cast<int>(opt->rep.wal_recovery_mode);
}
void rocksdb_options_set_compression(rocksdb_options_t* opt, int t) {
opt->rep.compression = static_cast<CompressionType>(t);
}
int rocksdb_options_get_compression(rocksdb_options_t* opt) {
return opt->rep.compression;
}
void rocksdb_options_set_bottommost_compression(rocksdb_options_t* opt, int t) {
opt->rep.bottommost_compression = static_cast<CompressionType>(t);
}
int rocksdb_options_get_bottommost_compression(rocksdb_options_t* opt) {
return opt->rep.bottommost_compression;
}
void rocksdb_options_set_compression_per_level(rocksdb_options_t* opt,
int* level_values,
size_t num_levels) {
@@ -2572,7 +2371,7 @@ void rocksdb_options_set_bottommost_compression_options(rocksdb_options_t* opt,
int w_bits, int level,
int strategy,
int max_dict_bytes,
unsigned char enabled) {
bool enabled) {
opt->rep.bottommost_compression_opts.window_bits = w_bits;
opt->rep.bottommost_compression_opts.level = level;
opt->rep.bottommost_compression_opts.strategy = strategy;
@@ -2580,13 +2379,6 @@ void rocksdb_options_set_bottommost_compression_options(rocksdb_options_t* opt,
opt->rep.bottommost_compression_opts.enabled = enabled;
}
void rocksdb_options_set_bottommost_compression_options_zstd_max_train_bytes(
rocksdb_options_t* opt, int zstd_max_train_bytes, unsigned char enabled) {
opt->rep.bottommost_compression_opts.zstd_max_train_bytes =
zstd_max_train_bytes;
opt->rep.bottommost_compression_opts.enabled = enabled;
}
void rocksdb_options_set_compression_options(rocksdb_options_t* opt, int w_bits,
int level, int strategy,
int max_dict_bytes) {
@@ -2596,11 +2388,6 @@ void rocksdb_options_set_compression_options(rocksdb_options_t* opt, int w_bits,
opt->rep.compression_opts.max_dict_bytes = max_dict_bytes;
}
void rocksdb_options_set_compression_options_zstd_max_train_bytes(
rocksdb_options_t* opt, int zstd_max_train_bytes) {
opt->rep.compression_opts.zstd_max_train_bytes = zstd_max_train_bytes;
}
void rocksdb_options_set_prefix_extractor(
rocksdb_options_t* opt, rocksdb_slicetransform_t* prefix_extractor) {
opt->rep.prefix_extractor.reset(prefix_extractor);
@@ -2611,10 +2398,6 @@ void rocksdb_options_set_use_fsync(
opt->rep.use_fsync = use_fsync;
}
int rocksdb_options_get_use_fsync(rocksdb_options_t* opt) {
return opt->rep.use_fsync;
}
void rocksdb_options_set_db_log_dir(
rocksdb_options_t* opt, const char* db_log_dir) {
opt->rep.db_log_dir = db_log_dir;
@@ -2629,28 +2412,16 @@ void rocksdb_options_set_WAL_ttl_seconds(rocksdb_options_t* opt, uint64_t ttl) {
opt->rep.WAL_ttl_seconds = ttl;
}
uint64_t rocksdb_options_get_WAL_ttl_seconds(rocksdb_options_t* opt) {
return opt->rep.WAL_ttl_seconds;
}
void rocksdb_options_set_WAL_size_limit_MB(
rocksdb_options_t* opt, uint64_t limit) {
opt->rep.WAL_size_limit_MB = limit;
}
uint64_t rocksdb_options_get_WAL_size_limit_MB(rocksdb_options_t* opt) {
return opt->rep.WAL_size_limit_MB;
}
void rocksdb_options_set_manifest_preallocation_size(
rocksdb_options_t* opt, size_t v) {
opt->rep.manifest_preallocation_size = v;
}
size_t rocksdb_options_get_manifest_preallocation_size(rocksdb_options_t* opt) {
return opt->rep.manifest_preallocation_size;
}
// noop
void rocksdb_options_set_purge_redundant_kvs_while_flush(
rocksdb_options_t* /*opt*/, unsigned char /*v*/) {}
@@ -2660,86 +2431,41 @@ void rocksdb_options_set_use_direct_reads(rocksdb_options_t* opt,
opt->rep.use_direct_reads = v;
}
unsigned char rocksdb_options_get_use_direct_reads(rocksdb_options_t* opt) {
return opt->rep.use_direct_reads;
}
void rocksdb_options_set_use_direct_io_for_flush_and_compaction(
rocksdb_options_t* opt, unsigned char v) {
opt->rep.use_direct_io_for_flush_and_compaction = v;
}
unsigned char rocksdb_options_get_use_direct_io_for_flush_and_compaction(
rocksdb_options_t* opt) {
return opt->rep.use_direct_io_for_flush_and_compaction;
}
void rocksdb_options_set_allow_mmap_reads(
rocksdb_options_t* opt, unsigned char v) {
opt->rep.allow_mmap_reads = v;
}
unsigned char rocksdb_options_get_allow_mmap_reads(rocksdb_options_t* opt) {
return opt->rep.allow_mmap_reads;
}
void rocksdb_options_set_allow_mmap_writes(
rocksdb_options_t* opt, unsigned char v) {
opt->rep.allow_mmap_writes = v;
}
unsigned char rocksdb_options_get_allow_mmap_writes(rocksdb_options_t* opt) {
return opt->rep.allow_mmap_writes;
}
void rocksdb_options_set_is_fd_close_on_exec(
rocksdb_options_t* opt, unsigned char v) {
opt->rep.is_fd_close_on_exec = v;
}
unsigned char rocksdb_options_get_is_fd_close_on_exec(rocksdb_options_t* opt) {
return opt->rep.is_fd_close_on_exec;
}
void rocksdb_options_set_skip_log_error_on_recovery(
rocksdb_options_t* opt, unsigned char v) {
opt->rep.skip_log_error_on_recovery = v;
}
unsigned char rocksdb_options_get_skip_log_error_on_recovery(
rocksdb_options_t* opt) {
return opt->rep.skip_log_error_on_recovery;
}
void rocksdb_options_set_stats_dump_period_sec(
rocksdb_options_t* opt, unsigned int v) {
opt->rep.stats_dump_period_sec = v;
}
unsigned int rocksdb_options_get_stats_dump_period_sec(rocksdb_options_t* opt) {
return opt->rep.stats_dump_period_sec;
}
void rocksdb_options_set_stats_persist_period_sec(rocksdb_options_t* opt,
unsigned int v) {
opt->rep.stats_persist_period_sec = v;
}
unsigned int rocksdb_options_get_stats_persist_period_sec(
rocksdb_options_t* opt) {
return opt->rep.stats_persist_period_sec;
}
void rocksdb_options_set_advise_random_on_open(
rocksdb_options_t* opt, unsigned char v) {
opt->rep.advise_random_on_open = v;
}
unsigned char rocksdb_options_get_advise_random_on_open(
rocksdb_options_t* opt) {
return opt->rep.advise_random_on_open;
}
void rocksdb_options_set_access_hint_on_compaction_start(
rocksdb_options_t* opt, int v) {
switch(v) {
@@ -2762,271 +2488,139 @@ void rocksdb_options_set_access_hint_on_compaction_start(
}
}
int rocksdb_options_get_access_hint_on_compaction_start(
rocksdb_options_t* opt) {
return opt->rep.access_hint_on_compaction_start;
}
void rocksdb_options_set_use_adaptive_mutex(
rocksdb_options_t* opt, unsigned char v) {
opt->rep.use_adaptive_mutex = v;
}
unsigned char rocksdb_options_get_use_adaptive_mutex(rocksdb_options_t* opt) {
return opt->rep.use_adaptive_mutex;
}
void rocksdb_options_set_wal_bytes_per_sync(
rocksdb_options_t* opt, uint64_t v) {
opt->rep.wal_bytes_per_sync = v;
}
uint64_t rocksdb_options_get_wal_bytes_per_sync(rocksdb_options_t* opt) {
return opt->rep.wal_bytes_per_sync;
}
void rocksdb_options_set_bytes_per_sync(
rocksdb_options_t* opt, uint64_t v) {
opt->rep.bytes_per_sync = v;
}
uint64_t rocksdb_options_get_bytes_per_sync(rocksdb_options_t* opt) {
return opt->rep.bytes_per_sync;
}
void rocksdb_options_set_writable_file_max_buffer_size(rocksdb_options_t* opt,
uint64_t v) {
opt->rep.writable_file_max_buffer_size = static_cast<size_t>(v);
}
uint64_t rocksdb_options_get_writable_file_max_buffer_size(
rocksdb_options_t* opt) {
return opt->rep.writable_file_max_buffer_size;
}
void rocksdb_options_set_allow_concurrent_memtable_write(rocksdb_options_t* opt,
unsigned char v) {
opt->rep.allow_concurrent_memtable_write = v;
}
unsigned char rocksdb_options_get_allow_concurrent_memtable_write(
rocksdb_options_t* opt) {
return opt->rep.allow_concurrent_memtable_write;
}
void rocksdb_options_set_enable_write_thread_adaptive_yield(
rocksdb_options_t* opt, unsigned char v) {
opt->rep.enable_write_thread_adaptive_yield = v;
}
unsigned char rocksdb_options_get_enable_write_thread_adaptive_yield(
rocksdb_options_t* opt) {
return opt->rep.enable_write_thread_adaptive_yield;
}
void rocksdb_options_set_max_sequential_skip_in_iterations(
rocksdb_options_t* opt, uint64_t v) {
opt->rep.max_sequential_skip_in_iterations = v;
}
uint64_t rocksdb_options_get_max_sequential_skip_in_iterations(
rocksdb_options_t* opt) {
return opt->rep.max_sequential_skip_in_iterations;
}
void rocksdb_options_set_max_write_buffer_number(rocksdb_options_t* opt, int n) {
opt->rep.max_write_buffer_number = n;
}
int rocksdb_options_get_max_write_buffer_number(rocksdb_options_t* opt) {
return opt->rep.max_write_buffer_number;
}
void rocksdb_options_set_min_write_buffer_number_to_merge(rocksdb_options_t* opt, int n) {
opt->rep.min_write_buffer_number_to_merge = n;
}
int rocksdb_options_get_min_write_buffer_number_to_merge(
rocksdb_options_t* opt) {
return opt->rep.min_write_buffer_number_to_merge;
}
void rocksdb_options_set_max_write_buffer_number_to_maintain(
rocksdb_options_t* opt, int n) {
opt->rep.max_write_buffer_number_to_maintain = n;
}
int rocksdb_options_get_max_write_buffer_number_to_maintain(
rocksdb_options_t* opt) {
return opt->rep.max_write_buffer_number_to_maintain;
}
void rocksdb_options_set_max_write_buffer_size_to_maintain(
rocksdb_options_t* opt, int64_t n) {
opt->rep.max_write_buffer_size_to_maintain = n;
}
int64_t rocksdb_options_get_max_write_buffer_size_to_maintain(
rocksdb_options_t* opt) {
return opt->rep.max_write_buffer_size_to_maintain;
}
void rocksdb_options_set_enable_pipelined_write(rocksdb_options_t* opt,
unsigned char v) {
opt->rep.enable_pipelined_write = v;
}
unsigned char rocksdb_options_get_enable_pipelined_write(
rocksdb_options_t* opt) {
return opt->rep.enable_pipelined_write;
}
void rocksdb_options_set_unordered_write(rocksdb_options_t* opt,
unsigned char v) {
opt->rep.unordered_write = v;
}
unsigned char rocksdb_options_get_unordered_write(rocksdb_options_t* opt) {
return opt->rep.unordered_write;
}
void rocksdb_options_set_max_subcompactions(rocksdb_options_t* opt,
uint32_t n) {
opt->rep.max_subcompactions = n;
}
uint32_t rocksdb_options_get_max_subcompactions(rocksdb_options_t* opt) {
return opt->rep.max_subcompactions;
}
void rocksdb_options_set_max_background_jobs(rocksdb_options_t* opt, int n) {
opt->rep.max_background_jobs = n;
}
int rocksdb_options_get_max_background_jobs(rocksdb_options_t* opt) {
return opt->rep.max_background_jobs;
}
void rocksdb_options_set_max_background_compactions(rocksdb_options_t* opt, int n) {
opt->rep.max_background_compactions = n;
}
int rocksdb_options_get_max_background_compactions(rocksdb_options_t* opt) {
return opt->rep.max_background_compactions;
}
void rocksdb_options_set_base_background_compactions(rocksdb_options_t* opt,
int n) {
opt->rep.base_background_compactions = n;
}
int rocksdb_options_get_base_background_compactions(rocksdb_options_t* opt) {
return opt->rep.base_background_compactions;
}
void rocksdb_options_set_max_background_flushes(rocksdb_options_t* opt, int n) {
opt->rep.max_background_flushes = n;
}
int rocksdb_options_get_max_background_flushes(rocksdb_options_t* opt) {
return opt->rep.max_background_flushes;
}
void rocksdb_options_set_max_log_file_size(rocksdb_options_t* opt, size_t v) {
opt->rep.max_log_file_size = v;
}
size_t rocksdb_options_get_max_log_file_size(rocksdb_options_t* opt) {
return opt->rep.max_log_file_size;
}
void rocksdb_options_set_log_file_time_to_roll(rocksdb_options_t* opt, size_t v) {
opt->rep.log_file_time_to_roll = v;
}
size_t rocksdb_options_get_log_file_time_to_roll(rocksdb_options_t* opt) {
return opt->rep.log_file_time_to_roll;
}
void rocksdb_options_set_keep_log_file_num(rocksdb_options_t* opt, size_t v) {
opt->rep.keep_log_file_num = v;
}
size_t rocksdb_options_get_keep_log_file_num(rocksdb_options_t* opt) {
return opt->rep.keep_log_file_num;
}
void rocksdb_options_set_recycle_log_file_num(rocksdb_options_t* opt,
size_t v) {
opt->rep.recycle_log_file_num = v;
}
size_t rocksdb_options_get_recycle_log_file_num(rocksdb_options_t* opt) {
return opt->rep.recycle_log_file_num;
}
void rocksdb_options_set_soft_rate_limit(rocksdb_options_t* opt, double v) {
opt->rep.soft_rate_limit = v;
}
double rocksdb_options_get_soft_rate_limit(rocksdb_options_t* opt) {
return opt->rep.soft_rate_limit;
}
void rocksdb_options_set_hard_rate_limit(rocksdb_options_t* opt, double v) {
opt->rep.hard_rate_limit = v;
}
double rocksdb_options_get_hard_rate_limit(rocksdb_options_t* opt) {
return opt->rep.hard_rate_limit;
}
void rocksdb_options_set_soft_pending_compaction_bytes_limit(rocksdb_options_t* opt, size_t v) {
opt->rep.soft_pending_compaction_bytes_limit = v;
}
size_t rocksdb_options_get_soft_pending_compaction_bytes_limit(
rocksdb_options_t* opt) {
return opt->rep.soft_pending_compaction_bytes_limit;
}
void rocksdb_options_set_hard_pending_compaction_bytes_limit(rocksdb_options_t* opt, size_t v) {
opt->rep.hard_pending_compaction_bytes_limit = v;
}
size_t rocksdb_options_get_hard_pending_compaction_bytes_limit(
rocksdb_options_t* opt) {
return opt->rep.hard_pending_compaction_bytes_limit;
}
void rocksdb_options_set_rate_limit_delay_max_milliseconds(
rocksdb_options_t* opt, unsigned int v) {
opt->rep.rate_limit_delay_max_milliseconds = v;
}
unsigned int rocksdb_options_get_rate_limit_delay_max_milliseconds(
rocksdb_options_t* opt) {
return opt->rep.rate_limit_delay_max_milliseconds;
}
void rocksdb_options_set_max_manifest_file_size(
rocksdb_options_t* opt, size_t v) {
opt->rep.max_manifest_file_size = v;
}
size_t rocksdb_options_get_max_manifest_file_size(rocksdb_options_t* opt) {
return opt->rep.max_manifest_file_size;
}
void rocksdb_options_set_table_cache_numshardbits(
rocksdb_options_t* opt, int v) {
opt->rep.table_cache_numshardbits = v;
}
int rocksdb_options_get_table_cache_numshardbits(rocksdb_options_t* opt) {
return opt->rep.table_cache_numshardbits;
}
void rocksdb_options_set_table_cache_remove_scan_count_limit(
rocksdb_options_t* /*opt*/, int /*v*/) {
// this option is deprecated
@@ -3037,38 +2631,19 @@ void rocksdb_options_set_arena_block_size(
opt->rep.arena_block_size = v;
}
size_t rocksdb_options_get_arena_block_size(rocksdb_options_t* opt) {
return opt->rep.arena_block_size;
}
void rocksdb_options_set_disable_auto_compactions(rocksdb_options_t* opt, int disable) {
opt->rep.disable_auto_compactions = disable;
}
unsigned char rocksdb_options_get_disable_auto_compactions(
rocksdb_options_t* opt) {
return opt->rep.disable_auto_compactions;
}
void rocksdb_options_set_optimize_filters_for_hits(rocksdb_options_t* opt, int v) {
opt->rep.optimize_filters_for_hits = v;
}
unsigned char rocksdb_options_get_optimize_filters_for_hits(
rocksdb_options_t* opt) {
return opt->rep.optimize_filters_for_hits;
}
void rocksdb_options_set_delete_obsolete_files_period_micros(
rocksdb_options_t* opt, uint64_t v) {
opt->rep.delete_obsolete_files_period_micros = v;
}
uint64_t rocksdb_options_get_delete_obsolete_files_period_micros(
rocksdb_options_t* opt) {
return opt->rep.delete_obsolete_files_period_micros;
}
void rocksdb_options_prepare_for_bulk_load(rocksdb_options_t* opt) {
opt->rep.PrepareForBulkLoad();
}
@@ -3082,20 +2657,11 @@ void rocksdb_options_set_memtable_prefix_bloom_size_ratio(
opt->rep.memtable_prefix_bloom_size_ratio = v;
}
double rocksdb_options_get_memtable_prefix_bloom_size_ratio(
rocksdb_options_t* opt) {
return opt->rep.memtable_prefix_bloom_size_ratio;
}
void rocksdb_options_set_memtable_huge_page_size(rocksdb_options_t* opt,
size_t v) {
opt->rep.memtable_huge_page_size = v;
}
size_t rocksdb_options_get_memtable_huge_page_size(rocksdb_options_t* opt) {
return opt->rep.memtable_huge_page_size;
}
void rocksdb_options_set_hash_skip_list_rep(
rocksdb_options_t *opt, size_t bucket_count,
int32_t skiplist_height, int32_t skiplist_branching_factor) {
@@ -3130,56 +2696,31 @@ void rocksdb_options_set_max_successive_merges(
opt->rep.max_successive_merges = v;
}
size_t rocksdb_options_get_max_successive_merges(rocksdb_options_t* opt) {
return opt->rep.max_successive_merges;
}
void rocksdb_options_set_bloom_locality(
rocksdb_options_t* opt, uint32_t v) {
opt->rep.bloom_locality = v;
}
uint32_t rocksdb_options_get_bloom_locality(rocksdb_options_t* opt) {
return opt->rep.bloom_locality;
}
void rocksdb_options_set_inplace_update_support(
rocksdb_options_t* opt, unsigned char v) {
opt->rep.inplace_update_support = v;
}
unsigned char rocksdb_options_get_inplace_update_support(
rocksdb_options_t* opt) {
return opt->rep.inplace_update_support;
}
void rocksdb_options_set_inplace_update_num_locks(
rocksdb_options_t* opt, size_t v) {
opt->rep.inplace_update_num_locks = v;
}
size_t rocksdb_options_get_inplace_update_num_locks(rocksdb_options_t* opt) {
return opt->rep.inplace_update_num_locks;
}
void rocksdb_options_set_report_bg_io_stats(
rocksdb_options_t* opt, int v) {
opt->rep.report_bg_io_stats = v;
}
unsigned char rocksdb_options_get_report_bg_io_stats(rocksdb_options_t* opt) {
return opt->rep.report_bg_io_stats;
}
void rocksdb_options_set_compaction_style(rocksdb_options_t *opt, int style) {
opt->rep.compaction_style =
static_cast<ROCKSDB_NAMESPACE::CompactionStyle>(style);
}
int rocksdb_options_get_compaction_style(rocksdb_options_t* opt) {
return opt->rep.compaction_style;
}
void rocksdb_options_set_universal_compaction_options(rocksdb_options_t *opt, rocksdb_universal_compaction_options_t *uco) {
opt->rep.compaction_options_universal = *(uco->rep);
}
@@ -3209,10 +2750,6 @@ void rocksdb_options_set_atomic_flush(rocksdb_options_t* opt,
opt->rep.atomic_flush = atomic_flush;
}
unsigned char rocksdb_options_get_atomic_flush(rocksdb_options_t* opt) {
return opt->rep.atomic_flush;
}
rocksdb_ratelimiter_t* rocksdb_ratelimiter_create(
int64_t rate_bytes_per_sec,
int64_t refill_period_us,
@@ -4904,25 +4441,11 @@ uint64_t rocksdb_approximate_memory_usage_get_cache_total(
return memory_usage->cache_total;
}
void rocksdb_options_set_dump_malloc_stats(rocksdb_options_t* opt,
unsigned char val) {
opt->rep.dump_malloc_stats = val;
}
void rocksdb_options_set_memtable_whole_key_filtering(rocksdb_options_t* opt,
unsigned char val) {
opt->rep.memtable_whole_key_filtering = val;
}
// deletes container with memory usage estimates
void rocksdb_approximate_memory_usage_destroy(rocksdb_memory_usage_t* usage) {
delete usage;
}
void rocksdb_cancel_all_background_work(rocksdb_t* db, unsigned char wait) {
CancelAllBackgroundWork(db->rep, wait);
}
} // end extern "C"
#endif // !ROCKSDB_LITE
-777
View File
@@ -1296,29 +1296,6 @@ int main(int argc, char** argv) {
Free(&vals[i]);
}
{
unsigned char value_found = 0;
CheckCondition(!rocksdb_key_may_exist(db, roptions, "invalid_key", 11,
NULL, NULL, NULL, 0, NULL));
CheckCondition(!rocksdb_key_may_exist(db, roptions, "invalid_key", 11,
&vals[0], &vals_sizes[0], NULL, 0,
&value_found));
if (value_found) {
Free(&vals[0]);
}
CheckCondition(!rocksdb_key_may_exist_cf(db, roptions, handles[1],
"invalid_key", 11, NULL, NULL,
NULL, 0, NULL));
CheckCondition(!rocksdb_key_may_exist_cf(db, roptions, handles[1],
"invalid_key", 11, &vals[0],
&vals_sizes[0], NULL, 0, NULL));
if (value_found) {
Free(&vals[0]);
}
}
rocksdb_iterator_t* iter = rocksdb_create_iterator_cf(db, roptions, handles[1]);
CheckCondition(!rocksdb_iter_valid(iter));
rocksdb_iter_seek_to_first(iter);
@@ -1484,757 +1461,6 @@ int main(int argc, char** argv) {
rocksdb_cuckoo_options_destroy(cuckoo_options);
}
StartPhase("options");
{
rocksdb_options_t* o;
o = rocksdb_options_create();
// Set and check options.
rocksdb_options_set_allow_ingest_behind(o, 1);
CheckCondition(1 == rocksdb_options_get_allow_ingest_behind(o));
rocksdb_options_compaction_readahead_size(o, 10);
CheckCondition(10 == rocksdb_options_get_compaction_readahead_size(o));
rocksdb_options_set_create_if_missing(o, 1);
CheckCondition(1 == rocksdb_options_get_create_if_missing(o));
rocksdb_options_set_create_missing_column_families(o, 1);
CheckCondition(1 == rocksdb_options_get_create_missing_column_families(o));
rocksdb_options_set_error_if_exists(o, 1);
CheckCondition(1 == rocksdb_options_get_error_if_exists(o));
rocksdb_options_set_paranoid_checks(o, 1);
CheckCondition(1 == rocksdb_options_get_paranoid_checks(o));
rocksdb_options_set_info_log_level(o, 3);
CheckCondition(3 == rocksdb_options_get_info_log_level(o));
rocksdb_options_set_write_buffer_size(o, 100);
CheckCondition(100 == rocksdb_options_get_write_buffer_size(o));
rocksdb_options_set_db_write_buffer_size(o, 1000);
CheckCondition(1000 == rocksdb_options_get_db_write_buffer_size(o));
rocksdb_options_set_max_open_files(o, 21);
CheckCondition(21 == rocksdb_options_get_max_open_files(o));
rocksdb_options_set_max_file_opening_threads(o, 5);
CheckCondition(5 == rocksdb_options_get_max_file_opening_threads(o));
rocksdb_options_set_max_total_wal_size(o, 400);
CheckCondition(400 == rocksdb_options_get_max_total_wal_size(o));
rocksdb_options_set_num_levels(o, 7);
CheckCondition(7 == rocksdb_options_get_num_levels(o));
rocksdb_options_set_level0_file_num_compaction_trigger(o, 4);
CheckCondition(4 ==
rocksdb_options_get_level0_file_num_compaction_trigger(o));
rocksdb_options_set_level0_slowdown_writes_trigger(o, 6);
CheckCondition(6 == rocksdb_options_get_level0_slowdown_writes_trigger(o));
rocksdb_options_set_level0_stop_writes_trigger(o, 8);
CheckCondition(8 == rocksdb_options_get_level0_stop_writes_trigger(o));
rocksdb_options_set_target_file_size_base(o, 256);
CheckCondition(256 == rocksdb_options_get_target_file_size_base(o));
rocksdb_options_set_target_file_size_multiplier(o, 3);
CheckCondition(3 == rocksdb_options_get_target_file_size_multiplier(o));
rocksdb_options_set_max_bytes_for_level_base(o, 1024);
CheckCondition(1024 == rocksdb_options_get_max_bytes_for_level_base(o));
rocksdb_options_set_level_compaction_dynamic_level_bytes(o, 1);
CheckCondition(1 ==
rocksdb_options_get_level_compaction_dynamic_level_bytes(o));
rocksdb_options_set_max_bytes_for_level_multiplier(o, 2.0);
CheckCondition(2.0 ==
rocksdb_options_get_max_bytes_for_level_multiplier(o));
rocksdb_options_set_skip_stats_update_on_db_open(o, 1);
CheckCondition(1 == rocksdb_options_get_skip_stats_update_on_db_open(o));
rocksdb_options_set_skip_checking_sst_file_sizes_on_db_open(o, 1);
CheckCondition(
1 == rocksdb_options_get_skip_checking_sst_file_sizes_on_db_open(o));
rocksdb_options_set_max_write_buffer_number(o, 97);
CheckCondition(97 == rocksdb_options_get_max_write_buffer_number(o));
rocksdb_options_set_min_write_buffer_number_to_merge(o, 23);
CheckCondition(23 ==
rocksdb_options_get_min_write_buffer_number_to_merge(o));
rocksdb_options_set_max_write_buffer_number_to_maintain(o, 64);
CheckCondition(64 ==
rocksdb_options_get_max_write_buffer_number_to_maintain(o));
rocksdb_options_set_max_write_buffer_size_to_maintain(o, 50000);
CheckCondition(50000 ==
rocksdb_options_get_max_write_buffer_size_to_maintain(o));
rocksdb_options_set_enable_pipelined_write(o, 1);
CheckCondition(1 == rocksdb_options_get_enable_pipelined_write(o));
rocksdb_options_set_unordered_write(o, 1);
CheckCondition(1 == rocksdb_options_get_unordered_write(o));
rocksdb_options_set_max_subcompactions(o, 123456);
CheckCondition(123456 == rocksdb_options_get_max_subcompactions(o));
rocksdb_options_set_max_background_jobs(o, 2);
CheckCondition(2 == rocksdb_options_get_max_background_jobs(o));
rocksdb_options_set_max_background_compactions(o, 3);
CheckCondition(3 == rocksdb_options_get_max_background_compactions(o));
rocksdb_options_set_base_background_compactions(o, 4);
CheckCondition(4 == rocksdb_options_get_base_background_compactions(o));
rocksdb_options_set_max_background_flushes(o, 5);
CheckCondition(5 == rocksdb_options_get_max_background_flushes(o));
rocksdb_options_set_max_log_file_size(o, 6);
CheckCondition(6 == rocksdb_options_get_max_log_file_size(o));
rocksdb_options_set_log_file_time_to_roll(o, 7);
CheckCondition(7 == rocksdb_options_get_log_file_time_to_roll(o));
rocksdb_options_set_keep_log_file_num(o, 8);
CheckCondition(8 == rocksdb_options_get_keep_log_file_num(o));
rocksdb_options_set_recycle_log_file_num(o, 9);
CheckCondition(9 == rocksdb_options_get_recycle_log_file_num(o));
rocksdb_options_set_soft_rate_limit(o, 2.0);
CheckCondition(2.0 == rocksdb_options_get_soft_rate_limit(o));
rocksdb_options_set_hard_rate_limit(o, 4.0);
CheckCondition(4.0 == rocksdb_options_get_hard_rate_limit(o));
rocksdb_options_set_soft_pending_compaction_bytes_limit(o, 10);
CheckCondition(10 ==
rocksdb_options_get_soft_pending_compaction_bytes_limit(o));
rocksdb_options_set_hard_pending_compaction_bytes_limit(o, 11);
CheckCondition(11 ==
rocksdb_options_get_hard_pending_compaction_bytes_limit(o));
rocksdb_options_set_rate_limit_delay_max_milliseconds(o, 1);
CheckCondition(1 ==
rocksdb_options_get_rate_limit_delay_max_milliseconds(o));
rocksdb_options_set_max_manifest_file_size(o, 12);
CheckCondition(12 == rocksdb_options_get_max_manifest_file_size(o));
rocksdb_options_set_table_cache_numshardbits(o, 13);
CheckCondition(13 == rocksdb_options_get_table_cache_numshardbits(o));
rocksdb_options_set_arena_block_size(o, 14);
CheckCondition(14 == rocksdb_options_get_arena_block_size(o));
rocksdb_options_set_use_fsync(o, 1);
CheckCondition(1 == rocksdb_options_get_use_fsync(o));
rocksdb_options_set_WAL_ttl_seconds(o, 15);
CheckCondition(15 == rocksdb_options_get_WAL_ttl_seconds(o));
rocksdb_options_set_WAL_size_limit_MB(o, 16);
CheckCondition(16 == rocksdb_options_get_WAL_size_limit_MB(o));
rocksdb_options_set_manifest_preallocation_size(o, 17);
CheckCondition(17 == rocksdb_options_get_manifest_preallocation_size(o));
rocksdb_options_set_allow_mmap_reads(o, 1);
CheckCondition(1 == rocksdb_options_get_allow_mmap_reads(o));
rocksdb_options_set_allow_mmap_writes(o, 1);
CheckCondition(1 == rocksdb_options_get_allow_mmap_writes(o));
rocksdb_options_set_use_direct_reads(o, 1);
CheckCondition(1 == rocksdb_options_get_use_direct_reads(o));
rocksdb_options_set_use_direct_io_for_flush_and_compaction(o, 1);
CheckCondition(
1 == rocksdb_options_get_use_direct_io_for_flush_and_compaction(o));
rocksdb_options_set_is_fd_close_on_exec(o, 1);
CheckCondition(1 == rocksdb_options_get_is_fd_close_on_exec(o));
rocksdb_options_set_skip_log_error_on_recovery(o, 1);
CheckCondition(1 == rocksdb_options_get_skip_log_error_on_recovery(o));
rocksdb_options_set_stats_dump_period_sec(o, 18);
CheckCondition(18 == rocksdb_options_get_stats_dump_period_sec(o));
rocksdb_options_set_stats_persist_period_sec(o, 5);
CheckCondition(5 == rocksdb_options_get_stats_persist_period_sec(o));
rocksdb_options_set_advise_random_on_open(o, 1);
CheckCondition(1 == rocksdb_options_get_advise_random_on_open(o));
rocksdb_options_set_access_hint_on_compaction_start(o, 3);
CheckCondition(3 == rocksdb_options_get_access_hint_on_compaction_start(o));
rocksdb_options_set_use_adaptive_mutex(o, 1);
CheckCondition(1 == rocksdb_options_get_use_adaptive_mutex(o));
rocksdb_options_set_bytes_per_sync(o, 19);
CheckCondition(19 == rocksdb_options_get_bytes_per_sync(o));
rocksdb_options_set_wal_bytes_per_sync(o, 20);
CheckCondition(20 == rocksdb_options_get_wal_bytes_per_sync(o));
rocksdb_options_set_writable_file_max_buffer_size(o, 21);
CheckCondition(21 == rocksdb_options_get_writable_file_max_buffer_size(o));
rocksdb_options_set_allow_concurrent_memtable_write(o, 1);
CheckCondition(1 == rocksdb_options_get_allow_concurrent_memtable_write(o));
rocksdb_options_set_enable_write_thread_adaptive_yield(o, 1);
CheckCondition(1 ==
rocksdb_options_get_enable_write_thread_adaptive_yield(o));
rocksdb_options_set_max_sequential_skip_in_iterations(o, 22);
CheckCondition(22 ==
rocksdb_options_get_max_sequential_skip_in_iterations(o));
rocksdb_options_set_disable_auto_compactions(o, 1);
CheckCondition(1 == rocksdb_options_get_disable_auto_compactions(o));
rocksdb_options_set_optimize_filters_for_hits(o, 1);
CheckCondition(1 == rocksdb_options_get_optimize_filters_for_hits(o));
rocksdb_options_set_delete_obsolete_files_period_micros(o, 23);
CheckCondition(23 ==
rocksdb_options_get_delete_obsolete_files_period_micros(o));
rocksdb_options_set_memtable_prefix_bloom_size_ratio(o, 2.0);
CheckCondition(2.0 ==
rocksdb_options_get_memtable_prefix_bloom_size_ratio(o));
rocksdb_options_set_max_compaction_bytes(o, 24);
CheckCondition(24 == rocksdb_options_get_max_compaction_bytes(o));
rocksdb_options_set_memtable_huge_page_size(o, 25);
CheckCondition(25 == rocksdb_options_get_memtable_huge_page_size(o));
rocksdb_options_set_max_successive_merges(o, 26);
CheckCondition(26 == rocksdb_options_get_max_successive_merges(o));
rocksdb_options_set_bloom_locality(o, 27);
CheckCondition(27 == rocksdb_options_get_bloom_locality(o));
rocksdb_options_set_inplace_update_support(o, 1);
CheckCondition(1 == rocksdb_options_get_inplace_update_support(o));
rocksdb_options_set_inplace_update_num_locks(o, 28);
CheckCondition(28 == rocksdb_options_get_inplace_update_num_locks(o));
rocksdb_options_set_report_bg_io_stats(o, 1);
CheckCondition(1 == rocksdb_options_get_report_bg_io_stats(o));
rocksdb_options_set_wal_recovery_mode(o, 2);
CheckCondition(2 == rocksdb_options_get_wal_recovery_mode(o));
rocksdb_options_set_compression(o, 5);
CheckCondition(5 == rocksdb_options_get_compression(o));
rocksdb_options_set_bottommost_compression(o, 4);
CheckCondition(4 == rocksdb_options_get_bottommost_compression(o));
rocksdb_options_set_compaction_style(o, 2);
CheckCondition(2 == rocksdb_options_get_compaction_style(o));
rocksdb_options_set_atomic_flush(o, 1);
CheckCondition(1 == rocksdb_options_get_atomic_flush(o));
// Create a copy that should be equal to the original.
rocksdb_options_t* copy;
copy = rocksdb_options_create_copy(o);
CheckCondition(1 == rocksdb_options_get_allow_ingest_behind(copy));
CheckCondition(10 == rocksdb_options_get_compaction_readahead_size(copy));
CheckCondition(1 == rocksdb_options_get_create_if_missing(copy));
CheckCondition(1 ==
rocksdb_options_get_create_missing_column_families(copy));
CheckCondition(1 == rocksdb_options_get_error_if_exists(copy));
CheckCondition(1 == rocksdb_options_get_paranoid_checks(copy));
CheckCondition(3 == rocksdb_options_get_info_log_level(copy));
CheckCondition(100 == rocksdb_options_get_write_buffer_size(copy));
CheckCondition(1000 == rocksdb_options_get_db_write_buffer_size(copy));
CheckCondition(21 == rocksdb_options_get_max_open_files(copy));
CheckCondition(5 == rocksdb_options_get_max_file_opening_threads(copy));
CheckCondition(400 == rocksdb_options_get_max_total_wal_size(copy));
CheckCondition(7 == rocksdb_options_get_num_levels(copy));
CheckCondition(
4 == rocksdb_options_get_level0_file_num_compaction_trigger(copy));
CheckCondition(6 ==
rocksdb_options_get_level0_slowdown_writes_trigger(copy));
CheckCondition(8 == rocksdb_options_get_level0_stop_writes_trigger(copy));
CheckCondition(256 == rocksdb_options_get_target_file_size_base(copy));
CheckCondition(3 == rocksdb_options_get_target_file_size_multiplier(copy));
CheckCondition(1024 == rocksdb_options_get_max_bytes_for_level_base(copy));
CheckCondition(
1 == rocksdb_options_get_level_compaction_dynamic_level_bytes(copy));
CheckCondition(2.0 ==
rocksdb_options_get_max_bytes_for_level_multiplier(copy));
CheckCondition(1 == rocksdb_options_get_skip_stats_update_on_db_open(copy));
CheckCondition(
1 == rocksdb_options_get_skip_checking_sst_file_sizes_on_db_open(copy));
CheckCondition(97 == rocksdb_options_get_max_write_buffer_number(copy));
CheckCondition(23 ==
rocksdb_options_get_min_write_buffer_number_to_merge(copy));
CheckCondition(
64 == rocksdb_options_get_max_write_buffer_number_to_maintain(copy));
CheckCondition(50000 ==
rocksdb_options_get_max_write_buffer_size_to_maintain(copy));
CheckCondition(1 == rocksdb_options_get_enable_pipelined_write(copy));
CheckCondition(1 == rocksdb_options_get_unordered_write(copy));
CheckCondition(123456 == rocksdb_options_get_max_subcompactions(copy));
CheckCondition(2 == rocksdb_options_get_max_background_jobs(copy));
CheckCondition(3 == rocksdb_options_get_max_background_compactions(copy));
CheckCondition(4 == rocksdb_options_get_base_background_compactions(copy));
CheckCondition(5 == rocksdb_options_get_max_background_flushes(copy));
CheckCondition(6 == rocksdb_options_get_max_log_file_size(copy));
CheckCondition(7 == rocksdb_options_get_log_file_time_to_roll(copy));
CheckCondition(8 == rocksdb_options_get_keep_log_file_num(copy));
CheckCondition(9 == rocksdb_options_get_recycle_log_file_num(copy));
CheckCondition(2.0 == rocksdb_options_get_soft_rate_limit(copy));
CheckCondition(4.0 == rocksdb_options_get_hard_rate_limit(copy));
CheckCondition(
10 == rocksdb_options_get_soft_pending_compaction_bytes_limit(copy));
CheckCondition(
11 == rocksdb_options_get_hard_pending_compaction_bytes_limit(copy));
CheckCondition(1 ==
rocksdb_options_get_rate_limit_delay_max_milliseconds(copy));
CheckCondition(12 == rocksdb_options_get_max_manifest_file_size(copy));
CheckCondition(13 == rocksdb_options_get_table_cache_numshardbits(copy));
CheckCondition(14 == rocksdb_options_get_arena_block_size(copy));
CheckCondition(1 == rocksdb_options_get_use_fsync(copy));
CheckCondition(15 == rocksdb_options_get_WAL_ttl_seconds(copy));
CheckCondition(16 == rocksdb_options_get_WAL_size_limit_MB(copy));
CheckCondition(17 == rocksdb_options_get_manifest_preallocation_size(copy));
CheckCondition(1 == rocksdb_options_get_allow_mmap_reads(copy));
CheckCondition(1 == rocksdb_options_get_allow_mmap_writes(copy));
CheckCondition(1 == rocksdb_options_get_use_direct_reads(copy));
CheckCondition(
1 == rocksdb_options_get_use_direct_io_for_flush_and_compaction(copy));
CheckCondition(1 == rocksdb_options_get_is_fd_close_on_exec(copy));
CheckCondition(1 == rocksdb_options_get_skip_log_error_on_recovery(copy));
CheckCondition(18 == rocksdb_options_get_stats_dump_period_sec(copy));
CheckCondition(5 == rocksdb_options_get_stats_persist_period_sec(copy));
CheckCondition(1 == rocksdb_options_get_advise_random_on_open(copy));
CheckCondition(3 ==
rocksdb_options_get_access_hint_on_compaction_start(copy));
CheckCondition(1 == rocksdb_options_get_use_adaptive_mutex(copy));
CheckCondition(19 == rocksdb_options_get_bytes_per_sync(copy));
CheckCondition(20 == rocksdb_options_get_wal_bytes_per_sync(copy));
CheckCondition(21 ==
rocksdb_options_get_writable_file_max_buffer_size(copy));
CheckCondition(1 ==
rocksdb_options_get_allow_concurrent_memtable_write(copy));
CheckCondition(
1 == rocksdb_options_get_enable_write_thread_adaptive_yield(copy));
CheckCondition(22 ==
rocksdb_options_get_max_sequential_skip_in_iterations(copy));
CheckCondition(1 == rocksdb_options_get_disable_auto_compactions(copy));
CheckCondition(1 == rocksdb_options_get_optimize_filters_for_hits(copy));
CheckCondition(
23 == rocksdb_options_get_delete_obsolete_files_period_micros(copy));
CheckCondition(2.0 ==
rocksdb_options_get_memtable_prefix_bloom_size_ratio(copy));
CheckCondition(24 == rocksdb_options_get_max_compaction_bytes(copy));
CheckCondition(25 == rocksdb_options_get_memtable_huge_page_size(copy));
CheckCondition(26 == rocksdb_options_get_max_successive_merges(copy));
CheckCondition(27 == rocksdb_options_get_bloom_locality(copy));
CheckCondition(1 == rocksdb_options_get_inplace_update_support(copy));
CheckCondition(28 == rocksdb_options_get_inplace_update_num_locks(copy));
CheckCondition(1 == rocksdb_options_get_report_bg_io_stats(copy));
CheckCondition(2 == rocksdb_options_get_wal_recovery_mode(copy));
CheckCondition(5 == rocksdb_options_get_compression(copy));
CheckCondition(4 == rocksdb_options_get_bottommost_compression(copy));
CheckCondition(2 == rocksdb_options_get_compaction_style(copy));
CheckCondition(1 == rocksdb_options_get_atomic_flush(copy));
// Copies should be independent.
rocksdb_options_set_allow_ingest_behind(copy, 0);
CheckCondition(0 == rocksdb_options_get_allow_ingest_behind(copy));
CheckCondition(1 == rocksdb_options_get_allow_ingest_behind(o));
rocksdb_options_compaction_readahead_size(copy, 20);
CheckCondition(20 == rocksdb_options_get_compaction_readahead_size(copy));
CheckCondition(10 == rocksdb_options_get_compaction_readahead_size(o));
rocksdb_options_set_create_if_missing(copy, 0);
CheckCondition(0 == rocksdb_options_get_create_if_missing(copy));
CheckCondition(1 == rocksdb_options_get_create_if_missing(o));
rocksdb_options_set_create_missing_column_families(copy, 0);
CheckCondition(0 ==
rocksdb_options_get_create_missing_column_families(copy));
CheckCondition(1 == rocksdb_options_get_create_missing_column_families(o));
rocksdb_options_set_error_if_exists(copy, 0);
CheckCondition(0 == rocksdb_options_get_error_if_exists(copy));
CheckCondition(1 == rocksdb_options_get_error_if_exists(o));
rocksdb_options_set_paranoid_checks(copy, 0);
CheckCondition(0 == rocksdb_options_get_paranoid_checks(copy));
CheckCondition(1 == rocksdb_options_get_paranoid_checks(o));
rocksdb_options_set_info_log_level(copy, 2);
CheckCondition(2 == rocksdb_options_get_info_log_level(copy));
CheckCondition(3 == rocksdb_options_get_info_log_level(o));
rocksdb_options_set_write_buffer_size(copy, 200);
CheckCondition(200 == rocksdb_options_get_write_buffer_size(copy));
CheckCondition(100 == rocksdb_options_get_write_buffer_size(o));
rocksdb_options_set_db_write_buffer_size(copy, 2000);
CheckCondition(2000 == rocksdb_options_get_db_write_buffer_size(copy));
CheckCondition(1000 == rocksdb_options_get_db_write_buffer_size(o));
rocksdb_options_set_max_open_files(copy, 42);
CheckCondition(42 == rocksdb_options_get_max_open_files(copy));
CheckCondition(21 == rocksdb_options_get_max_open_files(o));
rocksdb_options_set_max_file_opening_threads(copy, 3);
CheckCondition(3 == rocksdb_options_get_max_file_opening_threads(copy));
CheckCondition(5 == rocksdb_options_get_max_file_opening_threads(o));
rocksdb_options_set_max_total_wal_size(copy, 4000);
CheckCondition(4000 == rocksdb_options_get_max_total_wal_size(copy));
CheckCondition(400 == rocksdb_options_get_max_total_wal_size(o));
rocksdb_options_set_num_levels(copy, 6);
CheckCondition(6 == rocksdb_options_get_num_levels(copy));
CheckCondition(7 == rocksdb_options_get_num_levels(o));
rocksdb_options_set_level0_file_num_compaction_trigger(copy, 14);
CheckCondition(
14 == rocksdb_options_get_level0_file_num_compaction_trigger(copy));
CheckCondition(4 ==
rocksdb_options_get_level0_file_num_compaction_trigger(o));
rocksdb_options_set_level0_slowdown_writes_trigger(copy, 61);
CheckCondition(61 ==
rocksdb_options_get_level0_slowdown_writes_trigger(copy));
CheckCondition(6 == rocksdb_options_get_level0_slowdown_writes_trigger(o));
rocksdb_options_set_level0_stop_writes_trigger(copy, 17);
CheckCondition(17 == rocksdb_options_get_level0_stop_writes_trigger(copy));
CheckCondition(8 == rocksdb_options_get_level0_stop_writes_trigger(o));
rocksdb_options_set_target_file_size_base(copy, 128);
CheckCondition(128 == rocksdb_options_get_target_file_size_base(copy));
CheckCondition(256 == rocksdb_options_get_target_file_size_base(o));
rocksdb_options_set_target_file_size_multiplier(copy, 13);
CheckCondition(13 == rocksdb_options_get_target_file_size_multiplier(copy));
CheckCondition(3 == rocksdb_options_get_target_file_size_multiplier(o));
rocksdb_options_set_max_bytes_for_level_base(copy, 900);
CheckCondition(900 == rocksdb_options_get_max_bytes_for_level_base(copy));
CheckCondition(1024 == rocksdb_options_get_max_bytes_for_level_base(o));
rocksdb_options_set_level_compaction_dynamic_level_bytes(copy, 0);
CheckCondition(
0 == rocksdb_options_get_level_compaction_dynamic_level_bytes(copy));
CheckCondition(1 ==
rocksdb_options_get_level_compaction_dynamic_level_bytes(o));
rocksdb_options_set_max_bytes_for_level_multiplier(copy, 8.0);
CheckCondition(8.0 ==
rocksdb_options_get_max_bytes_for_level_multiplier(copy));
CheckCondition(2.0 ==
rocksdb_options_get_max_bytes_for_level_multiplier(o));
rocksdb_options_set_skip_stats_update_on_db_open(copy, 0);
CheckCondition(0 == rocksdb_options_get_skip_stats_update_on_db_open(copy));
CheckCondition(1 == rocksdb_options_get_skip_stats_update_on_db_open(o));
rocksdb_options_set_skip_checking_sst_file_sizes_on_db_open(copy, 0);
CheckCondition(
0 == rocksdb_options_get_skip_checking_sst_file_sizes_on_db_open(copy));
CheckCondition(
1 == rocksdb_options_get_skip_checking_sst_file_sizes_on_db_open(o));
rocksdb_options_set_max_write_buffer_number(copy, 2000);
CheckCondition(2000 == rocksdb_options_get_max_write_buffer_number(copy));
CheckCondition(97 == rocksdb_options_get_max_write_buffer_number(o));
rocksdb_options_set_min_write_buffer_number_to_merge(copy, 146);
CheckCondition(146 ==
rocksdb_options_get_min_write_buffer_number_to_merge(copy));
CheckCondition(23 ==
rocksdb_options_get_min_write_buffer_number_to_merge(o));
rocksdb_options_set_max_write_buffer_number_to_maintain(copy, 128);
CheckCondition(
128 == rocksdb_options_get_max_write_buffer_number_to_maintain(copy));
CheckCondition(64 ==
rocksdb_options_get_max_write_buffer_number_to_maintain(o));
rocksdb_options_set_max_write_buffer_size_to_maintain(copy, 9000);
CheckCondition(9000 ==
rocksdb_options_get_max_write_buffer_size_to_maintain(copy));
CheckCondition(50000 ==
rocksdb_options_get_max_write_buffer_size_to_maintain(o));
rocksdb_options_set_enable_pipelined_write(copy, 0);
CheckCondition(0 == rocksdb_options_get_enable_pipelined_write(copy));
CheckCondition(1 == rocksdb_options_get_enable_pipelined_write(o));
rocksdb_options_set_unordered_write(copy, 0);
CheckCondition(0 == rocksdb_options_get_unordered_write(copy));
CheckCondition(1 == rocksdb_options_get_unordered_write(o));
rocksdb_options_set_max_subcompactions(copy, 90001);
CheckCondition(90001 == rocksdb_options_get_max_subcompactions(copy));
CheckCondition(123456 == rocksdb_options_get_max_subcompactions(o));
rocksdb_options_set_max_background_jobs(copy, 12);
CheckCondition(12 == rocksdb_options_get_max_background_jobs(copy));
CheckCondition(2 == rocksdb_options_get_max_background_jobs(o));
rocksdb_options_set_max_background_compactions(copy, 13);
CheckCondition(13 == rocksdb_options_get_max_background_compactions(copy));
CheckCondition(3 == rocksdb_options_get_max_background_compactions(o));
rocksdb_options_set_base_background_compactions(copy, 14);
CheckCondition(14 == rocksdb_options_get_base_background_compactions(copy));
CheckCondition(4 == rocksdb_options_get_base_background_compactions(o));
rocksdb_options_set_max_background_flushes(copy, 15);
CheckCondition(15 == rocksdb_options_get_max_background_flushes(copy));
CheckCondition(5 == rocksdb_options_get_max_background_flushes(o));
rocksdb_options_set_max_log_file_size(copy, 16);
CheckCondition(16 == rocksdb_options_get_max_log_file_size(copy));
CheckCondition(6 == rocksdb_options_get_max_log_file_size(o));
rocksdb_options_set_log_file_time_to_roll(copy, 17);
CheckCondition(17 == rocksdb_options_get_log_file_time_to_roll(copy));
CheckCondition(7 == rocksdb_options_get_log_file_time_to_roll(o));
rocksdb_options_set_keep_log_file_num(copy, 18);
CheckCondition(18 == rocksdb_options_get_keep_log_file_num(copy));
CheckCondition(8 == rocksdb_options_get_keep_log_file_num(o));
rocksdb_options_set_recycle_log_file_num(copy, 19);
CheckCondition(19 == rocksdb_options_get_recycle_log_file_num(copy));
CheckCondition(9 == rocksdb_options_get_recycle_log_file_num(o));
rocksdb_options_set_soft_rate_limit(copy, 4.0);
CheckCondition(4.0 == rocksdb_options_get_soft_rate_limit(copy));
CheckCondition(2.0 == rocksdb_options_get_soft_rate_limit(o));
rocksdb_options_set_hard_rate_limit(copy, 2.0);
CheckCondition(2.0 == rocksdb_options_get_hard_rate_limit(copy));
CheckCondition(4.0 == rocksdb_options_get_hard_rate_limit(o));
rocksdb_options_set_soft_pending_compaction_bytes_limit(copy, 110);
CheckCondition(
110 == rocksdb_options_get_soft_pending_compaction_bytes_limit(copy));
CheckCondition(10 ==
rocksdb_options_get_soft_pending_compaction_bytes_limit(o));
rocksdb_options_set_hard_pending_compaction_bytes_limit(copy, 111);
CheckCondition(
111 == rocksdb_options_get_hard_pending_compaction_bytes_limit(copy));
CheckCondition(11 ==
rocksdb_options_get_hard_pending_compaction_bytes_limit(o));
rocksdb_options_set_rate_limit_delay_max_milliseconds(copy, 0);
CheckCondition(0 ==
rocksdb_options_get_rate_limit_delay_max_milliseconds(copy));
CheckCondition(1 ==
rocksdb_options_get_rate_limit_delay_max_milliseconds(o));
rocksdb_options_set_max_manifest_file_size(copy, 112);
CheckCondition(112 == rocksdb_options_get_max_manifest_file_size(copy));
CheckCondition(12 == rocksdb_options_get_max_manifest_file_size(o));
rocksdb_options_set_table_cache_numshardbits(copy, 113);
CheckCondition(113 == rocksdb_options_get_table_cache_numshardbits(copy));
CheckCondition(13 == rocksdb_options_get_table_cache_numshardbits(o));
rocksdb_options_set_arena_block_size(copy, 114);
CheckCondition(114 == rocksdb_options_get_arena_block_size(copy));
CheckCondition(14 == rocksdb_options_get_arena_block_size(o));
rocksdb_options_set_use_fsync(copy, 0);
CheckCondition(0 == rocksdb_options_get_use_fsync(copy));
CheckCondition(1 == rocksdb_options_get_use_fsync(o));
rocksdb_options_set_WAL_ttl_seconds(copy, 115);
CheckCondition(115 == rocksdb_options_get_WAL_ttl_seconds(copy));
CheckCondition(15 == rocksdb_options_get_WAL_ttl_seconds(o));
rocksdb_options_set_WAL_size_limit_MB(copy, 116);
CheckCondition(116 == rocksdb_options_get_WAL_size_limit_MB(copy));
CheckCondition(16 == rocksdb_options_get_WAL_size_limit_MB(o));
rocksdb_options_set_manifest_preallocation_size(copy, 117);
CheckCondition(117 ==
rocksdb_options_get_manifest_preallocation_size(copy));
CheckCondition(17 == rocksdb_options_get_manifest_preallocation_size(o));
rocksdb_options_set_allow_mmap_reads(copy, 0);
CheckCondition(0 == rocksdb_options_get_allow_mmap_reads(copy));
CheckCondition(1 == rocksdb_options_get_allow_mmap_reads(o));
rocksdb_options_set_allow_mmap_writes(copy, 0);
CheckCondition(0 == rocksdb_options_get_allow_mmap_writes(copy));
CheckCondition(1 == rocksdb_options_get_allow_mmap_writes(o));
rocksdb_options_set_use_direct_reads(copy, 0);
CheckCondition(0 == rocksdb_options_get_use_direct_reads(copy));
CheckCondition(1 == rocksdb_options_get_use_direct_reads(o));
rocksdb_options_set_use_direct_io_for_flush_and_compaction(copy, 0);
CheckCondition(
0 == rocksdb_options_get_use_direct_io_for_flush_and_compaction(copy));
CheckCondition(
1 == rocksdb_options_get_use_direct_io_for_flush_and_compaction(o));
rocksdb_options_set_is_fd_close_on_exec(copy, 0);
CheckCondition(0 == rocksdb_options_get_is_fd_close_on_exec(copy));
CheckCondition(1 == rocksdb_options_get_is_fd_close_on_exec(o));
rocksdb_options_set_skip_log_error_on_recovery(copy, 0);
CheckCondition(0 == rocksdb_options_get_skip_log_error_on_recovery(copy));
CheckCondition(1 == rocksdb_options_get_skip_log_error_on_recovery(o));
rocksdb_options_set_stats_dump_period_sec(copy, 218);
CheckCondition(218 == rocksdb_options_get_stats_dump_period_sec(copy));
CheckCondition(18 == rocksdb_options_get_stats_dump_period_sec(o));
rocksdb_options_set_stats_persist_period_sec(copy, 600);
CheckCondition(600 == rocksdb_options_get_stats_persist_period_sec(copy));
CheckCondition(5 == rocksdb_options_get_stats_persist_period_sec(o));
rocksdb_options_set_advise_random_on_open(copy, 0);
CheckCondition(0 == rocksdb_options_get_advise_random_on_open(copy));
CheckCondition(1 == rocksdb_options_get_advise_random_on_open(o));
rocksdb_options_set_access_hint_on_compaction_start(copy, 2);
CheckCondition(2 ==
rocksdb_options_get_access_hint_on_compaction_start(copy));
CheckCondition(3 == rocksdb_options_get_access_hint_on_compaction_start(o));
rocksdb_options_set_use_adaptive_mutex(copy, 0);
CheckCondition(0 == rocksdb_options_get_use_adaptive_mutex(copy));
CheckCondition(1 == rocksdb_options_get_use_adaptive_mutex(o));
rocksdb_options_set_bytes_per_sync(copy, 219);
CheckCondition(219 == rocksdb_options_get_bytes_per_sync(copy));
CheckCondition(19 == rocksdb_options_get_bytes_per_sync(o));
rocksdb_options_set_wal_bytes_per_sync(copy, 120);
CheckCondition(120 == rocksdb_options_get_wal_bytes_per_sync(copy));
CheckCondition(20 == rocksdb_options_get_wal_bytes_per_sync(o));
rocksdb_options_set_writable_file_max_buffer_size(copy, 121);
CheckCondition(121 ==
rocksdb_options_get_writable_file_max_buffer_size(copy));
CheckCondition(21 == rocksdb_options_get_writable_file_max_buffer_size(o));
rocksdb_options_set_allow_concurrent_memtable_write(copy, 0);
CheckCondition(0 ==
rocksdb_options_get_allow_concurrent_memtable_write(copy));
CheckCondition(1 == rocksdb_options_get_allow_concurrent_memtable_write(o));
rocksdb_options_set_enable_write_thread_adaptive_yield(copy, 0);
CheckCondition(
0 == rocksdb_options_get_enable_write_thread_adaptive_yield(copy));
CheckCondition(1 ==
rocksdb_options_get_enable_write_thread_adaptive_yield(o));
rocksdb_options_set_max_sequential_skip_in_iterations(copy, 122);
CheckCondition(122 ==
rocksdb_options_get_max_sequential_skip_in_iterations(copy));
CheckCondition(22 ==
rocksdb_options_get_max_sequential_skip_in_iterations(o));
rocksdb_options_set_disable_auto_compactions(copy, 0);
CheckCondition(0 == rocksdb_options_get_disable_auto_compactions(copy));
CheckCondition(1 == rocksdb_options_get_disable_auto_compactions(o));
rocksdb_options_set_optimize_filters_for_hits(copy, 0);
CheckCondition(0 == rocksdb_options_get_optimize_filters_for_hits(copy));
CheckCondition(1 == rocksdb_options_get_optimize_filters_for_hits(o));
rocksdb_options_set_delete_obsolete_files_period_micros(copy, 123);
CheckCondition(
123 == rocksdb_options_get_delete_obsolete_files_period_micros(copy));
CheckCondition(23 ==
rocksdb_options_get_delete_obsolete_files_period_micros(o));
rocksdb_options_set_memtable_prefix_bloom_size_ratio(copy, 4.0);
CheckCondition(4.0 ==
rocksdb_options_get_memtable_prefix_bloom_size_ratio(copy));
CheckCondition(2.0 ==
rocksdb_options_get_memtable_prefix_bloom_size_ratio(o));
rocksdb_options_set_max_compaction_bytes(copy, 124);
CheckCondition(124 == rocksdb_options_get_max_compaction_bytes(copy));
CheckCondition(24 == rocksdb_options_get_max_compaction_bytes(o));
rocksdb_options_set_memtable_huge_page_size(copy, 125);
CheckCondition(125 == rocksdb_options_get_memtable_huge_page_size(copy));
CheckCondition(25 == rocksdb_options_get_memtable_huge_page_size(o));
rocksdb_options_set_max_successive_merges(copy, 126);
CheckCondition(126 == rocksdb_options_get_max_successive_merges(copy));
CheckCondition(26 == rocksdb_options_get_max_successive_merges(o));
rocksdb_options_set_bloom_locality(copy, 127);
CheckCondition(127 == rocksdb_options_get_bloom_locality(copy));
CheckCondition(27 == rocksdb_options_get_bloom_locality(o));
rocksdb_options_set_inplace_update_support(copy, 0);
CheckCondition(0 == rocksdb_options_get_inplace_update_support(copy));
CheckCondition(1 == rocksdb_options_get_inplace_update_support(o));
rocksdb_options_set_inplace_update_num_locks(copy, 128);
CheckCondition(128 == rocksdb_options_get_inplace_update_num_locks(copy));
CheckCondition(28 == rocksdb_options_get_inplace_update_num_locks(o));
rocksdb_options_set_report_bg_io_stats(copy, 0);
CheckCondition(0 == rocksdb_options_get_report_bg_io_stats(copy));
CheckCondition(1 == rocksdb_options_get_report_bg_io_stats(o));
rocksdb_options_set_wal_recovery_mode(copy, 1);
CheckCondition(1 == rocksdb_options_get_wal_recovery_mode(copy));
CheckCondition(2 == rocksdb_options_get_wal_recovery_mode(o));
rocksdb_options_set_compression(copy, 4);
CheckCondition(4 == rocksdb_options_get_compression(copy));
CheckCondition(5 == rocksdb_options_get_compression(o));
rocksdb_options_set_bottommost_compression(copy, 3);
CheckCondition(3 == rocksdb_options_get_bottommost_compression(copy));
CheckCondition(4 == rocksdb_options_get_bottommost_compression(o));
rocksdb_options_set_compaction_style(copy, 1);
CheckCondition(1 == rocksdb_options_get_compaction_style(copy));
CheckCondition(2 == rocksdb_options_get_compaction_style(o));
rocksdb_options_set_atomic_flush(copy, 0);
CheckCondition(0 == rocksdb_options_get_atomic_flush(copy));
CheckCondition(1 == rocksdb_options_get_atomic_flush(o));
rocksdb_options_destroy(copy);
rocksdb_options_destroy(o);
}
StartPhase("iterate_upper_bound");
{
// Create new empty database
@@ -2614,9 +1840,6 @@ int main(int argc, char** argv) {
CheckNoError(err);
}
StartPhase("cancel_all_background_work");
rocksdb_cancel_all_background_work(db, 1);
StartPhase("cleanup");
rocksdb_close(db);
rocksdb_options_destroy(options);
+14 -18
View File
@@ -34,7 +34,6 @@
#include "table/block_based/block_based_table_factory.h"
#include "table/merging_iterator.h"
#include "util/autovector.h"
#include "util/cast_util.h"
#include "util/compression.h"
namespace ROCKSDB_NAMESPACE {
@@ -347,7 +346,7 @@ ColumnFamilyOptions SanitizeOptions(const ImmutableDBOptions& db_options,
}
bool is_block_based_table =
(result.table_factory->Name() == BlockBasedTableFactory::kName);
(result.table_factory->Name() == BlockBasedTableFactory().Name());
const uint64_t kAdjustedTtl = 30 * 24 * 60 * 60;
if (result.ttl == kDefaultTtl) {
@@ -1047,14 +1046,13 @@ bool ColumnFamilyData::NeedsCompaction() const {
}
Compaction* ColumnFamilyData::PickCompaction(
const MutableCFOptions& mutable_options,
const MutableDBOptions& mutable_db_options, LogBuffer* log_buffer) {
const MutableCFOptions& mutable_options, LogBuffer* log_buffer) {
SequenceNumber earliest_mem_seqno =
std::min(mem_->GetEarliestSequenceNumber(),
imm_.current()->GetEarliestSequenceNumber(false));
auto* result = compaction_picker_->PickCompaction(
GetName(), mutable_options, mutable_db_options, current_->storage_info(),
log_buffer, earliest_mem_seqno);
GetName(), mutable_options, current_->storage_info(), log_buffer,
earliest_mem_seqno);
if (result != nullptr) {
result->SetInputVersion(current_);
}
@@ -1124,16 +1122,14 @@ const int ColumnFamilyData::kCompactAllLevels = -1;
const int ColumnFamilyData::kCompactToBaseLevel = -2;
Compaction* ColumnFamilyData::CompactRange(
const MutableCFOptions& mutable_cf_options,
const MutableDBOptions& mutable_db_options, int input_level,
const MutableCFOptions& mutable_cf_options, int input_level,
int output_level, const CompactRangeOptions& compact_range_options,
const InternalKey* begin, const InternalKey* end,
InternalKey** compaction_end, bool* conflict,
uint64_t max_file_num_to_ignore) {
auto* result = compaction_picker_->CompactRange(
GetName(), mutable_cf_options, mutable_db_options,
current_->storage_info(), input_level, output_level,
compact_range_options, begin, end, compaction_end, conflict,
GetName(), mutable_cf_options, current_->storage_info(), input_level,
output_level, compact_range_options, begin, end, compaction_end, conflict,
max_file_num_to_ignore);
if (result != nullptr) {
result->SetInputVersion(current_);
@@ -1303,7 +1299,7 @@ Status ColumnFamilyData::ValidateOptions(
}
if (cf_options.ttl > 0 && cf_options.ttl != kDefaultTtl) {
if (cf_options.table_factory->Name() != BlockBasedTableFactory::kName) {
if (cf_options.table_factory->Name() != BlockBasedTableFactory().Name()) {
return Status::NotSupported(
"TTL is only supported in Block-Based Table format. ");
}
@@ -1311,7 +1307,7 @@ Status ColumnFamilyData::ValidateOptions(
if (cf_options.periodic_compaction_seconds > 0 &&
cf_options.periodic_compaction_seconds != kDefaultPeriodicCompSecs) {
if (cf_options.table_factory->Name() != BlockBasedTableFactory::kName) {
if (cf_options.table_factory->Name() != BlockBasedTableFactory().Name()) {
return Status::NotSupported(
"Periodic Compaction is only supported in "
"Block-Based Table format. ");
@@ -1401,8 +1397,8 @@ ColumnFamilySet::ColumnFamilySet(const std::string& dbname,
const ImmutableDBOptions* db_options,
const FileOptions& file_options,
Cache* table_cache,
WriteBufferManager* _write_buffer_manager,
WriteController* _write_controller,
WriteBufferManager* write_buffer_manager,
WriteController* write_controller,
BlockCacheTracer* const block_cache_tracer)
: max_column_family_(0),
dummy_cfd_(new ColumnFamilyData(
@@ -1414,8 +1410,8 @@ ColumnFamilySet::ColumnFamilySet(const std::string& dbname,
db_options_(db_options),
file_options_(file_options),
table_cache_(table_cache),
write_buffer_manager_(_write_buffer_manager),
write_controller_(_write_controller),
write_buffer_manager_(write_buffer_manager),
write_controller_(write_controller),
block_cache_tracer_(block_cache_tracer) {
// initialize linked list
dummy_cfd_->prev_ = dummy_cfd_;
@@ -1550,7 +1546,7 @@ ColumnFamilyHandle* ColumnFamilyMemTablesImpl::GetColumnFamilyHandle() {
uint32_t GetColumnFamilyID(ColumnFamilyHandle* column_family) {
uint32_t column_family_id = 0;
if (column_family != nullptr) {
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
column_family_id = cfh->GetID();
}
return column_family_id;
+2 -8
View File
@@ -387,7 +387,6 @@ class ColumnFamilyData {
bool NeedsCompaction() const;
// REQUIRES: DB mutex held
Compaction* PickCompaction(const MutableCFOptions& mutable_options,
const MutableDBOptions& mutable_db_options,
LogBuffer* log_buffer);
// Check if the passed range overlap with any running compactions.
@@ -413,7 +412,6 @@ class ColumnFamilyData {
static const int kCompactToBaseLevel;
// REQUIRES: DB mutex held
Compaction* CompactRange(const MutableCFOptions& mutable_cf_options,
const MutableDBOptions& mutable_db_options,
int input_level, int output_level,
const CompactRangeOptions& compact_range_options,
const InternalKey* begin, const InternalKey* end,
@@ -649,8 +647,8 @@ class ColumnFamilySet {
ColumnFamilySet(const std::string& dbname,
const ImmutableDBOptions* db_options,
const FileOptions& file_options, Cache* table_cache,
WriteBufferManager* _write_buffer_manager,
WriteController* _write_controller,
WriteBufferManager* write_buffer_manager,
WriteController* write_controller,
BlockCacheTracer* const block_cache_tracer);
~ColumnFamilySet();
@@ -680,10 +678,6 @@ class ColumnFamilySet {
Cache* get_table_cache() { return table_cache_; }
WriteBufferManager* write_buffer_manager() { return write_buffer_manager_; }
WriteController* write_controller() { return write_controller_; }
private:
friend class ColumnFamilyData;
// helper function that gets called from cfd destructor
+22 -28
View File
@@ -8,32 +8,40 @@
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#include <algorithm>
#include <vector>
#include <string>
#include <thread>
#include <vector>
#include "db/db_impl/db_impl.h"
#include "db/db_test_util.h"
#include "memtable/hash_skiplist_rep.h"
#include "options/options_parser.h"
#include "port/port.h"
#include "port/stack_trace.h"
#include "rocksdb/convenience.h"
#include "rocksdb/db.h"
#include "rocksdb/env.h"
#include "rocksdb/iterator.h"
#include "rocksdb/utilities/object_registry.h"
#include "test_util/fault_injection_test_env.h"
#include "test_util/sync_point.h"
#include "test_util/testharness.h"
#include "test_util/testutil.h"
#include "util/coding.h"
#include "util/string_util.h"
#include "utilities/fault_injection_env.h"
#include "utilities/merge_operators.h"
namespace ROCKSDB_NAMESPACE {
static const int kValueSize = 1000;
namespace {
std::string RandomString(Random* rnd, int len) {
std::string r;
test::RandomString(rnd, len, &r);
return r;
}
} // anonymous namespace
// counts how many operations were performed
class EnvCounter : public EnvWrapper {
public:
@@ -101,11 +109,11 @@ class ColumnFamilyTestBase : public testing::Test {
// preserves the implementation that was in place when all of the
// magic values in this file were picked.
*storage = std::string(kValueSize, ' ');
return Slice(*storage);
} else {
Random r(k);
*storage = r.RandomString(kValueSize);
return test::RandomString(&r, kValueSize, storage);
}
return Slice(*storage);
}
void Build(int base, int n, int flush_every = 0) {
@@ -114,7 +122,7 @@ class ColumnFamilyTestBase : public testing::Test {
for (int i = 0; i < n; i++) {
if (flush_every != 0 && i != 0 && i % flush_every == 0) {
DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
dbi->TEST_FlushMemTable();
}
@@ -219,7 +227,7 @@ class ColumnFamilyTestBase : public testing::Test {
Open({"default"});
}
DBImpl* dbfull() { return static_cast_with_check<DBImpl>(db_); }
DBImpl* dbfull() { return reinterpret_cast<DBImpl*>(db_); }
int GetProperty(int cf, std::string property) {
std::string value;
@@ -279,9 +287,7 @@ class ColumnFamilyTestBase : public testing::Test {
// Verify the CF options of the returned CF handle.
ColumnFamilyDescriptor desc;
ASSERT_OK(handles_[cfi]->GetDescriptor(&desc));
RocksDBOptionsParser::VerifyCFOptions(ConfigOptions(), desc.options,
current_cf_opt);
RocksDBOptionsParser::VerifyCFOptions(desc.options, current_cf_opt);
#endif // !ROCKSDB_LITE
cfi++;
}
@@ -321,11 +327,11 @@ class ColumnFamilyTestBase : public testing::Test {
// 10 bytes for key, rest is value
if (!save) {
ASSERT_OK(Put(cf, test::RandomKey(&rnd_, 11),
rnd_.RandomString(key_value_size - 10)));
RandomString(&rnd_, key_value_size - 10)));
} else {
std::string key = test::RandomKey(&rnd_, 11);
keys_[cf].insert(key);
ASSERT_OK(Put(cf, key, rnd_.RandomString(key_value_size - 10)));
ASSERT_OK(Put(cf, key, RandomString(&rnd_, key_value_size - 10)));
}
}
db_->FlushWAL(false);
@@ -562,7 +568,7 @@ TEST_P(ColumnFamilyTest, DontReuseColumnFamilyID) {
Open();
CreateColumnFamilies({"one", "two", "three"});
for (size_t i = 0; i < handles_.size(); ++i) {
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(handles_[i]);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(handles_[i]);
ASSERT_EQ(i, cfh->GetID());
}
if (iter == 1) {
@@ -578,7 +584,7 @@ TEST_P(ColumnFamilyTest, DontReuseColumnFamilyID) {
CreateColumnFamilies({"three2"});
// ID 3 that was used for dropped column family "three" should not be
// reused
auto cfh3 = static_cast_with_check<ColumnFamilyHandleImpl>(handles_[3]);
auto cfh3 = reinterpret_cast<ColumnFamilyHandleImpl*>(handles_[3]);
ASSERT_EQ(4U, cfh3->GetID());
Close();
Destroy();
@@ -2424,10 +2430,7 @@ TEST_P(ColumnFamilyTest, FlushAndDropRaceCondition) {
env_->Schedule(&test::SleepingBackgroundTask::DoSleepTask, &sleeping_task,
Env::Priority::HIGH);
// Make sure the task is sleeping. Otherwise, it might start to execute
// after sleeping_task.WaitUntilDone() and cause TSAN warning.
sleeping_task.WaitUntilSleeping();
// 1MB should create ~10 files for each CF
int kKeysNum = 10000;
PutRandomData(1, kKeysNum, 100);
@@ -2441,9 +2444,6 @@ TEST_P(ColumnFamilyTest, FlushAndDropRaceCondition) {
// now we sleep again. this is just so we're certain that flush job finished
env_->Schedule(&test::SleepingBackgroundTask::DoSleepTask, &sleeping_task,
Env::Priority::HIGH);
// Make sure the task is sleeping. Otherwise, it might start to execute
// after sleeping_task.WaitUntilDone() and cause TSAN warning.
sleeping_task.WaitUntilSleeping();
sleeping_task.WakeUp();
sleeping_task.WaitUntilDone();
@@ -2993,9 +2993,6 @@ TEST_P(ColumnFamilyTest, FlushCloseWALFiles) {
test::SleepingBackgroundTask sleeping_task;
env_->Schedule(&test::SleepingBackgroundTask::DoSleepTask, &sleeping_task,
Env::Priority::HIGH);
// Make sure the task is sleeping. Otherwise, it might start to execute
// after sleeping_task.WaitUntilDone() and cause TSAN warning.
sleeping_task.WaitUntilSleeping();
WriteOptions wo;
wo.sync = true;
@@ -3041,9 +3038,6 @@ TEST_P(ColumnFamilyTest, IteratorCloseWALFile1) {
test::SleepingBackgroundTask sleeping_task;
env_->Schedule(&test::SleepingBackgroundTask::DoSleepTask, &sleeping_task,
Env::Priority::HIGH);
// Make sure the task is sleeping. Otherwise, it might start to execute
// after sleeping_task.WaitUntilDone() and cause TSAN warning.
sleeping_task.WaitUntilSleeping();
WriteOptions wo;
wo.sync = true;
@@ -3358,7 +3352,7 @@ TEST_P(ColumnFamilyTest, MultipleCFPathsTest) {
// Re-open and verify the keys.
Reopen({ColumnFamilyOptions(), cf_opt1, cf_opt2});
DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
for (int cf = 1; cf != 3; ++cf) {
ReadOptions read_options;
read_options.readahead_size = 0;
+4 -5
View File
@@ -16,7 +16,6 @@
#include "rocksdb/env.h"
#include "test_util/sync_point.h"
#include "test_util/testharness.h"
#include "util/cast_util.h"
#include "util/string_util.h"
namespace ROCKSDB_NAMESPACE {
@@ -149,7 +148,7 @@ TEST_F(CompactFilesTest, ObsoleteFiles) {
auto l0_files = collector->GetFlushedFiles();
ASSERT_OK(db->CompactFiles(CompactionOptions(), l0_files, 1));
static_cast_with_check<DBImpl>(db)->TEST_WaitForCompact();
reinterpret_cast<DBImpl*>(db)->TEST_WaitForCompact();
// verify all compaction input files are deleted
for (auto fname : l0_files) {
@@ -184,13 +183,13 @@ TEST_F(CompactFilesTest, NotCutOutputOnLevel0) {
for (int i = 0; i < 500; ++i) {
db->Put(WriteOptions(), ToString(i), std::string(1000, 'a' + (i % 26)));
}
static_cast_with_check<DBImpl>(db)->TEST_WaitForFlushMemTable();
reinterpret_cast<DBImpl*>(db)->TEST_WaitForFlushMemTable();
auto l0_files_1 = collector->GetFlushedFiles();
collector->ClearFlushedFiles();
for (int i = 0; i < 500; ++i) {
db->Put(WriteOptions(), ToString(i), std::string(1000, 'a' + (i % 26)));
}
static_cast_with_check<DBImpl>(db)->TEST_WaitForFlushMemTable();
reinterpret_cast<DBImpl*>(db)->TEST_WaitForFlushMemTable();
auto l0_files_2 = collector->GetFlushedFiles();
ASSERT_OK(db->CompactFiles(CompactionOptions(), l0_files_1, 0));
ASSERT_OK(db->CompactFiles(CompactionOptions(), l0_files_2, 0));
@@ -384,7 +383,7 @@ TEST_F(CompactFilesTest, GetCompactionJobInfo) {
for (int i = 0; i < 500; ++i) {
db->Put(WriteOptions(), ToString(i), std::string(1000, 'a' + (i % 26)));
}
static_cast_with_check<DBImpl>(db)->TEST_WaitForFlushMemTable();
reinterpret_cast<DBImpl*>(db)->TEST_WaitForFlushMemTable();
auto l0_files_1 = collector->GetFlushedFiles();
CompactionOptions co;
co.compression = CompressionType::kLZ4Compression;
+2 -4
View File
@@ -5,11 +5,9 @@
#ifndef ROCKSDB_LITE
#include "db/compacted_db_impl.h"
#include "db/db_impl/db_impl.h"
#include "db/version_set.h"
#include "table/get_context.h"
#include "util/cast_util.h"
namespace ROCKSDB_NAMESPACE {
@@ -92,8 +90,8 @@ Status CompactedDBImpl::Init(const Options& options) {
ColumnFamilyOptions(options));
Status s = Recover({cf}, true /* read only */, false, true);
if (s.ok()) {
cfd_ = static_cast_with_check<ColumnFamilyHandleImpl>(DefaultColumnFamily())
->cfd();
cfd_ = reinterpret_cast<ColumnFamilyHandleImpl*>(
DefaultColumnFamily())->cfd();
cfd_->InstallSuperVersion(&sv_context, &mutex_);
}
mutex_.Unlock();
+3 -30
View File
@@ -7,14 +7,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "db/compaction/compaction.h"
#include <cinttypes>
#include <vector>
#include "db/column_family.h"
#include "db/compaction/compaction.h"
#include "rocksdb/compaction_filter.h"
#include "rocksdb/sst_partitioner.h"
#include "test_util/sync_point.h"
#include "util/string_util.h"
@@ -25,7 +23,7 @@ const uint64_t kRangeTombstoneSentinel =
int sstableKeyCompare(const Comparator* user_cmp, const InternalKey& a,
const InternalKey& b) {
auto c = user_cmp->CompareWithoutTimestamp(a.user_key(), b.user_key());
auto c = user_cmp->Compare(a.user_key(), b.user_key());
if (c != 0) {
return c;
}
@@ -207,7 +205,6 @@ bool Compaction::IsFullCompaction(
Compaction::Compaction(VersionStorageInfo* vstorage,
const ImmutableCFOptions& _immutable_cf_options,
const MutableCFOptions& _mutable_cf_options,
const MutableDBOptions& _mutable_db_options,
std::vector<CompactionInputFiles> _inputs,
int _output_level, uint64_t _target_file_size,
uint64_t _max_compaction_bytes, uint32_t _output_path_id,
@@ -246,7 +243,7 @@ Compaction::Compaction(VersionStorageInfo* vstorage,
compaction_reason_ = CompactionReason::kManualCompaction;
}
if (max_subcompactions_ == 0) {
max_subcompactions_ = _mutable_db_options.max_subcompactions;
max_subcompactions_ = immutable_cf_options_.max_subcompactions;
}
if (!bottommost_level_) {
// Currently we only enable dictionary compression during compaction to the
@@ -331,8 +328,6 @@ bool Compaction::IsTrivialMove() const {
// assert inputs_.size() == 1
std::unique_ptr<SstPartitioner> partitioner = CreateSstPartitioner();
for (const auto& file : inputs_.front().files) {
std::vector<FileMetaData*> file_grand_parents;
if (output_level_ + 1 >= number_levels_) {
@@ -345,13 +340,6 @@ bool Compaction::IsTrivialMove() const {
if (compaction_size > max_compaction_bytes_) {
return false;
}
if (partitioner.get() != nullptr) {
if (!partitioner->CanDoTrivialMove(file->smallest.user_key(),
file->largest.user_key())) {
return false;
}
}
}
return true;
@@ -537,21 +525,6 @@ std::unique_ptr<CompactionFilter> Compaction::CreateCompactionFilter() const {
context);
}
std::unique_ptr<SstPartitioner> Compaction::CreateSstPartitioner() const {
if (!immutable_cf_options_.sst_partitioner_factory) {
return nullptr;
}
SstPartitioner::Context context;
context.is_full_compaction = is_full_compaction_;
context.is_manual_compaction = is_manual_compaction_;
context.output_level = output_level_;
context.smallest_user_key = smallest_user_key_;
context.largest_user_key = largest_user_key_;
return immutable_cf_options_.sst_partitioner_factory->CreatePartitioner(
context);
}
bool Compaction::IsOutputLevelEmpty() const {
return inputs_.back().level != output_level_ || inputs_.back().empty();
}
-5
View File
@@ -11,7 +11,6 @@
#include "db/version_set.h"
#include "memory/arena.h"
#include "options/cf_options.h"
#include "rocksdb/sst_partitioner.h"
#include "util/autovector.h"
namespace ROCKSDB_NAMESPACE {
@@ -72,7 +71,6 @@ class Compaction {
Compaction(VersionStorageInfo* input_version,
const ImmutableCFOptions& immutable_cf_options,
const MutableCFOptions& mutable_cf_options,
const MutableDBOptions& mutable_db_options,
std::vector<CompactionInputFiles> inputs, int output_level,
uint64_t target_file_size, uint64_t max_compaction_bytes,
uint32_t output_path_id, CompressionType compression,
@@ -257,9 +255,6 @@ class Compaction {
// Create a CompactionFilter from compaction_filter_factory
std::unique_ptr<CompactionFilter> CreateCompactionFilter() const;
// Create a SstPartitioner from sst_partitioner_factory
std::unique_ptr<SstPartitioner> CreateSstPartitioner() const;
// Is the input level corresponding to output_level_ empty?
bool IsOutputLevelEmpty() const;
+6 -25
View File
@@ -182,7 +182,7 @@ void CompactionIterator::Next() {
PrepareOutput();
}
bool CompactionIterator::InvokeFilterIfNeeded(bool* need_skip,
void CompactionIterator::InvokeFilterIfNeeded(bool* need_skip,
Slice* skip_until) {
if (compaction_filter_ != nullptr &&
(ikey_.type == kTypeValue || ikey_.type == kTypeBlobIndex)) {
@@ -225,31 +225,14 @@ bool CompactionIterator::InvokeFilterIfNeeded(bool* need_skip,
value_.clear();
iter_stats_.num_record_drop_user++;
} else if (filter == CompactionFilter::Decision::kChangeValue) {
if (ikey_.type == kTypeBlobIndex) {
// value transfer from blob file to inlined data
ikey_.type = kTypeValue;
current_key_.UpdateInternalKey(ikey_.sequence, ikey_.type);
}
value_ = compaction_filter_value_;
} else if (filter == CompactionFilter::Decision::kRemoveAndSkipUntil) {
*need_skip = true;
compaction_filter_skip_until_.ConvertFromUserKey(kMaxSequenceNumber,
kValueTypeForSeek);
*skip_until = compaction_filter_skip_until_.Encode();
} else if (filter == CompactionFilter::Decision::kChangeBlobIndex) {
if (ikey_.type == kTypeValue) {
// value transfer from inlined data to blob file
ikey_.type = kTypeBlobIndex;
current_key_.UpdateInternalKey(ikey_.sequence, ikey_.type);
}
value_ = compaction_filter_value_;
} else if (filter == CompactionFilter::Decision::kIOError) {
status_ =
Status::IOError("Failed to access blob during compaction filter");
return false;
}
}
return true;
}
void CompactionIterator::NextFromInput() {
@@ -263,7 +246,6 @@ void CompactionIterator::NextFromInput() {
iter_stats_.num_input_records++;
if (!ParseInternalKey(key_, &ikey_)) {
iter_stats_.num_input_corrupt_records++;
// If `expect_valid_internal_key_` is false, return the corrupted key
// and let the caller decide what to do with it.
// TODO(noetzli): We should have a more elegant solution for this.
@@ -276,6 +258,7 @@ void CompactionIterator::NextFromInput() {
has_current_user_key_ = false;
current_user_key_sequence_ = kMaxSequenceNumber;
current_user_key_snapshot_ = 0;
iter_stats_.num_input_corrupt_records++;
valid_ = true;
break;
}
@@ -312,9 +295,8 @@ void CompactionIterator::NextFromInput() {
// Apply the compaction filter to the first committed version of the user
// key.
if (current_key_committed_ &&
!InvokeFilterIfNeeded(&need_skip, &skip_until)) {
break;
if (current_key_committed_) {
InvokeFilterIfNeeded(&need_skip, &skip_until);
}
} else {
// Update the current key to reflect the new sequence number/type without
@@ -334,9 +316,8 @@ void CompactionIterator::NextFromInput() {
current_key_committed_ = KeyCommitted(ikey_.sequence);
// Apply the compaction filter to the first committed version of the
// user key.
if (current_key_committed_ &&
!InvokeFilterIfNeeded(&need_skip, &skip_until)) {
break;
if (current_key_committed_) {
InvokeFilterIfNeeded(&need_skip, &skip_until);
}
}
}
+1 -2
View File
@@ -121,8 +121,7 @@ class CompactionIterator {
void PrepareOutput();
// Invoke compaction filter if needed.
// Return true on success, false on failures (e.g.: kIOError).
bool InvokeFilterIfNeeded(bool* need_skip, Slice* skip_until);
void InvokeFilterIfNeeded(bool* need_skip, Slice* skip_until);
// Given a sequence number, return the sequence number of the
// earliest snapshot that this sequence number is visible in.
+42 -128
View File
@@ -7,8 +7,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "db/compaction/compaction_job.h"
#include <algorithm>
#include <cinttypes>
#include <functional>
@@ -21,6 +19,7 @@
#include <vector>
#include "db/builder.h"
#include "db/compaction/compaction_job.h"
#include "db/db_impl/db_impl.h"
#include "db/db_iter.h"
#include "db/dbformat.h"
@@ -46,7 +45,6 @@
#include "port/port.h"
#include "rocksdb/db.h"
#include "rocksdb/env.h"
#include "rocksdb/sst_partitioner.h"
#include "rocksdb/statistics.h"
#include "rocksdb/status.h"
#include "rocksdb/table.h"
@@ -56,7 +54,6 @@
#include "table/table_builder.h"
#include "test_util/sync_point.h"
#include "util/coding.h"
#include "util/hash.h"
#include "util/mutexlock.h"
#include "util/random.h"
#include "util/stop_watch.h"
@@ -119,14 +116,10 @@ struct CompactionJob::SubcompactionState {
// The return status of this subcompaction
Status status;
// The return IO Status of this subcompaction
IOStatus io_status;
// Files produced by this subcompaction
struct Output {
FileMetaData meta;
bool finished;
uint64_t paranoid_hash;
std::shared_ptr<const TableProperties> table_properties;
};
@@ -136,7 +129,7 @@ struct CompactionJob::SubcompactionState {
std::unique_ptr<TableBuilder> builder;
Output* current_output() {
if (outputs.empty()) {
// This subcompaction's output could be empty if compaction was aborted
// This subcompaction's outptut could be empty if compaction was aborted
// before this subcompaction had a chance to generate any output files.
// When subcompactions are executed sequentially this is more likely and
// will be particulalry likely for the later subcompactions to be empty.
@@ -186,7 +179,6 @@ struct CompactionJob::SubcompactionState {
start = std::move(o.start);
end = std::move(o.end);
status = std::move(o.status);
io_status = std::move(o.io_status);
outputs = std::move(o.outputs);
outfile = std::move(o.outfile);
builder = std::move(o.builder);
@@ -206,21 +198,6 @@ struct CompactionJob::SubcompactionState {
SubcompactionState& operator=(const SubcompactionState&) = delete;
// Adds the key and value to the builder
// If paranoid is true, adds the key-value to the paranoid hash
void AddToBuilder(const Slice& key, const Slice& value, bool paranoid) {
auto curr = current_output();
assert(builder != nullptr);
assert(curr != nullptr);
if (paranoid) {
// Generate a rolling 64-bit hash of the key and values
curr->paranoid_hash = Hash64(key.data(), key.size(), curr->paranoid_hash);
curr->paranoid_hash =
Hash64(value.data(), value.size(), curr->paranoid_hash);
}
builder->Add(key, value);
}
// Returns true iff we should stop building the current output
// before processing "internal_key".
bool ShouldStopBefore(const Slice& internal_key, uint64_t curr_file_size) {
@@ -328,15 +305,12 @@ CompactionJob::CompactionJob(
const SnapshotChecker* snapshot_checker, std::shared_ptr<Cache> table_cache,
EventLogger* event_logger, bool paranoid_file_checks, bool measure_io_stats,
const std::string& dbname, CompactionJobStats* compaction_job_stats,
Env::Priority thread_pri, const std::atomic<bool>* manual_compaction_paused,
const std::string& db_id, const std::string& db_session_id)
Env::Priority thread_pri, const std::atomic<bool>* manual_compaction_paused)
: job_id_(job_id),
compact_(new CompactionState(compaction)),
compaction_job_stats_(compaction_job_stats),
compaction_stats_(compaction->compaction_reason(), 1),
dbname_(dbname),
db_id_(db_id),
db_session_id_(db_session_id),
db_options_(db_options),
file_options_(file_options),
env_(db_options.env),
@@ -568,7 +542,7 @@ void CompactionJob::GenSubcompactionBoundaries() {
// Greedily add ranges to the subcompaction until the sum of the ranges'
// sizes becomes >= the expected mean size of a subcompaction
sum = 0;
for (size_t i = 0; i + 1 < ranges.size(); i++) {
for (size_t i = 0; i < ranges.size() - 1; i++) {
sum += ranges[i].size;
if (subcompactions == 1) {
// If there's only one left to schedule then it goes to the end so no
@@ -632,42 +606,33 @@ Status CompactionJob::Run() {
// Check if any thread encountered an error during execution
Status status;
IOStatus io_s;
for (const auto& state : compact_->sub_compact_states) {
if (!state.status.ok()) {
status = state.status;
io_s = state.io_status;
break;
}
}
if (io_status_.ok()) {
io_status_ = io_s;
}
if (status.ok() && output_directory_) {
io_s = output_directory_->Fsync(IOOptions(), nullptr);
}
if (io_status_.ok()) {
io_status_ = io_s;
}
if (status.ok()) {
status = io_s;
status = output_directory_->Fsync(IOOptions(), nullptr);
}
if (status.ok()) {
thread_pool.clear();
std::vector<const CompactionJob::SubcompactionState::Output*> files_output;
std::vector<const FileMetaData*> files_meta;
for (const auto& state : compact_->sub_compact_states) {
for (const auto& output : state.outputs) {
files_output.emplace_back(&output);
files_meta.emplace_back(&output.meta);
}
}
ColumnFamilyData* cfd = compact_->compaction->column_family_data();
auto prefix_extractor =
compact_->compaction->mutable_cf_options()->prefix_extractor.get();
std::atomic<size_t> next_file_idx(0);
std::atomic<size_t> next_file_meta_idx(0);
auto verify_table = [&](Status& output_status) {
while (true) {
size_t file_idx = next_file_idx.fetch_add(1);
if (file_idx >= files_output.size()) {
size_t file_idx = next_file_meta_idx.fetch_add(1);
if (file_idx >= files_meta.size()) {
break;
}
// Verify that the table is usable
@@ -678,31 +643,19 @@ Status CompactionJob::Run() {
// to cache it here for further user reads
InternalIterator* iter = cfd->table_cache()->NewIterator(
ReadOptions(), file_options_, cfd->internal_comparator(),
files_output[file_idx]->meta, /*range_del_agg=*/nullptr,
prefix_extractor,
*files_meta[file_idx], /*range_del_agg=*/nullptr, prefix_extractor,
/*table_reader_ptr=*/nullptr,
cfd->internal_stats()->GetFileReadHist(
compact_->compaction->output_level()),
TableReaderCaller::kCompactionRefill, /*arena=*/nullptr,
/*skip_filters=*/false, compact_->compaction->output_level(),
MaxFileSizeForL0MetaPin(
*compact_->compaction->mutable_cf_options()),
/*smallest_compaction_key=*/nullptr,
/*largest_compaction_key=*/nullptr,
/*allow_unprepared_value=*/false);
/*largest_compaction_key=*/nullptr);
auto s = iter->status();
if (s.ok() && paranoid_file_checks_) {
uint64_t hash = 0;
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {
// Generate a rolling 64-bit hash of the key and values, using the
hash = Hash64(iter->key().data(), iter->key().size(), hash);
hash = Hash64(iter->value().data(), iter->value().size(), hash);
}
for (iter->SeekToFirst(); iter->Valid(); iter->Next()) {}
s = iter->status();
if (s.ok() && hash != files_output[file_idx]->paranoid_hash) {
s = Status::Corruption("Paraniod checksums do not match");
}
}
delete iter;
@@ -763,9 +716,6 @@ Status CompactionJob::Install(const MutableCFOptions& mutable_cf_options) {
if (status.ok()) {
status = InstallCompactionResults(mutable_cf_options);
}
if (!versions_->io_status().ok()) {
io_status_ = versions_->io_status();
}
VersionStorageInfo::LevelSummaryStorage tmp;
auto vstorage = cfd->current()->storage_info();
const auto& stats = compaction_stats_;
@@ -934,10 +884,9 @@ void CompactionJob::ProcessKeyValueCompaction(SubcompactionState* sub_compact) {
sub_compact->c_iter.reset(new CompactionIterator(
input.get(), cfd->user_comparator(), &merge, versions_->LastSequence(),
&existing_snapshots_, earliest_write_conflict_snapshot_,
snapshot_checker_, env_, ShouldReportDetailedTime(env_, stats_),
/*expect_valid_internal_key=*/true, &range_del_agg,
sub_compact->compaction, compaction_filter, shutting_down_,
preserve_deletes_seqnum_, manual_compaction_paused_,
snapshot_checker_, env_, ShouldReportDetailedTime(env_, stats_), false,
&range_del_agg, sub_compact->compaction, compaction_filter,
shutting_down_, preserve_deletes_seqnum_, manual_compaction_paused_,
db_options_.info_log));
auto c_iter = sub_compact->c_iter.get();
c_iter->SeekToFirst();
@@ -950,12 +899,6 @@ void CompactionJob::ProcessKeyValueCompaction(SubcompactionState* sub_compact) {
}
const auto& c_iter_stats = c_iter->iter_stats();
std::unique_ptr<SstPartitioner> partitioner =
sub_compact->compaction->output_level() == 0
? nullptr
: sub_compact->compaction->CreateSstPartitioner();
std::string last_key_for_partitioner;
while (status.ok() && !cfd->IsDropped() && c_iter->Valid()) {
// Invariant: c_iter.status() is guaranteed to be OK if c_iter->Valid()
// returns true.
@@ -982,10 +925,10 @@ void CompactionJob::ProcessKeyValueCompaction(SubcompactionState* sub_compact) {
break;
}
}
sub_compact->AddToBuilder(key, value, paranoid_file_checks_);
sub_compact->current_output_file_size =
sub_compact->builder->EstimatedFileSize();
assert(sub_compact->builder != nullptr);
assert(sub_compact->current_output() != nullptr);
sub_compact->builder->Add(key, value);
sub_compact->current_output_file_size = sub_compact->builder->FileSize();
const ParsedInternalKey& ikey = c_iter->ikey();
sub_compact->current_output()->meta.UpdateBoundaries(
key, value, ikey.sequence, ikey.type);
@@ -1013,29 +956,20 @@ void CompactionJob::ProcessKeyValueCompaction(SubcompactionState* sub_compact) {
"CompactionJob::Run():PausingManualCompaction:2",
reinterpret_cast<void*>(
const_cast<std::atomic<bool>*>(manual_compaction_paused_)));
if (partitioner.get()) {
last_key_for_partitioner.assign(c_iter->user_key().data_,
c_iter->user_key().size_);
}
c_iter->Next();
if (c_iter->status().IsManualCompactionPaused()) {
break;
}
if (!output_file_ended && c_iter->Valid()) {
if (((partitioner.get() &&
partitioner->ShouldPartition(PartitionerRequest(
last_key_for_partitioner, c_iter->user_key(),
sub_compact->current_output_file_size)) == kRequired) ||
(sub_compact->compaction->output_level() != 0 &&
sub_compact->ShouldStopBefore(
c_iter->key(), sub_compact->current_output_file_size))) &&
sub_compact->builder != nullptr) {
// (2) this key belongs to the next file. For historical reasons, the
// iterator status after advancing will be given to
// FinishCompactionOutputFile().
input_status = input->status();
output_file_ended = true;
}
if (!output_file_ended && c_iter->Valid() &&
sub_compact->compaction->output_level() != 0 &&
sub_compact->ShouldStopBefore(c_iter->key(),
sub_compact->current_output_file_size) &&
sub_compact->builder != nullptr) {
// (2) this key belongs to the next file. For historical reasons, the
// iterator status after advancing will be given to
// FinishCompactionOutputFile().
input_status = input->status();
output_file_ended = true;
}
if (output_file_ended) {
const Slice* next_key = nullptr;
@@ -1260,7 +1194,6 @@ Status CompactionJob::FinishCompactionOutputFile(
} else {
it->SeekToFirst();
}
TEST_SYNC_POINT("CompactionJob::FinishCompactionOutputFile1");
for (; it->Valid(); it->Next()) {
auto tombstone = it->Tombstone();
if (upper_bound != nullptr) {
@@ -1288,7 +1221,6 @@ Status CompactionJob::FinishCompactionOutputFile(
auto kv = tombstone.Serialize();
assert(lower_bound == nullptr ||
ucmp->Compare(*lower_bound, kv.second) < 0);
// Range tombstone is not supported by output validator yet.
sub_compact->builder->Add(kv.first.Encode(), kv.second);
InternalKey smallest_candidate = std::move(kv.first);
if (lower_bound != nullptr &&
@@ -1362,12 +1294,13 @@ Status CompactionJob::FinishCompactionOutputFile(
} else {
sub_compact->builder->Abandon();
}
IOStatus io_s = sub_compact->builder->io_status();
if (s.ok()) {
s = io_s;
}
const uint64_t current_bytes = sub_compact->builder->FileSize();
if (s.ok()) {
// Add the checksum information to file metadata.
meta->file_checksum = sub_compact->builder->GetFileChecksum();
meta->file_checksum_func_name =
sub_compact->builder->GetFileChecksumFuncName();
meta->fd.file_size = current_bytes;
}
sub_compact->current_output()->finished = true;
@@ -1376,22 +1309,10 @@ Status CompactionJob::FinishCompactionOutputFile(
// Finish and check for file errors
if (s.ok()) {
StopWatch sw(env_, stats_, COMPACTION_OUTFILE_SYNC_MICROS);
io_s = sub_compact->outfile->Sync(db_options_.use_fsync);
}
if (s.ok() && io_s.ok()) {
io_s = sub_compact->outfile->Close();
}
if (s.ok() && io_s.ok()) {
// Add the checksum information to file metadata.
meta->file_checksum = sub_compact->outfile->GetFileChecksum();
meta->file_checksum_func_name =
sub_compact->outfile->GetFileChecksumFuncName();
s = sub_compact->outfile->Sync(db_options_.use_fsync);
}
if (s.ok()) {
s = io_s;
}
if (sub_compact->io_status.ok()) {
sub_compact->io_status = io_s;
s = sub_compact->outfile->Close();
}
sub_compact->outfile.reset();
@@ -1541,12 +1462,7 @@ Status CompactionJob::OpenCompactionOutputFile(
TEST_SYNC_POINT_CALLBACK("CompactionJob::OpenCompactionOutputFile",
&syncpoint_arg);
#endif
Status s;
IOStatus io_s = NewWritableFile(fs_, fname, &writable_file, file_options_);
s = io_s;
if (sub_compact->io_status.ok()) {
sub_compact->io_status = io_s;
}
Status s = NewWritableFile(fs_, fname, &writable_file, file_options_);
if (!s.ok()) {
ROCKS_LOG_ERROR(
db_options_.info_log,
@@ -1586,7 +1502,6 @@ Status CompactionJob::OpenCompactionOutputFile(
out.meta.oldest_ancester_time = oldest_ancester_time;
out.meta.file_creation_time = current_time;
out.finished = false;
out.paranoid_hash = 0;
sub_compact->outputs.push_back(out);
}
@@ -1599,7 +1514,7 @@ Status CompactionJob::OpenCompactionOutputFile(
sub_compact->outfile.reset(
new WritableFileWriter(std::move(writable_file), fname, file_options_,
env_, db_options_.statistics.get(), listeners,
db_options_.file_checksum_gen_factory.get()));
db_options_.sst_file_checksum_func.get()));
// If the Column family flag is to only optimize filters for hits,
// we can skip creating filters if this is the bottommost_level where
@@ -1616,8 +1531,7 @@ Status CompactionJob::OpenCompactionOutputFile(
sub_compact->compaction->output_compression_opts(),
sub_compact->compaction->output_level(), skip_filters,
oldest_ancester_time, 0 /* oldest_key_time */,
sub_compact->compaction->max_output_file_size(), current_time, db_id_,
db_session_id_));
sub_compact->compaction->max_output_file_size(), current_time));
LogFlush(db_options_.info_log);
return s;
}
+1 -9
View File
@@ -78,9 +78,7 @@ class CompactionJob {
const std::string& dbname,
CompactionJobStats* compaction_job_stats,
Env::Priority thread_pri,
const std::atomic<bool>* manual_compaction_paused = nullptr,
const std::string& db_id = "",
const std::string& db_session_id = "");
const std::atomic<bool>* manual_compaction_paused = nullptr);
~CompactionJob();
@@ -102,9 +100,6 @@ class CompactionJob {
// Add compaction input/output to the current version
Status Install(const MutableCFOptions& mutable_cf_options);
// Return the IO status
IOStatus io_status() const { return io_status_; }
private:
struct SubcompactionState;
@@ -154,8 +149,6 @@ class CompactionJob {
// DBImpl state
const std::string& dbname_;
const std::string db_id_;
const std::string db_session_id_;
const ImmutableDBOptions& db_options_;
const FileOptions file_options_;
@@ -200,7 +193,6 @@ class CompactionJob {
std::vector<uint64_t> sizes_;
Env::WriteLifeTimeHint write_hint_;
Env::Priority thread_pri_;
IOStatus io_status_;
};
} // namespace ROCKSDB_NAMESPACE
+5 -4
View File
@@ -52,7 +52,6 @@
#include "test_util/sync_point.h"
#include "test_util/testharness.h"
#include "test_util/testutil.h"
#include "util/cast_util.h"
#include "util/compression.h"
#include "util/hash.h"
#include "util/mutexlock.h"
@@ -127,7 +126,9 @@ class CompactionJobStatsTest : public testing::Test,
static void SetUpTestCase() {}
static void TearDownTestCase() {}
DBImpl* dbfull() { return static_cast_with_check<DBImpl>(db_); }
DBImpl* dbfull() {
return reinterpret_cast<DBImpl*>(db_);
}
void CreateColumnFamilies(const std::vector<std::string>& cfs,
const Options& options) {
@@ -796,7 +797,7 @@ TEST_P(CompactionJobStatsTest, CompactionJobStatsTest) {
}
ASSERT_OK(Flush(1));
static_cast_with_check<DBImpl>(db_)->TEST_WaitForCompact();
reinterpret_cast<DBImpl*>(db_)->TEST_WaitForCompact();
stats_checker->set_verify_next_comp_io_stats(true);
std::atomic<bool> first_prepare_write(true);
@@ -1011,7 +1012,7 @@ TEST_P(CompactionJobStatsTest, UniversalCompactionTest) {
&rnd, start_key, start_key + key_base - 1,
kKeySize, kValueSize, key_interval,
compression_ratio, 1);
static_cast_with_check<DBImpl>(db_)->TEST_WaitForCompact();
reinterpret_cast<DBImpl*>(db_)->TEST_WaitForCompact();
}
ASSERT_EQ(stats_checker->NumberOfUnverifiedStats(), 0U);
}
+8 -11
View File
@@ -76,7 +76,6 @@ class CompactionJobTest : public testing::Test {
dbname_(test::PerThreadDBPath("compaction_job_test")),
db_options_(),
mutable_cf_options_(cf_options_),
mutable_db_options_(),
table_cache_(NewLRUCache(50000, 16)),
write_buffer_manager_(db_options_.db_write_buffer_size),
versions_(new VersionSet(dbname_, &db_options_, env_options_,
@@ -282,7 +281,7 @@ class CompactionJobTest : public testing::Test {
}
ASSERT_OK(s);
// Make "CURRENT" file that points to the new manifest file.
s = SetCurrentFile(fs_.get(), dbname_, 1, nullptr);
s = SetCurrentFile(env_, dbname_, 1, nullptr);
std::vector<ColumnFamilyDescriptor> column_families;
cf_options_.table_factory = mock_table_factory_;
@@ -315,12 +314,11 @@ class CompactionJobTest : public testing::Test {
num_input_files += level_files.size();
}
Compaction compaction(
cfd->current()->storage_info(), *cfd->ioptions(),
*cfd->GetLatestMutableCFOptions(), mutable_db_options_,
compaction_input_files, output_level, 1024 * 1024, 10 * 1024 * 1024, 0,
kNoCompression, cfd->GetLatestMutableCFOptions()->compression_opts, 0,
{}, true);
Compaction compaction(cfd->current()->storage_info(), *cfd->ioptions(),
*cfd->GetLatestMutableCFOptions(),
compaction_input_files, output_level, 1024 * 1024,
10 * 1024 * 1024, 0, kNoCompression,
cfd->ioptions()->compression_opts, 0, {}, true);
compaction.SetInputVersion(cfd->current());
LogBuffer log_buffer(InfoLogLevel::INFO_LEVEL, db_options_.info_log.get());
@@ -372,7 +370,6 @@ class CompactionJobTest : public testing::Test {
ImmutableDBOptions db_options_;
ColumnFamilyOptions cf_options_;
MutableCFOptions mutable_cf_options_;
MutableDBOptions mutable_db_options_;
std::shared_ptr<Cache> table_cache_;
WriteController write_controller_;
WriteBufferManager write_buffer_manager_;
@@ -398,7 +395,7 @@ TEST_F(CompactionJobTest, Simple) {
RunCompaction({ files }, expected_results);
}
TEST_F(CompactionJobTest, DISABLED_SimpleCorrupted) {
TEST_F(CompactionJobTest, SimpleCorrupted) {
NewDB();
auto expected_results = CreateTwoFiles(true);
@@ -992,7 +989,7 @@ TEST_F(CompactionJobTest, MultiSingleDelete) {
// single deletion and the (single) deletion gets removed while the corrupt key
// gets written out. TODO(noetzli): We probably want a better way to treat
// corrupt keys.
TEST_F(CompactionJobTest, DISABLED_CorruptionAfterDeletion) {
TEST_F(CompactionJobTest, CorruptionAfterDeletion) {
NewDB();
auto file1 =
+19 -22
View File
@@ -110,9 +110,9 @@ CompressionType GetCompressionType(const ImmutableCFOptions& ioptions,
// If bottommost_compression is set and we are compacting to the
// bottommost level then we should use it.
if (mutable_cf_options.bottommost_compression != kDisableCompressionOption &&
if (ioptions.bottommost_compression != kDisableCompressionOption &&
level >= (vstorage->num_non_empty_levels() - 1)) {
return mutable_cf_options.bottommost_compression;
return ioptions.bottommost_compression;
}
// If the user has specified a different compression level for each level,
// then pick the compression for that level.
@@ -132,22 +132,22 @@ CompressionType GetCompressionType(const ImmutableCFOptions& ioptions,
}
}
CompressionOptions GetCompressionOptions(const MutableCFOptions& cf_options,
CompressionOptions GetCompressionOptions(const ImmutableCFOptions& ioptions,
const VersionStorageInfo* vstorage,
int level,
const bool enable_compression) {
if (!enable_compression) {
return cf_options.compression_opts;
return ioptions.compression_opts;
}
// If bottommost_compression is set and we are compacting to the
// bottommost level then we should use the specified compression options
// for the bottmomost_compression.
if (cf_options.bottommost_compression != kDisableCompressionOption &&
if (ioptions.bottommost_compression != kDisableCompressionOption &&
level >= (vstorage->num_non_empty_levels() - 1) &&
cf_options.bottommost_compression_opts.enabled) {
return cf_options.bottommost_compression_opts;
ioptions.bottommost_compression_opts.enabled) {
return ioptions.bottommost_compression_opts;
}
return cf_options.compression_opts;
return ioptions.compression_opts;
}
CompactionPicker::CompactionPicker(const ImmutableCFOptions& ioptions,
@@ -332,7 +332,7 @@ Compaction* CompactionPicker::CompactFiles(
const CompactionOptions& compact_options,
const std::vector<CompactionInputFiles>& input_files, int output_level,
VersionStorageInfo* vstorage, const MutableCFOptions& mutable_cf_options,
const MutableDBOptions& mutable_db_options, uint32_t output_path_id) {
uint32_t output_path_id) {
assert(input_files.size());
// This compaction output should not overlap with a running compaction as
// `SanitizeCompactionInputFiles` should've checked earlier and db mutex
@@ -356,10 +356,10 @@ Compaction* CompactionPicker::CompactFiles(
compression_type = compact_options.compression;
}
auto c = new Compaction(
vstorage, ioptions_, mutable_cf_options, mutable_db_options, input_files,
output_level, compact_options.output_file_size_limit,
vstorage, ioptions_, mutable_cf_options, input_files, output_level,
compact_options.output_file_size_limit,
mutable_cf_options.max_compaction_bytes, output_path_id, compression_type,
GetCompressionOptions(mutable_cf_options, vstorage, output_level),
GetCompressionOptions(ioptions_, vstorage, output_level),
compact_options.max_subcompactions,
/* grandparents */ {}, true);
RegisterCompaction(c);
@@ -563,8 +563,7 @@ void CompactionPicker::GetGrandparents(
Compaction* CompactionPicker::CompactRange(
const std::string& cf_name, const MutableCFOptions& mutable_cf_options,
const MutableDBOptions& mutable_db_options, VersionStorageInfo* vstorage,
int input_level, int output_level,
VersionStorageInfo* vstorage, int input_level, int output_level,
const CompactRangeOptions& compact_range_options, const InternalKey* begin,
const InternalKey* end, InternalKey** compaction_end, bool* manual_conflict,
uint64_t max_file_num_to_ignore) {
@@ -627,15 +626,15 @@ Compaction* CompactionPicker::CompactRange(
}
Compaction* c = new Compaction(
vstorage, ioptions_, mutable_cf_options, mutable_db_options,
std::move(inputs), output_level,
vstorage, ioptions_, mutable_cf_options, std::move(inputs),
output_level,
MaxFileSizeForLevel(mutable_cf_options, output_level,
ioptions_.compaction_style),
/* max_compaction_bytes */ LLONG_MAX,
compact_range_options.target_path_id,
GetCompressionType(ioptions_, vstorage, mutable_cf_options,
output_level, 1),
GetCompressionOptions(mutable_cf_options, vstorage, output_level),
GetCompressionOptions(ioptions_, vstorage, output_level),
compact_range_options.max_subcompactions, /* grandparents */ {},
/* is manual */ true);
RegisterCompaction(c);
@@ -779,8 +778,8 @@ Compaction* CompactionPicker::CompactRange(
std::vector<FileMetaData*> grandparents;
GetGrandparents(vstorage, inputs, output_level_inputs, &grandparents);
Compaction* compaction = new Compaction(
vstorage, ioptions_, mutable_cf_options, mutable_db_options,
std::move(compaction_inputs), output_level,
vstorage, ioptions_, mutable_cf_options, std::move(compaction_inputs),
output_level,
MaxFileSizeForLevel(mutable_cf_options, output_level,
ioptions_.compaction_style, vstorage->base_level(),
ioptions_.level_compaction_dynamic_level_bytes),
@@ -788,7 +787,7 @@ Compaction* CompactionPicker::CompactRange(
compact_range_options.target_path_id,
GetCompressionType(ioptions_, vstorage, mutable_cf_options, output_level,
vstorage->base_level()),
GetCompressionOptions(mutable_cf_options, vstorage, output_level),
GetCompressionOptions(ioptions_, vstorage, output_level),
compact_range_options.max_subcompactions, std::move(grandparents),
/* is manual compaction */ true);
@@ -1086,8 +1085,6 @@ void CompactionPicker::PickFilesMarkedForCompaction(
Random64 rnd(/* seed */ reinterpret_cast<uint64_t>(vstorage));
size_t random_file_index = static_cast<size_t>(rnd.Uniform(
static_cast<uint64_t>(vstorage->FilesMarkedForCompaction().size())));
TEST_SYNC_POINT_CALLBACK("CompactionPicker::PickFilesMarkedForCompaction",
&random_file_index);
if (continuation(vstorage->FilesMarkedForCompaction()[random_file_index])) {
// found the compaction!
+6 -11
View File
@@ -56,8 +56,7 @@ class CompactionPicker {
// describes the compaction. Caller should delete the result.
virtual Compaction* PickCompaction(
const std::string& cf_name, const MutableCFOptions& mutable_cf_options,
const MutableDBOptions& mutable_db_options, VersionStorageInfo* vstorage,
LogBuffer* log_buffer,
VersionStorageInfo* vstorage, LogBuffer* log_buffer,
SequenceNumber earliest_memtable_seqno = kMaxSequenceNumber) = 0;
// Return a compaction object for compacting the range [begin,end] in
@@ -73,8 +72,7 @@ class CompactionPicker {
// *compaction_end should point to valid InternalKey!
virtual Compaction* CompactRange(
const std::string& cf_name, const MutableCFOptions& mutable_cf_options,
const MutableDBOptions& mutable_db_options, VersionStorageInfo* vstorage,
int input_level, int output_level,
VersionStorageInfo* vstorage, int input_level, int output_level,
const CompactRangeOptions& compact_range_options,
const InternalKey* begin, const InternalKey* end,
InternalKey** compaction_end, bool* manual_conflict,
@@ -115,7 +113,6 @@ class CompactionPicker {
const std::vector<CompactionInputFiles>& input_files,
int output_level, VersionStorageInfo* vstorage,
const MutableCFOptions& mutable_cf_options,
const MutableDBOptions& mutable_db_options,
uint32_t output_path_id);
// Converts a set of compaction input file numbers into
@@ -253,7 +250,6 @@ class NullCompactionPicker : public CompactionPicker {
Compaction* PickCompaction(
const std::string& /*cf_name*/,
const MutableCFOptions& /*mutable_cf_options*/,
const MutableDBOptions& /*mutable_db_options*/,
VersionStorageInfo* /*vstorage*/, LogBuffer* /* log_buffer */,
SequenceNumber /* earliest_memtable_seqno */) override {
return nullptr;
@@ -262,7 +258,6 @@ class NullCompactionPicker : public CompactionPicker {
// Always return "nullptr"
Compaction* CompactRange(const std::string& /*cf_name*/,
const MutableCFOptions& /*mutable_cf_options*/,
const MutableDBOptions& /*mutable_db_options*/,
VersionStorageInfo* /*vstorage*/,
int /*input_level*/, int /*output_level*/,
const CompactRangeOptions& /*compact_range_options*/,
@@ -310,9 +305,9 @@ CompressionType GetCompressionType(const ImmutableCFOptions& ioptions,
int level, int base_level,
const bool enable_compression = true);
CompressionOptions GetCompressionOptions(
const MutableCFOptions& mutable_cf_options,
const VersionStorageInfo* vstorage, int level,
const bool enable_compression = true);
CompressionOptions GetCompressionOptions(const ImmutableCFOptions& ioptions,
const VersionStorageInfo* vstorage,
int level,
const bool enable_compression = true);
} // namespace ROCKSDB_NAMESPACE
+24 -41
View File
@@ -36,8 +36,7 @@ bool FIFOCompactionPicker::NeedsCompaction(
Compaction* FIFOCompactionPicker::PickTTLCompaction(
const std::string& cf_name, const MutableCFOptions& mutable_cf_options,
const MutableDBOptions& mutable_db_options, VersionStorageInfo* vstorage,
LogBuffer* log_buffer) {
VersionStorageInfo* vstorage, LogBuffer* log_buffer) {
assert(mutable_cf_options.ttl > 0);
const int kLevel0 = 0;
@@ -72,14 +71,10 @@ Compaction* FIFOCompactionPicker::PickTTLCompaction(
if (current_time > mutable_cf_options.ttl) {
for (auto ritr = level_files.rbegin(); ritr != level_files.rend(); ++ritr) {
FileMetaData* f = *ritr;
assert(f);
if (f->fd.table_reader && f->fd.table_reader->GetTableProperties()) {
uint64_t creation_time =
f->fd.table_reader->GetTableProperties()->creation_time;
if (creation_time == 0 ||
creation_time >= (current_time - mutable_cf_options.ttl)) {
break;
}
uint64_t creation_time = f->TryGetFileCreationTime();
if (creation_time == kUnknownFileCreationTime ||
creation_time >= (current_time - mutable_cf_options.ttl)) {
break;
}
total_size -= f->compensated_file_size;
inputs[0].files.push_back(f);
@@ -97,31 +92,24 @@ Compaction* FIFOCompactionPicker::PickTTLCompaction(
}
for (const auto& f : inputs[0].files) {
uint64_t creation_time = 0;
assert(f);
if (f->fd.table_reader && f->fd.table_reader->GetTableProperties()) {
creation_time = f->fd.table_reader->GetTableProperties()->creation_time;
}
ROCKS_LOG_BUFFER(log_buffer,
"[%s] FIFO compaction: picking file %" PRIu64
" with creation time %" PRIu64 " for deletion",
cf_name.c_str(), f->fd.GetNumber(), creation_time);
cf_name.c_str(), f->fd.GetNumber(),
f->TryGetFileCreationTime());
}
Compaction* c = new Compaction(
vstorage, ioptions_, mutable_cf_options, mutable_db_options,
std::move(inputs), 0, 0, 0, 0, kNoCompression,
mutable_cf_options.compression_opts,
/* max_subcompactions */ 0, {}, /* is manual */ false,
vstorage->CompactionScore(0),
vstorage, ioptions_, mutable_cf_options, std::move(inputs), 0, 0, 0, 0,
kNoCompression, ioptions_.compression_opts, /* max_subcompactions */ 0,
{}, /* is manual */ false, vstorage->CompactionScore(0),
/* is deletion compaction */ true, CompactionReason::kFIFOTtl);
return c;
}
Compaction* FIFOCompactionPicker::PickSizeCompaction(
const std::string& cf_name, const MutableCFOptions& mutable_cf_options,
const MutableDBOptions& mutable_db_options, VersionStorageInfo* vstorage,
LogBuffer* log_buffer) {
VersionStorageInfo* vstorage, LogBuffer* log_buffer) {
const int kLevel0 = 0;
const std::vector<FileMetaData*>& level_files = vstorage->LevelFiles(kLevel0);
uint64_t total_size = GetTotalFilesSize(level_files);
@@ -150,11 +138,11 @@ Compaction* FIFOCompactionPicker::PickSizeCompaction(
max_compact_bytes_per_del_file,
mutable_cf_options.max_compaction_bytes, &comp_inputs)) {
Compaction* c = new Compaction(
vstorage, ioptions_, mutable_cf_options, mutable_db_options,
{comp_inputs}, 0, 16 * 1024 * 1024 /* output file size limit */,
vstorage, ioptions_, mutable_cf_options, {comp_inputs}, 0,
16 * 1024 * 1024 /* output file size limit */,
0 /* max compaction bytes, not applicable */,
0 /* output path ID */, mutable_cf_options.compression,
mutable_cf_options.compression_opts, 0 /* max_subcompactions */, {},
ioptions_.compression_opts, 0 /* max_subcompactions */, {},
/* is manual */ false, vstorage->CompactionScore(0),
/* is deletion compaction */ false,
CompactionReason::kFIFOReduceNumFiles);
@@ -201,29 +189,25 @@ Compaction* FIFOCompactionPicker::PickSizeCompaction(
}
Compaction* c = new Compaction(
vstorage, ioptions_, mutable_cf_options, mutable_db_options,
std::move(inputs), 0, 0, 0, 0, kNoCompression,
mutable_cf_options.compression_opts,
/* max_subcompactions */ 0, {}, /* is manual */ false,
vstorage->CompactionScore(0),
vstorage, ioptions_, mutable_cf_options, std::move(inputs), 0, 0, 0, 0,
kNoCompression, ioptions_.compression_opts, /* max_subcompactions */ 0,
{}, /* is manual */ false, vstorage->CompactionScore(0),
/* is deletion compaction */ true, CompactionReason::kFIFOMaxSize);
return c;
}
Compaction* FIFOCompactionPicker::PickCompaction(
const std::string& cf_name, const MutableCFOptions& mutable_cf_options,
const MutableDBOptions& mutable_db_options, VersionStorageInfo* vstorage,
LogBuffer* log_buffer, SequenceNumber /*earliest_memtable_seqno*/) {
VersionStorageInfo* vstorage, LogBuffer* log_buffer,
SequenceNumber /*earliest_memtable_seqno*/) {
assert(vstorage->num_levels() == 1);
Compaction* c = nullptr;
if (mutable_cf_options.ttl > 0) {
c = PickTTLCompaction(cf_name, mutable_cf_options, mutable_db_options,
vstorage, log_buffer);
c = PickTTLCompaction(cf_name, mutable_cf_options, vstorage, log_buffer);
}
if (c == nullptr) {
c = PickSizeCompaction(cf_name, mutable_cf_options, mutable_db_options,
vstorage, log_buffer);
c = PickSizeCompaction(cf_name, mutable_cf_options, vstorage, log_buffer);
}
RegisterCompaction(c);
return c;
@@ -231,8 +215,7 @@ Compaction* FIFOCompactionPicker::PickCompaction(
Compaction* FIFOCompactionPicker::CompactRange(
const std::string& cf_name, const MutableCFOptions& mutable_cf_options,
const MutableDBOptions& mutable_db_options, VersionStorageInfo* vstorage,
int input_level, int output_level,
VersionStorageInfo* vstorage, int input_level, int output_level,
const CompactRangeOptions& /*compact_range_options*/,
const InternalKey* /*begin*/, const InternalKey* /*end*/,
InternalKey** compaction_end, bool* /*manual_conflict*/,
@@ -245,8 +228,8 @@ Compaction* FIFOCompactionPicker::CompactRange(
assert(output_level == 0);
*compaction_end = nullptr;
LogBuffer log_buffer(InfoLogLevel::INFO_LEVEL, ioptions_.info_log);
Compaction* c = PickCompaction(cf_name, mutable_cf_options,
mutable_db_options, vstorage, &log_buffer);
Compaction* c =
PickCompaction(cf_name, mutable_cf_options, vstorage, &log_buffer);
log_buffer.FlushBufferToLog();
return c;
}
+2 -6
View File
@@ -21,14 +21,12 @@ class FIFOCompactionPicker : public CompactionPicker {
virtual Compaction* PickCompaction(
const std::string& cf_name, const MutableCFOptions& mutable_cf_options,
const MutableDBOptions& mutable_db_options, VersionStorageInfo* version,
LogBuffer* log_buffer,
VersionStorageInfo* version, LogBuffer* log_buffer,
SequenceNumber earliest_memtable_seqno = kMaxSequenceNumber) override;
virtual Compaction* CompactRange(
const std::string& cf_name, const MutableCFOptions& mutable_cf_options,
const MutableDBOptions& mutable_db_options, VersionStorageInfo* vstorage,
int input_level, int output_level,
VersionStorageInfo* vstorage, int input_level, int output_level,
const CompactRangeOptions& compact_range_options,
const InternalKey* begin, const InternalKey* end,
InternalKey** compaction_end, bool* manual_conflict,
@@ -43,13 +41,11 @@ class FIFOCompactionPicker : public CompactionPicker {
private:
Compaction* PickTTLCompaction(const std::string& cf_name,
const MutableCFOptions& mutable_cf_options,
const MutableDBOptions& mutable_db_options,
VersionStorageInfo* version,
LogBuffer* log_buffer);
Compaction* PickSizeCompaction(const std::string& cf_name,
const MutableCFOptions& mutable_cf_options,
const MutableDBOptions& mutable_db_options,
VersionStorageInfo* version,
LogBuffer* log_buffer);
};
+107 -59
View File
@@ -49,16 +49,14 @@ class LevelCompactionBuilder {
CompactionPicker* compaction_picker,
LogBuffer* log_buffer,
const MutableCFOptions& mutable_cf_options,
const ImmutableCFOptions& ioptions,
const MutableDBOptions& mutable_db_options)
const ImmutableCFOptions& ioptions)
: cf_name_(cf_name),
vstorage_(vstorage),
earliest_mem_seqno_(earliest_mem_seqno),
compaction_picker_(compaction_picker),
log_buffer_(log_buffer),
mutable_cf_options_(mutable_cf_options),
ioptions_(ioptions),
mutable_db_options_(mutable_db_options) {}
ioptions_(ioptions) {}
// Pick and return a compaction.
Compaction* PickCompaction();
@@ -95,13 +93,9 @@ class LevelCompactionBuilder {
// otherwise, returns false.
bool PickIntraL0Compaction();
// Picks a file from level_files to compact.
// level_files is a vector of (level, file metadata) in ascending order of
// level. If compact_to_next_level is true, compact the file to the next
// level, otherwise, compact to the same level as the input file.
void PickFileToCompact(
const autovector<std::pair<int, FileMetaData*>>& level_files,
bool compact_to_next_level);
void PickExpiredTtlFiles();
void PickFilesMarkedForPeriodicCompaction();
const std::string& cf_name_;
VersionStorageInfo* vstorage_;
@@ -122,7 +116,6 @@ class LevelCompactionBuilder {
const MutableCFOptions& mutable_cf_options_;
const ImmutableCFOptions& ioptions_;
const MutableDBOptions& mutable_db_options_;
// Pick a path ID to place a newly generated file, with its level
static uint32_t GetPathId(const ImmutableCFOptions& ioptions,
const MutableCFOptions& mutable_cf_options,
@@ -131,34 +124,72 @@ class LevelCompactionBuilder {
static const int kMinFilesForIntraL0Compaction = 4;
};
void LevelCompactionBuilder::PickFileToCompact(
const autovector<std::pair<int, FileMetaData*>>& level_files,
bool compact_to_next_level) {
for (auto& level_file : level_files) {
void LevelCompactionBuilder::PickExpiredTtlFiles() {
if (vstorage_->ExpiredTtlFiles().empty()) {
return;
}
auto continuation = [&](std::pair<int, FileMetaData*> level_file) {
// If it's being compacted it has nothing to do here.
// If this assert() fails that means that some function marked some
// files as being_compacted, but didn't call ComputeCompactionScore()
assert(!level_file.second->being_compacted);
start_level_ = level_file.first;
if ((compact_to_next_level &&
start_level_ == vstorage_->num_non_empty_levels() - 1) ||
output_level_ =
(start_level_ == 0) ? vstorage_->base_level() : start_level_ + 1;
if ((start_level_ == vstorage_->num_non_empty_levels() - 1) ||
(start_level_ == 0 &&
!compaction_picker_->level0_compactions_in_progress()->empty())) {
continue;
}
if (compact_to_next_level) {
output_level_ =
(start_level_ == 0) ? vstorage_->base_level() : start_level_ + 1;
} else {
output_level_ = start_level_;
return false;
}
start_level_inputs_.files = {level_file.second};
start_level_inputs_.level = start_level_;
if (compaction_picker_->ExpandInputsToCleanCut(cf_name_, vstorage_,
&start_level_inputs_)) {
return compaction_picker_->ExpandInputsToCleanCut(cf_name_, vstorage_,
&start_level_inputs_);
};
for (auto& level_file : vstorage_->ExpiredTtlFiles()) {
if (continuation(level_file)) {
// found the compaction!
return;
}
}
start_level_inputs_.files.clear();
}
void LevelCompactionBuilder::PickFilesMarkedForPeriodicCompaction() {
if (vstorage_->FilesMarkedForPeriodicCompaction().empty()) {
return;
}
auto continuation = [&](std::pair<int, FileMetaData*> level_file) {
// If it's being compacted it has nothing to do here.
// If this assert() fails that means that some function marked some
// files as being_compacted, but didn't call ComputeCompactionScore()
assert(!level_file.second->being_compacted);
output_level_ = start_level_ = level_file.first;
if (start_level_ == 0 &&
!compaction_picker_->level0_compactions_in_progress()->empty()) {
return false;
}
start_level_inputs_.files = {level_file.second};
start_level_inputs_.level = start_level_;
return compaction_picker_->ExpandInputsToCleanCut(cf_name_, vstorage_,
&start_level_inputs_);
};
for (auto& level_file : vstorage_->FilesMarkedForPeriodicCompaction()) {
if (continuation(level_file)) {
// found the compaction!
return;
}
}
start_level_inputs_.files.clear();
}
@@ -207,46 +238,64 @@ void LevelCompactionBuilder::SetupInitialFiles() {
}
}
}
} else {
// Compaction scores are sorted in descending order, no further scores
// will be >= 1.
break;
}
}
if (!start_level_inputs_.empty()) {
return;
}
// if we didn't find a compaction, check if there are any files marked for
// compaction
parent_index_ = base_index_ = -1;
if (start_level_inputs_.empty()) {
parent_index_ = base_index_ = -1;
compaction_picker_->PickFilesMarkedForCompaction(
cf_name_, vstorage_, &start_level_, &output_level_, &start_level_inputs_);
if (!start_level_inputs_.empty()) {
compaction_reason_ = CompactionReason::kFilesMarkedForCompaction;
return;
compaction_picker_->PickFilesMarkedForCompaction(
cf_name_, vstorage_, &start_level_, &output_level_,
&start_level_inputs_);
if (!start_level_inputs_.empty()) {
is_manual_ = true;
compaction_reason_ = CompactionReason::kFilesMarkedForCompaction;
return;
}
}
// Bottommost Files Compaction on deleting tombstones
PickFileToCompact(vstorage_->BottommostFilesMarkedForCompaction(), false);
if (!start_level_inputs_.empty()) {
compaction_reason_ = CompactionReason::kBottommostFiles;
return;
if (start_level_inputs_.empty()) {
size_t i;
for (i = 0; i < vstorage_->BottommostFilesMarkedForCompaction().size();
++i) {
auto& level_and_file = vstorage_->BottommostFilesMarkedForCompaction()[i];
assert(!level_and_file.second->being_compacted);
start_level_inputs_.level = output_level_ = start_level_ =
level_and_file.first;
start_level_inputs_.files = {level_and_file.second};
if (compaction_picker_->ExpandInputsToCleanCut(cf_name_, vstorage_,
&start_level_inputs_)) {
break;
}
}
if (i == vstorage_->BottommostFilesMarkedForCompaction().size()) {
start_level_inputs_.clear();
} else {
assert(!start_level_inputs_.empty());
compaction_reason_ = CompactionReason::kBottommostFiles;
return;
}
}
// TTL Compaction
PickFileToCompact(vstorage_->ExpiredTtlFiles(), true);
if (!start_level_inputs_.empty()) {
compaction_reason_ = CompactionReason::kTtl;
return;
if (start_level_inputs_.empty()) {
PickExpiredTtlFiles();
if (!start_level_inputs_.empty()) {
compaction_reason_ = CompactionReason::kTtl;
return;
}
}
// Periodic Compaction
PickFileToCompact(vstorage_->FilesMarkedForPeriodicCompaction(), false);
if (!start_level_inputs_.empty()) {
compaction_reason_ = CompactionReason::kPeriodicCompaction;
return;
if (start_level_inputs_.empty()) {
PickFilesMarkedForPeriodicCompaction();
if (!start_level_inputs_.empty()) {
compaction_reason_ = CompactionReason::kPeriodicCompaction;
return;
}
}
}
@@ -326,8 +375,8 @@ Compaction* LevelCompactionBuilder::PickCompaction() {
Compaction* LevelCompactionBuilder::GetCompaction() {
auto c = new Compaction(
vstorage_, ioptions_, mutable_cf_options_, mutable_db_options_,
std::move(compaction_inputs_), output_level_,
vstorage_, ioptions_, mutable_cf_options_, std::move(compaction_inputs_),
output_level_,
MaxFileSizeForLevel(mutable_cf_options_, output_level_,
ioptions_.compaction_style, vstorage_->base_level(),
ioptions_.level_compaction_dynamic_level_bytes),
@@ -335,7 +384,7 @@ Compaction* LevelCompactionBuilder::GetCompaction() {
GetPathId(ioptions_, mutable_cf_options_, output_level_),
GetCompressionType(ioptions_, vstorage_, mutable_cf_options_,
output_level_, vstorage_->base_level()),
GetCompressionOptions(mutable_cf_options_, vstorage_, output_level_),
GetCompressionOptions(ioptions_, vstorage_, output_level_),
/* max_subcompactions */ 0, std::move(grandparents_), is_manual_,
start_level_score_, false /* deletion_compaction */, compaction_reason_);
@@ -500,11 +549,10 @@ bool LevelCompactionBuilder::PickIntraL0Compaction() {
Compaction* LevelCompactionPicker::PickCompaction(
const std::string& cf_name, const MutableCFOptions& mutable_cf_options,
const MutableDBOptions& mutable_db_options, VersionStorageInfo* vstorage,
LogBuffer* log_buffer, SequenceNumber earliest_mem_seqno) {
VersionStorageInfo* vstorage, LogBuffer* log_buffer,
SequenceNumber earliest_mem_seqno) {
LevelCompactionBuilder builder(cf_name, vstorage, earliest_mem_seqno, this,
log_buffer, mutable_cf_options, ioptions_,
mutable_db_options);
log_buffer, mutable_cf_options, ioptions_);
return builder.PickCompaction();
}
} // namespace ROCKSDB_NAMESPACE
+1 -2
View File
@@ -22,8 +22,7 @@ class LevelCompactionPicker : public CompactionPicker {
: CompactionPicker(ioptions, icmp) {}
virtual Compaction* PickCompaction(
const std::string& cf_name, const MutableCFOptions& mutable_cf_options,
const MutableDBOptions& mutable_db_options, VersionStorageInfo* vstorage,
LogBuffer* log_buffer,
VersionStorageInfo* vstorage, LogBuffer* log_buffer,
SequenceNumber earliest_memtable_seqno = kMaxSequenceNumber) override;
virtual bool NeedsCompaction(
+59 -344
View File
@@ -33,7 +33,6 @@ class CompactionPickerTest : public testing::Test {
Options options_;
ImmutableCFOptions ioptions_;
MutableCFOptions mutable_cf_options_;
MutableDBOptions mutable_db_options_;
LevelCompactionPicker level_compaction_picker;
std::string cf_name_;
CountingLogger logger_;
@@ -53,7 +52,6 @@ class CompactionPickerTest : public testing::Test {
icmp_(ucmp_),
ioptions_(options_),
mutable_cf_options_(options_),
mutable_db_options_(),
level_compaction_picker(ioptions_, &icmp_),
cf_name_("dummy"),
log_buffer_(InfoLogLevel::INFO_LEVEL, &logger_),
@@ -80,17 +78,8 @@ class CompactionPickerTest : public testing::Test {
vstorage_->CalculateBaseBytes(ioptions_, mutable_cf_options_);
}
// Create a new VersionStorageInfo object so we can add mode files and then
// merge it with the existing VersionStorageInfo
void AddVersionStorage() {
temp_vstorage_.reset(new VersionStorageInfo(
&icmp_, ucmp_, options_.num_levels, ioptions_.compaction_style,
vstorage_.get(), false));
}
void DeleteVersionStorage() {
vstorage_.reset();
temp_vstorage_.reset();
files_.clear();
file_map_.clear();
input_files_.clear();
@@ -99,24 +88,18 @@ class CompactionPickerTest : public testing::Test {
void Add(int level, uint32_t file_number, const char* smallest,
const char* largest, uint64_t file_size = 1, uint32_t path_id = 0,
SequenceNumber smallest_seq = 100, SequenceNumber largest_seq = 100,
size_t compensated_file_size = 0, bool marked_for_compact = false) {
VersionStorageInfo* vstorage;
if (temp_vstorage_) {
vstorage = temp_vstorage_.get();
} else {
vstorage = vstorage_.get();
}
assert(level < vstorage->num_levels());
size_t compensated_file_size = 0) {
assert(level < vstorage_->num_levels());
FileMetaData* f = new FileMetaData(
file_number, path_id, file_size,
InternalKey(smallest, smallest_seq, kTypeValue),
InternalKey(largest, largest_seq, kTypeValue), smallest_seq,
largest_seq, marked_for_compact, kInvalidBlobFileNumber,
largest_seq, /* marked_for_compact */ false, kInvalidBlobFileNumber,
kUnknownOldestAncesterTime, kUnknownFileCreationTime,
kUnknownFileChecksum, kUnknownFileChecksumFuncName);
f->compensated_file_size =
(compensated_file_size != 0) ? compensated_file_size : file_size;
vstorage->AddFile(level, f);
vstorage_->AddFile(level, f);
files_.emplace_back(f);
file_map_.insert({file_number, {f, level}});
}
@@ -139,12 +122,6 @@ class CompactionPickerTest : public testing::Test {
}
void UpdateVersionStorageInfo() {
if (temp_vstorage_) {
VersionBuilder builder(FileOptions(), &ioptions_, nullptr,
vstorage_.get(), nullptr);
builder.SaveTo(temp_vstorage_.get());
vstorage_ = std::move(temp_vstorage_);
}
vstorage_->CalculateBaseBytes(ioptions_, mutable_cf_options_);
vstorage_->UpdateFilesByCompactionPri(ioptions_.compaction_pri);
vstorage_->UpdateNumNonEmptyLevels();
@@ -155,36 +132,13 @@ class CompactionPickerTest : public testing::Test {
vstorage_->ComputeFilesMarkedForCompaction();
vstorage_->SetFinalized();
}
void AddFileToVersionStorage(int level, uint32_t file_number,
const char* smallest, const char* largest,
uint64_t file_size = 1, uint32_t path_id = 0,
SequenceNumber smallest_seq = 100,
SequenceNumber largest_seq = 100,
size_t compensated_file_size = 0,
bool marked_for_compact = false) {
VersionStorageInfo* base_vstorage = vstorage_.release();
vstorage_.reset(new VersionStorageInfo(&icmp_, ucmp_, options_.num_levels,
kCompactionStyleUniversal,
base_vstorage, false));
Add(level, file_number, smallest, largest, file_size, path_id, smallest_seq,
largest_seq, compensated_file_size, marked_for_compact);
VersionBuilder builder(FileOptions(), &ioptions_, nullptr, base_vstorage,
nullptr);
builder.SaveTo(vstorage_.get());
UpdateVersionStorageInfo();
}
private:
std::unique_ptr<VersionStorageInfo> temp_vstorage_;
};
TEST_F(CompactionPickerTest, Empty) {
NewVersionStorage(6, kCompactionStyleLevel);
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() == nullptr);
}
@@ -195,8 +149,7 @@ TEST_F(CompactionPickerTest, Single) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() == nullptr);
}
@@ -209,8 +162,7 @@ TEST_F(CompactionPickerTest, Level0Trigger) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(2U, compaction->num_input_files(0));
ASSERT_EQ(1U, compaction->input(0, 0)->fd.GetNumber());
@@ -223,8 +175,7 @@ TEST_F(CompactionPickerTest, Level1Trigger) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(1U, compaction->num_input_files(0));
ASSERT_EQ(66U, compaction->input(0, 0)->fd.GetNumber());
@@ -242,8 +193,7 @@ TEST_F(CompactionPickerTest, Level1Trigger2) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(1U, compaction->num_input_files(0));
ASSERT_EQ(2U, compaction->num_input_files(1));
@@ -274,8 +224,7 @@ TEST_F(CompactionPickerTest, LevelMaxScore) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(1U, compaction->num_input_files(0));
ASSERT_EQ(7U, compaction->input(0, 0)->fd.GetNumber());
@@ -322,8 +271,7 @@ TEST_F(CompactionPickerTest, Level0TriggerDynamic) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(2U, compaction->num_input_files(0));
ASSERT_EQ(1U, compaction->input(0, 0)->fd.GetNumber());
@@ -347,8 +295,7 @@ TEST_F(CompactionPickerTest, Level0TriggerDynamic2) {
ASSERT_EQ(vstorage_->base_level(), num_levels - 2);
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(2U, compaction->num_input_files(0));
ASSERT_EQ(1U, compaction->input(0, 0)->fd.GetNumber());
@@ -373,8 +320,7 @@ TEST_F(CompactionPickerTest, Level0TriggerDynamic3) {
ASSERT_EQ(vstorage_->base_level(), num_levels - 3);
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(2U, compaction->num_input_files(0));
ASSERT_EQ(1U, compaction->input(0, 0)->fd.GetNumber());
@@ -403,8 +349,7 @@ TEST_F(CompactionPickerTest, Level0TriggerDynamic4) {
ASSERT_EQ(vstorage_->base_level(), num_levels - 3);
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(2U, compaction->num_input_files(0));
ASSERT_EQ(1U, compaction->input(0, 0)->fd.GetNumber());
@@ -426,8 +371,8 @@ TEST_F(CompactionPickerTest, LevelTriggerDynamic4) {
mutable_cf_options_.max_bytes_for_level_multiplier = 10;
NewVersionStorage(num_levels, kCompactionStyleLevel);
Add(0, 1U, "150", "200");
Add(num_levels - 1, 2U, "200", "250", 300U);
Add(num_levels - 1, 3U, "300", "350", 3000U);
Add(num_levels - 1, 3U, "200", "250", 300U);
Add(num_levels - 1, 4U, "300", "350", 3000U);
Add(num_levels - 1, 4U, "400", "450", 3U);
Add(num_levels - 2, 5U, "150", "180", 300U);
Add(num_levels - 2, 6U, "181", "350", 500U);
@@ -436,8 +381,7 @@ TEST_F(CompactionPickerTest, LevelTriggerDynamic4) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(1U, compaction->num_input_files(0));
ASSERT_EQ(5U, compaction->input(0, 0)->fd.GetNumber());
@@ -494,8 +438,7 @@ TEST_F(CompactionPickerTest, CompactionUniversalIngestBehindReservedLevel) {
std::unique_ptr<Compaction> compaction(
universal_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
// output level should be the one above the bottom-most
ASSERT_EQ(1, compaction->output_level());
@@ -529,8 +472,7 @@ TEST_F(CompactionPickerTest, CannotTrivialMoveUniversal) {
std::unique_ptr<Compaction> compaction(
universal_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(!compaction->is_trivial_move());
}
@@ -556,8 +498,7 @@ TEST_F(CompactionPickerTest, AllowsTrivialMoveUniversal) {
std::unique_ptr<Compaction> compaction(
universal_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction->is_trivial_move());
}
@@ -585,8 +526,7 @@ TEST_F(CompactionPickerTest, UniversalPeriodicCompaction1) {
std::unique_ptr<Compaction> compaction(
universal_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction);
ASSERT_EQ(4, compaction->output_level());
@@ -616,8 +556,7 @@ TEST_F(CompactionPickerTest, UniversalPeriodicCompaction2) {
std::unique_ptr<Compaction> compaction(
universal_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_FALSE(compaction);
}
@@ -643,8 +582,7 @@ TEST_F(CompactionPickerTest, UniversalPeriodicCompaction3) {
std::unique_ptr<Compaction> compaction(
universal_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_FALSE(compaction);
}
@@ -674,8 +612,7 @@ TEST_F(CompactionPickerTest, UniversalPeriodicCompaction4) {
std::unique_ptr<Compaction> compaction(
universal_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(!compaction ||
compaction->start_level() != compaction->output_level());
}
@@ -695,8 +632,7 @@ TEST_F(CompactionPickerTest, UniversalPeriodicCompaction5) {
std::unique_ptr<Compaction> compaction(
universal_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction);
ASSERT_EQ(0, compaction->start_level());
ASSERT_EQ(1U, compaction->num_input_files(0));
@@ -720,8 +656,7 @@ TEST_F(CompactionPickerTest, UniversalPeriodicCompaction6) {
std::unique_ptr<Compaction> compaction(
universal_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction);
ASSERT_EQ(4, compaction->start_level());
ASSERT_EQ(2U, compaction->num_input_files(0));
@@ -781,8 +716,7 @@ TEST_F(CompactionPickerTest, CompactionPriMinOverlapping1) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(1U, compaction->num_input_files(0));
// Pick file 8 because it overlaps with 0 files on level 3.
@@ -805,7 +739,7 @@ TEST_F(CompactionPickerTest, CompactionPriMinOverlapping2) {
Add(2, 8U, "201", "300",
60000000U); // Overlaps with file 28, 29, total size 521M
Add(3, 25U, "100", "110", 261000000U);
Add(3, 26U, "100", "110", 261000000U);
Add(3, 26U, "150", "170", 261000000U);
Add(3, 27U, "171", "179", 260000000U);
Add(3, 28U, "191", "220", 260000000U);
@@ -814,8 +748,7 @@ TEST_F(CompactionPickerTest, CompactionPriMinOverlapping2) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(1U, compaction->num_input_files(0));
// Picking file 7 because overlapping ratio is the biggest.
@@ -842,8 +775,7 @@ TEST_F(CompactionPickerTest, CompactionPriMinOverlapping3) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(1U, compaction->num_input_files(0));
// Picking file 8 because overlapping ratio is the biggest.
@@ -872,8 +804,7 @@ TEST_F(CompactionPickerTest, CompactionPriMinOverlapping4) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(1U, compaction->num_input_files(0));
// Picking file 8 because overlapping ratio is the biggest.
@@ -900,8 +831,7 @@ TEST_F(CompactionPickerTest, ParentIndexResetBug) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
}
// This test checks ExpandWhileOverlapping() by having overlapping user keys
@@ -918,8 +848,7 @@ TEST_F(CompactionPickerTest, OverlappingUserKeys) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(1U, compaction->num_input_levels());
ASSERT_EQ(2U, compaction->num_input_files(0));
@@ -938,8 +867,7 @@ TEST_F(CompactionPickerTest, OverlappingUserKeys2) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(2U, compaction->num_input_levels());
ASSERT_EQ(2U, compaction->num_input_files(0));
@@ -966,8 +894,7 @@ TEST_F(CompactionPickerTest, OverlappingUserKeys3) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(2U, compaction->num_input_levels());
ASSERT_EQ(5U, compaction->num_input_files(0));
@@ -997,8 +924,7 @@ TEST_F(CompactionPickerTest, OverlappingUserKeys4) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(2U, compaction->num_input_levels());
ASSERT_EQ(1U, compaction->num_input_files(0));
@@ -1021,8 +947,7 @@ TEST_F(CompactionPickerTest, OverlappingUserKeys5) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() == nullptr);
}
@@ -1043,8 +968,7 @@ TEST_F(CompactionPickerTest, OverlappingUserKeys6) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(2U, compaction->num_input_levels());
ASSERT_EQ(1U, compaction->num_input_files(0));
@@ -1064,8 +988,7 @@ TEST_F(CompactionPickerTest, OverlappingUserKeys7) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(2U, compaction->num_input_levels());
ASSERT_GE(1U, compaction->num_input_files(0));
@@ -1093,8 +1016,7 @@ TEST_F(CompactionPickerTest, OverlappingUserKeys8) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(2U, compaction->num_input_levels());
ASSERT_EQ(3U, compaction->num_input_files(0));
@@ -1126,8 +1048,7 @@ TEST_F(CompactionPickerTest, OverlappingUserKeys9) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(2U, compaction->num_input_levels());
ASSERT_EQ(5U, compaction->num_input_files(0));
@@ -1167,8 +1088,7 @@ TEST_F(CompactionPickerTest, OverlappingUserKeys10) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(2U, compaction->num_input_levels());
ASSERT_EQ(1U, compaction->num_input_files(0));
@@ -1206,8 +1126,7 @@ TEST_F(CompactionPickerTest, OverlappingUserKeys11) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(2U, compaction->num_input_levels());
ASSERT_EQ(1U, compaction->num_input_files(0));
@@ -1244,8 +1163,7 @@ TEST_F(CompactionPickerTest, NotScheduleL1IfL0WithHigherPri1) {
ASSERT_EQ(0, vstorage_->CompactionScoreLevel(0));
ASSERT_EQ(1, vstorage_->CompactionScoreLevel(1));
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() == nullptr);
}
@@ -1275,8 +1193,7 @@ TEST_F(CompactionPickerTest, NotScheduleL1IfL0WithHigherPri2) {
ASSERT_EQ(0, vstorage_->CompactionScoreLevel(0));
ASSERT_EQ(1, vstorage_->CompactionScoreLevel(1));
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
}
@@ -1309,8 +1226,7 @@ TEST_F(CompactionPickerTest, NotScheduleL1IfL0WithHigherPri3) {
ASSERT_EQ(1, vstorage_->CompactionScoreLevel(0));
ASSERT_EQ(0, vstorage_->CompactionScoreLevel(1));
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
}
@@ -1339,7 +1255,7 @@ TEST_F(CompactionPickerTest, EstimateCompactionBytesNeeded1) {
// Size ratio L4/L3 is 9.9
// After merge from L3, L4 size is 1000900
Add(4, 11U, "400", "500", 999900);
Add(5, 12U, "400", "500", 8007200);
Add(5, 11U, "400", "500", 8007200);
UpdateVersionStorageInfo();
@@ -1604,8 +1520,7 @@ TEST_F(CompactionPickerTest, MaxCompactionBytesHit) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(2U, compaction->num_input_levels());
ASSERT_EQ(1U, compaction->num_input_files(0));
@@ -1629,8 +1544,7 @@ TEST_F(CompactionPickerTest, MaxCompactionBytesNotHit) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(2U, compaction->num_input_levels());
ASSERT_EQ(3U, compaction->num_input_files(0));
@@ -1654,43 +1568,16 @@ TEST_F(CompactionPickerTest, IsTrivialMoveOn) {
Add(3, 5U, "120", "130", 7000U);
Add(3, 6U, "170", "180", 7000U);
Add(3, 7U, "220", "230", 7000U);
Add(3, 8U, "270", "280", 7000U);
Add(3, 5U, "220", "230", 7000U);
Add(3, 5U, "270", "280", 7000U);
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_TRUE(compaction->IsTrivialMove());
}
TEST_F(CompactionPickerTest, IsTrivialMoveOffSstPartitioned) {
mutable_cf_options_.max_bytes_for_level_base = 10000u;
mutable_cf_options_.max_compaction_bytes = 10001u;
ioptions_.level_compaction_dynamic_level_bytes = false;
ioptions_.sst_partitioner_factory = NewSstPartitionerFixedPrefixFactory(1);
NewVersionStorage(6, kCompactionStyleLevel);
// A compaction should be triggered and pick file 2
Add(1, 1U, "100", "150", 3000U);
Add(1, 2U, "151", "200", 3001U);
Add(1, 3U, "201", "250", 3000U);
Add(1, 4U, "251", "300", 3000U);
Add(3, 5U, "120", "130", 7000U);
Add(3, 6U, "170", "180", 7000U);
Add(3, 7U, "220", "230", 7000U);
Add(3, 8U, "270", "280", 7000U);
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
// No trivial move, because partitioning is applied
ASSERT_TRUE(!compaction->IsTrivialMove());
}
TEST_F(CompactionPickerTest, IsTrivialMoveOff) {
mutable_cf_options_.max_bytes_for_level_base = 1000000u;
mutable_cf_options_.max_compaction_bytes = 10000u;
@@ -1707,8 +1594,7 @@ TEST_F(CompactionPickerTest, IsTrivialMoveOff) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_FALSE(compaction->IsTrivialMove());
}
@@ -1733,8 +1619,7 @@ TEST_F(CompactionPickerTest, CacheNextCompactionIndex) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(1U, compaction->num_input_levels());
ASSERT_EQ(1U, compaction->num_input_files(0));
@@ -1743,8 +1628,7 @@ TEST_F(CompactionPickerTest, CacheNextCompactionIndex) {
ASSERT_EQ(2, vstorage_->NextCompactionIndex(1 /* level */));
compaction.reset(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(1U, compaction->num_input_levels());
ASSERT_EQ(1U, compaction->num_input_files(0));
@@ -1753,8 +1637,7 @@ TEST_F(CompactionPickerTest, CacheNextCompactionIndex) {
ASSERT_EQ(3, vstorage_->NextCompactionIndex(1 /* level */));
compaction.reset(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() == nullptr);
ASSERT_EQ(4, vstorage_->NextCompactionIndex(1 /* level */));
}
@@ -1779,8 +1662,7 @@ TEST_F(CompactionPickerTest, IntraL0MaxCompactionBytesNotHit) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(1U, compaction->num_input_levels());
ASSERT_EQ(5U, compaction->num_input_files(0));
@@ -1810,8 +1692,7 @@ TEST_F(CompactionPickerTest, IntraL0MaxCompactionBytesHit) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(1U, compaction->num_input_levels());
ASSERT_EQ(4U, compaction->num_input_files(0));
@@ -1843,8 +1724,7 @@ TEST_F(CompactionPickerTest, IntraL0ForEarliestSeqno) {
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(level_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_, 107));
cf_name_, mutable_cf_options_, vstorage_.get(), &log_buffer_, 107));
ASSERT_TRUE(compaction.get() != nullptr);
ASSERT_EQ(1U, compaction->num_input_levels());
ASSERT_EQ(4U, compaction->num_input_files(0));
@@ -1853,171 +1733,6 @@ TEST_F(CompactionPickerTest, IntraL0ForEarliestSeqno) {
ASSERT_EQ(0, compaction->output_level());
}
#ifndef ROCKSDB_LITE
TEST_F(CompactionPickerTest, UniversalMarkedCompactionFullOverlap) {
const uint64_t kFileSize = 100000;
ioptions_.compaction_style = kCompactionStyleUniversal;
UniversalCompactionPicker universal_compaction_picker(ioptions_, &icmp_);
// This test covers the case where a "regular" universal compaction is
// scheduled first, followed by a delete triggered compaction. The latter
// should fail
NewVersionStorage(5, kCompactionStyleUniversal);
Add(0, 1U, "150", "200", kFileSize, 0, 500, 550);
Add(0, 2U, "201", "250", 2 * kFileSize, 0, 401, 450);
Add(0, 4U, "260", "300", 4 * kFileSize, 0, 260, 300);
Add(3, 5U, "010", "080", 8 * kFileSize, 0, 200, 251);
Add(4, 3U, "301", "350", 8 * kFileSize, 0, 101, 150);
Add(4, 6U, "501", "750", 8 * kFileSize, 0, 101, 150);
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(
universal_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
ASSERT_TRUE(compaction);
// Validate that its a compaction to reduce sorted runs
ASSERT_EQ(CompactionReason::kUniversalSortedRunNum,
compaction->compaction_reason());
ASSERT_EQ(0, compaction->output_level());
ASSERT_EQ(0, compaction->start_level());
ASSERT_EQ(2U, compaction->num_input_files(0));
AddVersionStorage();
// Simulate a flush and mark the file for compaction
Add(0, 7U, "150", "200", kFileSize, 0, 551, 600, 0, true);
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction2(
universal_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
ASSERT_FALSE(compaction2);
}
TEST_F(CompactionPickerTest, UniversalMarkedCompactionFullOverlap2) {
const uint64_t kFileSize = 100000;
ioptions_.compaction_style = kCompactionStyleUniversal;
UniversalCompactionPicker universal_compaction_picker(ioptions_, &icmp_);
// This test covers the case where a delete triggered compaction is
// scheduled first, followed by a "regular" compaction. The latter
// should fail
NewVersionStorage(5, kCompactionStyleUniversal);
// Mark file number 4 for compaction
Add(0, 4U, "260", "300", 4 * kFileSize, 0, 260, 300, 0, true);
Add(3, 5U, "240", "290", 8 * kFileSize, 0, 201, 250);
Add(4, 3U, "301", "350", 8 * kFileSize, 0, 101, 150);
Add(4, 6U, "501", "750", 8 * kFileSize, 0, 101, 150);
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(
universal_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
ASSERT_TRUE(compaction);
// Validate that its a delete triggered compaction
ASSERT_EQ(CompactionReason::kFilesMarkedForCompaction,
compaction->compaction_reason());
ASSERT_EQ(3, compaction->output_level());
ASSERT_EQ(0, compaction->start_level());
ASSERT_EQ(1U, compaction->num_input_files(0));
ASSERT_EQ(1U, compaction->num_input_files(1));
AddVersionStorage();
Add(0, 1U, "150", "200", kFileSize, 0, 500, 550);
Add(0, 2U, "201", "250", 2 * kFileSize, 0, 401, 450);
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction2(
universal_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
ASSERT_FALSE(compaction2);
}
TEST_F(CompactionPickerTest, UniversalMarkedCompactionStartOutputOverlap) {
// The case where universal periodic compaction can be picked
// with some newer files being compacted.
const uint64_t kFileSize = 100000;
ioptions_.compaction_style = kCompactionStyleUniversal;
bool input_level_overlap = false;
bool output_level_overlap = false;
// Let's mark 2 files in 2 different levels for compaction. The
// compaction picker will randomly pick one, so use the sync point to
// ensure a deterministic order. Loop until both cases are covered
size_t random_index = 0;
SyncPoint::GetInstance()->SetCallBack(
"CompactionPicker::PickFilesMarkedForCompaction", [&](void* arg) {
size_t* index = static_cast<size_t*>(arg);
*index = random_index;
});
SyncPoint::GetInstance()->EnableProcessing();
while (!input_level_overlap || !output_level_overlap) {
// Ensure that the L0 file gets picked first
random_index = !input_level_overlap ? 0 : 1;
UniversalCompactionPicker universal_compaction_picker(ioptions_, &icmp_);
NewVersionStorage(5, kCompactionStyleUniversal);
Add(0, 1U, "260", "300", 4 * kFileSize, 0, 260, 300, 0, true);
Add(3, 2U, "010", "020", 2 * kFileSize, 0, 201, 248);
Add(3, 3U, "250", "270", 2 * kFileSize, 0, 202, 249);
Add(3, 4U, "290", "310", 2 * kFileSize, 0, 203, 250);
Add(3, 5U, "310", "320", 2 * kFileSize, 0, 204, 251, 0, true);
Add(4, 6U, "301", "350", 8 * kFileSize, 0, 101, 150);
Add(4, 7U, "501", "750", 8 * kFileSize, 0, 101, 150);
UpdateVersionStorageInfo();
std::unique_ptr<Compaction> compaction(
universal_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
ASSERT_TRUE(compaction);
// Validate that its a delete triggered compaction
ASSERT_EQ(CompactionReason::kFilesMarkedForCompaction,
compaction->compaction_reason());
ASSERT_TRUE(compaction->start_level() == 0 ||
compaction->start_level() == 3);
if (compaction->start_level() == 0) {
// The L0 file was picked. The next compaction will detect an
// overlap on its input level
input_level_overlap = true;
ASSERT_EQ(3, compaction->output_level());
ASSERT_EQ(1U, compaction->num_input_files(0));
ASSERT_EQ(3U, compaction->num_input_files(1));
} else {
// The level 3 file was picked. The next compaction will pick
// the L0 file and will detect overlap when adding output
// level inputs
output_level_overlap = true;
ASSERT_EQ(4, compaction->output_level());
ASSERT_EQ(2U, compaction->num_input_files(0));
ASSERT_EQ(1U, compaction->num_input_files(1));
}
vstorage_->ComputeCompactionScore(ioptions_, mutable_cf_options_);
// After recomputing the compaction score, only one marked file will remain
random_index = 0;
std::unique_ptr<Compaction> compaction2(
universal_compaction_picker.PickCompaction(
cf_name_, mutable_cf_options_, mutable_db_options_, vstorage_.get(),
&log_buffer_));
ASSERT_FALSE(compaction2);
DeleteVersionStorage();
}
}
#endif // ROCKSDB_LITE
} // namespace ROCKSDB_NAMESPACE
int main(int argc, char** argv) {
+49 -41
View File
@@ -31,16 +31,17 @@ namespace {
// PickCompaction().
class UniversalCompactionBuilder {
public:
UniversalCompactionBuilder(
const ImmutableCFOptions& ioptions, const InternalKeyComparator* icmp,
const std::string& cf_name, const MutableCFOptions& mutable_cf_options,
const MutableDBOptions& mutable_db_options, VersionStorageInfo* vstorage,
UniversalCompactionPicker* picker, LogBuffer* log_buffer)
UniversalCompactionBuilder(const ImmutableCFOptions& ioptions,
const InternalKeyComparator* icmp,
const std::string& cf_name,
const MutableCFOptions& mutable_cf_options,
VersionStorageInfo* vstorage,
UniversalCompactionPicker* picker,
LogBuffer* log_buffer)
: ioptions_(ioptions),
icmp_(icmp),
cf_name_(cf_name),
mutable_cf_options_(mutable_cf_options),
mutable_db_options_(mutable_db_options),
vstorage_(vstorage),
picker_(picker),
log_buffer_(log_buffer) {}
@@ -114,13 +115,13 @@ class UniversalCompactionBuilder {
std::vector<SortedRun> sorted_runs_;
const std::string& cf_name_;
const MutableCFOptions& mutable_cf_options_;
const MutableDBOptions& mutable_db_options_;
VersionStorageInfo* vstorage_;
UniversalCompactionPicker* picker_;
LogBuffer* log_buffer_;
static std::vector<SortedRun> CalculateSortedRuns(
const VersionStorageInfo& vstorage);
const VersionStorageInfo& vstorage, const ImmutableCFOptions& ioptions,
const MutableCFOptions& mutable_cf_options);
// Pick a path ID to place a newly generated file, with its estimated file
// size.
@@ -277,11 +278,11 @@ bool UniversalCompactionPicker::NeedsCompaction(
Compaction* UniversalCompactionPicker::PickCompaction(
const std::string& cf_name, const MutableCFOptions& mutable_cf_options,
const MutableDBOptions& mutable_db_options, VersionStorageInfo* vstorage,
LogBuffer* log_buffer, SequenceNumber /* earliest_memtable_seqno */) {
VersionStorageInfo* vstorage, LogBuffer* log_buffer,
SequenceNumber /* earliest_memtable_seqno */) {
UniversalCompactionBuilder builder(ioptions_, icmp_, cf_name,
mutable_cf_options, mutable_db_options,
vstorage, this, log_buffer);
mutable_cf_options, vstorage, this,
log_buffer);
return builder.PickCompaction();
}
@@ -324,7 +325,8 @@ void UniversalCompactionBuilder::SortedRun::DumpSizeInfo(
std::vector<UniversalCompactionBuilder::SortedRun>
UniversalCompactionBuilder::CalculateSortedRuns(
const VersionStorageInfo& vstorage) {
const VersionStorageInfo& vstorage, const ImmutableCFOptions& /*ioptions*/,
const MutableCFOptions& mutable_cf_options) {
std::vector<UniversalCompactionBuilder::SortedRun> ret;
for (FileMetaData* f : vstorage.LevelFiles(0)) {
ret.emplace_back(0, f, f->fd.GetFileSize(), f->compensated_file_size,
@@ -334,16 +336,27 @@ UniversalCompactionBuilder::CalculateSortedRuns(
uint64_t total_compensated_size = 0U;
uint64_t total_size = 0U;
bool being_compacted = false;
bool is_first = true;
for (FileMetaData* f : vstorage.LevelFiles(level)) {
total_compensated_size += f->compensated_file_size;
total_size += f->fd.GetFileSize();
// Size amp, read amp and periodic compactions always include all files
// for a non-zero level. However, a delete triggered compaction and
// a trivial move might pick a subset of files in a sorted run. So
// always check all files in a sorted run and mark the entire run as
// being compacted if one or more files are being compacted
if (f->being_compacted) {
if (mutable_cf_options.compaction_options_universal.allow_trivial_move ==
true) {
if (f->being_compacted) {
being_compacted = f->being_compacted;
}
} else {
// Compaction always includes all files for a non-zero level, so for a
// non-zero level, all the files should share the same being_compacted
// value.
// This assumption is only valid when
// mutable_cf_options.compaction_options_universal.allow_trivial_move
// is false
assert(is_first || f->being_compacted == being_compacted);
}
if (is_first) {
being_compacted = f->being_compacted;
is_first = false;
}
}
if (total_compensated_size > 0) {
@@ -359,7 +372,8 @@ UniversalCompactionBuilder::CalculateSortedRuns(
Compaction* UniversalCompactionBuilder::PickCompaction() {
const int kLevel0 = 0;
score_ = vstorage_->CompactionScore(kLevel0);
sorted_runs_ = CalculateSortedRuns(*vstorage_);
sorted_runs_ =
CalculateSortedRuns(*vstorage_, ioptions_, mutable_cf_options_);
if (sorted_runs_.size() == 0 ||
(vstorage_->FilesMarkedForPeriodicCompaction().empty() &&
@@ -375,7 +389,7 @@ Compaction* UniversalCompactionBuilder::PickCompaction() {
VersionStorageInfo::LevelSummaryStorage tmp;
ROCKS_LOG_BUFFER_MAX_SZ(
log_buffer_, 3072,
"[%s] Universal: sorted runs: %" ROCKSDB_PRIszt " files: %s\n",
"[%s] Universal: sorted runs files(%" ROCKSDB_PRIszt "): %s\n",
cf_name_.c_str(), sorted_runs_.size(), vstorage_->LevelSummary(&tmp));
Compaction* c = nullptr;
@@ -730,14 +744,14 @@ Compaction* UniversalCompactionBuilder::PickCompactionToReduceSortedRuns(
compaction_reason = CompactionReason::kUniversalSortedRunNum;
}
return new Compaction(
vstorage_, ioptions_, mutable_cf_options_, mutable_db_options_,
std::move(inputs), output_level,
vstorage_, ioptions_, mutable_cf_options_, std::move(inputs),
output_level,
MaxFileSizeForLevel(mutable_cf_options_, output_level,
kCompactionStyleUniversal),
LLONG_MAX, path_id,
GetCompressionType(ioptions_, vstorage_, mutable_cf_options_, start_level,
1, enable_compression),
GetCompressionOptions(mutable_cf_options_, vstorage_, start_level,
GetCompressionOptions(ioptions_, vstorage_, start_level,
enable_compression),
/* max_subcompactions */ 0, /* grandparents */ {}, /* is manual */ false,
score_, false /* deletion_compaction */, compaction_reason);
@@ -765,7 +779,7 @@ Compaction* UniversalCompactionBuilder::PickCompactionToReduceSizeAmp() {
}
// Skip files that are already being compacted
for (size_t loop = 0; loop + 1 < sorted_runs_.size(); loop++) {
for (size_t loop = 0; loop < sorted_runs_.size() - 1; loop++) {
sr = &sorted_runs_[loop];
if (!sr->being_compacted) {
start_index = loop; // Consider this as the first candidate.
@@ -793,7 +807,7 @@ Compaction* UniversalCompactionBuilder::PickCompactionToReduceSizeAmp() {
}
// keep adding up all the remaining files
for (size_t loop = start_index; loop + 1 < sorted_runs_.size(); loop++) {
for (size_t loop = start_index; loop < sorted_runs_.size() - 1; loop++) {
sr = &sorted_runs_[loop];
if (sr->being_compacted) {
char file_num_buf[kFormatFileNumberBufSize];
@@ -841,7 +855,6 @@ Compaction* UniversalCompactionBuilder::PickDeleteTriggeredCompaction() {
std::vector<CompactionInputFiles> inputs;
if (vstorage_->num_levels() == 1) {
#if defined(ENABLE_SINGLE_LEVEL_DTC)
// This is single level universal. Since we're basically trying to reclaim
// space by processing files marked for compaction due to high tombstone
// density, let's do the same thing as compaction to reduce size amp which
@@ -864,11 +877,6 @@ Compaction* UniversalCompactionBuilder::PickDeleteTriggeredCompaction() {
return nullptr;
}
inputs.push_back(start_level_inputs);
#else
// Disable due to a known race condition.
// TODO: Reenable once the race condition is fixed
return nullptr;
#endif // ENABLE_SINGLE_LEVEL_DTC
} else {
int start_level;
@@ -944,15 +952,15 @@ Compaction* UniversalCompactionBuilder::PickDeleteTriggeredCompaction() {
uint32_t path_id =
GetPathId(ioptions_, mutable_cf_options_, estimated_total_size);
return new Compaction(
vstorage_, ioptions_, mutable_cf_options_, mutable_db_options_,
std::move(inputs), output_level,
vstorage_, ioptions_, mutable_cf_options_, std::move(inputs),
output_level,
MaxFileSizeForLevel(mutable_cf_options_, output_level,
kCompactionStyleUniversal),
/* max_grandparent_overlap_bytes */ LLONG_MAX, path_id,
GetCompressionType(ioptions_, vstorage_, mutable_cf_options_,
output_level, 1),
GetCompressionOptions(mutable_cf_options_, vstorage_, output_level),
/* max_subcompactions */ 0, /* grandparents */ {}, /* is manual */ false,
GetCompressionOptions(ioptions_, vstorage_, output_level),
/* max_subcompactions */ 0, /* grandparents */ {}, /* is manual */ true,
score_, false /* deletion_compaction */,
CompactionReason::kFilesMarkedForCompaction);
}
@@ -1014,14 +1022,14 @@ Compaction* UniversalCompactionBuilder::PickCompactionToOldest(
// compaction_options_universal.compression_size_percent,
// because we always compact all the files, so always compress.
return new Compaction(
vstorage_, ioptions_, mutable_cf_options_, mutable_db_options_,
std::move(inputs), output_level,
vstorage_, ioptions_, mutable_cf_options_, std::move(inputs),
output_level,
MaxFileSizeForLevel(mutable_cf_options_, output_level,
kCompactionStyleUniversal),
LLONG_MAX, path_id,
GetCompressionType(ioptions_, vstorage_, mutable_cf_options_,
output_level, 1, true /* enable_compression */),
GetCompressionOptions(mutable_cf_options_, vstorage_, output_level,
GetCompressionType(ioptions_, vstorage_, mutable_cf_options_, start_level,
1, true /* enable_compression */),
GetCompressionOptions(ioptions_, vstorage_, start_level,
true /* enable_compression */),
/* max_subcompactions */ 0, /* grandparents */ {}, /* is manual */ false,
score_, false /* deletion_compaction */, compaction_reason);
+1 -2
View File
@@ -20,8 +20,7 @@ class UniversalCompactionPicker : public CompactionPicker {
: CompactionPicker(ioptions, icmp) {}
virtual Compaction* PickCompaction(
const std::string& cf_name, const MutableCFOptions& mutable_cf_options,
const MutableDBOptions& mutable_db_options, VersionStorageInfo* vstorage,
LogBuffer* log_buffer,
VersionStorageInfo* vstorage, LogBuffer* log_buffer,
SequenceNumber earliest_memtable_seqno = kMaxSequenceNumber) override;
virtual int MaxOutputLevel() const override { return NumberLevels() - 1; }
-44
View File
@@ -1,44 +0,0 @@
// 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).
//
#include "rocksdb/sst_partitioner.h"
#include <algorithm>
namespace ROCKSDB_NAMESPACE {
PartitionerResult SstPartitionerFixedPrefix::ShouldPartition(
const PartitionerRequest& request) {
Slice last_key_fixed(*request.prev_user_key);
if (last_key_fixed.size() > len_) {
last_key_fixed.size_ = len_;
}
Slice current_key_fixed(*request.current_user_key);
if (current_key_fixed.size() > len_) {
current_key_fixed.size_ = len_;
}
return last_key_fixed.compare(current_key_fixed) != 0 ? kRequired
: kNotRequired;
}
bool SstPartitionerFixedPrefix::CanDoTrivialMove(
const Slice& smallest_user_key, const Slice& largest_user_key) {
return ShouldPartition(PartitionerRequest(smallest_user_key, largest_user_key,
0)) == kNotRequired;
}
std::unique_ptr<SstPartitioner>
SstPartitionerFixedPrefixFactory::CreatePartitioner(
const SstPartitioner::Context& /* context */) const {
return std::unique_ptr<SstPartitioner>(new SstPartitionerFixedPrefix(len_));
}
std::shared_ptr<SstPartitionerFactory> NewSstPartitionerFixedPrefixFactory(
size_t prefix_len) {
return std::make_shared<SstPartitionerFixedPrefixFactory>(prefix_len);
}
} // namespace ROCKSDB_NAMESPACE
+2 -3
View File
@@ -13,7 +13,6 @@
#include "test_util/testutil.h"
#include "util/hash.h"
#include "util/kv_map.h"
#include "util/random.h"
#include "util/string_util.h"
#include "utilities/merge_operators.h"
@@ -343,12 +342,12 @@ TEST_P(ComparatorDBTest, SimpleSuffixReverseComparator) {
std::vector<std::string> source_prefixes;
// Randomly generate 5 prefixes
for (int i = 0; i < 5; i++) {
source_prefixes.push_back(rnd.HumanReadableString(8));
source_prefixes.push_back(test::RandomHumanReadableString(&rnd, 8));
}
for (int j = 0; j < 20; j++) {
int prefix_index = rnd.Uniform(static_cast<int>(source_prefixes.size()));
std::string key = source_prefixes[prefix_index] +
rnd.HumanReadableString(rnd.Uniform(8));
test::RandomHumanReadableString(&rnd, rnd.Uniform(8));
source_strings.push_back(key);
}
+3 -4
View File
@@ -14,7 +14,7 @@
namespace ROCKSDB_NAMESPACE {
void CancelAllBackgroundWork(DB* db, bool wait) {
(static_cast_with_check<DBImpl>(db->GetRootDB()))
(static_cast_with_check<DBImpl, DB>(db->GetRootDB()))
->CancelAllBackgroundWork(wait);
}
@@ -28,7 +28,7 @@ Status DeleteFilesInRange(DB* db, ColumnFamilyHandle* column_family,
Status DeleteFilesInRanges(DB* db, ColumnFamilyHandle* column_family,
const RangePtr* ranges, size_t n,
bool include_end) {
return (static_cast_with_check<DBImpl>(db->GetRootDB()))
return (static_cast_with_check<DBImpl, DB>(db->GetRootDB()))
->DeleteFilesInRanges(column_family, ranges, n, include_end);
}
@@ -61,8 +61,7 @@ Status VerifySstFileChecksum(const Options& options,
s = ioptions.table_factory->NewTableReader(
TableReaderOptions(ioptions, options.prefix_extractor.get(), env_options,
internal_comparator, false /* skip_filters */,
!kImmortal, false /* force_direct_prefetch */,
-1 /* level */),
!kImmortal, -1 /* level */),
std::move(file_reader), file_size, &table_reader,
false /* prefetch_index_and_filter_in_cache */);
if (!s.ok()) {
+57 -174
View File
@@ -9,13 +9,13 @@
#ifndef ROCKSDB_LITE
#include "rocksdb/db.h"
#include <errno.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <cinttypes>
#include "db/db_impl/db_impl.h"
#include "db/db_test_util.h"
#include "db/log_format.h"
@@ -24,16 +24,13 @@
#include "file/filename.h"
#include "rocksdb/cache.h"
#include "rocksdb/convenience.h"
#include "rocksdb/db.h"
#include "rocksdb/env.h"
#include "rocksdb/table.h"
#include "rocksdb/write_batch.h"
#include "table/block_based/block_based_table_builder.h"
#include "table/meta_blocks.h"
#include "table/mock_table.h"
#include "test_util/testharness.h"
#include "test_util/testutil.h"
#include "util/random.h"
#include "util/string_util.h"
namespace ROCKSDB_NAMESPACE {
@@ -104,24 +101,22 @@ class CorruptionTest : public testing::Test {
ASSERT_OK(::ROCKSDB_NAMESPACE::RepairDB(dbname_, options_));
}
void Build(int n, int start, int flush_every) {
void Build(int n, int flush_every = 0) {
std::string key_space, value_space;
WriteBatch batch;
for (int i = 0; i < n; i++) {
if (flush_every != 0 && i != 0 && i % flush_every == 0) {
DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
dbi->TEST_FlushMemTable();
}
//if ((i % 100) == 0) fprintf(stderr, "@ %d of %d\n", i, n);
Slice key = Key(i + start, &key_space);
Slice key = Key(i, &key_space);
batch.Clear();
batch.Put(key, Value(i, &value_space));
ASSERT_OK(db_->Write(WriteOptions(), &batch));
}
}
void Build(int n, int flush_every = 0) { Build(n, 0, flush_every); }
void Check(int min_expected, int max_expected) {
uint64_t next_expected = 0;
uint64_t missed = 0;
@@ -162,6 +157,43 @@ class CorruptionTest : public testing::Test {
ASSERT_GE(max_expected, correct);
}
void CorruptFile(const std::string& fname, int offset, int bytes_to_corrupt) {
struct stat sbuf;
if (stat(fname.c_str(), &sbuf) != 0) {
const char* msg = strerror(errno);
FAIL() << fname << ": " << msg;
}
if (offset < 0) {
// Relative to end of file; make it absolute
if (-offset > sbuf.st_size) {
offset = 0;
} else {
offset = static_cast<int>(sbuf.st_size + offset);
}
}
if (offset > sbuf.st_size) {
offset = static_cast<int>(sbuf.st_size);
}
if (offset + bytes_to_corrupt > sbuf.st_size) {
bytes_to_corrupt = static_cast<int>(sbuf.st_size - offset);
}
// Do it
std::string contents;
Status s = ReadFileToString(Env::Default(), fname, &contents);
ASSERT_TRUE(s.ok()) << s.ToString();
for (int i = 0; i < bytes_to_corrupt; i++) {
contents[i + offset] ^= 0x80;
}
s = WriteStringToFile(Env::Default(), contents, fname);
ASSERT_TRUE(s.ok()) << s.ToString();
Options options;
EnvOptions env_options;
options.file_system.reset(new LegacyFileSystemWrapper(options.env));
ASSERT_NOK(VerifySstFileChecksum(options, env_options, fname));
}
void Corrupt(FileType filetype, int offset, int bytes_to_corrupt) {
// Pick file to corrupt
std::vector<std::string> filenames;
@@ -180,7 +212,7 @@ class CorruptionTest : public testing::Test {
}
ASSERT_TRUE(!fname.empty()) << filetype;
test::CorruptFile(fname, offset, bytes_to_corrupt);
CorruptFile(fname, offset, bytes_to_corrupt);
}
// corrupts exactly one file at level `level`. if no file found at level,
@@ -190,7 +222,7 @@ class CorruptionTest : public testing::Test {
db_->GetLiveFilesMetaData(&metadata);
for (const auto& m : metadata) {
if (m.level == level) {
test::CorruptFile(dbname_ + "/" + m.name, offset, bytes_to_corrupt);
CorruptFile(dbname_ + "/" + m.name, offset, bytes_to_corrupt);
return;
}
}
@@ -224,11 +256,11 @@ class CorruptionTest : public testing::Test {
// preserves the implementation that was in place when all of the
// magic values in this file were picked.
*storage = std::string(kValueSize, ' ');
return Slice(*storage);
} else {
Random r(k);
*storage = r.RandomString(kValueSize);
return test::RandomString(&r, kValueSize, storage);
}
return Slice(*storage);
}
};
@@ -286,7 +318,7 @@ TEST_F(CorruptionTest, NewFileErrorDuringWrite) {
TEST_F(CorruptionTest, TableFile) {
Build(100);
DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
dbi->TEST_FlushMemTable();
dbi->TEST_CompactRange(0, nullptr, nullptr);
dbi->TEST_CompactRange(1, nullptr, nullptr);
@@ -309,7 +341,7 @@ TEST_F(CorruptionTest, VerifyChecksumReadahead) {
Reopen(&options);
Build(10000);
DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
dbi->TEST_FlushMemTable();
dbi->TEST_CompactRange(0, nullptr, nullptr);
dbi->TEST_CompactRange(1, nullptr, nullptr);
@@ -356,14 +388,14 @@ TEST_F(CorruptionTest, TableFileIndexData) {
Reopen(&options);
// build 2 tables, flush at 5000
Build(10000, 5000);
DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
dbi->TEST_FlushMemTable();
// corrupt an index block of an entire file
Corrupt(kTableFile, -2000, 500);
options.paranoid_checks = false;
Reopen(&options);
dbi = static_cast_with_check<DBImpl>(db_);
dbi = reinterpret_cast<DBImpl*>(db_);
// one full file may be readable, since only one was corrupted
// the other file should be fully non-readable, since index was corrupted
Check(0, 5000);
@@ -403,7 +435,7 @@ TEST_F(CorruptionTest, SequenceNumberRecovery) {
TEST_F(CorruptionTest, CorruptedDescriptor) {
ASSERT_OK(db_->Put(WriteOptions(), "foo", "hello"));
DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
dbi->TEST_FlushMemTable();
dbi->TEST_CompactRange(0, nullptr, nullptr);
@@ -422,7 +454,7 @@ TEST_F(CorruptionTest, CompactionInputError) {
Options options;
Reopen(&options);
Build(10);
DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
dbi->TEST_FlushMemTable();
dbi->TEST_CompactRange(0, nullptr, nullptr);
dbi->TEST_CompactRange(1, nullptr, nullptr);
@@ -444,7 +476,7 @@ TEST_F(CorruptionTest, CompactionInputErrorParanoid) {
options.write_buffer_size = 131072;
options.max_write_buffer_number = 2;
Reopen(&options);
DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
// Fill levels >= 1
for (int level = 1; level < dbi->NumberLevels(); level++) {
@@ -459,7 +491,7 @@ TEST_F(CorruptionTest, CompactionInputErrorParanoid) {
Reopen(&options);
dbi = static_cast_with_check<DBImpl>(db_);
dbi = reinterpret_cast<DBImpl*>(db_);
Build(10);
dbi->TEST_FlushMemTable();
dbi->TEST_WaitForCompact();
@@ -486,7 +518,7 @@ TEST_F(CorruptionTest, CompactionInputErrorParanoid) {
TEST_F(CorruptionTest, UnrelatedKeys) {
Build(10);
DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
dbi->TEST_FlushMemTable();
Corrupt(kTableFile, 100, 1);
ASSERT_NOK(dbi->VerifyChecksum());
@@ -525,7 +557,7 @@ TEST_F(CorruptionTest, RangeDeletionCorrupted) {
ImmutableCFOptions(options_), kRangeDelBlock, &range_del_handle));
ASSERT_OK(TryReopen());
test::CorruptFile(filename, static_cast<int>(range_del_handle.offset()), 1);
CorruptFile(filename, static_cast<int>(range_del_handle.offset()), 1);
ASSERT_TRUE(TryReopen().IsCorruption());
}
@@ -537,7 +569,7 @@ TEST_F(CorruptionTest, FileSystemStateCorrupted) {
Reopen(&options);
Build(10);
ASSERT_OK(db_->Flush(FlushOptions()));
DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
DBImpl* dbi = reinterpret_cast<DBImpl*>(db_);
std::vector<LiveFileMetaData> metadata;
dbi->GetLiveFilesMetaData(&metadata);
ASSERT_GT(metadata.size(), size_t(0));
@@ -563,155 +595,6 @@ TEST_F(CorruptionTest, FileSystemStateCorrupted) {
}
}
static const auto& corruption_modes = {mock::MockTableFactory::kCorruptNone,
mock::MockTableFactory::kCorruptKey,
mock::MockTableFactory::kCorruptValue};
TEST_F(CorruptionTest, ParaniodFileChecksOnFlush) {
Options options;
options.paranoid_file_checks = true;
options.create_if_missing = true;
Status s;
for (const auto& mode : corruption_modes) {
delete db_;
s = DestroyDB(dbname_, options);
std::shared_ptr<mock::MockTableFactory> mock =
std::make_shared<mock::MockTableFactory>();
options.table_factory = mock;
mock->SetCorruptionMode(mode);
ASSERT_OK(DB::Open(options, dbname_, &db_));
Build(10);
s = db_->Flush(FlushOptions());
if (mode == mock::MockTableFactory::kCorruptNone) {
ASSERT_OK(s);
} else {
ASSERT_NOK(s);
}
}
}
TEST_F(CorruptionTest, ParaniodFileChecksOnCompact) {
Options options;
options.paranoid_file_checks = true;
options.create_if_missing = true;
Status s;
for (const auto& mode : corruption_modes) {
delete db_;
s = DestroyDB(dbname_, options);
std::shared_ptr<mock::MockTableFactory> mock =
std::make_shared<mock::MockTableFactory>();
options.table_factory = mock;
ASSERT_OK(DB::Open(options, dbname_, &db_));
Build(100, 2);
// ASSERT_OK(db_->Flush(FlushOptions()));
DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
ASSERT_OK(dbi->TEST_FlushMemTable());
mock->SetCorruptionMode(mode);
s = dbi->TEST_CompactRange(0, nullptr, nullptr, nullptr, true);
if (mode == mock::MockTableFactory::kCorruptNone) {
ASSERT_OK(s);
} else {
ASSERT_NOK(s);
}
}
}
TEST_F(CorruptionTest, ParanoidFileChecksWithDeleteRangeFirst) {
Options options;
options.paranoid_file_checks = true;
options.create_if_missing = true;
for (bool do_flush : {true, false}) {
delete db_;
db_ = nullptr;
ASSERT_OK(DestroyDB(dbname_, options));
ASSERT_OK(DB::Open(options, dbname_, &db_));
std::string start, end;
assert(db_ != nullptr);
ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
Key(3, &start), Key(7, &end)));
auto snap = db_->GetSnapshot();
ASSERT_NE(snap, nullptr);
ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
Key(8, &start), Key(9, &end)));
ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
Key(2, &start), Key(5, &end)));
Build(10);
if (do_flush) {
ASSERT_OK(db_->Flush(FlushOptions()));
} else {
DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
ASSERT_OK(dbi->TEST_FlushMemTable());
ASSERT_OK(dbi->TEST_CompactRange(0, nullptr, nullptr, nullptr, true));
}
db_->ReleaseSnapshot(snap);
}
}
TEST_F(CorruptionTest, ParanoidFileChecksWithDeleteRange) {
Options options;
options.paranoid_file_checks = true;
options.create_if_missing = true;
for (bool do_flush : {true, false}) {
delete db_;
db_ = nullptr;
ASSERT_OK(DestroyDB(dbname_, options));
ASSERT_OK(DB::Open(options, dbname_, &db_));
assert(db_ != nullptr);
Build(10, 0, 0);
std::string start, end;
ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
Key(5, &start), Key(15, &end)));
auto snap = db_->GetSnapshot();
ASSERT_NE(snap, nullptr);
ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
Key(8, &start), Key(9, &end)));
ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
Key(12, &start), Key(17, &end)));
ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
Key(2, &start), Key(4, &end)));
Build(10, 10, 0);
if (do_flush) {
ASSERT_OK(db_->Flush(FlushOptions()));
} else {
DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
ASSERT_OK(dbi->TEST_FlushMemTable());
ASSERT_OK(dbi->TEST_CompactRange(0, nullptr, nullptr, nullptr, true));
}
db_->ReleaseSnapshot(snap);
}
}
TEST_F(CorruptionTest, ParanoidFileChecksWithDeleteRangeLast) {
Options options;
options.paranoid_file_checks = true;
options.create_if_missing = true;
for (bool do_flush : {true, false}) {
delete db_;
db_ = nullptr;
ASSERT_OK(DestroyDB(dbname_, options));
ASSERT_OK(DB::Open(options, dbname_, &db_));
assert(db_ != nullptr);
std::string start, end;
Build(10);
ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
Key(3, &start), Key(7, &end)));
auto snap = db_->GetSnapshot();
ASSERT_NE(snap, nullptr);
ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
Key(6, &start), Key(8, &end)));
ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
Key(2, &start), Key(5, &end)));
if (do_flush) {
ASSERT_OK(db_->Flush(FlushOptions()));
} else {
DBImpl* dbi = static_cast_with_check<DBImpl>(db_);
ASSERT_OK(dbi->TEST_FlushMemTable());
ASSERT_OK(dbi->TEST_CompactRange(0, nullptr, nullptr, nullptr, true));
}
db_->ReleaseSnapshot(snap);
}
}
} // namespace ROCKSDB_NAMESPACE
int main(int argc, char** argv) {
+3 -2
View File
@@ -13,7 +13,6 @@
#include "table/meta_blocks.h"
#include "test_util/testharness.h"
#include "test_util/testutil.h"
#include "util/cast_util.h"
#include "util/string_util.h"
namespace ROCKSDB_NAMESPACE {
@@ -47,7 +46,9 @@ class CuckooTableDBTest : public testing::Test {
return options;
}
DBImpl* dbfull() { return static_cast_with_check<DBImpl>(db_); }
DBImpl* dbfull() {
return reinterpret_cast<DBImpl*>(db_);
}
// The following util methods are copied from plain_table_db_test.
void Reopen(Options* options = nullptr) {
+175 -1232
View File
File diff suppressed because it is too large Load Diff
+6 -141
View File
@@ -7,12 +7,10 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#include <cstdlib>
#include "cache/lru_cache.h"
#include "db/db_test_util.h"
#include "port/stack_trace.h"
#include "util/compression.h"
#include "util/random.h"
namespace ROCKSDB_NAMESPACE {
@@ -189,7 +187,7 @@ TEST_F(DBBlockCacheTest, TestWithoutCompressedBlockCache) {
Iterator* iter = nullptr;
// Load blocks into cache.
for (size_t i = 0; i + 1 < kNumBlocks; i++) {
for (size_t i = 0; i < kNumBlocks - 1; i++) {
iter = db_->NewIterator(read_options);
iter->Seek(ToString(i));
ASSERT_OK(iter->status());
@@ -211,12 +209,12 @@ TEST_F(DBBlockCacheTest, TestWithoutCompressedBlockCache) {
iter = nullptr;
// Release iterators and access cache again.
for (size_t i = 0; i + 1 < kNumBlocks; i++) {
for (size_t i = 0; i < kNumBlocks - 1; i++) {
iterators[i].reset();
CheckCacheCounters(options, 0, 0, 0, 0);
}
ASSERT_EQ(0, cache->GetPinnedUsage());
for (size_t i = 0; i + 1 < kNumBlocks; i++) {
for (size_t i = 0; i < kNumBlocks - 1; i++) {
iter = db_->NewIterator(read_options);
iter->Seek(ToString(i));
ASSERT_OK(iter->status());
@@ -245,7 +243,7 @@ TEST_F(DBBlockCacheTest, TestWithCompressedBlockCache) {
Iterator* iter = nullptr;
// Load blocks into cache.
for (size_t i = 0; i + 1 < kNumBlocks; i++) {
for (size_t i = 0; i < kNumBlocks - 1; i++) {
iter = db_->NewIterator(read_options);
iter->Seek(ToString(i));
ASSERT_OK(iter->status());
@@ -519,139 +517,6 @@ TEST_F(DBBlockCacheTest, IndexAndFilterBlocksCachePriority) {
}
}
namespace {
// An LRUCache wrapper that can falsely report "not found" on Lookup.
// This allows us to manipulate BlockBasedTableReader into thinking
// another thread inserted the data in between Lookup and Insert,
// while mostly preserving the LRUCache interface/behavior.
class LookupLiarCache : public CacheWrapper {
int nth_lookup_not_found_ = 0;
public:
explicit LookupLiarCache(std::shared_ptr<Cache> target)
: CacheWrapper(std::move(target)) {}
Handle* Lookup(const Slice& key, Statistics* stats) override {
if (nth_lookup_not_found_ == 1) {
nth_lookup_not_found_ = 0;
return nullptr;
}
if (nth_lookup_not_found_ > 1) {
--nth_lookup_not_found_;
}
return CacheWrapper::Lookup(key, stats);
}
// 1 == next lookup, 2 == after next, etc.
void SetNthLookupNotFound(int n) { nth_lookup_not_found_ = n; }
};
} // anonymous namespace
TEST_F(DBBlockCacheTest, AddRedundantStats) {
const size_t capacity = size_t{1} << 25;
const int num_shard_bits = 0; // 1 shard
int iterations_tested = 0;
for (std::shared_ptr<Cache> base_cache :
{NewLRUCache(capacity, num_shard_bits),
NewClockCache(capacity, num_shard_bits)}) {
if (!base_cache) {
// Skip clock cache when not supported
continue;
}
++iterations_tested;
Options options = CurrentOptions();
options.create_if_missing = true;
options.statistics = ROCKSDB_NAMESPACE::CreateDBStatistics();
std::shared_ptr<LookupLiarCache> cache =
std::make_shared<LookupLiarCache>(base_cache);
BlockBasedTableOptions table_options;
table_options.cache_index_and_filter_blocks = true;
table_options.block_cache = cache;
table_options.filter_policy.reset(NewBloomFilterPolicy(50));
options.table_factory.reset(new BlockBasedTableFactory(table_options));
DestroyAndReopen(options);
// Create a new table.
ASSERT_OK(Put("foo", "value"));
ASSERT_OK(Put("bar", "value"));
ASSERT_OK(Flush());
ASSERT_EQ(1, NumTableFilesAtLevel(0));
// Normal access filter+index+data.
ASSERT_EQ("value", Get("foo"));
ASSERT_EQ(1, TestGetTickerCount(options, BLOCK_CACHE_INDEX_ADD));
ASSERT_EQ(1, TestGetTickerCount(options, BLOCK_CACHE_FILTER_ADD));
ASSERT_EQ(1, TestGetTickerCount(options, BLOCK_CACHE_DATA_ADD));
// --------
ASSERT_EQ(3, TestGetTickerCount(options, BLOCK_CACHE_ADD));
ASSERT_EQ(0, TestGetTickerCount(options, BLOCK_CACHE_INDEX_ADD_REDUNDANT));
ASSERT_EQ(0, TestGetTickerCount(options, BLOCK_CACHE_FILTER_ADD_REDUNDANT));
ASSERT_EQ(0, TestGetTickerCount(options, BLOCK_CACHE_DATA_ADD_REDUNDANT));
// --------
ASSERT_EQ(0, TestGetTickerCount(options, BLOCK_CACHE_ADD_REDUNDANT));
// Againt access filter+index+data, but force redundant load+insert on index
cache->SetNthLookupNotFound(2);
ASSERT_EQ("value", Get("bar"));
ASSERT_EQ(2, TestGetTickerCount(options, BLOCK_CACHE_INDEX_ADD));
ASSERT_EQ(1, TestGetTickerCount(options, BLOCK_CACHE_FILTER_ADD));
ASSERT_EQ(1, TestGetTickerCount(options, BLOCK_CACHE_DATA_ADD));
// --------
ASSERT_EQ(4, TestGetTickerCount(options, BLOCK_CACHE_ADD));
ASSERT_EQ(1, TestGetTickerCount(options, BLOCK_CACHE_INDEX_ADD_REDUNDANT));
ASSERT_EQ(0, TestGetTickerCount(options, BLOCK_CACHE_FILTER_ADD_REDUNDANT));
ASSERT_EQ(0, TestGetTickerCount(options, BLOCK_CACHE_DATA_ADD_REDUNDANT));
// --------
ASSERT_EQ(1, TestGetTickerCount(options, BLOCK_CACHE_ADD_REDUNDANT));
// Access just filter (with high probability), and force redundant
// load+insert
cache->SetNthLookupNotFound(1);
ASSERT_EQ("NOT_FOUND", Get("this key was not added"));
EXPECT_EQ(2, TestGetTickerCount(options, BLOCK_CACHE_INDEX_ADD));
EXPECT_EQ(2, TestGetTickerCount(options, BLOCK_CACHE_FILTER_ADD));
EXPECT_EQ(1, TestGetTickerCount(options, BLOCK_CACHE_DATA_ADD));
// --------
EXPECT_EQ(5, TestGetTickerCount(options, BLOCK_CACHE_ADD));
EXPECT_EQ(1, TestGetTickerCount(options, BLOCK_CACHE_INDEX_ADD_REDUNDANT));
EXPECT_EQ(1, TestGetTickerCount(options, BLOCK_CACHE_FILTER_ADD_REDUNDANT));
EXPECT_EQ(0, TestGetTickerCount(options, BLOCK_CACHE_DATA_ADD_REDUNDANT));
// --------
EXPECT_EQ(2, TestGetTickerCount(options, BLOCK_CACHE_ADD_REDUNDANT));
// Access just data, forcing redundant load+insert
ReadOptions read_options;
std::unique_ptr<Iterator> iter{db_->NewIterator(read_options)};
cache->SetNthLookupNotFound(1);
iter->SeekToFirst();
ASSERT_TRUE(iter->Valid());
ASSERT_EQ(iter->key(), "bar");
EXPECT_EQ(2, TestGetTickerCount(options, BLOCK_CACHE_INDEX_ADD));
EXPECT_EQ(2, TestGetTickerCount(options, BLOCK_CACHE_FILTER_ADD));
EXPECT_EQ(2, TestGetTickerCount(options, BLOCK_CACHE_DATA_ADD));
// --------
EXPECT_EQ(6, TestGetTickerCount(options, BLOCK_CACHE_ADD));
EXPECT_EQ(1, TestGetTickerCount(options, BLOCK_CACHE_INDEX_ADD_REDUNDANT));
EXPECT_EQ(1, TestGetTickerCount(options, BLOCK_CACHE_FILTER_ADD_REDUNDANT));
EXPECT_EQ(1, TestGetTickerCount(options, BLOCK_CACHE_DATA_ADD_REDUNDANT));
// --------
EXPECT_EQ(3, TestGetTickerCount(options, BLOCK_CACHE_ADD_REDUNDANT));
}
EXPECT_GE(iterations_tested, 1);
}
TEST_F(DBBlockCacheTest, ParanoidFileChecks) {
Options options = CurrentOptions();
options.create_if_missing = true;
@@ -766,7 +631,7 @@ TEST_F(DBBlockCacheTest, CompressedCache) {
std::string str;
for (int i = 0; i < num_iter; i++) {
if (i % 4 == 0) { // high compression ratio
str = rnd.RandomString(1000);
str = RandomString(&rnd, 1000);
}
values.push_back(str);
ASSERT_OK(Put(1, Key(i), values[i]));
@@ -853,7 +718,7 @@ TEST_F(DBBlockCacheTest, CacheCompressionDict) {
for (int i = 0; i < kNumFiles; ++i) {
ASSERT_EQ(i, NumTableFilesAtLevel(0, 0));
for (int j = 0; j < kNumEntriesPerFile; ++j) {
std::string value = rnd.RandomString(kNumBytesPerEntry);
std::string value = RandomString(&rnd, kNumBytesPerEntry);
ASSERT_OK(Put(Key(j * kNumFiles + i), value.c_str()));
}
ASSERT_OK(Flush());
+2 -211
View File
@@ -8,7 +8,6 @@
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "db/db_test_util.h"
#include "options/options_helper.h"
#include "port/stack_trace.h"
#include "rocksdb/perf_context.h"
#include "table/block_based/filter_policy_internal.h"
@@ -1030,215 +1029,6 @@ TEST_F(DBBloomFilterTest, MemtablePrefixBloomOutOfDomain) {
ASSERT_EQ(kKey, iter->key());
}
class DBBloomFilterTestVaryPrefixAndFormatVer
: public DBTestBase,
public testing::WithParamInterface<std::tuple<bool, uint32_t>> {
protected:
bool use_prefix_;
uint32_t format_version_;
public:
DBBloomFilterTestVaryPrefixAndFormatVer()
: DBTestBase("/db_bloom_filter_tests") {}
~DBBloomFilterTestVaryPrefixAndFormatVer() override {}
void SetUp() override {
use_prefix_ = std::get<0>(GetParam());
format_version_ = std::get<1>(GetParam());
}
static std::string UKey(uint32_t i) { return Key(static_cast<int>(i)); }
};
TEST_P(DBBloomFilterTestVaryPrefixAndFormatVer, PartitionedMultiGet) {
Options options = CurrentOptions();
if (use_prefix_) {
// Entire key from UKey()
options.prefix_extractor.reset(NewCappedPrefixTransform(9));
}
options.statistics = ROCKSDB_NAMESPACE::CreateDBStatistics();
BlockBasedTableOptions bbto;
bbto.filter_policy.reset(NewBloomFilterPolicy(20));
bbto.partition_filters = true;
bbto.index_type = BlockBasedTableOptions::IndexType::kTwoLevelIndexSearch;
bbto.whole_key_filtering = !use_prefix_;
if (use_prefix_) { // (not related to prefix, just alternating between)
// Make sure code appropriately deals with metadata block size setting
// that is "too small" (smaller than minimum size for filter builder)
bbto.metadata_block_size = 63;
} else {
// Make sure the test will work even on platforms with large minimum
// filter size, due to large cache line size.
// (Largest cache line size + 10+% overhead.)
bbto.metadata_block_size = 290;
}
options.table_factory.reset(NewBlockBasedTableFactory(bbto));
DestroyAndReopen(options);
ReadOptions ropts;
constexpr uint32_t N = 12000;
// Add N/2 evens
for (uint32_t i = 0; i < N; i += 2) {
ASSERT_OK(Put(UKey(i), UKey(i)));
}
ASSERT_OK(Flush());
#ifndef ROCKSDB_LITE
ASSERT_EQ(TotalTableFiles(), 1);
#endif
constexpr uint32_t Q = 29;
// MultiGet In
std::array<std::string, Q> keys;
std::array<Slice, Q> key_slices;
std::array<ColumnFamilyHandle*, Q> column_families;
// MultiGet Out
std::array<Status, Q> statuses;
std::array<PinnableSlice, Q> values;
TestGetAndResetTickerCount(options, BLOCK_CACHE_FILTER_HIT);
TestGetAndResetTickerCount(options, BLOCK_CACHE_FILTER_MISS);
TestGetAndResetTickerCount(options, BLOOM_FILTER_PREFIX_USEFUL);
TestGetAndResetTickerCount(options, BLOOM_FILTER_USEFUL);
TestGetAndResetTickerCount(options, BLOOM_FILTER_PREFIX_CHECKED);
TestGetAndResetTickerCount(options, BLOOM_FILTER_FULL_POSITIVE);
TestGetAndResetTickerCount(options, BLOOM_FILTER_FULL_TRUE_POSITIVE);
// Check that initial clump of keys only loads one partition filter from
// block cache.
// And that spread out keys load many partition filters.
// In both cases, mix present vs. not present keys.
for (uint32_t stride : {uint32_t{1}, (N / Q) | 1}) {
for (uint32_t i = 0; i < Q; ++i) {
keys[i] = UKey(i * stride);
key_slices[i] = Slice(keys[i]);
column_families[i] = db_->DefaultColumnFamily();
statuses[i] = Status();
values[i] = PinnableSlice();
}
db_->MultiGet(ropts, Q, &column_families[0], &key_slices[0], &values[0],
/*timestamps=*/nullptr, &statuses[0], true);
// Confirm correct status results
uint32_t number_not_found = 0;
for (uint32_t i = 0; i < Q; ++i) {
if ((i * stride % 2) == 0) {
ASSERT_OK(statuses[i]);
} else {
ASSERT_TRUE(statuses[i].IsNotFound());
++number_not_found;
}
}
// Confirm correct Bloom stats (no FPs)
uint64_t filter_useful = TestGetAndResetTickerCount(
options,
use_prefix_ ? BLOOM_FILTER_PREFIX_USEFUL : BLOOM_FILTER_USEFUL);
uint64_t filter_checked =
TestGetAndResetTickerCount(options, use_prefix_
? BLOOM_FILTER_PREFIX_CHECKED
: BLOOM_FILTER_FULL_POSITIVE) +
(use_prefix_ ? 0 : filter_useful);
EXPECT_EQ(filter_useful, number_not_found);
EXPECT_EQ(filter_checked, Q);
if (!use_prefix_) {
EXPECT_EQ(
TestGetAndResetTickerCount(options, BLOOM_FILTER_FULL_TRUE_POSITIVE),
Q - number_not_found);
}
// Confirm no duplicate loading same filter partition
uint64_t filter_accesses =
TestGetAndResetTickerCount(options, BLOCK_CACHE_FILTER_HIT) +
TestGetAndResetTickerCount(options, BLOCK_CACHE_FILTER_MISS);
if (stride == 1) {
EXPECT_EQ(filter_accesses, 1);
} else {
// for large stride
EXPECT_GE(filter_accesses, Q / 2 + 1);
}
}
// Check that a clump of keys (present and not) works when spanning
// two partitions
int found_spanning = 0;
for (uint32_t start = 0; start < N / 2;) {
for (uint32_t i = 0; i < Q; ++i) {
keys[i] = UKey(start + i);
key_slices[i] = Slice(keys[i]);
column_families[i] = db_->DefaultColumnFamily();
statuses[i] = Status();
values[i] = PinnableSlice();
}
db_->MultiGet(ropts, Q, &column_families[0], &key_slices[0], &values[0],
/*timestamps=*/nullptr, &statuses[0], true);
// Confirm correct status results
uint32_t number_not_found = 0;
for (uint32_t i = 0; i < Q; ++i) {
if (((start + i) % 2) == 0) {
ASSERT_OK(statuses[i]);
} else {
ASSERT_TRUE(statuses[i].IsNotFound());
++number_not_found;
}
}
// Confirm correct Bloom stats (might see some FPs)
uint64_t filter_useful = TestGetAndResetTickerCount(
options,
use_prefix_ ? BLOOM_FILTER_PREFIX_USEFUL : BLOOM_FILTER_USEFUL);
uint64_t filter_checked =
TestGetAndResetTickerCount(options, use_prefix_
? BLOOM_FILTER_PREFIX_CHECKED
: BLOOM_FILTER_FULL_POSITIVE) +
(use_prefix_ ? 0 : filter_useful);
EXPECT_GE(filter_useful, number_not_found - 2); // possible FP
EXPECT_EQ(filter_checked, Q);
if (!use_prefix_) {
EXPECT_EQ(
TestGetAndResetTickerCount(options, BLOOM_FILTER_FULL_TRUE_POSITIVE),
Q - number_not_found);
}
// Confirm no duplicate loading of same filter partition
uint64_t filter_accesses =
TestGetAndResetTickerCount(options, BLOCK_CACHE_FILTER_HIT) +
TestGetAndResetTickerCount(options, BLOCK_CACHE_FILTER_MISS);
if (filter_accesses == 2) {
// Spanned across partitions.
++found_spanning;
if (found_spanning >= 2) {
break;
} else {
// Ensure that at least once we have at least one present and
// one non-present key on both sides of partition boundary.
start += 2;
}
} else {
EXPECT_EQ(filter_accesses, 1);
// See explanation at "start += 2"
start += Q - 4;
}
}
EXPECT_TRUE(found_spanning >= 2);
}
INSTANTIATE_TEST_CASE_P(DBBloomFilterTestVaryPrefixAndFormatVer,
DBBloomFilterTestVaryPrefixAndFormatVer,
::testing::Values(
// (use_prefix, format_version)
std::make_tuple(false, 2),
std::make_tuple(false, 3),
std::make_tuple(false, 4),
std::make_tuple(false, 5),
std::make_tuple(true, 2),
std::make_tuple(true, 3),
std::make_tuple(true, 4),
std::make_tuple(true, 5)));
#ifndef ROCKSDB_LITE
namespace {
namespace BFP2 {
@@ -1553,7 +1343,8 @@ TEST_F(DBBloomFilterTest, OptimizeFiltersForHits) {
for (int i = 0; i < numkeys; i += 2) {
keys.push_back(i);
}
RandomShuffle(std::begin(keys), std::end(keys));
std::random_shuffle(std::begin(keys), std::end(keys));
int num_inserted = 0;
for (int key : keys) {
ASSERT_OK(Put(1, Key(key), "val"));
+106 -365
View File
@@ -14,10 +14,9 @@
#include "rocksdb/experimental.h"
#include "rocksdb/sst_file_writer.h"
#include "rocksdb/utilities/convenience.h"
#include "test_util/fault_injection_test_env.h"
#include "test_util/sync_point.h"
#include "util/concurrent_task_limiter_impl.h"
#include "util/random.h"
#include "utilities/fault_injection_env.h"
namespace ROCKSDB_NAMESPACE {
@@ -158,21 +157,21 @@ Options DeletionTriggerOptions(Options options) {
bool HaveOverlappingKeyRanges(
const Comparator* c,
const SstFileMetaData& a, const SstFileMetaData& b) {
if (c->CompareWithoutTimestamp(a.smallestkey, b.smallestkey) >= 0) {
if (c->CompareWithoutTimestamp(a.smallestkey, b.largestkey) <= 0) {
if (c->Compare(a.smallestkey, b.smallestkey) >= 0) {
if (c->Compare(a.smallestkey, b.largestkey) <= 0) {
// b.smallestkey <= a.smallestkey <= b.largestkey
return true;
}
} else if (c->CompareWithoutTimestamp(a.largestkey, b.smallestkey) >= 0) {
} else if (c->Compare(a.largestkey, b.smallestkey) >= 0) {
// a.smallestkey < b.smallestkey <= a.largestkey
return true;
}
if (c->CompareWithoutTimestamp(a.largestkey, b.largestkey) <= 0) {
if (c->CompareWithoutTimestamp(a.largestkey, b.smallestkey) >= 0) {
if (c->Compare(a.largestkey, b.largestkey) <= 0) {
if (c->Compare(a.largestkey, b.smallestkey) >= 0) {
// b.smallestkey <= a.largestkey <= b.largestkey
return true;
}
} else if (c->CompareWithoutTimestamp(a.smallestkey, b.largestkey) <= 0) {
} else if (c->Compare(a.smallestkey, b.largestkey) <= 0) {
// a.smallestkey <= b.largestkey < a.largestkey
return true;
}
@@ -296,7 +295,7 @@ TEST_P(DBCompactionTestWithParam, CompactionDeletionTrigger) {
const int kTestSize = kCDTKeysPerBuffer * 1024;
std::vector<std::string> values;
for (int k = 0; k < kTestSize; ++k) {
values.push_back(rnd.RandomString(kCDTValueSize));
values.push_back(RandomString(&rnd, kCDTValueSize));
ASSERT_OK(Put(Key(k), values[k]));
}
dbfull()->TEST_WaitForFlushMemTable();
@@ -344,7 +343,7 @@ TEST_P(DBCompactionTestWithParam, CompactionsPreserveDeletes) {
const int kTestSize = kCDTKeysPerBuffer;
std::vector<std::string> values;
for (int k = 0; k < kTestSize; ++k) {
values.push_back(rnd.RandomString(kCDTValueSize));
values.push_back(RandomString(&rnd, kCDTValueSize));
ASSERT_OK(Put(Key(k), values[k]));
}
@@ -409,7 +408,7 @@ TEST_F(DBCompactionTest, SkipStatsUpdateTest) {
const int kTestSize = kCDTKeysPerBuffer * 512;
std::vector<std::string> values;
for (int k = 0; k < kTestSize; ++k) {
values.push_back(rnd.RandomString(kCDTValueSize));
values.push_back(RandomString(&rnd, kCDTValueSize));
ASSERT_OK(Put(Key(k), values[k]));
}
@@ -556,7 +555,7 @@ TEST_P(DBCompactionTestWithParam, CompactionDeletionTriggerReopen) {
const int kTestSize = kCDTKeysPerBuffer * 512;
std::vector<std::string> values;
for (int k = 0; k < kTestSize; ++k) {
values.push_back(rnd.RandomString(kCDTValueSize));
values.push_back(RandomString(&rnd, kCDTValueSize));
ASSERT_OK(Put(Key(k), values[k]));
}
dbfull()->TEST_WaitForFlushMemTable();
@@ -594,72 +593,6 @@ TEST_P(DBCompactionTestWithParam, CompactionDeletionTriggerReopen) {
}
}
TEST_F(DBCompactionTest, CompactRangeBottomPri) {
ASSERT_OK(Put(Key(50), ""));
ASSERT_OK(Flush());
ASSERT_OK(Put(Key(100), ""));
ASSERT_OK(Flush());
ASSERT_OK(Put(Key(200), ""));
ASSERT_OK(Flush());
{
CompactRangeOptions cro;
cro.change_level = true;
cro.target_level = 2;
dbfull()->CompactRange(cro, nullptr, nullptr);
}
ASSERT_EQ("0,0,3", FilesPerLevel(0));
ASSERT_OK(Put(Key(1), ""));
ASSERT_OK(Put(Key(199), ""));
ASSERT_OK(Flush());
ASSERT_OK(Put(Key(2), ""));
ASSERT_OK(Put(Key(199), ""));
ASSERT_OK(Flush());
ASSERT_EQ("2,0,3", FilesPerLevel(0));
// Now we have 2 L0 files, and 3 L2 files, and a manual compaction will
// be triggered.
// Two compaction jobs will run. One compacts 2 L0 files in Low Pri Pool
// and one compact to L2 in bottom pri pool.
int low_pri_count = 0;
int bottom_pri_count = 0;
SyncPoint::GetInstance()->SetCallBack(
"ThreadPoolImpl::Impl::BGThread:BeforeRun", [&](void* arg) {
Env::Priority* pri = reinterpret_cast<Env::Priority*>(arg);
// First time is low pri pool in the test case.
if (low_pri_count == 0 && bottom_pri_count == 0) {
ASSERT_EQ(Env::Priority::LOW, *pri);
}
if (*pri == Env::Priority::LOW) {
low_pri_count++;
} else {
bottom_pri_count++;
}
});
SyncPoint::GetInstance()->EnableProcessing();
env_->SetBackgroundThreads(1, Env::Priority::BOTTOM);
dbfull()->CompactRange(CompactRangeOptions(), nullptr, nullptr);
ASSERT_EQ(1, low_pri_count);
ASSERT_EQ(1, bottom_pri_count);
ASSERT_EQ("0,0,2", FilesPerLevel(0));
// Recompact bottom most level uses bottom pool
CompactRangeOptions cro;
cro.bottommost_level_compaction = BottommostLevelCompaction::kForce;
dbfull()->CompactRange(cro, nullptr, nullptr);
ASSERT_EQ(1, low_pri_count);
ASSERT_EQ(2, bottom_pri_count);
env_->SetBackgroundThreads(0, Env::Priority::BOTTOM);
dbfull()->CompactRange(cro, nullptr, nullptr);
// Low pri pool is used if bottom pool has size 0.
ASSERT_EQ(2, low_pri_count);
ASSERT_EQ(2, bottom_pri_count);
SyncPoint::GetInstance()->DisableProcessing();
}
TEST_F(DBCompactionTest, DisableStatsUpdateReopen) {
uint64_t db_size[3];
for (int test = 0; test < 2; ++test) {
@@ -674,7 +607,7 @@ TEST_F(DBCompactionTest, DisableStatsUpdateReopen) {
const int kTestSize = kCDTKeysPerBuffer * 512;
std::vector<std::string> values;
for (int k = 0; k < kTestSize; ++k) {
values.push_back(rnd.RandomString(kCDTValueSize));
values.push_back(RandomString(&rnd, kCDTValueSize));
ASSERT_OK(Put(Key(k), values[k]));
}
dbfull()->TEST_WaitForFlushMemTable();
@@ -737,7 +670,7 @@ TEST_P(DBCompactionTestWithParam, CompactionTrigger) {
std::vector<std::string> values;
// Write 100KB (100 values, each 1K)
for (int i = 0; i < kNumKeysPerFile; i++) {
values.push_back(rnd.RandomString(990));
values.push_back(RandomString(&rnd, 990));
ASSERT_OK(Put(1, Key(i), values[i]));
}
// put extra key to trigger flush
@@ -749,7 +682,7 @@ TEST_P(DBCompactionTestWithParam, CompactionTrigger) {
// generate one more file in level-0, and should trigger level-0 compaction
std::vector<std::string> values;
for (int i = 0; i < kNumKeysPerFile; i++) {
values.push_back(rnd.RandomString(990));
values.push_back(RandomString(&rnd, 990));
ASSERT_OK(Put(1, Key(i), values[i]));
}
// put extra key to trigger flush
@@ -868,7 +801,7 @@ TEST_P(DBCompactionTestWithParam, CompactionsGenerateMultipleFiles) {
ASSERT_EQ(NumTableFilesAtLevel(0, 1), 0);
std::vector<std::string> values;
for (int i = 0; i < 80; i++) {
values.push_back(rnd.RandomString(100000));
values.push_back(RandomString(&rnd, 100000));
ASSERT_OK(Put(1, Key(i), values[i]));
}
@@ -977,60 +910,6 @@ TEST_F(DBCompactionTest, UserKeyCrossFile2) {
ASSERT_EQ("NOT_FOUND", Get("3"));
}
TEST_F(DBCompactionTest, CompactionSstPartitioner) {
Options options = CurrentOptions();
options.compaction_style = kCompactionStyleLevel;
options.level0_file_num_compaction_trigger = 3;
std::shared_ptr<SstPartitionerFactory> factory(
NewSstPartitionerFixedPrefixFactory(4));
options.sst_partitioner_factory = factory;
DestroyAndReopen(options);
// create first file and flush to l0
Put("aaaa1", "A");
Put("bbbb1", "B");
Flush();
dbfull()->TEST_WaitForFlushMemTable();
Put("aaaa1", "A2");
Flush();
dbfull()->TEST_WaitForFlushMemTable();
// move both files down to l1
dbfull()->CompactRange(CompactRangeOptions(), nullptr, nullptr);
std::vector<LiveFileMetaData> files;
dbfull()->GetLiveFilesMetaData(&files);
ASSERT_EQ(2, files.size());
ASSERT_EQ("A2", Get("aaaa1"));
ASSERT_EQ("B", Get("bbbb1"));
}
TEST_F(DBCompactionTest, CompactionSstPartitionerNonTrivial) {
Options options = CurrentOptions();
options.compaction_style = kCompactionStyleLevel;
options.level0_file_num_compaction_trigger = 1;
std::shared_ptr<SstPartitionerFactory> factory(
NewSstPartitionerFixedPrefixFactory(4));
options.sst_partitioner_factory = factory;
DestroyAndReopen(options);
// create first file and flush to l0
Put("aaaa1", "A");
Put("bbbb1", "B");
Flush();
dbfull()->TEST_WaitForFlushMemTable();
dbfull()->TEST_WaitForCompact(true);
std::vector<LiveFileMetaData> files;
dbfull()->GetLiveFilesMetaData(&files);
ASSERT_EQ(2, files.size());
ASSERT_EQ("A", Get("aaaa1"));
ASSERT_EQ("B", Get("bbbb1"));
}
TEST_F(DBCompactionTest, ZeroSeqIdCompaction) {
Options options = CurrentOptions();
options.compaction_style = kCompactionStyleLevel;
@@ -1160,7 +1039,7 @@ TEST_P(DBCompactionTestWithParam, TrivialMoveOneFile) {
Random rnd(301);
std::vector<std::string> values;
for (int i = 0; i < num_keys; i++) {
values.push_back(rnd.RandomString(value_size));
values.push_back(RandomString(&rnd, value_size));
ASSERT_OK(Put(Key(i), values[i]));
}
@@ -1232,7 +1111,7 @@ TEST_P(DBCompactionTestWithParam, TrivialMoveNonOverlappingFiles) {
std::map<int32_t, std::string> values;
for (size_t i = 0; i < ranges.size(); i++) {
for (int32_t j = ranges[i].first; j <= ranges[i].second; j++) {
values[j] = rnd.RandomString(value_size);
values[j] = RandomString(&rnd, value_size);
ASSERT_OK(Put(Key(j), values[j]));
}
ASSERT_OK(Flush());
@@ -1278,7 +1157,7 @@ TEST_P(DBCompactionTestWithParam, TrivialMoveNonOverlappingFiles) {
};
for (size_t i = 0; i < ranges.size(); i++) {
for (int32_t j = ranges[i].first; j <= ranges[i].second; j++) {
values[j] = rnd.RandomString(value_size);
values[j] = RandomString(&rnd, value_size);
ASSERT_OK(Put(Key(j), values[j]));
}
ASSERT_OK(Flush());
@@ -1323,14 +1202,14 @@ TEST_P(DBCompactionTestWithParam, TrivialMoveTargetLevel) {
// file 1 [0 => 300]
for (int32_t i = 0; i <= 300; i++) {
values[i] = rnd.RandomString(value_size);
values[i] = RandomString(&rnd, value_size);
ASSERT_OK(Put(Key(i), values[i]));
}
ASSERT_OK(Flush());
// file 2 [600 => 700]
for (int32_t i = 600; i <= 700; i++) {
values[i] = rnd.RandomString(value_size);
values[i] = RandomString(&rnd, value_size);
ASSERT_OK(Put(Key(i), values[i]));
}
ASSERT_OK(Flush());
@@ -1404,14 +1283,14 @@ TEST_P(DBCompactionTestWithParam, ManualCompactionPartial) {
// file 1 [0 => 100]
for (int32_t i = 0; i < 100; i++) {
values[i] = rnd.RandomString(value_size);
values[i] = RandomString(&rnd, value_size);
ASSERT_OK(Put(Key(i), values[i]));
}
ASSERT_OK(Flush());
// file 2 [100 => 300]
for (int32_t i = 100; i < 300; i++) {
values[i] = rnd.RandomString(value_size);
values[i] = RandomString(&rnd, value_size);
ASSERT_OK(Put(Key(i), values[i]));
}
ASSERT_OK(Flush());
@@ -1432,7 +1311,7 @@ TEST_P(DBCompactionTestWithParam, ManualCompactionPartial) {
// file 3 [ 0 => 200]
for (int32_t i = 0; i < 200; i++) {
values[i] = rnd.RandomString(value_size);
values[i] = RandomString(&rnd, value_size);
ASSERT_OK(Put(Key(i), values[i]));
}
ASSERT_OK(Flush());
@@ -1464,21 +1343,21 @@ TEST_P(DBCompactionTestWithParam, ManualCompactionPartial) {
TEST_SYNC_POINT("DBCompaction::ManualPartial:1");
// file 4 [300 => 400)
for (int32_t i = 300; i <= 400; i++) {
values[i] = rnd.RandomString(value_size);
values[i] = RandomString(&rnd, value_size);
ASSERT_OK(Put(Key(i), values[i]));
}
ASSERT_OK(Flush());
// file 5 [400 => 500)
for (int32_t i = 400; i <= 500; i++) {
values[i] = rnd.RandomString(value_size);
values[i] = RandomString(&rnd, value_size);
ASSERT_OK(Put(Key(i), values[i]));
}
ASSERT_OK(Flush());
// file 6 [500 => 600)
for (int32_t i = 500; i <= 600; i++) {
values[i] = rnd.RandomString(value_size);
values[i] = RandomString(&rnd, value_size);
ASSERT_OK(Put(Key(i), values[i]));
}
// Second non-trivial compaction is triggered
@@ -1546,14 +1425,14 @@ TEST_F(DBCompactionTest, DISABLED_ManualPartialFill) {
// file 1 [0 => 100]
for (int32_t i = 0; i < 100; i++) {
values[i] = rnd.RandomString(value_size);
values[i] = RandomString(&rnd, value_size);
ASSERT_OK(Put(Key(i), values[i]));
}
ASSERT_OK(Flush());
// file 2 [100 => 300]
for (int32_t i = 100; i < 300; i++) {
values[i] = rnd.RandomString(value_size);
values[i] = RandomString(&rnd, value_size);
ASSERT_OK(Put(Key(i), values[i]));
}
ASSERT_OK(Flush());
@@ -1572,7 +1451,7 @@ TEST_F(DBCompactionTest, DISABLED_ManualPartialFill) {
// file 3 [ 0 => 200]
for (int32_t i = 0; i < 200; i++) {
values[i] = rnd.RandomString(value_size);
values[i] = RandomString(&rnd, value_size);
ASSERT_OK(Put(Key(i), values[i]));
}
ASSERT_OK(Flush());
@@ -1604,7 +1483,7 @@ TEST_F(DBCompactionTest, DISABLED_ManualPartialFill) {
ASSERT_OK(Flush());
dbfull()->TEST_WaitForFlushMemTable();
}
values[j] = rnd.RandomString(value_size);
values[j] = RandomString(&rnd, value_size);
ASSERT_OK(Put(Key(j), values[j]));
}
}
@@ -1675,14 +1554,14 @@ TEST_F(DBCompactionTest, DeleteFileRange) {
// file 1 [0 => 100]
for (int32_t i = 0; i < 100; i++) {
values[i] = rnd.RandomString(value_size);
values[i] = RandomString(&rnd, value_size);
ASSERT_OK(Put(Key(i), values[i]));
}
ASSERT_OK(Flush());
// file 2 [100 => 300]
for (int32_t i = 100; i < 300; i++) {
values[i] = rnd.RandomString(value_size);
values[i] = RandomString(&rnd, value_size);
ASSERT_OK(Put(Key(i), values[i]));
}
ASSERT_OK(Flush());
@@ -1698,7 +1577,7 @@ TEST_F(DBCompactionTest, DeleteFileRange) {
// file 3 [ 0 => 200]
for (int32_t i = 0; i < 200; i++) {
values[i] = rnd.RandomString(value_size);
values[i] = RandomString(&rnd, value_size);
ASSERT_OK(Put(Key(i), values[i]));
}
ASSERT_OK(Flush());
@@ -1710,7 +1589,7 @@ TEST_F(DBCompactionTest, DeleteFileRange) {
ASSERT_OK(Flush());
dbfull()->TEST_WaitForFlushMemTable();
}
values[j] = rnd.RandomString(value_size);
values[j] = RandomString(&rnd, value_size);
ASSERT_OK(Put(Key(j), values[j]));
}
}
@@ -1797,7 +1676,7 @@ TEST_F(DBCompactionTest, DeleteFilesInRanges) {
for (auto i = 0; i < 10; i++) {
for (auto j = 0; j < 100; j++) {
auto k = i * 100 + j;
values[k] = rnd.RandomString(value_size);
values[k] = RandomString(&rnd, value_size);
ASSERT_OK(Put(Key(k), values[k]));
}
ASSERT_OK(Flush());
@@ -1929,7 +1808,7 @@ TEST_F(DBCompactionTest, DeleteFileRangeFileEndpointsOverlapBug) {
// would cause `1 -> vals[0]` (an older key) to reappear.
std::string vals[kNumL0Files];
for (int i = 0; i < kNumL0Files; ++i) {
vals[i] = rnd.RandomString(kValSize);
vals[i] = RandomString(&rnd, kValSize);
Put(Key(i), vals[i]);
Put(Key(i + 1), vals[i]);
Flush();
@@ -1971,7 +1850,7 @@ TEST_P(DBCompactionTestWithParam, TrivialMoveToLastLevelWithFiles) {
std::vector<std::string> values;
// File with keys [ 0 => 99 ]
for (int i = 0; i < 100; i++) {
values.push_back(rnd.RandomString(value_size));
values.push_back(RandomString(&rnd, value_size));
ASSERT_OK(Put(Key(i), values[i]));
}
ASSERT_OK(Flush());
@@ -1989,7 +1868,7 @@ TEST_P(DBCompactionTestWithParam, TrivialMoveToLastLevelWithFiles) {
// File with keys [ 100 => 199 ]
for (int i = 100; i < 200; i++) {
values.push_back(rnd.RandomString(value_size));
values.push_back(RandomString(&rnd, value_size));
ASSERT_OK(Put(Key(i), values[i]));
}
ASSERT_OK(Flush());
@@ -2384,7 +2263,7 @@ TEST_P(DBCompactionTestWithParam, ConvertCompactionStyle) {
for (int i = 0; i <= max_key_level_insert; i++) {
// each value is 10K
ASSERT_OK(Put(1, Key(i), rnd.RandomString(10000)));
ASSERT_OK(Put(1, Key(i), RandomString(&rnd, 10000)));
}
ASSERT_OK(Flush(1));
dbfull()->TEST_WaitForCompact();
@@ -2442,7 +2321,7 @@ TEST_P(DBCompactionTestWithParam, ConvertCompactionStyle) {
ReopenWithColumnFamilies({"default", "pikachu"}, options);
for (int i = max_key_level_insert / 2; i <= max_key_universal_insert; i++) {
ASSERT_OK(Put(1, Key(i), rnd.RandomString(10000)));
ASSERT_OK(Put(1, Key(i), RandomString(&rnd, 10000)));
}
dbfull()->Flush(FlushOptions());
ASSERT_OK(Flush(1));
@@ -2737,7 +2616,7 @@ TEST_P(DBCompactionTestWithParam, DISABLED_CompactFilesOnLevelCompaction) {
Random rnd(301);
for (int key = 64 * kEntriesPerBuffer; key >= 0; --key) {
ASSERT_OK(Put(1, ToString(key), rnd.RandomString(kTestValueSize)));
ASSERT_OK(Put(1, ToString(key), RandomString(&rnd, kTestValueSize)));
}
dbfull()->TEST_WaitForFlushMemTable(handles_[1]);
dbfull()->TEST_WaitForCompact();
@@ -2813,8 +2692,8 @@ TEST_P(DBCompactionTestWithParam, PartialCompactionFailure) {
std::vector<std::string> keys;
std::vector<std::string> values;
for (int k = 0; k < kNumInsertedKeys; ++k) {
keys.emplace_back(rnd.RandomString(kKeySize));
values.emplace_back(rnd.RandomString(kKvSize - kKeySize));
keys.emplace_back(RandomString(&rnd, kKeySize));
values.emplace_back(RandomString(&rnd, kKvSize - kKeySize));
ASSERT_OK(Put(Slice(keys[k]), Slice(values[k])));
dbfull()->TEST_WaitForFlushMemTable();
}
@@ -2880,7 +2759,7 @@ TEST_P(DBCompactionTestWithParam, DeleteMovedFileAfterCompaction) {
for (int i = 0; i < 2; ++i) {
// Create 1MB sst file
for (int j = 0; j < 100; ++j) {
ASSERT_OK(Put(Key(i * 50 + j), rnd.RandomString(10 * 1024)));
ASSERT_OK(Put(Key(i * 50 + j), RandomString(&rnd, 10 * 1024)));
}
ASSERT_OK(Flush());
}
@@ -2915,7 +2794,7 @@ TEST_P(DBCompactionTestWithParam, DeleteMovedFileAfterCompaction) {
for (int i = 0; i < 2; ++i) {
// Create 1MB sst file
for (int j = 0; j < 100; ++j) {
ASSERT_OK(Put(Key(i * 50 + j + 100), rnd.RandomString(10 * 1024)));
ASSERT_OK(Put(Key(i * 50 + j + 100), RandomString(&rnd, 10 * 1024)));
}
ASSERT_OK(Flush());
}
@@ -3173,7 +3052,7 @@ TEST_P(DBCompactionTestWithParam, ForceBottommostLevelCompaction) {
std::vector<std::string> values;
// File with keys [ 0 => 99 ]
for (int i = 0; i < 100; i++) {
values.push_back(rnd.RandomString(value_size));
values.push_back(RandomString(&rnd, value_size));
ASSERT_OK(Put(ShortKey(i), values[i]));
}
ASSERT_OK(Flush());
@@ -3190,7 +3069,7 @@ TEST_P(DBCompactionTestWithParam, ForceBottommostLevelCompaction) {
// File with keys [ 100 => 199 ]
for (int i = 100; i < 200; i++) {
values.push_back(rnd.RandomString(value_size));
values.push_back(RandomString(&rnd, value_size));
ASSERT_OK(Put(ShortKey(i), values[i]));
}
ASSERT_OK(Flush());
@@ -3208,7 +3087,7 @@ TEST_P(DBCompactionTestWithParam, ForceBottommostLevelCompaction) {
// File with keys [ 200 => 299 ]
for (int i = 200; i < 300; i++) {
values.push_back(rnd.RandomString(value_size));
values.push_back(RandomString(&rnd, value_size));
ASSERT_OK(Put(ShortKey(i), values[i]));
}
ASSERT_OK(Flush());
@@ -3239,20 +3118,11 @@ TEST_P(DBCompactionTestWithParam, IntraL0Compaction) {
options.level0_file_num_compaction_trigger = 5;
options.max_background_compactions = 2;
options.max_subcompactions = max_subcompactions_;
options.statistics = ROCKSDB_NAMESPACE::CreateDBStatistics();
options.write_buffer_size = 2 << 20; // 2MB
BlockBasedTableOptions table_options;
table_options.block_cache = NewLRUCache(64 << 20); // 64MB
table_options.cache_index_and_filter_blocks = true;
table_options.pin_l0_filter_and_index_blocks_in_cache = true;
options.table_factory.reset(new BlockBasedTableFactory(table_options));
DestroyAndReopen(options);
const size_t kValueSize = 1 << 20;
Random rnd(301);
std::string value(rnd.RandomString(kValueSize));
std::string value(RandomString(&rnd, kValueSize));
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->LoadDependency(
{{"LevelCompactionPicker::PickCompactionBySize:0",
@@ -3292,16 +3162,6 @@ TEST_P(DBCompactionTestWithParam, IntraL0Compaction) {
for (int i = 0; i < 2; ++i) {
ASSERT_GE(level_to_files[0][i].fd.file_size, 1 << 21);
}
// The index/filter in the file produced by intra-L0 should not be pinned.
// That means clearing unref'd entries in block cache and re-accessing the
// file produced by intra-L0 should bump the index block miss count.
uint64_t prev_index_misses =
TestGetTickerCount(options, BLOCK_CACHE_INDEX_MISS);
table_options.block_cache->EraseUnRefEntries();
ASSERT_EQ("", Get(Key(0)));
ASSERT_EQ(prev_index_misses + 1,
TestGetTickerCount(options, BLOCK_CACHE_INDEX_MISS));
}
TEST_P(DBCompactionTestWithParam, IntraL0CompactionDoesNotObsoleteDeletions) {
@@ -3316,7 +3176,7 @@ TEST_P(DBCompactionTestWithParam, IntraL0CompactionDoesNotObsoleteDeletions) {
const size_t kValueSize = 1 << 20;
Random rnd(301);
std::string value(rnd.RandomString(kValueSize));
std::string value(RandomString(&rnd, kValueSize));
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->LoadDependency(
{{"LevelCompactionPicker::PickCompactionBySize:0",
@@ -3535,7 +3395,7 @@ TEST_F(DBCompactionTest, CompactBottomLevelFilesWithDeletions) {
for (int i = 0; i < kNumLevelFiles; ++i) {
for (int j = 0; j < kNumKeysPerFile; ++j) {
ASSERT_OK(
Put(Key(i * kNumKeysPerFile + j), rnd.RandomString(kValueSize)));
Put(Key(i * kNumKeysPerFile + j), RandomString(&rnd, kValueSize)));
}
if (i == kNumLevelFiles - 1) {
snapshot = db_->GetSnapshot();
@@ -3607,7 +3467,7 @@ TEST_F(DBCompactionTest, LevelCompactExpiredTtlFiles) {
for (int i = 0; i < kNumLevelFiles; ++i) {
for (int j = 0; j < kNumKeysPerFile; ++j) {
ASSERT_OK(
Put(Key(i * kNumKeysPerFile + j), rnd.RandomString(kValueSize)));
Put(Key(i * kNumKeysPerFile + j), RandomString(&rnd, kValueSize)));
}
Flush();
}
@@ -3653,7 +3513,7 @@ TEST_F(DBCompactionTest, LevelCompactExpiredTtlFiles) {
for (int i = 0; i < kNumLevelFiles; ++i) {
for (int j = 0; j < kNumKeysPerFile; ++j) {
ASSERT_OK(
Put(Key(i * kNumKeysPerFile + j), rnd.RandomString(kValueSize)));
Put(Key(i * kNumKeysPerFile + j), RandomString(&rnd, kValueSize)));
}
Flush();
}
@@ -3748,7 +3608,7 @@ TEST_F(DBCompactionTest, LevelTtlCascadingCompactions) {
// Add two L6 files with key ranges: [1 .. 100], [101 .. 200].
Random rnd(301);
for (int i = 1; i <= 100; ++i) {
ASSERT_OK(Put(Key(i), rnd.RandomString(kValueSize)));
ASSERT_OK(Put(Key(i), RandomString(&rnd, kValueSize)));
}
Flush();
// Get the first file's creation time. This will be the oldest file in the
@@ -3761,7 +3621,7 @@ TEST_F(DBCompactionTest, LevelTtlCascadingCompactions) {
// Add 1 hour and do another flush.
env_->addon_time_.fetch_add(1 * 60 * 60);
for (int i = 101; i <= 200; ++i) {
ASSERT_OK(Put(Key(i), rnd.RandomString(kValueSize)));
ASSERT_OK(Put(Key(i), RandomString(&rnd, kValueSize)));
}
Flush();
MoveFilesToLevel(6);
@@ -3770,12 +3630,12 @@ TEST_F(DBCompactionTest, LevelTtlCascadingCompactions) {
env_->addon_time_.fetch_add(1 * 60 * 60);
// Add two L4 files with key ranges: [1 .. 50], [51 .. 150].
for (int i = 1; i <= 50; ++i) {
ASSERT_OK(Put(Key(i), rnd.RandomString(kValueSize)));
ASSERT_OK(Put(Key(i), RandomString(&rnd, kValueSize)));
}
Flush();
env_->addon_time_.fetch_add(1 * 60 * 60);
for (int i = 51; i <= 150; ++i) {
ASSERT_OK(Put(Key(i), rnd.RandomString(kValueSize)));
ASSERT_OK(Put(Key(i), RandomString(&rnd, kValueSize)));
}
Flush();
MoveFilesToLevel(4);
@@ -3784,7 +3644,7 @@ TEST_F(DBCompactionTest, LevelTtlCascadingCompactions) {
env_->addon_time_.fetch_add(1 * 60 * 60);
// Add one L1 file with key range: [26, 75].
for (int i = 26; i <= 75; ++i) {
ASSERT_OK(Put(Key(i), rnd.RandomString(kValueSize)));
ASSERT_OK(Put(Key(i), RandomString(&rnd, kValueSize)));
}
Flush();
dbfull()->TEST_WaitForCompact();
@@ -3895,8 +3755,8 @@ TEST_F(DBCompactionTest, LevelPeriodicCompaction) {
Random rnd(301);
for (int i = 0; i < kNumLevelFiles; ++i) {
for (int j = 0; j < kNumKeysPerFile; ++j) {
ASSERT_OK(
Put(Key(i * kNumKeysPerFile + j), rnd.RandomString(kValueSize)));
ASSERT_OK(Put(Key(i * kNumKeysPerFile + j),
RandomString(&rnd, kValueSize)));
}
Flush();
}
@@ -3990,7 +3850,7 @@ TEST_F(DBCompactionTest, LevelPeriodicCompactionWithOldDB) {
for (int i = 0; i < kNumFiles; ++i) {
for (int j = 0; j < kNumKeysPerFile; ++j) {
ASSERT_OK(
Put(Key(i * kNumKeysPerFile + j), rnd.RandomString(kValueSize)));
Put(Key(i * kNumKeysPerFile + j), RandomString(&rnd, kValueSize)));
}
Flush();
// Move the first two files to L2.
@@ -4053,7 +3913,7 @@ TEST_F(DBCompactionTest, LevelPeriodicAndTtlCompaction) {
for (int i = 0; i < kNumLevelFiles; ++i) {
for (int j = 0; j < kNumKeysPerFile; ++j) {
ASSERT_OK(
Put(Key(i * kNumKeysPerFile + j), rnd.RandomString(kValueSize)));
Put(Key(i * kNumKeysPerFile + j), RandomString(&rnd, kValueSize)));
}
Flush();
}
@@ -4164,7 +4024,7 @@ TEST_F(DBCompactionTest, LevelPeriodicCompactionWithCompactionFilters) {
for (int i = 0; i < kNumLevelFiles; ++i) {
for (int j = 0; j < kNumKeysPerFile; ++j) {
ASSERT_OK(
Put(Key(i * kNumKeysPerFile + j), rnd.RandomString(kValueSize)));
Put(Key(i * kNumKeysPerFile + j), RandomString(&rnd, kValueSize)));
}
Flush();
}
@@ -4224,7 +4084,7 @@ TEST_F(DBCompactionTest, CompactRangeDelayedByL0FileCount) {
Random rnd(301);
for (int j = 0; j < kNumL0FilesLimit - 1; ++j) {
for (int k = 0; k < 2; ++k) {
ASSERT_OK(Put(Key(k), rnd.RandomString(1024)));
ASSERT_OK(Put(Key(k), RandomString(&rnd, 1024)));
}
Flush();
}
@@ -4278,7 +4138,7 @@ TEST_F(DBCompactionTest, CompactRangeDelayedByImmMemTableCount) {
Random rnd(301);
for (int j = 0; j < kNumImmMemTableLimit - 1; ++j) {
ASSERT_OK(Put(Key(0), rnd.RandomString(1024)));
ASSERT_OK(Put(Key(0), RandomString(&rnd, 1024)));
FlushOptions flush_opts;
flush_opts.wait = false;
flush_opts.allow_write_stall = true;
@@ -4326,7 +4186,7 @@ TEST_F(DBCompactionTest, CompactRangeShutdownWhileDelayed) {
Random rnd(301);
for (int j = 0; j < kNumL0FilesLimit - 1; ++j) {
for (int k = 0; k < 2; ++k) {
ASSERT_OK(Put(1, Key(k), rnd.RandomString(1024)));
ASSERT_OK(Put(1, Key(k), RandomString(&rnd, 1024)));
}
Flush(1);
}
@@ -4386,7 +4246,7 @@ TEST_F(DBCompactionTest, CompactRangeSkipFlushAfterDelay) {
flush_opts.allow_write_stall = true;
for (int i = 0; i < kNumL0FilesLimit - 1; ++i) {
for (int j = 0; j < 2; ++j) {
ASSERT_OK(Put(Key(j), rnd.RandomString(1024)));
ASSERT_OK(Put(Key(j), RandomString(&rnd, 1024)));
}
dbfull()->Flush(flush_opts);
}
@@ -4397,9 +4257,9 @@ TEST_F(DBCompactionTest, CompactRangeSkipFlushAfterDelay) {
});
TEST_SYNC_POINT("DBCompactionTest::CompactRangeSkipFlushAfterDelay:PreFlush");
Put(ToString(0), rnd.RandomString(1024));
Put(ToString(0), RandomString(&rnd, 1024));
dbfull()->Flush(flush_opts);
Put(ToString(0), rnd.RandomString(1024));
Put(ToString(0), RandomString(&rnd, 1024));
TEST_SYNC_POINT("DBCompactionTest::CompactRangeSkipFlushAfterDelay:PostFlush");
manual_compaction_thread.join();
@@ -4836,10 +4696,10 @@ TEST_P(CompactionPriTest, Test) {
for (int i = 0; i < kNKeys; i++) {
keys[i] = i;
}
RandomShuffle(std::begin(keys), std::end(keys), rnd.Next());
std::random_shuffle(std::begin(keys), std::end(keys));
for (int i = 0; i < kNKeys; i++) {
ASSERT_OK(Put(Key(keys[i]), rnd.RandomString(102)));
ASSERT_OK(Put(Key(keys[i]), RandomString(&rnd, 102)));
}
dbfull()->TEST_WaitForCompact();
@@ -4881,7 +4741,7 @@ TEST_F(DBCompactionTest, PartialManualCompaction) {
Random rnd(301);
for (auto i = 0; i < 8; ++i) {
for (auto j = 0; j < 10; ++j) {
Merge("foo", rnd.RandomString(1024));
Merge("foo", RandomString(&rnd, 1024));
}
Flush();
}
@@ -4913,8 +4773,8 @@ TEST_F(DBCompactionTest, ManualCompactionFailsInReadOnlyMode) {
Random rnd(301);
for (int i = 0; i < kNumL0Files; ++i) {
// Make sure files are overlapping in key-range to prevent trivial move.
Put("key1", rnd.RandomString(1024));
Put("key2", rnd.RandomString(1024));
Put("key1", RandomString(&rnd, 1024));
Put("key2", RandomString(&rnd, 1024));
Flush();
}
ASSERT_EQ(kNumL0Files, NumTableFilesAtLevel(0));
@@ -4923,7 +4783,7 @@ TEST_F(DBCompactionTest, ManualCompactionFailsInReadOnlyMode) {
mock_env->SetFilesystemActive(false);
// Make sure this is outside `CompactRange`'s range so that it doesn't fail
// early trying to flush memtable.
ASSERT_NOK(Put("key3", rnd.RandomString(1024)));
ASSERT_NOK(Put("key3", RandomString(&rnd, 1024)));
// In the bug scenario, the first manual compaction would fail and forget to
// unregister itself, causing the second one to hang forever due to conflict
@@ -4962,7 +4822,7 @@ TEST_F(DBCompactionTest, ManualCompactionBottomLevelOptimized) {
for (auto i = 0; i < 8; ++i) {
for (auto j = 0; j < 10; ++j) {
ASSERT_OK(
Put("foo" + std::to_string(i * 10 + j), rnd.RandomString(1024)));
Put("foo" + std::to_string(i * 10 + j), RandomString(&rnd, 1024)));
}
Flush();
}
@@ -4972,7 +4832,7 @@ TEST_F(DBCompactionTest, ManualCompactionBottomLevelOptimized) {
for (auto i = 0; i < 8; ++i) {
for (auto j = 0; j < 10; ++j) {
ASSERT_OK(
Put("bar" + std::to_string(i * 10 + j), rnd.RandomString(1024)));
Put("bar" + std::to_string(i * 10 + j), RandomString(&rnd, 1024)));
}
Flush();
}
@@ -5006,7 +4866,7 @@ TEST_F(DBCompactionTest, CompactionDuringShutdown) {
for (auto i = 0; i < 2; ++i) {
for (auto j = 0; j < 10; ++j) {
ASSERT_OK(
Put("foo" + std::to_string(i * 10 + j), rnd.RandomString(1024)));
Put("foo" + std::to_string(i * 10 + j), RandomString(&rnd, 1024)));
}
Flush();
}
@@ -5029,7 +4889,7 @@ TEST_P(DBCompactionTestWithParam, FixFileIngestionCompactionDeadlock) {
// Generate an external SST file containing a single key, i.e. 99
std::string sst_files_dir = dbname_ + "/sst_files/";
DestroyDir(env_, sst_files_dir);
test::DestroyDir(env_, sst_files_dir);
ASSERT_OK(env_->CreateDir(sst_files_dir));
SstFileWriter sst_writer(EnvOptions(), options);
const std::string sst_file_path = sst_files_dir + "test.sst";
@@ -5056,7 +4916,7 @@ TEST_P(DBCompactionTestWithParam, FixFileIngestionCompactionDeadlock) {
// Generate level0_stop_writes_trigger L0 files to trigger write stop
for (int i = 0; i != options.level0_file_num_compaction_trigger; ++i) {
for (int j = 0; j != kNumKeysPerFile; ++j) {
ASSERT_OK(Put(Key(j), rnd.RandomString(990)));
ASSERT_OK(Put(Key(j), RandomString(&rnd, 990)));
}
if (0 == i) {
// When we reach here, the memtables have kNumKeysPerFile keys. Note that
@@ -5098,11 +4958,10 @@ TEST_P(DBCompactionTestWithParam, FixFileIngestionCompactionDeadlock) {
TEST_F(DBCompactionTest, ConsistencyFailTest) {
Options options = CurrentOptions();
options.force_consistency_checks = true;
DestroyAndReopen(options);
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
"VersionBuilder::CheckConsistency0", [&](void* arg) {
"VersionBuilder::CheckConsistency", [&](void* arg) {
auto p =
reinterpret_cast<std::pair<FileMetaData**, FileMetaData**>*>(arg);
// just swap the two FileMetaData so that we hit error
@@ -5121,48 +4980,6 @@ TEST_F(DBCompactionTest, ConsistencyFailTest) {
ASSERT_NOK(Put("foo", "bar"));
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->DisableProcessing();
SyncPoint::GetInstance()->ClearAllCallBacks();
}
TEST_F(DBCompactionTest, ConsistencyFailTest2) {
Options options = CurrentOptions();
options.force_consistency_checks = true;
options.target_file_size_base = 1000;
options.level0_file_num_compaction_trigger = 2;
BlockBasedTableOptions bbto;
bbto.block_size = 400; // small block size
options.table_factory.reset(new BlockBasedTableFactory(bbto));
DestroyAndReopen(options);
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
"VersionBuilder::CheckConsistency1", [&](void* arg) {
auto p =
reinterpret_cast<std::pair<FileMetaData**, FileMetaData**>*>(arg);
// just swap the two FileMetaData so that we hit error
// in CheckConsistency funcion
FileMetaData* temp = *(p->first);
*(p->first) = *(p->second);
*(p->second) = temp;
});
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
Random rnd(301);
std::string value = rnd.RandomString(1000);
ASSERT_OK(Put("foo1", value));
ASSERT_OK(Put("z", ""));
Flush();
ASSERT_OK(Put("foo2", value));
ASSERT_OK(Put("z", ""));
Flush();
// This probably returns non-OK, but we rely on the next Put()
// to determine the DB is frozen.
dbfull()->TEST_WaitForCompact();
ASSERT_NOK(Put("foo", "bar"));
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->DisableProcessing();
SyncPoint::GetInstance()->ClearAllCallBacks();
}
void IngestOneKeyValue(DBImpl* db, const std::string& key,
@@ -5195,7 +5012,7 @@ TEST_P(DBCompactionTestWithParam,
const size_t kValueSize = 1 << 20;
Random rnd(301);
std::atomic<int> pick_intra_l0_count(0);
std::string value(rnd.RandomString(kValueSize));
std::string value(RandomString(&rnd, kValueSize));
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->LoadDependency(
{{"DBCompactionTestWithParam::FlushAfterIntraL0:1",
@@ -5237,6 +5054,7 @@ TEST_P(DBCompactionTestWithParam,
// Put one key, to make biggest log sequence number in this memtable is bigger
// than sst which would be ingested in next step.
ASSERT_OK(Put(Key(2), "b"));
ASSERT_EQ(10, NumTableFilesAtLevel(0));
dbfull()->TEST_WaitForCompact();
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->DisableProcessing();
std::vector<std::vector<FileMetaData>> level_to_files;
@@ -5262,8 +5080,8 @@ TEST_P(DBCompactionTestWithParam,
const size_t kValueSize = 1 << 20;
Random rnd(301);
std::string value(rnd.RandomString(kValueSize));
std::string value2(rnd.RandomString(kValueSize));
std::string value(RandomString(&rnd, kValueSize));
std::string value2(RandomString(&rnd, kValueSize));
std::string bigvalue = value + value;
// prevents trivial move
@@ -5333,106 +5151,29 @@ TEST_P(DBCompactionTestWithParam,
}
}
TEST_F(DBCompactionTest, UpdateLevelSubCompactionTest) {
Options options = CurrentOptions();
options.max_subcompactions = 10;
options.target_file_size_base = 1 << 10; // 1KB
DestroyAndReopen(options);
bool has_compaction = false;
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
"LevelCompactionPicker::PickCompaction:Return", [&](void* arg) {
Compaction* compaction = reinterpret_cast<Compaction*>(arg);
ASSERT_TRUE(compaction->max_subcompactions() == 10);
has_compaction = true;
});
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
ASSERT_TRUE(dbfull()->GetDBOptions().max_subcompactions == 10);
// Trigger compaction
for (int i = 0; i < 32; i++) {
for (int j = 0; j < 5000; j++) {
Put(std::to_string(j), std::string(1, 'A'));
TEST_F(DBCompactionTest, FifoCompactionGetFileCreationTime) {
MockEnv mock_env(env_);
do {
Options options = CurrentOptions();
options.table_factory.reset(new BlockBasedTableFactory());
options.env = &mock_env;
options.ttl = static_cast<uint64_t>(24) * 3600;
options.compaction_style = kCompactionStyleFIFO;
constexpr size_t kNumFiles = 24;
options.max_open_files = 20;
constexpr size_t kNumKeysPerFile = 10;
DestroyAndReopen(options);
for (size_t i = 0; i < kNumFiles; ++i) {
for (size_t j = 0; j < kNumKeysPerFile; ++j) {
ASSERT_OK(Put(std::to_string(j), "value_" + std::to_string(i)));
}
ASSERT_OK(Flush());
}
mock_env.FakeSleepForMicroseconds(
static_cast<uint64_t>(1000 * 1000 * (1 + options.ttl)));
ASSERT_OK(Put("foo", "value"));
ASSERT_OK(Flush());
ASSERT_OK(dbfull()->TEST_WaitForFlushMemTable());
}
dbfull()->TEST_WaitForCompact();
ASSERT_TRUE(has_compaction);
has_compaction = false;
ASSERT_OK(dbfull()->SetDBOptions({{"max_subcompactions", "2"}}));
ASSERT_TRUE(dbfull()->GetDBOptions().max_subcompactions == 2);
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
"LevelCompactionPicker::PickCompaction:Return", [&](void* arg) {
Compaction* compaction = reinterpret_cast<Compaction*>(arg);
ASSERT_TRUE(compaction->max_subcompactions() == 2);
has_compaction = true;
});
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
// Trigger compaction
for (int i = 0; i < 32; i++) {
for (int j = 0; j < 5000; j++) {
Put(std::to_string(j), std::string(1, 'A'));
}
ASSERT_OK(Flush());
ASSERT_OK(dbfull()->TEST_WaitForFlushMemTable());
}
dbfull()->TEST_WaitForCompact();
ASSERT_TRUE(has_compaction);
}
TEST_F(DBCompactionTest, UpdateUniversalSubCompactionTest) {
Options options = CurrentOptions();
options.max_subcompactions = 10;
options.compaction_style = kCompactionStyleUniversal;
options.target_file_size_base = 1 << 10; // 1KB
DestroyAndReopen(options);
bool has_compaction = false;
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
"UniversalCompactionBuilder::PickCompaction:Return", [&](void* arg) {
Compaction* compaction = reinterpret_cast<Compaction*>(arg);
ASSERT_TRUE(compaction->max_subcompactions() == 10);
has_compaction = true;
});
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
// Trigger compaction
for (int i = 0; i < 32; i++) {
for (int j = 0; j < 5000; j++) {
Put(std::to_string(j), std::string(1, 'A'));
}
ASSERT_OK(Flush());
ASSERT_OK(dbfull()->TEST_WaitForFlushMemTable());
}
dbfull()->TEST_WaitForCompact();
ASSERT_TRUE(has_compaction);
has_compaction = false;
ASSERT_OK(dbfull()->SetDBOptions({{"max_subcompactions", "2"}}));
ASSERT_TRUE(dbfull()->GetDBOptions().max_subcompactions == 2);
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
"UniversalCompactionBuilder::PickCompaction:Return", [&](void* arg) {
Compaction* compaction = reinterpret_cast<Compaction*>(arg);
ASSERT_TRUE(compaction->max_subcompactions() == 2);
has_compaction = true;
});
ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
// Trigger compaction
for (int i = 0; i < 32; i++) {
for (int j = 0; j < 5000; j++) {
Put(std::to_string(j), std::string(1, 'A'));
}
ASSERT_OK(Flush());
ASSERT_OK(dbfull()->TEST_WaitForFlushMemTable());
}
dbfull()->TEST_WaitForCompact();
ASSERT_TRUE(has_compaction);
} while (ChangeOptions());
}
#endif // !defined(ROCKSDB_LITE)
+18 -19
View File
@@ -15,7 +15,6 @@
#include "db/db_test_util.h"
#include "port/port.h"
#include "port/stack_trace.h"
#include "util/random.h"
namespace ROCKSDB_NAMESPACE {
class DBTestDynamicLevel : public DBTestBase {
@@ -51,7 +50,7 @@ TEST_F(DBTestDynamicLevel, DynamicLevelMaxBytesBase) {
keys[i] = i;
}
if (ordered_insert == 0) {
RandomShuffle(std::begin(keys), std::end(keys), rnd.Next());
std::random_shuffle(std::begin(keys), std::end(keys));
}
for (int max_background_compactions = 1; max_background_compactions < 4;
max_background_compactions += 2) {
@@ -81,9 +80,9 @@ TEST_F(DBTestDynamicLevel, DynamicLevelMaxBytesBase) {
for (int i = 0; i < kNKeys; i++) {
int key = keys[i];
ASSERT_OK(Put(Key(kNKeys + key), rnd.RandomString(102)));
ASSERT_OK(Put(Key(key), rnd.RandomString(102)));
ASSERT_OK(Put(Key(kNKeys * 2 + key), rnd.RandomString(102)));
ASSERT_OK(Put(Key(kNKeys + key), RandomString(&rnd, 102)));
ASSERT_OK(Put(Key(key), RandomString(&rnd, 102)));
ASSERT_OK(Put(Key(kNKeys * 2 + key), RandomString(&rnd, 102)));
ASSERT_OK(Delete(Key(kNKeys + keys[i / 10])));
env_->SleepForMicroseconds(5000);
}
@@ -159,7 +158,7 @@ TEST_F(DBTestDynamicLevel, DynamicLevelMaxBytesBase2) {
// Put about 28K to L0
for (int i = 0; i < 70; i++) {
ASSERT_OK(Put(Key(static_cast<int>(rnd.Uniform(kMaxKey))),
rnd.RandomString(380)));
RandomString(&rnd, 380)));
}
ASSERT_OK(dbfull()->SetOptions({
{"disable_auto_compactions", "false"},
@@ -176,7 +175,7 @@ TEST_F(DBTestDynamicLevel, DynamicLevelMaxBytesBase2) {
}));
for (int i = 0; i < 70; i++) {
ASSERT_OK(Put(Key(static_cast<int>(rnd.Uniform(kMaxKey))),
rnd.RandomString(380)));
RandomString(&rnd, 380)));
}
ASSERT_OK(dbfull()->SetOptions({
@@ -198,7 +197,7 @@ TEST_F(DBTestDynamicLevel, DynamicLevelMaxBytesBase2) {
// Write about 40K more
for (int i = 0; i < 100; i++) {
ASSERT_OK(Put(Key(static_cast<int>(rnd.Uniform(kMaxKey))),
rnd.RandomString(380)));
RandomString(&rnd, 380)));
}
ASSERT_OK(dbfull()->SetOptions({
{"disable_auto_compactions", "false"},
@@ -217,7 +216,7 @@ TEST_F(DBTestDynamicLevel, DynamicLevelMaxBytesBase2) {
// Each file is about 11KB, with 9KB of data.
for (int i = 0; i < 1300; i++) {
ASSERT_OK(Put(Key(static_cast<int>(rnd.Uniform(kMaxKey))),
rnd.RandomString(380)));
RandomString(&rnd, 380)));
}
// Make sure that the compaction starts before the last bit of data is
@@ -258,7 +257,7 @@ TEST_F(DBTestDynamicLevel, DynamicLevelMaxBytesBase2) {
TEST_SYNC_POINT("DynamicLevelMaxBytesBase2:1");
for (int i = 0; i < 2; i++) {
ASSERT_OK(Put(Key(static_cast<int>(rnd.Uniform(kMaxKey))),
rnd.RandomString(380)));
RandomString(&rnd, 380)));
}
TEST_SYNC_POINT("DynamicLevelMaxBytesBase2:2");
@@ -311,15 +310,15 @@ TEST_F(DBTestDynamicLevel, DynamicLevelMaxBytesCompactRange) {
// Put about 7K to L0
for (int i = 0; i < 140; i++) {
ASSERT_OK(
Put(Key(static_cast<int>(rnd.Uniform(kMaxKey))), rnd.RandomString(80)));
ASSERT_OK(Put(Key(static_cast<int>(rnd.Uniform(kMaxKey))),
RandomString(&rnd, 80)));
}
Flush();
dbfull()->TEST_WaitForCompact();
if (NumTableFilesAtLevel(0) == 0) {
// Make sure level 0 is not empty
ASSERT_OK(
Put(Key(static_cast<int>(rnd.Uniform(kMaxKey))), rnd.RandomString(80)));
ASSERT_OK(Put(Key(static_cast<int>(rnd.Uniform(kMaxKey))),
RandomString(&rnd, 80)));
Flush();
}
@@ -383,7 +382,7 @@ TEST_F(DBTestDynamicLevel, DynamicLevelMaxBytesBaseInc) {
const int total_keys = 3000;
const int random_part_size = 100;
for (int i = 0; i < total_keys; i++) {
std::string value = rnd.RandomString(random_part_size);
std::string value = RandomString(&rnd, random_part_size);
PutFixed32(&value, static_cast<uint32_t>(i));
ASSERT_OK(Put(Key(i), value));
}
@@ -442,8 +441,8 @@ TEST_F(DBTestDynamicLevel, DISABLED_MigrateToDynamicLevelMaxBytesBase) {
int total_keys = 1000;
for (int i = 0; i < total_keys; i++) {
ASSERT_OK(Put(Key(i), rnd.RandomString(102)));
ASSERT_OK(Put(Key(kMaxKey + i), rnd.RandomString(102)));
ASSERT_OK(Put(Key(i), RandomString(&rnd, 102)));
ASSERT_OK(Put(Key(kMaxKey + i), RandomString(&rnd, 102)));
ASSERT_OK(Delete(Key(i / 10)));
}
verify_func(total_keys, false);
@@ -476,8 +475,8 @@ TEST_F(DBTestDynamicLevel, DISABLED_MigrateToDynamicLevelMaxBytesBase) {
int total_keys2 = 2000;
for (int i = total_keys; i < total_keys2; i++) {
ASSERT_OK(Put(Key(i), rnd.RandomString(102)));
ASSERT_OK(Put(Key(kMaxKey + i), rnd.RandomString(102)));
ASSERT_OK(Put(Key(i), RandomString(&rnd, 102)));
ASSERT_OK(Put(Key(kMaxKey + i), RandomString(&rnd, 102)));
ASSERT_OK(Delete(Key(i / 10)));
}
+61 -21
View File
@@ -23,6 +23,57 @@
namespace ROCKSDB_NAMESPACE {
Status DBImpl::DisableFileDeletions() {
InstrumentedMutexLock l(&mutex_);
++disable_delete_obsolete_files_;
if (disable_delete_obsolete_files_ == 1) {
ROCKS_LOG_INFO(immutable_db_options_.info_log, "File Deletions Disabled");
} else {
ROCKS_LOG_WARN(immutable_db_options_.info_log,
"File Deletions Disabled, but already disabled. Counter: %d",
disable_delete_obsolete_files_);
}
return Status::OK();
}
Status DBImpl::EnableFileDeletions(bool force) {
// Job id == 0 means that this is not our background process, but rather
// user thread
JobContext job_context(0);
bool file_deletion_enabled = false;
{
InstrumentedMutexLock l(&mutex_);
if (force) {
// if force, we need to enable file deletions right away
disable_delete_obsolete_files_ = 0;
} else if (disable_delete_obsolete_files_ > 0) {
--disable_delete_obsolete_files_;
}
if (disable_delete_obsolete_files_ == 0) {
file_deletion_enabled = true;
FindObsoleteFiles(&job_context, true);
bg_cv_.SignalAll();
}
}
if (file_deletion_enabled) {
ROCKS_LOG_INFO(immutable_db_options_.info_log, "File Deletions Enabled");
if (job_context.HaveSomethingToDelete()) {
PurgeObsoleteFiles(job_context);
}
} else {
ROCKS_LOG_WARN(immutable_db_options_.info_log,
"File Deletions Enable, but not really enabled. Counter: %d",
disable_delete_obsolete_files_);
}
job_context.Clean();
LogFlush(immutable_db_options_.info_log);
return Status::OK();
}
int DBImpl::IsFileDeletionsEnabled() const {
return !disable_delete_obsolete_files_;
}
Status DBImpl::GetLiveFiles(std::vector<std::string>& ret,
uint64_t* manifest_file_size,
bool flush_memtable) {
@@ -39,9 +90,6 @@ Status DBImpl::GetLiveFiles(std::vector<std::string>& ret,
mutex_.Unlock();
status = AtomicFlushMemTables(cfds, FlushOptions(),
FlushReason::kGetLiveFiles);
if (status.IsColumnFamilyDropped()) {
status = Status::OK();
}
mutex_.Lock();
} else {
for (auto cfd : *versions_->GetColumnFamilySet()) {
@@ -55,10 +103,8 @@ Status DBImpl::GetLiveFiles(std::vector<std::string>& ret,
TEST_SYNC_POINT("DBImpl::GetLiveFiles:2");
mutex_.Lock();
cfd->UnrefAndTryDelete();
if (!status.ok() && !status.IsColumnFamilyDropped()) {
if (!status.ok()) {
break;
} else if (status.IsColumnFamilyDropped()) {
status = Status::OK();
}
}
}
@@ -72,33 +118,27 @@ Status DBImpl::GetLiveFiles(std::vector<std::string>& ret,
}
}
// Make a set of all of the live table and blob files
std::vector<uint64_t> live_table_files;
std::vector<uint64_t> live_blob_files;
// Make a set of all of the live *.sst files
std::vector<FileDescriptor> live;
for (auto cfd : *versions_->GetColumnFamilySet()) {
if (cfd->IsDropped()) {
continue;
}
cfd->current()->AddLiveFiles(&live_table_files, &live_blob_files);
cfd->current()->AddLiveFiles(&live);
}
ret.clear();
ret.reserve(live_table_files.size() + live_blob_files.size() +
3); // for CURRENT + MANIFEST + OPTIONS
ret.reserve(live.size() + 3); // *.sst + CURRENT + MANIFEST + OPTIONS
// create names of the live files. The names are not absolute
// paths, instead they are relative to dbname_;
for (const auto& table_file_number : live_table_files) {
ret.emplace_back(MakeTableFileName("", table_file_number));
for (const auto& live_file : live) {
ret.push_back(MakeTableFileName("", live_file.GetNumber()));
}
for (const auto& blob_file_number : live_blob_files) {
ret.emplace_back(BlobFileName("", blob_file_number));
}
ret.emplace_back(CurrentFileName(""));
ret.emplace_back(DescriptorFileName("", versions_->manifest_file_number()));
ret.emplace_back(OptionsFileName("", versions_->options_file_number()));
ret.push_back(CurrentFileName(""));
ret.push_back(DescriptorFileName("", versions_->manifest_file_number()));
ret.push_back(OptionsFileName("", versions_->options_file_number()));
// find length of manifest file while holding the mutex lock
*manifest_file_size = versions_->manifest_file_size();
+7 -7
View File
@@ -13,10 +13,10 @@
#include "db/db_test_util.h"
#include "port/port.h"
#include "port/stack_trace.h"
#include "test_util/fault_injection_test_env.h"
#include "test_util/sync_point.h"
#include "util/cast_util.h"
#include "util/mutexlock.h"
#include "utilities/fault_injection_env.h"
namespace ROCKSDB_NAMESPACE {
@@ -89,7 +89,7 @@ TEST_F(DBFlushTest, SyncFail) {
CreateAndReopenWithCF({"pikachu"}, options);
Put("key", "value");
auto* cfd =
static_cast_with_check<ColumnFamilyHandleImpl>(db_->DefaultColumnFamily())
reinterpret_cast<ColumnFamilyHandleImpl*>(db_->DefaultColumnFamily())
->cfd();
FlushOptions flush_options;
flush_options.wait = false;
@@ -379,9 +379,9 @@ TEST_F(DBFlushTest, FireOnFlushCompletedAfterCommittedResult) {
DBImpl* db_impl = static_cast_with_check<DBImpl>(db);
InstrumentedMutex* mutex = db_impl->mutex();
mutex->Lock();
auto* cfd = static_cast_with_check<ColumnFamilyHandleImpl>(
db->DefaultColumnFamily())
->cfd();
auto* cfd =
reinterpret_cast<ColumnFamilyHandleImpl*>(db->DefaultColumnFamily())
->cfd();
ASSERT_LT(seq, cfd->imm()->current()->GetEarliestSequenceNumber());
mutex->Unlock();
}
@@ -499,13 +499,13 @@ TEST_P(DBAtomicFlushTest, AtomicFlushTriggeredByMemTableFull) {
TEST_SYNC_POINT(
"DBAtomicFlushTest::AtomicFlushTriggeredByMemTableFull:BeforeCheck");
if (options.atomic_flush) {
for (size_t i = 0; i + 1 != num_cfs; ++i) {
for (size_t i = 0; i != num_cfs - 1; ++i) {
auto cfh = static_cast<ColumnFamilyHandleImpl*>(handles_[i]);
ASSERT_EQ(0, cfh->cfd()->imm()->NumNotFlushed());
ASSERT_TRUE(cfh->cfd()->mem()->IsEmpty());
}
} else {
for (size_t i = 0; i + 1 != num_cfs; ++i) {
for (size_t i = 0; i != num_cfs - 1; ++i) {
auto cfh = static_cast<ColumnFamilyHandleImpl*>(handles_[i]);
ASSERT_EQ(0, cfh->cfd()->imm()->NumNotFlushed());
ASSERT_FALSE(cfh->cfd()->mem()->IsEmpty());
+89 -388
View File
@@ -87,10 +87,10 @@
#include "table/get_context.h"
#include "table/merging_iterator.h"
#include "table/multiget_context.h"
#include "table/sst_file_dumper.h"
#include "table/table_builder.h"
#include "table/two_level_iterator.h"
#include "test_util/sync_point.h"
#include "tools/sst_dump_tool_imp.h"
#include "util/autovector.h"
#include "util/build_version.h"
#include "util/cast_util.h"
@@ -150,7 +150,7 @@ DBImpl::DBImpl(const DBOptions& options, const std::string& dbname,
own_info_log_(options.info_log == nullptr),
initial_db_options_(SanitizeOptions(dbname, options)),
env_(initial_db_options_.env),
fs_(initial_db_options_.env->GetFileSystem()),
fs_(initial_db_options_.file_system),
immutable_db_options_(initial_db_options_),
mutable_db_options_(initial_db_options_),
stats_(immutable_db_options_.statistics.get()),
@@ -249,8 +249,7 @@ DBImpl::DBImpl(const DBOptions& options, const std::string& dbname,
new ColumnFamilyMemTablesImpl(versions_->GetColumnFamilySet()));
DumpRocksDBBuildVersion(immutable_db_options_.info_log.get());
SetDbSessionId();
DumpDBFileSummary(immutable_db_options_, dbname_, db_session_id_);
DumpDBFileSummary(immutable_db_options_, dbname_);
immutable_db_options_.Dump(immutable_db_options_.info_log.get());
mutable_db_options_.Dump(immutable_db_options_.info_log.get());
DumpSupportInfo(immutable_db_options_.info_log.get());
@@ -312,40 +311,6 @@ Status DBImpl::ResumeImpl() {
s = bg_error;
}
// Make sure the IO Status stored in version set is set to OK.
bool file_deletion_disabled = !IsFileDeletionsEnabled();
if (s.ok()) {
IOStatus io_s = versions_->io_status();
if (io_s.IsIOError()) {
// If resuming from IOError resulted from MANIFEST write, then assert
// that we must have already set the MANIFEST writer to nullptr during
// clean-up phase MANIFEST writing. We must have also disabled file
// deletions.
assert(!versions_->descriptor_log_);
assert(file_deletion_disabled);
// Since we are trying to recover from MANIFEST write error, we need to
// switch to a new MANIFEST anyway. The old MANIFEST can be corrupted.
// Therefore, force writing a dummy version edit because we do not know
// whether there are flush jobs with non-empty data to flush, triggering
// appends to MANIFEST.
VersionEdit edit;
auto cfh =
static_cast_with_check<ColumnFamilyHandleImpl>(default_cf_handle_);
assert(cfh);
ColumnFamilyData* cfd = cfh->cfd();
const MutableCFOptions& cf_opts = *cfd->GetLatestMutableCFOptions();
s = versions_->LogAndApply(cfd, cf_opts, &edit, &mutex_,
directories_.GetDbDir());
if (!s.ok()) {
io_s = versions_->io_status();
if (!io_s.ok()) {
s = error_handler_.SetBGError(io_s,
BackgroundErrorReason::kManifestWrite);
}
}
}
}
// We cannot guarantee consistency of the WAL. So force flush Memtables of
// all the column families
if (s.ok()) {
@@ -394,13 +359,6 @@ Status DBImpl::ResumeImpl() {
job_context.Clean();
if (s.ok()) {
assert(versions_->io_status().ok());
// If we reach here, we should re-enable file deletions if it was disabled
// during previous error handling.
if (file_deletion_disabled) {
// Always return ok
EnableFileDeletions(/*force=*/true);
}
ROCKS_LOG_INFO(immutable_db_options_.info_log, "Successfully resumed DB");
}
mutex_.Lock();
@@ -685,17 +643,9 @@ void DBImpl::StartTimedTasks() {
stats_dump_period_sec = mutable_db_options_.stats_dump_period_sec;
if (stats_dump_period_sec > 0) {
if (!thread_dump_stats_) {
// In case of many `DB::Open()` in rapid succession we can have all
// threads dumping at once, which causes severe lock contention in
// jemalloc. Ensure successive `DB::Open()`s are staggered by at least
// one second in the common case.
static std::atomic<uint64_t> stats_dump_threads_started(0);
thread_dump_stats_.reset(new ROCKSDB_NAMESPACE::RepeatableThread(
[this]() { DBImpl::DumpStats(); }, "dump_st", env_,
static_cast<uint64_t>(stats_dump_period_sec) * kMicrosInSecond,
stats_dump_threads_started.fetch_add(1) %
static_cast<uint64_t>(stats_dump_period_sec) *
kMicrosInSecond));
static_cast<uint64_t>(stats_dump_period_sec) * kMicrosInSecond));
}
}
stats_persist_period_sec = mutable_db_options_.stats_persist_period_sec;
@@ -915,7 +865,9 @@ void DBImpl::DumpStats() {
Status DBImpl::TablesRangeTombstoneSummary(ColumnFamilyHandle* column_family,
int max_entries_to_print,
std::string* out_str) {
auto* cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto* cfh =
static_cast_with_check<ColumnFamilyHandleImpl, ColumnFamilyHandle>(
column_family);
ColumnFamilyData* cfd = cfh->cfd();
SuperVersion* super_version = cfd->GetReferencedSuperVersion(this);
@@ -954,8 +906,7 @@ Status DBImpl::SetOptions(
(void)options_map;
return Status::NotSupported("Not supported in ROCKSDB LITE");
#else
auto* cfd =
static_cast_with_check<ColumnFamilyHandleImpl>(column_family)->cfd();
auto* cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family)->cfd();
if (options_map.empty()) {
ROCKS_LOG_WARN(immutable_db_options_.info_log,
"SetOptions() on column family [%s], empty input",
@@ -1054,12 +1005,12 @@ Status DBImpl::SetDBOptions(
}
if (s.ok()) {
const BGJobLimits current_bg_job_limits =
GetBGJobLimits(mutable_db_options_.max_background_flushes,
GetBGJobLimits(immutable_db_options_.max_background_flushes,
mutable_db_options_.max_background_compactions,
mutable_db_options_.max_background_jobs,
/* parallelize_compactions */ true);
const BGJobLimits new_bg_job_limits = GetBGJobLimits(
new_options.max_background_flushes,
immutable_db_options_.max_background_flushes,
new_options.max_background_compactions,
new_options.max_background_jobs, /* parallelize_compactions */ true);
@@ -1091,18 +1042,9 @@ Status DBImpl::SetDBOptions(
mutex_.Lock();
}
if (new_options.stats_dump_period_sec > 0) {
// In case many DBs have `stats_dump_period_sec` enabled in rapid
// succession, we can have all threads dumping at once, which causes
// severe lock contention in jemalloc. Ensure successive enabling of
// `stats_dump_period_sec` are staggered by at least one second in the
// common case.
static std::atomic<uint64_t> stats_dump_threads_started(0);
thread_dump_stats_.reset(new ROCKSDB_NAMESPACE::RepeatableThread(
[this]() { DBImpl::DumpStats(); }, "dump_st", env_,
static_cast<uint64_t>(new_options.stats_dump_period_sec) *
kMicrosInSecond,
stats_dump_threads_started.fetch_add(1) %
static_cast<uint64_t>(new_options.stats_dump_period_sec) *
kMicrosInSecond));
} else {
thread_dump_stats_.reset();
@@ -1204,25 +1146,25 @@ int DBImpl::FindMinimumEmptyLevelFitting(
Status DBImpl::FlushWAL(bool sync) {
if (manual_wal_flush_) {
IOStatus io_s;
Status s;
{
// We need to lock log_write_mutex_ since logs_ might change concurrently
InstrumentedMutexLock wl(&log_write_mutex_);
log::Writer* cur_log_writer = logs_.back().writer;
io_s = cur_log_writer->WriteBuffer();
s = cur_log_writer->WriteBuffer();
}
if (!io_s.ok()) {
if (!s.ok()) {
ROCKS_LOG_ERROR(immutable_db_options_.info_log, "WAL flush error %s",
io_s.ToString().c_str());
s.ToString().c_str());
// In case there is a fs error we should set it globally to prevent the
// future writes
IOStatusCheck(io_s);
WriteStatusCheck(s);
// whether sync or not, we should abort the rest of function upon error
return std::move(io_s);
return s;
}
if (!sync) {
ROCKS_LOG_DEBUG(immutable_db_options_.info_log, "FlushWAL sync=false");
return std::move(io_s);
return s;
}
}
if (!sync) {
@@ -1274,21 +1216,12 @@ Status DBImpl::SyncWAL() {
TEST_SYNC_POINT("DBWALTest::SyncWALNotWaitWrite:1");
RecordTick(stats_, WAL_FILE_SYNCED);
Status status;
IOStatus io_s;
for (log::Writer* log : logs_to_sync) {
io_s = log->file()->SyncWithoutFlush(immutable_db_options_.use_fsync);
if (!io_s.ok()) {
status = io_s;
status = log->file()->SyncWithoutFlush(immutable_db_options_.use_fsync);
if (!status.ok()) {
break;
}
}
if (!io_s.ok()) {
ROCKS_LOG_ERROR(immutable_db_options_.info_log, "WAL Sync error %s",
io_s.ToString().c_str());
// In case there is a fs error we should set it globally to prevent the
// future writes
IOStatusCheck(io_s);
}
if (status.ok() && need_log_dir_sync) {
status = directories_.GetWalDir()->Fsync(IOOptions(), nullptr);
}
@@ -1315,7 +1248,7 @@ Status DBImpl::LockWAL() {
// future writes
WriteStatusCheck(status);
}
return std::move(status);
return status;
}
Status DBImpl::UnlockWAL() {
@@ -1366,12 +1299,12 @@ bool DBImpl::SetPreserveDeletesSequenceNumber(SequenceNumber seqnum) {
InternalIterator* DBImpl::NewInternalIterator(
Arena* arena, RangeDelAggregator* range_del_agg, SequenceNumber sequence,
ColumnFamilyHandle* column_family, bool allow_unprepared_value) {
ColumnFamilyHandle* column_family) {
ColumnFamilyData* cfd;
if (column_family == nullptr) {
cfd = default_cf_handle_->cfd();
} else {
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
cfd = cfh->cfd();
}
@@ -1380,7 +1313,7 @@ InternalIterator* DBImpl::NewInternalIterator(
mutex_.Unlock();
ReadOptions roptions;
return NewInternalIterator(roptions, cfd, super_version, arena, range_del_agg,
sequence, allow_unprepared_value);
sequence);
}
void DBImpl::SchedulePurge() {
@@ -1503,8 +1436,7 @@ InternalIterator* DBImpl::NewInternalIterator(const ReadOptions& read_options,
SuperVersion* super_version,
Arena* arena,
RangeDelAggregator* range_del_agg,
SequenceNumber sequence,
bool allow_unprepared_value) {
SequenceNumber sequence) {
InternalIterator* internal_iter;
assert(arena != nullptr);
assert(range_del_agg != nullptr);
@@ -1536,8 +1468,7 @@ InternalIterator* DBImpl::NewInternalIterator(const ReadOptions& read_options,
// Collect iterators for files in L0 - Ln
if (read_options.read_tier != kMemtableTier) {
super_version->current->AddIterators(read_options, file_options_,
&merge_iter_builder, range_del_agg,
allow_unprepared_value);
&merge_iter_builder, range_del_agg);
}
internal_iter = merge_iter_builder.Finish();
IterState* cleanup =
@@ -1582,26 +1513,12 @@ Status DBImpl::GetImpl(const ReadOptions& read_options, const Slice& key,
GetImplOptions& get_impl_options) {
assert(get_impl_options.value != nullptr ||
get_impl_options.merge_operands != nullptr);
#ifndef NDEBUG
assert(get_impl_options.column_family);
ColumnFamilyHandle* cf = get_impl_options.column_family;
const Comparator* const ucmp = cf->GetComparator();
assert(ucmp);
if (ucmp->timestamp_size() > 0) {
assert(read_options.timestamp);
assert(read_options.timestamp->size() == ucmp->timestamp_size());
} else {
assert(!read_options.timestamp);
}
#endif // NDEBUG
PERF_CPU_TIMER_GUARD(get_cpu_nanos, env_);
StopWatch sw(env_, stats_, DB_GET);
PERF_TIMER_GUARD(get_snapshot_time);
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(
get_impl_options.column_family);
auto cfh =
reinterpret_cast<ColumnFamilyHandleImpl*>(get_impl_options.column_family);
auto cfd = cfh->cfd();
if (tracer_) {
@@ -1770,39 +1687,17 @@ std::vector<Status> DBImpl::MultiGet(
const ReadOptions& read_options,
const std::vector<ColumnFamilyHandle*>& column_family,
const std::vector<Slice>& keys, std::vector<std::string>* values) {
return MultiGet(read_options, column_family, keys, values,
/*timestamps=*/nullptr);
}
std::vector<Status> DBImpl::MultiGet(
const ReadOptions& read_options,
const std::vector<ColumnFamilyHandle*>& column_family,
const std::vector<Slice>& keys, std::vector<std::string>* values,
std::vector<std::string>* timestamps) {
PERF_CPU_TIMER_GUARD(get_cpu_nanos, env_);
StopWatch sw(env_, stats_, DB_MULTIGET);
PERF_TIMER_GUARD(get_snapshot_time);
#ifndef NDEBUG
for (const auto* cfh : column_family) {
assert(cfh);
const Comparator* const ucmp = cfh->GetComparator();
assert(ucmp);
if (ucmp->timestamp_size() > 0) {
assert(read_options.timestamp);
assert(ucmp->timestamp_size() == read_options.timestamp->size());
} else {
assert(!read_options.timestamp);
}
}
#endif // NDEBUG
SequenceNumber consistent_seqnum;
;
std::unordered_map<uint32_t, MultiGetColumnFamilyData> multiget_cf_data(
column_family.size());
for (auto cf : column_family) {
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(cf);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(cf);
auto cfd = cfh->cfd();
if (multiget_cf_data.find(cfd->GetID()) == multiget_cf_data.end()) {
multiget_cf_data.emplace(cfd->GetID(),
@@ -1828,9 +1723,6 @@ std::vector<Status> DBImpl::MultiGet(
size_t num_keys = keys.size();
std::vector<Status> stat_list(num_keys);
values->resize(num_keys);
if (timestamps) {
timestamps->resize(num_keys);
}
// Keep track of bytes that we read for statistics-recording later
uint64_t bytes_read = 0;
@@ -1841,17 +1733,13 @@ std::vector<Status> DBImpl::MultiGet(
// s is both in/out. When in, s could either be OK or MergeInProgress.
// merge_operands will contain the sequence of merges in the latter case.
size_t num_found = 0;
size_t keys_read;
uint64_t curr_value_size = 0;
for (keys_read = 0; keys_read < num_keys; ++keys_read) {
for (size_t i = 0; i < num_keys; ++i) {
merge_context.Clear();
Status& s = stat_list[keys_read];
std::string* value = &(*values)[keys_read];
std::string* timestamp = timestamps ? &(*timestamps)[keys_read] : nullptr;
Status& s = stat_list[i];
std::string* value = &(*values)[i];
LookupKey lkey(keys[keys_read], consistent_seqnum, read_options.timestamp);
auto cfh =
static_cast_with_check<ColumnFamilyHandleImpl>(column_family[keys_read]);
LookupKey lkey(keys[i], consistent_seqnum);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family[i]);
SequenceNumber max_covering_tombstone_seq = 0;
auto mgd_iter = multiget_cf_data.find(cfh->cfd()->GetID());
assert(mgd_iter != multiget_cf_data.end());
@@ -1862,12 +1750,13 @@ std::vector<Status> DBImpl::MultiGet(
has_unpersisted_data_.load(std::memory_order_relaxed));
bool done = false;
if (!skip_memtable) {
if (super_version->mem->Get(lkey, value, timestamp, &s, &merge_context,
&max_covering_tombstone_seq, read_options)) {
if (super_version->mem->Get(lkey, value, /*timestamp=*/nullptr, &s,
&merge_context, &max_covering_tombstone_seq,
read_options)) {
done = true;
RecordTick(stats_, MEMTABLE_HIT);
} else if (super_version->imm->Get(
lkey, value, timestamp, &s, &merge_context,
lkey, value, nullptr, &s, &merge_context,
&max_covering_tombstone_seq, read_options)) {
done = true;
RecordTick(stats_, MEMTABLE_HIT);
@@ -1876,8 +1765,8 @@ std::vector<Status> DBImpl::MultiGet(
if (!done) {
PinnableSlice pinnable_val;
PERF_TIMER_GUARD(get_from_output_files_time);
super_version->current->Get(read_options, lkey, &pinnable_val, timestamp,
&s, &merge_context,
super_version->current->Get(read_options, lkey, &pinnable_val,
/*timestamp=*/nullptr, &s, &merge_context,
&max_covering_tombstone_seq);
value->assign(pinnable_val.data(), pinnable_val.size());
RecordTick(stats_, MEMTABLE_MISS);
@@ -1886,29 +1775,6 @@ std::vector<Status> DBImpl::MultiGet(
if (s.ok()) {
bytes_read += value->size();
num_found++;
curr_value_size += value->size();
if (curr_value_size > read_options.value_size_soft_limit) {
while (++keys_read < num_keys) {
stat_list[keys_read] = Status::Aborted();
}
break;
}
}
if (read_options.deadline.count() &&
env_->NowMicros() >
static_cast<uint64_t>(read_options.deadline.count())) {
break;
}
}
if (keys_read < num_keys) {
// The only reason to break out of the loop is when the deadline is
// exceeded
assert(env_->NowMicros() >
static_cast<uint64_t>(read_options.deadline.count()));
for (++keys_read; keys_read < num_keys; ++keys_read) {
stat_list[keys_read] = Status::TimedOut();
}
}
@@ -2063,39 +1929,14 @@ void DBImpl::MultiGet(const ReadOptions& read_options, const size_t num_keys,
ColumnFamilyHandle** column_families, const Slice* keys,
PinnableSlice* values, Status* statuses,
const bool sorted_input) {
return MultiGet(read_options, num_keys, column_families, keys, values,
/*timestamps=*/nullptr, statuses, sorted_input);
}
void DBImpl::MultiGet(const ReadOptions& read_options, const size_t num_keys,
ColumnFamilyHandle** column_families, const Slice* keys,
PinnableSlice* values, std::string* timestamps,
Status* statuses, const bool sorted_input) {
if (num_keys == 0) {
return;
}
#ifndef NDEBUG
for (size_t i = 0; i < num_keys; ++i) {
ColumnFamilyHandle* cfh = column_families[i];
assert(cfh);
const Comparator* const ucmp = cfh->GetComparator();
assert(ucmp);
if (ucmp->timestamp_size() > 0) {
assert(read_options.timestamp);
assert(read_options.timestamp->size() == ucmp->timestamp_size());
} else {
assert(!read_options.timestamp);
}
}
#endif // NDEBUG
autovector<KeyContext, MultiGetContext::MAX_BATCH_SIZE> key_context;
autovector<KeyContext*, MultiGetContext::MAX_BATCH_SIZE> sorted_keys;
sorted_keys.resize(num_keys);
for (size_t i = 0; i < num_keys; ++i) {
key_context.emplace_back(column_families[i], keys[i], &values[i],
timestamps ? &timestamps[i] : nullptr,
&statuses[i]);
}
for (size_t i = 0; i < num_keys; ++i) {
@@ -2136,31 +1977,14 @@ void DBImpl::MultiGet(const ReadOptions& read_options, const size_t num_keys,
read_options, nullptr, iter_deref_lambda, &multiget_cf_data,
&consistent_seqnum);
Status s;
auto cf_iter = multiget_cf_data.begin();
for (; cf_iter != multiget_cf_data.end(); ++cf_iter) {
s = MultiGetImpl(read_options, cf_iter->start, cf_iter->num_keys,
&sorted_keys, cf_iter->super_version, consistent_seqnum,
nullptr, nullptr);
if (!s.ok()) {
break;
}
}
if (!s.ok()) {
assert(s.IsTimedOut() || s.IsAborted());
for (++cf_iter; cf_iter != multiget_cf_data.end(); ++cf_iter) {
for (size_t i = cf_iter->start; i < cf_iter->start + cf_iter->num_keys;
++i) {
*sorted_keys[i]->s = s;
}
}
}
for (const auto& iter : multiget_cf_data) {
for (auto cf_iter = multiget_cf_data.begin();
cf_iter != multiget_cf_data.end(); ++cf_iter) {
MultiGetImpl(read_options, cf_iter->start, cf_iter->num_keys, &sorted_keys,
cf_iter->super_version, consistent_seqnum, nullptr, nullptr);
if (!unref_only) {
ReturnAndCleanupSuperVersion(iter.cfd, iter.super_version);
ReturnAndCleanupSuperVersion(cf_iter->cfd, cf_iter->super_version);
} else {
iter.cfd->GetSuperVersion()->Unref();
cf_iter->cfd->GetSuperVersion()->Unref();
}
}
}
@@ -2183,8 +2007,7 @@ struct CompareKeyContext {
}
// Both keys are from the same column family
int cmp = comparator->CompareWithoutTimestamp(
*(lhs->key), /*a_has_ts=*/false, *(rhs->key), /*b_has_ts=*/false);
int cmp = comparator->Compare(*(lhs->key), *(rhs->key));
if (cmp < 0) {
return true;
}
@@ -2204,11 +2027,10 @@ void DBImpl::PrepareMultiGetKeys(
KeyContext* lhs = (*sorted_keys)[index - 1];
KeyContext* rhs = (*sorted_keys)[index];
ColumnFamilyHandleImpl* cfh =
static_cast_with_check<ColumnFamilyHandleImpl>(lhs->column_family);
reinterpret_cast<ColumnFamilyHandleImpl*>(lhs->column_family);
uint32_t cfd_id1 = cfh->cfd()->GetID();
const Comparator* comparator = cfh->cfd()->user_comparator();
cfh =
static_cast_with_check<ColumnFamilyHandleImpl>(lhs->column_family);
cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(lhs->column_family);
uint32_t cfd_id2 = cfh->cfd()->GetID();
assert(cfd_id1 <= cfd_id2);
@@ -2217,8 +2039,7 @@ void DBImpl::PrepareMultiGetKeys(
}
// Both keys are from the same column family
int cmp = comparator->CompareWithoutTimestamp(
*(lhs->key), /*a_has_ts=*/false, *(rhs->key), /*b_has_ts=*/false);
int cmp = comparator->Compare(*(lhs->key), *(rhs->key));
assert(cmp <= 0);
}
index++;
@@ -2236,22 +2057,11 @@ void DBImpl::MultiGet(const ReadOptions& read_options,
ColumnFamilyHandle* column_family, const size_t num_keys,
const Slice* keys, PinnableSlice* values,
Status* statuses, const bool sorted_input) {
return MultiGet(read_options, column_family, num_keys, keys, values,
/*timestamp=*/nullptr, statuses, sorted_input);
}
void DBImpl::MultiGet(const ReadOptions& read_options,
ColumnFamilyHandle* column_family, const size_t num_keys,
const Slice* keys, PinnableSlice* values,
std::string* timestamps, Status* statuses,
const bool sorted_input) {
autovector<KeyContext, MultiGetContext::MAX_BATCH_SIZE> key_context;
autovector<KeyContext*, MultiGetContext::MAX_BATCH_SIZE> sorted_keys;
sorted_keys.resize(num_keys);
for (size_t i = 0; i < num_keys; ++i) {
key_context.emplace_back(column_family, keys[i], &values[i],
timestamps ? &timestamps[i] : nullptr,
&statuses[i]);
key_context.emplace_back(column_family, keys[i], &values[i], &statuses[i]);
}
for (size_t i = 0; i < num_keys; ++i) {
sorted_keys[i] = &key_context[i];
@@ -2304,24 +2114,14 @@ void DBImpl::MultiGetWithCallback(
consistent_seqnum = callback->max_visible_seq();
}
Status s = MultiGetImpl(read_options, 0, num_keys, sorted_keys,
multiget_cf_data[0].super_version, consistent_seqnum,
nullptr, nullptr);
assert(s.ok() || s.IsTimedOut() || s.IsAborted());
MultiGetImpl(read_options, 0, num_keys, sorted_keys,
multiget_cf_data[0].super_version, consistent_seqnum, nullptr,
nullptr);
ReturnAndCleanupSuperVersion(multiget_cf_data[0].cfd,
multiget_cf_data[0].super_version);
}
// The actual implementation of batched MultiGet. Parameters -
// start_key - Index in the sorted_keys vector to start processing from
// num_keys - Number of keys to lookup, starting with sorted_keys[start_key]
// sorted_keys - The entire batch of sorted keys for this CF
//
// The per key status is returned in the KeyContext structures pointed to by
// sorted_keys. An overall Status is also returned, with the only possible
// values being Status::OK() and Status::TimedOut(). The latter indicates
// that the call exceeded read_options.deadline
Status DBImpl::MultiGetImpl(
void DBImpl::MultiGetImpl(
const ReadOptions& read_options, size_t start_key, size_t num_keys,
autovector<KeyContext*, MultiGetContext::MAX_BATCH_SIZE>* sorted_keys,
SuperVersion* super_version, SequenceNumber snapshot,
@@ -2334,23 +2134,13 @@ Status DBImpl::MultiGetImpl(
// s is both in/out. When in, s could either be OK or MergeInProgress.
// merge_operands will contain the sequence of merges in the latter case.
size_t keys_left = num_keys;
Status s;
uint64_t curr_value_size = 0;
while (keys_left) {
if (read_options.deadline.count() &&
env_->NowMicros() >
static_cast<uint64_t>(read_options.deadline.count())) {
s = Status::TimedOut();
break;
}
size_t batch_size = (keys_left > MultiGetContext::MAX_BATCH_SIZE)
? MultiGetContext::MAX_BATCH_SIZE
: keys_left;
MultiGetContext ctx(sorted_keys, start_key + num_keys - keys_left,
batch_size, snapshot, read_options);
batch_size, snapshot);
MultiGetRange range = ctx.GetMultiGetRange();
range.AddValueSize(curr_value_size);
bool lookup_current = false;
keys_left -= batch_size;
@@ -2381,32 +2171,19 @@ Status DBImpl::MultiGetImpl(
super_version->current->MultiGet(read_options, &range, callback,
is_blob_index);
}
curr_value_size = range.GetValueSize();
if (curr_value_size > read_options.value_size_soft_limit) {
s = Status::Aborted();
break;
}
}
// Post processing (decrement reference counts and record statistics)
PERF_TIMER_GUARD(get_post_process_time);
size_t num_found = 0;
uint64_t bytes_read = 0;
for (size_t i = start_key; i < start_key + num_keys - keys_left; ++i) {
for (size_t i = start_key; i < start_key + num_keys; ++i) {
KeyContext* key = (*sorted_keys)[i];
if (key->s->ok()) {
bytes_read += key->value->size();
num_found++;
}
}
if (keys_left) {
assert(s.IsTimedOut() || s.IsAborted());
for (size_t i = start_key + num_keys - keys_left; i < start_key + num_keys;
++i) {
KeyContext* key = (*sorted_keys)[i];
*key->s = s;
}
}
RecordTick(stats_, NUMBER_MULTIGET_CALLS);
RecordTick(stats_, NUMBER_MULTIGET_KEYS_READ, num_keys);
@@ -2415,8 +2192,6 @@ Status DBImpl::MultiGetImpl(
RecordInHistogram(stats_, BYTES_PER_MULTIGET, bytes_read);
PERF_COUNTER_ADD(multiget_read_bytes, bytes_read);
PERF_TIMER_STOP(get_post_process_time);
return s;
}
Status DBImpl::CreateColumnFamily(const ColumnFamilyOptions& cf_options,
@@ -2572,7 +2347,7 @@ Status DBImpl::CreateColumnFamilyImpl(const ColumnFamilyOptions& cf_options,
// this is outside the mutex
if (s.ok()) {
NewThreadStatusCfInfo(
static_cast_with_check<ColumnFamilyHandleImpl>(*handle)->cfd());
reinterpret_cast<ColumnFamilyHandleImpl*>(*handle)->cfd());
}
return s;
}
@@ -2609,7 +2384,7 @@ Status DBImpl::DropColumnFamilies(
}
Status DBImpl::DropColumnFamilyImpl(ColumnFamilyHandle* column_family) {
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
auto cfd = cfh->cfd();
if (cfd->GetID() == 0) {
return Status::InvalidArgument("Can't drop default column family");
@@ -2705,10 +2480,6 @@ Iterator* DBImpl::NewIterator(const ReadOptions& read_options,
return NewErrorIterator(
Status::NotSupported("Managed iterator is not supported anymore."));
}
if (read_options.deadline != std::chrono::microseconds::zero()) {
return NewErrorIterator(
Status::NotSupported("ReadOptions deadline is not supported"));
}
Iterator* result = nullptr;
if (read_options.read_tier == kPersistedTier) {
return NewErrorIterator(Status::NotSupported(
@@ -2723,9 +2494,8 @@ Iterator* DBImpl::NewIterator(const ReadOptions& read_options,
"Iterator requested internal keys which are too old and are not"
" guaranteed to be preserved, try larger iter_start_seqnum opt."));
}
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
ColumnFamilyData* cfd = cfh->cfd();
assert(cfd != nullptr);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
auto cfd = cfh->cfd();
ReadCallback* read_callback = nullptr; // No read callback provided.
if (read_options.tailing) {
#ifdef ROCKSDB_LITE
@@ -2734,8 +2504,7 @@ Iterator* DBImpl::NewIterator(const ReadOptions& read_options,
#else
SuperVersion* sv = cfd->GetReferencedSuperVersion(this);
auto iter = new ForwardIterator(this, read_options, cfd, sv,
/* allow_unprepared_value */ true);
auto iter = new ForwardIterator(this, read_options, cfd, sv);
result = NewDBIterator(
env_, read_options, *cfd->ioptions(), sv->mutable_cf_options,
cfd->user_comparator(), iter, kMaxSequenceNumber,
@@ -2746,11 +2515,10 @@ Iterator* DBImpl::NewIterator(const ReadOptions& read_options,
// Note: no need to consider the special case of
// last_seq_same_as_publish_seq_==false since NewIterator is overridden in
// WritePreparedTxnDB
result = NewIteratorImpl(read_options, cfd,
(read_options.snapshot != nullptr)
? read_options.snapshot->GetSequenceNumber()
: kMaxSequenceNumber,
read_callback);
auto snapshot = read_options.snapshot != nullptr
? read_options.snapshot->GetSequenceNumber()
: versions_->LastSequence();
result = NewIteratorImpl(read_options, cfd, snapshot, read_callback);
}
return result;
}
@@ -2763,24 +2531,6 @@ ArenaWrappedDBIter* DBImpl::NewIteratorImpl(const ReadOptions& read_options,
bool allow_refresh) {
SuperVersion* sv = cfd->GetReferencedSuperVersion(this);
TEST_SYNC_POINT("DBImpl::NewIterator:1");
TEST_SYNC_POINT("DBImpl::NewIterator:2");
if (snapshot == kMaxSequenceNumber) {
// Note that the snapshot is assigned AFTER referencing the super
// version because otherwise a flush happening in between may compact away
// data for the snapshot, so the reader would see neither data that was be
// visible to the snapshot before compaction nor the newer data inserted
// afterwards.
// Note that the super version might not contain all the data available
// to this snapshot, but in that case it can see all the data in the
// super version, which is a valid consistent state after the user
// calls NewIterator().
snapshot = versions_->LastSequence();
TEST_SYNC_POINT("DBImpl::NewIterator:3");
TEST_SYNC_POINT("DBImpl::NewIterator:4");
}
// Try to generate a DB iterator tree in continuous memory area to be
// cache friendly. Here is an example of result:
// +-------------------------------+
@@ -2831,8 +2581,7 @@ ArenaWrappedDBIter* DBImpl::NewIteratorImpl(const ReadOptions& read_options,
InternalIterator* internal_iter =
NewInternalIterator(read_options, cfd, sv, db_iter->GetArena(),
db_iter->GetRangeDelAggregator(), snapshot,
/* allow_unprepared_value */ true);
db_iter->GetRangeDelAggregator(), snapshot);
db_iter->SetIterUnderDBIter(internal_iter);
return db_iter;
@@ -2858,10 +2607,9 @@ Status DBImpl::NewIterators(
"Tailing iterator not supported in RocksDB lite");
#else
for (auto cfh : column_families) {
auto cfd = static_cast_with_check<ColumnFamilyHandleImpl>(cfh)->cfd();
auto cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(cfh)->cfd();
SuperVersion* sv = cfd->GetReferencedSuperVersion(this);
auto iter = new ForwardIterator(this, read_options, cfd, sv,
/* allow_unprepared_value */ true);
auto iter = new ForwardIterator(this, read_options, cfd, sv);
iterators->push_back(NewDBIterator(
env_, read_options, *cfd->ioptions(), sv->mutable_cf_options,
cfd->user_comparator(), iter, kMaxSequenceNumber,
@@ -2878,8 +2626,7 @@ Status DBImpl::NewIterators(
: versions_->LastSequence();
for (size_t i = 0; i < column_families.size(); ++i) {
auto* cfd =
static_cast_with_check<ColumnFamilyHandleImpl>(column_families[i])
->cfd();
reinterpret_cast<ColumnFamilyHandleImpl*>(column_families[i])->cfd();
iterators->push_back(
NewIteratorImpl(read_options, cfd, snapshot, read_callback));
}
@@ -2986,7 +2733,7 @@ void DBImpl::ReleaseSnapshot(const Snapshot* s) {
#ifndef ROCKSDB_LITE
Status DBImpl::GetPropertiesOfAllTables(ColumnFamilyHandle* column_family,
TablePropertiesCollection* props) {
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
auto cfd = cfh->cfd();
// Increment the ref count
@@ -3008,7 +2755,7 @@ Status DBImpl::GetPropertiesOfAllTables(ColumnFamilyHandle* column_family,
Status DBImpl::GetPropertiesOfTablesInRange(ColumnFamilyHandle* column_family,
const Range* range, std::size_t n,
TablePropertiesCollection* props) {
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
auto cfd = cfh->cfd();
// Increment the ref count
@@ -3044,7 +2791,7 @@ FileSystem* DBImpl::GetFileSystem() const {
Options DBImpl::GetOptions(ColumnFamilyHandle* column_family) const {
InstrumentedMutexLock l(&mutex_);
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
return Options(BuildDBOptions(immutable_db_options_, mutable_db_options_),
cfh->cfd()->GetLatestCFOptions());
}
@@ -3058,8 +2805,7 @@ bool DBImpl::GetProperty(ColumnFamilyHandle* column_family,
const Slice& property, std::string* value) {
const DBPropertyInfo* property_info = GetPropertyInfo(property);
value->clear();
auto cfd =
static_cast_with_check<ColumnFamilyHandleImpl>(column_family)->cfd();
auto cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family)->cfd();
if (property_info == nullptr) {
return false;
} else if (property_info->handle_int) {
@@ -3093,8 +2839,7 @@ bool DBImpl::GetMapProperty(ColumnFamilyHandle* column_family,
std::map<std::string, std::string>* value) {
const DBPropertyInfo* property_info = GetPropertyInfo(property);
value->clear();
auto cfd =
static_cast_with_check<ColumnFamilyHandleImpl>(column_family)->cfd();
auto cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family)->cfd();
if (property_info == nullptr) {
return false;
} else if (property_info->handle_map) {
@@ -3113,8 +2858,7 @@ bool DBImpl::GetIntProperty(ColumnFamilyHandle* column_family,
if (property_info == nullptr || property_info->handle_int == nullptr) {
return false;
}
auto cfd =
static_cast_with_check<ColumnFamilyHandleImpl>(column_family)->cfd();
auto cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family)->cfd();
return GetIntPropertyInternal(cfd, *property_info, false, value);
}
@@ -3287,7 +3031,7 @@ void DBImpl::GetApproximateMemTableStats(ColumnFamilyHandle* column_family,
uint64_t* const count,
uint64_t* const size) {
ColumnFamilyHandleImpl* cfh =
static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
ColumnFamilyData* cfd = cfh->cfd();
SuperVersion* sv = GetAndRefSuperVersion(cfd);
@@ -3312,7 +3056,7 @@ Status DBImpl::GetApproximateSizes(const SizeApproximationOptions& options,
}
Version* v;
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
auto cfd = cfh->cfd();
SuperVersion* sv = GetAndRefSuperVersion(cfd);
v = sv->current;
@@ -3470,7 +3214,7 @@ Status DBImpl::DeleteFilesInRanges(ColumnFamilyHandle* column_family,
const RangePtr* ranges, size_t n,
bool include_end) {
Status status;
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
ColumnFamilyData* cfd = cfh->cfd();
VersionEdit edit;
std::set<FileMetaData*> deleted_files;
@@ -3560,16 +3304,10 @@ void DBImpl::GetLiveFilesMetaData(std::vector<LiveFileMetaData>* metadata) {
versions_->GetLiveFilesMetaData(metadata);
}
Status DBImpl::GetLiveFilesChecksumInfo(FileChecksumList* checksum_list) {
InstrumentedMutexLock l(&mutex_);
return versions_->GetLiveFilesChecksumInfo(checksum_list);
}
void DBImpl::GetColumnFamilyMetaData(ColumnFamilyHandle* column_family,
ColumnFamilyMetaData* cf_meta) {
assert(column_family);
auto* cfd =
static_cast_with_check<ColumnFamilyHandleImpl>(column_family)->cfd();
auto* cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family)->cfd();
auto* sv = GetAndRefSuperVersion(cfd);
{
// Without mutex, Version::GetColumnFamilyMetaData will have data race with
@@ -3685,37 +3423,6 @@ Status DBImpl::GetDbIdentityFromIdentityFile(std::string* identity) const {
return s;
}
Status DBImpl::GetDbSessionId(std::string& session_id) const {
session_id.assign(db_session_id_);
return Status::OK();
}
void DBImpl::SetDbSessionId() {
// GenerateUniqueId() generates an identifier that has a negligible
// probability of being duplicated, ~128 bits of entropy
std::string uuid = env_->GenerateUniqueId();
// Hash and reformat that down to a more compact format, 20 characters
// in base-36 ([0-9A-Z]), which is ~103 bits of entropy, which is enough
// to expect no collisions across a billion servers each opening DBs
// a million times (~2^50). Benefits vs. raw unique id:
// * Save ~ dozen bytes per SST file
// * Shorter shared backup file names (some platforms have low limits)
// * Visually distinct from DB id format
uint64_t a = NPHash64(uuid.data(), uuid.size(), 1234U);
uint64_t b = NPHash64(uuid.data(), uuid.size(), 5678U);
db_session_id_.resize(20);
static const char* const base36 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
size_t i = 0;
for (; i < 10U; ++i, a /= 36U) {
db_session_id_[i] = base36[a % 36];
}
for (; i < 20U; ++i, b /= 36U) {
db_session_id_[i] = base36[b % 36];
}
TEST_SYNC_POINT_CALLBACK("DBImpl::SetDbSessionId", &db_session_id_);
}
// Default implementation -- returns not supported status
Status DB::CreateColumnFamily(const ColumnFamilyOptions& /*cf_options*/,
const std::string& /*column_family_name*/,
@@ -3771,8 +3478,12 @@ Status DBImpl::Close() {
Status DB::ListColumnFamilies(const DBOptions& db_options,
const std::string& name,
std::vector<std::string>* column_families) {
const std::shared_ptr<FileSystem>& fs = db_options.env->GetFileSystem();
return VersionSet::ListColumnFamilies(column_families, name, fs.get());
FileSystem* fs = db_options.file_system.get();
LegacyFileSystemWrapper legacy_fs(db_options.env);
if (!fs) {
fs = &legacy_fs;
}
return VersionSet::ListColumnFamilies(column_families, name, fs);
}
Snapshot::~Snapshot() {}
@@ -4295,8 +4006,7 @@ Status DBImpl::IngestExternalFiles(
static_cast<ColumnFamilyHandleImpl*>(args[i].column_family)->cfd();
SuperVersion* super_version = cfd->GetReferencedSuperVersion(this);
exec_results[i].second = ingestion_jobs[i].Prepare(
args[i].external_files, args[i].files_checksums,
args[i].files_checksum_func_names, start_file_number, super_version);
args[i].external_files, start_file_number, super_version);
exec_results[i].first = true;
CleanupSuperVersion(super_version);
}
@@ -4307,8 +4017,7 @@ Status DBImpl::IngestExternalFiles(
static_cast<ColumnFamilyHandleImpl*>(args[0].column_family)->cfd();
SuperVersion* super_version = cfd->GetReferencedSuperVersion(this);
exec_results[0].second = ingestion_jobs[0].Prepare(
args[0].external_files, args[0].files_checksums,
args[0].files_checksum_func_names, next_file_number, super_version);
args[0].external_files, next_file_number, super_version);
exec_results[0].first = true;
CleanupSuperVersion(super_version);
}
@@ -4484,14 +4193,6 @@ Status DBImpl::IngestExternalFiles(
#endif // !NDEBUG
}
}
} else if (versions_->io_status().IsIOError()) {
// Error while writing to MANIFEST.
// In fact, versions_->io_status() can also be the result of renaming
// CURRENT file. With current code, it's just difficult to tell. So just
// be pessimistic and try write to a new MANIFEST.
// TODO: distinguish between MANIFEST write and CURRENT renaming
const IOStatus& io_s = versions_->io_status();
error_handler_.SetBGError(io_s, BackgroundErrorReason::kManifestWrite);
}
// Resume writes to the DB
@@ -4551,7 +4252,7 @@ Status DBImpl::CreateColumnFamilyWithImport(
}
// Import sst files from metadata.
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(*handle);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(*handle);
auto cfd = cfh->cfd();
ImportColumnFamilyJob import_job(env_, versions_.get(), cfd,
immutable_db_options_, file_options_,
+22 -81
View File
@@ -188,11 +188,6 @@ class DBImpl : public DB {
const std::vector<ColumnFamilyHandle*>& column_family,
const std::vector<Slice>& keys,
std::vector<std::string>* values) override;
virtual std::vector<Status> MultiGet(
const ReadOptions& options,
const std::vector<ColumnFamilyHandle*>& column_family,
const std::vector<Slice>& keys, std::vector<std::string>* values,
std::vector<std::string>* timestamps) override;
// This MultiGet is a batched version, which may be faster than calling Get
// multiple times, especially if the keys have some spatial locality that
@@ -206,22 +201,11 @@ class DBImpl : public DB {
const size_t num_keys, const Slice* keys,
PinnableSlice* values, Status* statuses,
const bool sorted_input = false) override;
virtual void MultiGet(const ReadOptions& options,
ColumnFamilyHandle* column_family,
const size_t num_keys, const Slice* keys,
PinnableSlice* values, std::string* timestamps,
Status* statuses,
const bool sorted_input = false) override;
virtual void MultiGet(const ReadOptions& options, const size_t num_keys,
ColumnFamilyHandle** column_families, const Slice* keys,
PinnableSlice* values, Status* statuses,
const bool sorted_input = false) override;
virtual void MultiGet(const ReadOptions& options, const size_t num_keys,
ColumnFamilyHandle** column_families, const Slice* keys,
PinnableSlice* values, std::string* timestamps,
Status* statuses,
const bool sorted_input = false) override;
virtual void MultiGetWithCallback(
const ReadOptions& options, ColumnFamilyHandle* column_family,
@@ -350,20 +334,12 @@ class DBImpl : public DB {
virtual Status GetDbIdentityFromIdentityFile(std::string* identity) const;
virtual Status GetDbSessionId(std::string& session_id) const override;
ColumnFamilyHandle* DefaultColumnFamily() const override;
ColumnFamilyHandle* PersistentStatsColumnFamily() const;
virtual Status Close() override;
virtual Status DisableFileDeletions() override;
virtual Status EnableFileDeletions(bool force) override;
virtual bool IsFileDeletionsEnabled() const;
Status GetStatsHistory(
uint64_t start_time, uint64_t end_time,
std::unique_ptr<StatsHistoryIterator>* stats_iterator) override;
@@ -371,6 +347,9 @@ class DBImpl : public DB {
#ifndef ROCKSDB_LITE
using DB::ResetStats;
virtual Status ResetStats() override;
virtual Status DisableFileDeletions() override;
virtual Status EnableFileDeletions(bool force) override;
virtual int IsFileDeletionsEnabled() const;
// All the returned filenames start with "/"
virtual Status GetLiveFiles(std::vector<std::string>&,
uint64_t* manifest_file_size,
@@ -393,9 +372,6 @@ class DBImpl : public DB {
virtual void GetLiveFilesMetaData(
std::vector<LiveFileMetaData>* metadata) override;
virtual Status GetLiveFilesChecksumInfo(
FileChecksumList* checksum_list) override;
// Obtains the meta data of the specified column family of the DB.
// Status::NotFound() will be returned if the current DB does not have
// any column family match the specified name.
@@ -485,7 +461,6 @@ class DBImpl : public DB {
Status GetImpl(const ReadOptions& options, const Slice& key,
GetImplOptions& get_impl_options);
// If `snapshot` == kMaxSequenceNumber, set a recent one inside the file.
ArenaWrappedDBIter* NewIteratorImpl(const ReadOptions& options,
ColumnFamilyData* cfd,
SequenceNumber snapshot,
@@ -590,14 +565,9 @@ class DBImpl : public DB {
// Return an internal iterator over the current state of the database.
// The keys of this iterator are internal keys (see format.h).
// The returned iterator should be deleted when no longer needed.
// If allow_unprepared_value is true, the returned iterator may defer reading
// the value and so will require PrepareValue() to be called before value();
// allow_unprepared_value = false is convenient when this optimization is not
// useful, e.g. when reading the whole column family.
InternalIterator* NewInternalIterator(
Arena* arena, RangeDelAggregator* range_del_agg, SequenceNumber sequence,
ColumnFamilyHandle* column_family = nullptr,
bool allow_unprepared_value = false);
ColumnFamilyHandle* column_family = nullptr);
LogsWithPrepTracker* logs_with_prep_tracker() {
return &logs_with_prep_tracker_;
@@ -723,8 +693,7 @@ class DBImpl : public DB {
InternalIterator* NewInternalIterator(
const ReadOptions&, ColumnFamilyData* cfd, SuperVersion* super_version,
Arena* arena, RangeDelAggregator* range_del_agg, SequenceNumber sequence,
bool allow_unprepared_value);
Arena* arena, RangeDelAggregator* range_del_agg, SequenceNumber sequence);
// hollow transactions shell used for recovery.
// these will then be passed to TransactionDB so that
@@ -852,8 +821,8 @@ class DBImpl : public DB {
InstrumentedMutex* mutex() const { return &mutex_; }
// Initialize a brand new DB. The DB directory is expected to be empty before
// calling it. Push new manifest file name into `new_filenames`.
Status NewDB(std::vector<std::string>* new_filenames);
// calling it.
Status NewDB();
// This is to be used only by internal rocksdb classes.
static Status Open(const DBOptions& db_options, const std::string& name,
@@ -978,20 +947,11 @@ class DBImpl : public DB {
void TEST_WaitForPersistStatsRun(std::function<void()> callback) const;
bool TEST_IsPersistentStatsEnabled() const;
size_t TEST_EstimateInMemoryStatsHistorySize() const;
VersionSet* TEST_GetVersionSet() const { return versions_.get(); }
const std::unordered_set<uint64_t>& TEST_GetFilesGrabbedForPurge() const {
return files_grabbed_for_purge_;
}
#endif // NDEBUG
protected:
const std::string dbname_;
std::string db_id_;
// db_session_id_ is an identifier that gets reset
// every time the DB is opened
std::string db_session_id_;
std::unique_ptr<VersionSet> versions_;
// Flag to check whether we allocated and own the info log file
bool own_info_log_;
@@ -1164,19 +1124,6 @@ class DBImpl : public DB {
virtual bool OwnTablesAndLogs() const { return true; }
// REQUIRES: db mutex held when calling this function, but the db mutex can
// be released and re-acquired. Db mutex will be held when the function
// returns.
// After best-efforts recovery, there may be SST files in db/cf paths that are
// not referenced in the MANIFEST. We delete these SST files. In the
// meantime, we find out the largest file number present in the paths, and
// bump up the version set's next_file_number_ to be 1 + largest_file_number.
Status FinishBestEffortsRecovery();
// SetDbSessionId() should be called in the constuctor DBImpl()
// to ensure that db_session_id_ gets updated every time the DB is opened
void SetDbSessionId();
private:
friend class DB;
friend class ErrorHandler;
@@ -1202,7 +1149,7 @@ class DBImpl : public DB {
friend class StatsHistoryTest_PersistentStatsCreateColumnFamilies_Test;
#ifndef NDEBUG
friend class DBTest2_ReadCallbackTest_Test;
friend class WriteCallbackPTest_WriteWithCallbackTest_Test;
friend class WriteCallbackTest_WriteWithCallbackTest_Test;
friend class XFTransactionWriteHandler;
friend class DBBlobIndexTest;
friend class WriteUnpreparedTransactionTest_RecoveryTest_Test;
@@ -1390,7 +1337,7 @@ class DBImpl : public DB {
void ReleaseFileNumberFromPendingOutputs(
std::unique_ptr<std::list<uint64_t>::iterator>& v);
IOStatus SyncClosedLogs(JobContext* job_context);
Status SyncClosedLogs(JobContext* job_context);
// Flush the in-memory write buffer to storage. Switches to a new
// log-file/memtable and writes a new descriptor iff successful. Then
@@ -1527,25 +1474,21 @@ class DBImpl : public DB {
WriteBatch* tmp_batch, size_t* write_with_wal,
WriteBatch** to_be_cached_state);
IOStatus WriteToWAL(const WriteBatch& merged_batch, log::Writer* log_writer,
uint64_t* log_used, uint64_t* log_size);
Status WriteToWAL(const WriteBatch& merged_batch, log::Writer* log_writer,
uint64_t* log_used, uint64_t* log_size);
IOStatus WriteToWAL(const WriteThread::WriteGroup& write_group,
log::Writer* log_writer, uint64_t* log_used,
bool need_log_sync, bool need_log_dir_sync,
SequenceNumber sequence);
Status WriteToWAL(const WriteThread::WriteGroup& write_group,
log::Writer* log_writer, uint64_t* log_used,
bool need_log_sync, bool need_log_dir_sync,
SequenceNumber sequence);
IOStatus ConcurrentWriteToWAL(const WriteThread::WriteGroup& write_group,
uint64_t* log_used,
SequenceNumber* last_sequence, size_t seq_inc);
Status ConcurrentWriteToWAL(const WriteThread::WriteGroup& write_group,
uint64_t* log_used, SequenceNumber* last_sequence,
size_t seq_inc);
// Used by WriteImpl to update bg_error_ if paranoid check is enabled.
void WriteStatusCheck(const Status& status);
// Used by WriteImpl to update bg_error_ when IO error happens, e.g., write
// WAL, sync WAL fails, if paranoid check is enabled.
void IOStatusCheck(const IOStatus& status);
// Used by WriteImpl to update bg_error_ in case of memtable insert error.
void MemTableInsertStatusCheck(const Status& memtable_insert_status);
@@ -1710,8 +1653,8 @@ class DBImpl : public DB {
size_t GetWalPreallocateBlockSize(uint64_t write_buffer_size) const;
Env::WriteLifeTimeHint CalculateWALWriteHint() { return Env::WLTH_SHORT; }
IOStatus CreateWAL(uint64_t log_file_num, uint64_t recycle_log_number,
size_t preallocate_block_size, log::Writer** new_log);
Status CreateWAL(uint64_t log_file_num, uint64_t recycle_log_number,
size_t preallocate_block_size, log::Writer** new_log);
// Validate self-consistency of DB options
static Status ValidateOptions(const DBOptions& db_options);
@@ -1789,14 +1732,12 @@ class DBImpl : public DB {
// to have acquired the SuperVersion and pass in a snapshot sequence number
// in order to construct the LookupKeys. The start_key and num_keys specify
// the range of keys in the sorted_keys vector for a single column family.
Status MultiGetImpl(
void MultiGetImpl(
const ReadOptions& read_options, size_t start_key, size_t num_keys,
autovector<KeyContext*, MultiGetContext::MAX_BATCH_SIZE>* sorted_keys,
SuperVersion* sv, SequenceNumber snap_seqnum, ReadCallback* callback,
bool* is_blob_index);
Status DisableFileDeletionsWithLock();
// table_cache_ provides its own synchronization
std::shared_ptr<Cache> table_cache_;
@@ -1959,7 +1900,7 @@ class DBImpl : public DB {
std::unordered_map<uint64_t, PurgeFileInfo> purge_files_;
// A vector to store the file numbers that have been assigned to certain
// JobContext. Current implementation tracks table and blob files only.
// JobContext. Current implementation tracks ssts only.
std::unordered_set<uint64_t> files_grabbed_for_purge_;
// A queue to store log writers to close
+48 -134
View File
@@ -79,7 +79,7 @@ bool DBImpl::RequestCompactionToken(ColumnFamilyData* cfd, bool force,
return false;
}
IOStatus DBImpl::SyncClosedLogs(JobContext* job_context) {
Status DBImpl::SyncClosedLogs(JobContext* job_context) {
TEST_SYNC_POINT("DBImpl::SyncClosedLogs:Start");
mutex_.AssertHeld();
autovector<log::Writer*, 1> logs_to_sync;
@@ -96,7 +96,7 @@ IOStatus DBImpl::SyncClosedLogs(JobContext* job_context) {
logs_to_sync.push_back(log.writer);
}
IOStatus io_s;
Status s;
if (!logs_to_sync.empty()) {
mutex_.Unlock();
@@ -104,34 +104,34 @@ IOStatus DBImpl::SyncClosedLogs(JobContext* job_context) {
ROCKS_LOG_INFO(immutable_db_options_.info_log,
"[JOB %d] Syncing log #%" PRIu64, job_context->job_id,
log->get_log_number());
io_s = log->file()->Sync(immutable_db_options_.use_fsync);
if (!io_s.ok()) {
s = log->file()->Sync(immutable_db_options_.use_fsync);
if (!s.ok()) {
break;
}
if (immutable_db_options_.recycle_log_file_num > 0) {
io_s = log->Close();
if (!io_s.ok()) {
s = log->Close();
if (!s.ok()) {
break;
}
}
}
if (io_s.ok()) {
io_s = directories_.GetWalDir()->Fsync(IOOptions(), nullptr);
if (s.ok()) {
s = directories_.GetWalDir()->Fsync(IOOptions(), nullptr);
}
mutex_.Lock();
// "number <= current_log_number - 1" is equivalent to
// "number < current_log_number".
MarkLogsSynced(current_log_number - 1, true, io_s);
if (!io_s.ok()) {
error_handler_.SetBGError(io_s, BackgroundErrorReason::kFlush);
MarkLogsSynced(current_log_number - 1, true, s);
if (!s.ok()) {
error_handler_.SetBGError(s, BackgroundErrorReason::kFlush);
TEST_SYNC_POINT("DBImpl::SyncClosedLogs:Failed");
return io_s;
return s;
}
}
return io_s;
return s;
}
Status DBImpl::FlushMemTableToOutputFile(
@@ -154,8 +154,8 @@ Status DBImpl::FlushMemTableToOutputFile(
GetDataDir(cfd, 0U),
GetCompressionFlush(*cfd->ioptions(), mutable_cf_options), stats_,
&event_logger_, mutable_cf_options.report_bg_io_stats,
true /* sync_output_directory */, true /* write_manifest */, thread_pri,
db_id_, db_session_id_);
true /* sync_output_directory */, true /* write_manifest */, thread_pri);
FileMetaData file_meta;
TEST_SYNC_POINT("DBImpl::FlushMemTableToOutputFile:BeforePickMemtables");
@@ -168,7 +168,6 @@ Status DBImpl::FlushMemTableToOutputFile(
#endif // ROCKSDB_LITE
Status s;
IOStatus io_s;
if (logfile_number_ > 0 &&
versions_->GetColumnFamilySet()->NumberOfColumnFamilies() > 1) {
// If there are more than one column families, we need to make sure that
@@ -177,8 +176,7 @@ Status DBImpl::FlushMemTableToOutputFile(
// flushed SST may contain data from write batches whose updates to
// other column families are missing.
// SyncClosedLogs() may unlock and re-lock the db_mutex.
io_s = SyncClosedLogs(job_context);
s = io_s;
s = SyncClosedLogs(job_context);
} else {
TEST_SYNC_POINT("DBImpl::SyncClosedLogs:Skip");
}
@@ -194,9 +192,6 @@ Status DBImpl::FlushMemTableToOutputFile(
} else {
flush_job.Cancel();
}
if (io_s.ok()) {
io_s = flush_job.io_status();
}
if (s.ok()) {
InstallSuperVersionAndScheduleWork(cfd, superversion_context,
@@ -211,21 +206,8 @@ Status DBImpl::FlushMemTableToOutputFile(
}
if (!s.ok() && !s.IsShutdownInProgress() && !s.IsColumnFamilyDropped()) {
if (!io_s.ok() && !io_s.IsShutdownInProgress() &&
!io_s.IsColumnFamilyDropped()) {
// Error while writing to MANIFEST.
// In fact, versions_->io_status() can also be the result of renaming
// CURRENT file. With current code, it's just difficult to tell. So just
// be pessimistic and try write to a new MANIFEST.
// TODO: distinguish between MANIFEST write and CURRENT renaming
auto err_reason = versions_->io_status().ok()
? BackgroundErrorReason::kFlush
: BackgroundErrorReason::kManifestWrite;
error_handler_.SetBGError(io_s, err_reason);
} else {
Status new_bg_error = s;
error_handler_.SetBGError(new_bg_error, BackgroundErrorReason::kFlush);
}
Status new_bg_error = s;
error_handler_.SetBGError(new_bg_error, BackgroundErrorReason::kFlush);
}
if (s.ok()) {
#ifndef ROCKSDB_LITE
@@ -356,13 +338,12 @@ Status DBImpl::AtomicFlushMemTablesToOutputFiles(
data_dir, GetCompressionFlush(*cfd->ioptions(), mutable_cf_options),
stats_, &event_logger_, mutable_cf_options.report_bg_io_stats,
false /* sync_output_directory */, false /* write_manifest */,
thread_pri, db_id_, db_session_id_));
thread_pri));
jobs.back()->PickMemTable();
}
std::vector<FileMetaData> file_meta(num_cfs);
Status s;
IOStatus io_s;
assert(num_cfs == static_cast<int>(jobs.size()));
#ifndef ROCKSDB_LITE
@@ -377,18 +358,15 @@ Status DBImpl::AtomicFlushMemTablesToOutputFiles(
if (logfile_number_ > 0) {
// TODO (yanqin) investigate whether we should sync the closed logs for
// single column family case.
io_s = SyncClosedLogs(job_context);
s = io_s;
s = SyncClosedLogs(job_context);
}
// exec_status stores the execution status of flush_jobs as
// <bool /* executed */, Status /* status code */>
autovector<std::pair<bool, Status>> exec_status;
autovector<IOStatus> io_status;
for (int i = 0; i != num_cfs; ++i) {
// Initially all jobs are not executed, with status OK.
exec_status.emplace_back(false, Status::OK());
io_status.emplace_back(IOStatus::OK());
}
if (s.ok()) {
@@ -397,7 +375,6 @@ Status DBImpl::AtomicFlushMemTablesToOutputFiles(
exec_status[i].second =
jobs[i]->Run(&logs_with_prep_tracker_, &file_meta[i]);
exec_status[i].first = true;
io_status[i] = jobs[i]->io_status();
}
if (num_cfs > 1) {
TEST_SYNC_POINT(
@@ -410,7 +387,6 @@ Status DBImpl::AtomicFlushMemTablesToOutputFiles(
exec_status[0].second =
jobs[0]->Run(&logs_with_prep_tracker_, &file_meta[0]);
exec_status[0].first = true;
io_status[0] = jobs[0]->io_status();
Status error_status;
for (const auto& e : exec_status) {
@@ -429,20 +405,6 @@ Status DBImpl::AtomicFlushMemTablesToOutputFiles(
s = error_status.ok() ? s : error_status;
}
if (io_s.ok()) {
IOStatus io_error = IOStatus::OK();
for (int i = 0; i != static_cast<int>(io_status.size()); i++) {
if (!io_status[i].ok() && !io_status[i].IsShutdownInProgress() &&
!io_status[i].IsColumnFamilyDropped()) {
io_error = io_status[i];
}
}
io_s = io_error;
if (s.ok() && !io_s.ok()) {
s = io_s;
}
}
if (s.IsColumnFamilyDropped()) {
s = Status::OK();
}
@@ -581,23 +543,9 @@ Status DBImpl::AtomicFlushMemTablesToOutputFiles(
#endif // ROCKSDB_LITE
}
// Need to undo atomic flush if something went wrong, i.e. s is not OK and
// it is not because of CF drop.
if (!s.ok() && !s.IsColumnFamilyDropped()) {
if (!io_s.ok() && !io_s.IsColumnFamilyDropped()) {
// Error while writing to MANIFEST.
// In fact, versions_->io_status() can also be the result of renaming
// CURRENT file. With current code, it's just difficult to tell. So just
// be pessimistic and try write to a new MANIFEST.
// TODO: distinguish between MANIFEST write and CURRENT renaming
auto err_reason = versions_->io_status().ok()
? BackgroundErrorReason::kFlush
: BackgroundErrorReason::kManifestWrite;
error_handler_.SetBGError(io_s, err_reason);
} else {
Status new_bg_error = s;
error_handler_.SetBGError(new_bg_error, BackgroundErrorReason::kFlush);
}
if (!s.ok() && !s.IsShutdownInProgress()) {
Status new_bg_error = s;
error_handler_.SetBGError(new_bg_error, BackgroundErrorReason::kFlush);
}
return s;
@@ -697,7 +645,7 @@ void DBImpl::NotifyOnFlushCompleted(
Status DBImpl::CompactRange(const CompactRangeOptions& options,
ColumnFamilyHandle* column_family,
const Slice* begin, const Slice* end) {
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
auto cfd = cfh->cfd();
if (options.target_path_id >= cfd->ioptions()->cf_paths.size()) {
@@ -887,8 +835,7 @@ Status DBImpl::CompactFiles(const CompactionOptions& compact_options,
return Status::InvalidArgument("ColumnFamilyHandle must be non-null.");
}
auto cfd =
static_cast_with_check<ColumnFamilyHandleImpl>(column_family)->cfd();
auto cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family)->cfd();
assert(cfd);
Status s;
@@ -1021,7 +968,7 @@ Status DBImpl::CompactFilesImpl(
assert(cfd->compaction_picker());
c.reset(cfd->compaction_picker()->CompactFiles(
compact_options, input_files, output_level, version->storage_info(),
*cfd->GetLatestMutableCFOptions(), mutable_db_options_, output_path_id));
*cfd->GetLatestMutableCFOptions(), output_path_id));
// we already sanitized the set of input files and checked for conflicts
// without releasing the lock, so we're guaranteed a compaction can be formed.
assert(c != nullptr);
@@ -1051,8 +998,7 @@ Status DBImpl::CompactFilesImpl(
snapshot_checker, table_cache_, &event_logger_,
c->mutable_cf_options()->paranoid_file_checks,
c->mutable_cf_options()->report_bg_io_stats, dbname_,
&compaction_job_stats, Env::Priority::USER, &manual_compaction_paused_,
db_id_, db_session_id_);
&compaction_job_stats, Env::Priority::USER, &manual_compaction_paused_);
// Creating a compaction influences the compaction score because the score
// takes running compactions into account (by skipping files that are already
@@ -1109,12 +1055,7 @@ Status DBImpl::CompactFilesImpl(
"[%s] [JOB %d] Compaction error: %s",
c->column_family_data()->GetName().c_str(),
job_context->job_id, status.ToString().c_str());
IOStatus io_s = compaction_job.io_status();
if (!io_s.ok()) {
error_handler_.SetBGError(io_s, BackgroundErrorReason::kCompaction);
} else {
error_handler_.SetBGError(status, BackgroundErrorReason::kCompaction);
}
error_handler_.SetBGError(status, BackgroundErrorReason::kCompaction);
}
if (output_file_names != nullptr) {
@@ -1367,7 +1308,7 @@ Status DBImpl::ReFitLevel(ColumnFamilyData* cfd, int level, int target_level) {
}
int DBImpl::NumberLevels(ColumnFamilyHandle* column_family) {
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
return cfh->cfd()->NumberLevels();
}
@@ -1376,7 +1317,7 @@ int DBImpl::MaxMemCompactionLevel(ColumnFamilyHandle* /*column_family*/) {
}
int DBImpl::Level0StopWriteTrigger(ColumnFamilyHandle* column_family) {
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
InstrumentedMutexLock l(&mutex_);
return cfh->cfd()
->GetSuperVersion()
@@ -1385,7 +1326,7 @@ int DBImpl::Level0StopWriteTrigger(ColumnFamilyHandle* column_family) {
Status DBImpl::Flush(const FlushOptions& flush_options,
ColumnFamilyHandle* column_family) {
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
ROCKS_LOG_INFO(immutable_db_options_.info_log, "[%s] Manual flush start.",
cfh->GetName().c_str());
Status s;
@@ -1536,9 +1477,9 @@ Status DBImpl::RunManualCompaction(
scheduled ||
(((manual.manual_end = &manual.tmp_storage1) != nullptr) &&
((compaction = manual.cfd->CompactRange(
*manual.cfd->GetLatestMutableCFOptions(), mutable_db_options_,
manual.input_level, manual.output_level, compact_range_options,
manual.begin, manual.end, &manual.manual_end, &manual_conflict,
*manual.cfd->GetLatestMutableCFOptions(), manual.input_level,
manual.output_level, compact_range_options, manual.begin,
manual.end, &manual.manual_end, &manual_conflict,
max_file_num_to_ignore)) == nullptr &&
manual_conflict))) {
// exclusive manual compactions should not see a conflict during
@@ -1569,12 +1510,7 @@ Status DBImpl::RunManualCompaction(
}
manual.incomplete = false;
bg_compaction_scheduled_++;
Env::Priority thread_pool_pri = Env::Priority::LOW;
if (compaction->bottommost_level() &&
env_->GetBackgroundThreads(Env::Priority::BOTTOM) > 0) {
thread_pool_pri = Env::Priority::BOTTOM;
}
env_->Schedule(&DBImpl::BGWorkCompaction, ca, thread_pool_pri, this,
env_->Schedule(&DBImpl::BGWorkCompaction, ca, Env::Priority::LOW, this,
&DBImpl::UnscheduleCompactionCallback);
scheduled = true;
}
@@ -1932,7 +1868,7 @@ Status DBImpl::WaitForFlushMemTables(
}
}
if (1 == num_dropped && 1 == num) {
return Status::ColumnFamilyDropped();
return Status::InvalidArgument("Cannot flush a dropped CF");
}
// Column families involved in this flush request have either been dropped
// or finished flush. Then it's time to finish waiting.
@@ -2056,7 +1992,7 @@ void DBImpl::MaybeScheduleFlushOrCompaction() {
DBImpl::BGJobLimits DBImpl::GetBGJobLimits() const {
mutex_.AssertHeld();
return GetBGJobLimits(mutable_db_options_.max_background_flushes,
return GetBGJobLimits(immutable_db_options_.max_background_flushes,
mutable_db_options_.max_background_compactions,
mutable_db_options_.max_background_jobs,
write_controller_.NeedSpeedupCompaction());
@@ -2169,7 +2105,8 @@ void DBImpl::BGWorkFlush(void* arg) {
IOSTATS_SET_THREAD_POOL_ID(fta.thread_pri_);
TEST_SYNC_POINT("DBImpl::BGWorkFlush");
static_cast_with_check<DBImpl>(fta.db_)->BackgroundCallFlush(fta.thread_pri_);
static_cast_with_check<DBImpl, DB>(fta.db_)->BackgroundCallFlush(
fta.thread_pri_);
TEST_SYNC_POINT("DBImpl::BGWorkFlush:done");
}
@@ -2180,7 +2117,7 @@ void DBImpl::BGWorkCompaction(void* arg) {
TEST_SYNC_POINT("DBImpl::BGWorkCompaction");
auto prepicked_compaction =
static_cast<PrepickedCompaction*>(ca.prepicked_compaction);
static_cast_with_check<DBImpl>(ca.db)->BackgroundCallCompaction(
static_cast_with_check<DBImpl, DB>(ca.db)->BackgroundCallCompaction(
prepicked_compaction, Env::Priority::LOW);
delete prepicked_compaction;
}
@@ -2574,8 +2511,8 @@ Status DBImpl::BackgroundCompaction(bool* made_progress,
"[%s] Manual compaction from level-%d from %s .. "
"%s; nothing to do\n",
m->cfd->GetName().c_str(), m->input_level,
(m->begin ? m->begin->DebugString(true).c_str() : "(begin)"),
(m->end ? m->end->DebugString(true).c_str() : "(end)"));
(m->begin ? m->begin->DebugString().c_str() : "(begin)"),
(m->end ? m->end->DebugString().c_str() : "(end)"));
} else {
// First check if we have enough room to do the compaction
bool enough_room = EnoughRoomForCompaction(
@@ -2594,11 +2531,11 @@ Status DBImpl::BackgroundCompaction(bool* made_progress,
"[%s] Manual compaction from level-%d to level-%d from %s .. "
"%s; will stop at %s\n",
m->cfd->GetName().c_str(), m->input_level, c->output_level(),
(m->begin ? m->begin->DebugString(true).c_str() : "(begin)"),
(m->end ? m->end->DebugString(true).c_str() : "(end)"),
(m->begin ? m->begin->DebugString().c_str() : "(begin)"),
(m->end ? m->end->DebugString().c_str() : "(end)"),
((m->done || m->manual_end == nullptr)
? "(end)"
: m->manual_end->DebugString(true).c_str()));
: m->manual_end->DebugString().c_str()));
}
}
} else if (!is_prepicked && !compaction_queue_.empty()) {
@@ -2642,8 +2579,7 @@ Status DBImpl::BackgroundCompaction(bool* made_progress,
// compaction is not necessary. Need to make sure mutex is held
// until we make a copy in the following code
TEST_SYNC_POINT("DBImpl::BackgroundCompaction():BeforePickCompaction");
c.reset(cfd->PickCompaction(*mutable_cf_options, mutable_db_options_,
log_buffer));
c.reset(cfd->PickCompaction(*mutable_cf_options, log_buffer));
TEST_SYNC_POINT("DBImpl::BackgroundCompaction():AfterPickCompaction");
if (c != nullptr) {
@@ -2692,7 +2628,6 @@ Status DBImpl::BackgroundCompaction(bool* made_progress,
}
}
IOStatus io_s;
if (!c) {
// Nothing to do
ROCKS_LOG_BUFFER(log_buffer, "Compaction nothing to do");
@@ -2717,7 +2652,6 @@ Status DBImpl::BackgroundCompaction(bool* made_progress,
status = versions_->LogAndApply(c->column_family_data(),
*c->mutable_cf_options(), c->edit(),
&mutex_, directories_.GetDbDir());
io_s = versions_->io_status();
InstallSuperVersionAndScheduleWork(c->column_family_data(),
&job_context->superversion_contexts[0],
*c->mutable_cf_options());
@@ -2774,7 +2708,6 @@ Status DBImpl::BackgroundCompaction(bool* made_progress,
status = versions_->LogAndApply(c->column_family_data(),
*c->mutable_cf_options(), c->edit(),
&mutex_, directories_.GetDbDir());
io_s = versions_->io_status();
// Use latest MutableCFOptions
InstallSuperVersionAndScheduleWork(c->column_family_data(),
&job_context->superversion_contexts[0],
@@ -2847,8 +2780,7 @@ Status DBImpl::BackgroundCompaction(bool* made_progress,
&event_logger_, c->mutable_cf_options()->paranoid_file_checks,
c->mutable_cf_options()->report_bg_io_stats, dbname_,
&compaction_job_stats, thread_pri,
is_manual ? &manual_compaction_paused_ : nullptr, db_id_,
db_session_id_);
is_manual ? &manual_compaction_paused_ : nullptr);
compaction_job.Prepare();
NotifyOnCompactionBegin(c->column_family_data(), c.get(), status,
@@ -2862,7 +2794,6 @@ Status DBImpl::BackgroundCompaction(bool* made_progress,
mutex_.Lock();
status = compaction_job.Install(*c->mutable_cf_options());
io_s = compaction_job.io_status();
if (status.ok()) {
InstallSuperVersionAndScheduleWork(c->column_family_data(),
&job_context->superversion_contexts[0],
@@ -2872,11 +2803,6 @@ Status DBImpl::BackgroundCompaction(bool* made_progress,
TEST_SYNC_POINT_CALLBACK("DBImpl::BackgroundCompaction:AfterCompaction",
c->column_family_data());
}
if (status.ok() && !io_s.ok()) {
status = io_s;
}
if (c != nullptr) {
c->ReleaseCompactionFiles(status);
*made_progress = true;
@@ -2902,19 +2828,7 @@ Status DBImpl::BackgroundCompaction(bool* made_progress,
} else {
ROCKS_LOG_WARN(immutable_db_options_.info_log, "Compaction error: %s",
status.ToString().c_str());
if (!io_s.ok()) {
// Error while writing to MANIFEST.
// In fact, versions_->io_status() can also be the result of renaming
// CURRENT file. With current code, it's just difficult to tell. So just
// be pessimistic and try write to a new MANIFEST.
// TODO: distinguish between MANIFEST write and CURRENT renaming
auto err_reason = versions_->io_status().ok()
? BackgroundErrorReason::kCompaction
: BackgroundErrorReason::kManifestWrite;
error_handler_.SetBGError(io_s, err_reason);
} else {
error_handler_.SetBGError(status, BackgroundErrorReason::kCompaction);
}
error_handler_.SetBGError(status, BackgroundErrorReason::kCompaction);
if (c != nullptr && !is_manual && !error_handler_.IsBGWorkStopped()) {
// Put this cfd back in the compaction queue so we can retry after some
// time
+6 -6
View File
@@ -47,7 +47,7 @@ int64_t DBImpl::TEST_MaxNextLevelOverlappingBytes(
if (column_family == nullptr) {
cfd = default_cf_handle_->cfd();
} else {
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
cfd = cfh->cfd();
}
InstrumentedMutexLock l(&mutex_);
@@ -57,7 +57,7 @@ int64_t DBImpl::TEST_MaxNextLevelOverlappingBytes(
void DBImpl::TEST_GetFilesMetaData(
ColumnFamilyHandle* column_family,
std::vector<std::vector<FileMetaData>>* metadata) {
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
auto cfd = cfh->cfd();
InstrumentedMutexLock l(&mutex_);
metadata->resize(NumberLevels());
@@ -88,7 +88,7 @@ Status DBImpl::TEST_CompactRange(int level, const Slice* begin,
if (column_family == nullptr) {
cfd = default_cf_handle_->cfd();
} else {
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
cfd = cfh->cfd();
}
int output_level =
@@ -131,7 +131,7 @@ Status DBImpl::TEST_FlushMemTable(bool wait, bool allow_write_stall,
if (cfh == nullptr) {
cfd = default_cf_handle_->cfd();
} else {
auto cfhi = static_cast_with_check<ColumnFamilyHandleImpl>(cfh);
auto cfhi = reinterpret_cast<ColumnFamilyHandleImpl*>(cfh);
cfd = cfhi->cfd();
}
return FlushMemTable(cfd, fo, FlushReason::kTest);
@@ -152,7 +152,7 @@ Status DBImpl::TEST_WaitForFlushMemTable(ColumnFamilyHandle* column_family) {
if (column_family == nullptr) {
cfd = default_cf_handle_->cfd();
} else {
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
cfd = cfh->cfd();
}
return WaitForFlushMemTable(cfd, nullptr, false);
@@ -242,7 +242,7 @@ Status DBImpl::TEST_GetLatestMutableCFOptions(
ColumnFamilyHandle* column_family, MutableCFOptions* mutable_cf_options) {
InstrumentedMutexLock l(&mutex_);
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
*mutable_cf_options = *cfh->cfd()->GetLatestMutableCFOptions();
return Status::OK();
}
+3 -3
View File
@@ -7,22 +7,22 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#include "db/db_impl/db_impl.h"
#include <cinttypes>
#include <vector>
#include "db/column_family.h"
#include "db/db_impl/db_impl.h"
#include "db/job_context.h"
#include "db/version_set.h"
#include "rocksdb/status.h"
#include "util/cast_util.h"
namespace ROCKSDB_NAMESPACE {
#ifndef ROCKSDB_LITE
Status DBImpl::SuggestCompactRange(ColumnFamilyHandle* column_family,
const Slice* begin, const Slice* end) {
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
auto cfd = cfh->cfd();
InternalKey start_key, end_key;
if (begin != nullptr) {
+26 -169
View File
@@ -14,7 +14,6 @@
#include "db/event_helpers.h"
#include "db/memtable_list.h"
#include "file/file_util.h"
#include "file/filename.h"
#include "file/sst_file_manager_impl.h"
#include "util/autovector.h"
@@ -36,63 +35,7 @@ uint64_t DBImpl::MinObsoleteSstNumberToKeep() {
return std::numeric_limits<uint64_t>::max();
}
Status DBImpl::DisableFileDeletions() {
InstrumentedMutexLock l(&mutex_);
return DisableFileDeletionsWithLock();
}
Status DBImpl::DisableFileDeletionsWithLock() {
mutex_.AssertHeld();
++disable_delete_obsolete_files_;
if (disable_delete_obsolete_files_ == 1) {
ROCKS_LOG_INFO(immutable_db_options_.info_log, "File Deletions Disabled");
} else {
ROCKS_LOG_WARN(immutable_db_options_.info_log,
"File Deletions Disabled, but already disabled. Counter: %d",
disable_delete_obsolete_files_);
}
return Status::OK();
}
Status DBImpl::EnableFileDeletions(bool force) {
// Job id == 0 means that this is not our background process, but rather
// user thread
JobContext job_context(0);
bool file_deletion_enabled = false;
{
InstrumentedMutexLock l(&mutex_);
if (force) {
// if force, we need to enable file deletions right away
disable_delete_obsolete_files_ = 0;
} else if (disable_delete_obsolete_files_ > 0) {
--disable_delete_obsolete_files_;
}
if (disable_delete_obsolete_files_ == 0) {
file_deletion_enabled = true;
FindObsoleteFiles(&job_context, true);
bg_cv_.SignalAll();
}
}
if (file_deletion_enabled) {
ROCKS_LOG_INFO(immutable_db_options_.info_log, "File Deletions Enabled");
if (job_context.HaveSomethingToDelete()) {
PurgeObsoleteFiles(job_context);
}
} else {
ROCKS_LOG_WARN(immutable_db_options_.info_log,
"File Deletions Enable, but not really enabled. Counter: %d",
disable_delete_obsolete_files_);
}
job_context.Clean();
LogFlush(immutable_db_options_.info_log);
return Status::OK();
}
bool DBImpl::IsFileDeletionsEnabled() const {
return 0 == disable_delete_obsolete_files_;
}
// * Returns the list of live files in 'sst_live' and 'blob_live'.
// * Returns the list of live files in 'sst_live'
// If it's doing full scan:
// * Returns the list of all files in the filesystem in
// 'full_scan_candidate_files'.
@@ -133,26 +76,26 @@ void DBImpl::FindObsoleteFiles(JobContext* job_context, bool force,
// Since job_context->min_pending_output is set, until file scan finishes,
// mutex_ cannot be released. Otherwise, we might see no min_pending_output
// here but later find newer generated unfinalized files while scanning.
job_context->min_pending_output = MinObsoleteSstNumberToKeep();
if (!pending_outputs_.empty()) {
job_context->min_pending_output = *pending_outputs_.begin();
} else {
// delete all of them
job_context->min_pending_output = std::numeric_limits<uint64_t>::max();
}
// Get obsolete files. This function will also update the list of
// pending files in VersionSet().
versions_->GetObsoleteFiles(
&job_context->sst_delete_files, &job_context->blob_delete_files,
&job_context->manifest_delete_files, job_context->min_pending_output);
versions_->GetObsoleteFiles(&job_context->sst_delete_files,
&job_context->manifest_delete_files,
job_context->min_pending_output);
// Mark the elements in job_context->sst_delete_files and
// job_context->blob_delete_files as "grabbed for purge" so that other threads
// calling FindObsoleteFiles with full_scan=true will not add these files to
// candidate list for purge.
// Mark the elements in job_context->sst_delete_files as grabbedForPurge
// so that other threads calling FindObsoleteFiles with full_scan=true
// will not add these files to candidate list for purge.
for (const auto& sst_to_del : job_context->sst_delete_files) {
MarkAsGrabbedForPurge(sst_to_del.metadata->fd.GetNumber());
}
for (const auto& blob_file : job_context->blob_delete_files) {
MarkAsGrabbedForPurge(blob_file.GetBlobFileNumber());
}
// store the current filenum, lognum, etc
job_context->manifest_file_number = versions_->manifest_file_number();
job_context->pending_manifest_file_number =
@@ -160,7 +103,7 @@ void DBImpl::FindObsoleteFiles(JobContext* job_context, bool force,
job_context->log_number = MinLogNumberToKeep();
job_context->prev_log_number = versions_->prev_log_number();
versions_->AddLiveFiles(&job_context->sst_live, &job_context->blob_live);
versions_->AddLiveFiles(&job_context->sst_live);
if (doing_the_full_scan) {
InfoLogPrefix info_log_prefix(!immutable_db_options_.db_log_dir.empty(),
dbname_);
@@ -190,7 +133,7 @@ void DBImpl::FindObsoleteFiles(JobContext* job_context, bool force,
// set of all files in the directory. We'll exclude files that are still
// alive in the subsequent processings.
std::vector<std::string> files;
env_->GetChildren(path, &files).PermitUncheckedError(); // Ignore errors
env_->GetChildren(path, &files); // Ignore errors
for (const std::string& file : files) {
uint64_t number;
FileType type;
@@ -313,11 +256,8 @@ bool CompareCandidateFile(const JobContext::CandidateFileInfo& first,
void DBImpl::DeleteObsoleteFileImpl(int job_id, const std::string& fname,
const std::string& path_to_sync,
FileType type, uint64_t number) {
TEST_SYNC_POINT_CALLBACK("DBImpl::DeleteObsoleteFileImpl::BeforeDeletion",
const_cast<std::string*>(&fname));
Status file_deletion_status;
if (type == kTableFile || type == kBlobFile || type == kLogFile) {
if (type == kTableFile || type == kLogFile) {
file_deletion_status =
DeleteDBFile(&immutable_db_options_, fname, path_to_sync,
/*force_bg=*/false, /*force_fg=*/!wal_in_db_path_);
@@ -363,19 +303,19 @@ void DBImpl::PurgeObsoleteFiles(JobContext& state, bool schedule_only) {
// FindObsoleteFiles() should've populated this so nonzero
assert(state.manifest_file_number != 0);
// Now, convert lists to unordered sets, WITHOUT mutex held; set is slow.
std::unordered_set<uint64_t> sst_live_set(state.sst_live.begin(),
state.sst_live.end());
std::unordered_set<uint64_t> blob_live_set(state.blob_live.begin(),
state.blob_live.end());
// Now, convert live list to an unordered map, WITHOUT mutex held;
// set is slow.
std::unordered_map<uint64_t, const FileDescriptor*> sst_live_map;
for (const FileDescriptor& fd : state.sst_live) {
sst_live_map[fd.GetNumber()] = &fd;
}
std::unordered_set<uint64_t> log_recycle_files_set(
state.log_recycle_files.begin(), state.log_recycle_files.end());
auto candidate_files = state.full_scan_candidate_files;
candidate_files.reserve(
candidate_files.size() + state.sst_delete_files.size() +
state.blob_delete_files.size() + state.log_delete_files.size() +
state.manifest_delete_files.size());
state.log_delete_files.size() + state.manifest_delete_files.size());
// We may ignore the dbname when generating the file names.
for (auto& file : state.sst_delete_files) {
candidate_files.emplace_back(
@@ -386,11 +326,6 @@ void DBImpl::PurgeObsoleteFiles(JobContext& state, bool schedule_only) {
file.DeleteMetadata();
}
for (const auto& blob_file : state.blob_delete_files) {
candidate_files.emplace_back(BlobFileName(blob_file.GetBlobFileNumber()),
blob_file.GetPath());
}
for (auto file_num : state.log_delete_files) {
if (file_num > 0) {
candidate_files.emplace_back(LogFileName(file_num),
@@ -477,19 +412,12 @@ void DBImpl::PurgeObsoleteFiles(JobContext& state, bool schedule_only) {
case kTableFile:
// If the second condition is not there, this makes
// DontDeletePendingOutputs fail
keep = (sst_live_set.find(number) != sst_live_set.end()) ||
keep = (sst_live_map.find(number) != sst_live_map.end()) ||
number >= state.min_pending_output;
if (!keep) {
files_to_del.insert(number);
}
break;
case kBlobFile:
keep = number >= state.min_pending_output ||
(blob_live_set.find(number) != blob_live_set.end());
if (!keep) {
files_to_del.insert(number);
}
break;
case kTempFile:
// Any temp files that are currently being written to must
// be recorded in pending_outputs_, which is inserted into "live".
@@ -499,8 +427,7 @@ void DBImpl::PurgeObsoleteFiles(JobContext& state, bool schedule_only) {
//
// TODO(yhchiang): carefully modify the third condition to safely
// remove the temp options files.
keep = (sst_live_set.find(number) != sst_live_set.end()) ||
(blob_live_set.find(number) != blob_live_set.end()) ||
keep = (sst_live_map.find(number) != sst_live_map.end()) ||
(number == state.pending_manifest_file_number) ||
(to_delete.find(kOptionsFileNamePrefix) != std::string::npos);
break;
@@ -523,6 +450,7 @@ void DBImpl::PurgeObsoleteFiles(JobContext& state, bool schedule_only) {
case kDBLockFile:
case kIdentityFile:
case kMetaDatabase:
case kBlobFile:
keep = true;
break;
}
@@ -538,9 +466,6 @@ void DBImpl::PurgeObsoleteFiles(JobContext& state, bool schedule_only) {
TableCache::Evict(table_cache_.get(), number);
fname = MakeTableFileName(candidate_file.file_path, number);
dir_to_sync = candidate_file.file_path;
} else if (type == kBlobFile) {
fname = BlobFileName(candidate_file.file_path, number);
dir_to_sync = candidate_file.file_path;
} else {
dir_to_sync =
(type == kLogFile) ? immutable_db_options_.wal_dir : dbname_;
@@ -739,72 +664,4 @@ uint64_t PrecomputeMinLogNumberToKeep(
return min_log_number_to_keep;
}
Status DBImpl::FinishBestEffortsRecovery() {
mutex_.AssertHeld();
std::vector<std::string> paths;
paths.push_back(NormalizePath(dbname_ + std::string(1, kFilePathSeparator)));
for (const auto& db_path : immutable_db_options_.db_paths) {
paths.push_back(
NormalizePath(db_path.path + std::string(1, kFilePathSeparator)));
}
for (const auto* cfd : *versions_->GetColumnFamilySet()) {
for (const auto& cf_path : cfd->ioptions()->cf_paths) {
paths.push_back(
NormalizePath(cf_path.path + std::string(1, kFilePathSeparator)));
}
}
// Dedup paths
std::sort(paths.begin(), paths.end());
paths.erase(std::unique(paths.begin(), paths.end()), paths.end());
uint64_t next_file_number = versions_->current_next_file_number();
uint64_t largest_file_number = next_file_number;
std::set<std::string> files_to_delete;
for (const auto& path : paths) {
std::vector<std::string> files;
env_->GetChildren(path, &files);
for (const auto& fname : files) {
uint64_t number = 0;
FileType type;
if (!ParseFileName(fname, &number, &type)) {
continue;
}
// path ends with '/' or '\\'
const std::string normalized_fpath = path + fname;
largest_file_number = std::max(largest_file_number, number);
if (type == kTableFile && number >= next_file_number &&
files_to_delete.find(normalized_fpath) == files_to_delete.end()) {
files_to_delete.insert(normalized_fpath);
}
}
}
if (largest_file_number > next_file_number) {
versions_->next_file_number_.store(largest_file_number + 1);
}
VersionEdit edit;
edit.SetNextFile(versions_->next_file_number_.load());
assert(versions_->GetColumnFamilySet());
ColumnFamilyData* default_cfd = versions_->GetColumnFamilySet()->GetDefault();
assert(default_cfd);
// Even if new_descriptor_log is false, we will still switch to a new
// MANIFEST and update CURRENT file, since this is in recovery.
Status s = versions_->LogAndApply(
default_cfd, *default_cfd->GetLatestMutableCFOptions(), &edit, &mutex_,
directories_.GetDbDir(), /*new_descriptor_log*/ false);
if (!s.ok()) {
return s;
}
mutex_.Unlock();
for (const auto& fname : files_to_delete) {
s = env_->DeleteFile(fname);
if (!s.ok()) {
break;
}
}
mutex_.Lock();
return s;
}
} // namespace ROCKSDB_NAMESPACE
+43 -126
View File
@@ -35,8 +35,16 @@ Options SanitizeOptions(const std::string& dbname, const Options& src) {
DBOptions SanitizeOptions(const std::string& dbname, const DBOptions& src) {
DBOptions result(src);
if (result.env == nullptr) {
result.env = Env::Default();
if (result.file_system == nullptr) {
if (result.env == Env::Default()) {
result.file_system = FileSystem::Default();
} else {
result.file_system.reset(new LegacyFileSystemWrapper(result.env));
}
} else {
if (result.env == nullptr) {
result.env = Env::Default();
}
}
// result.max_open_files means an "infinite" open files.
@@ -244,16 +252,10 @@ Status DBImpl::ValidateOptions(const DBOptions& db_options) {
"atomic_flush is incompatible with enable_pipelined_write");
}
// TODO remove this restriction
if (db_options.atomic_flush && db_options.best_efforts_recovery) {
return Status::InvalidArgument(
"atomic_flush is currently incompatible with best-efforts recovery");
}
return Status::OK();
}
Status DBImpl::NewDB(std::vector<std::string>* new_filenames) {
Status DBImpl::NewDB() {
VersionEdit new_db;
Status s = SetIdentityFile(env_, dbname_);
if (!s.ok()) {
@@ -292,11 +294,7 @@ Status DBImpl::NewDB(std::vector<std::string>* new_filenames) {
}
if (s.ok()) {
// Make "CURRENT" file that points to the new manifest file.
s = SetCurrentFile(fs_.get(), dbname_, 1, directories_.GetDbDir());
if (new_filenames) {
new_filenames->emplace_back(
manifest.substr(manifest.find_last_of("/\\") + 1));
}
s = SetCurrentFile(env_, dbname_, 1, directories_.GetDbDir());
} else {
fs_->DeleteFile(manifest, IOOptions(), nullptr);
}
@@ -360,7 +358,6 @@ Status DBImpl::Recover(
bool is_new_db = false;
assert(db_lock_ == nullptr);
std::vector<std::string> files_in_dbname;
if (!read_only) {
Status s = directories_.SetDirectories(fs_.get(), dbname_,
immutable_db_options_.wal_dir,
@@ -375,35 +372,10 @@ Status DBImpl::Recover(
}
std::string current_fname = CurrentFileName(dbname_);
// Path to any MANIFEST file in the db dir. It does not matter which one.
// Since best-efforts recovery ignores CURRENT file, existence of a
// MANIFEST indicates the recovery to recover existing db. If no MANIFEST
// can be found, a new db will be created.
std::string manifest_path;
if (!immutable_db_options_.best_efforts_recovery) {
s = env_->FileExists(current_fname);
} else {
s = Status::NotFound();
Status io_s = env_->GetChildren(dbname_, &files_in_dbname);
if (!io_s.ok()) {
s = io_s;
files_in_dbname.clear();
}
for (const std::string& file : files_in_dbname) {
uint64_t number = 0;
FileType type = kLogFile; // initialize
if (ParseFileName(file, &number, &type) && type == kDescriptorFile) {
// Found MANIFEST (descriptor log), thus best-efforts recovery does
// not have to treat the db as empty.
s = Status::OK();
manifest_path = dbname_ + "/" + file;
break;
}
}
}
s = env_->FileExists(current_fname);
if (s.IsNotFound()) {
if (immutable_db_options_.create_if_missing) {
s = NewDB(&files_in_dbname);
s = NewDB();
is_new_db = true;
if (!s.ok()) {
return s;
@@ -428,14 +400,14 @@ Status DBImpl::Recover(
FileOptions customized_fs(file_options_);
customized_fs.use_direct_reads |=
immutable_db_options_.use_direct_io_for_flush_and_compaction;
const std::string& fname =
manifest_path.empty() ? current_fname : manifest_path;
s = fs_->NewRandomAccessFile(fname, customized_fs, &idfile, nullptr);
s = fs_->NewRandomAccessFile(current_fname, customized_fs, &idfile,
nullptr);
if (!s.ok()) {
std::string error_str = s.ToString();
// Check if unsupported Direct I/O is the root cause
customized_fs.use_direct_reads = false;
s = fs_->NewRandomAccessFile(fname, customized_fs, &idfile, nullptr);
s = fs_->NewRandomAccessFile(current_fname, customized_fs, &idfile,
nullptr);
if (s.ok()) {
return Status::InvalidArgument(
"Direct I/O is not supported by the specified DB.");
@@ -445,33 +417,9 @@ Status DBImpl::Recover(
}
}
}
} else if (immutable_db_options_.best_efforts_recovery) {
assert(files_in_dbname.empty());
Status s = env_->GetChildren(dbname_, &files_in_dbname);
if (s.IsNotFound()) {
return Status::InvalidArgument(dbname_,
"does not exist (open for read only)");
} else if (s.IsIOError()) {
return s;
}
assert(s.ok());
}
assert(db_id_.empty());
Status s;
bool missing_table_file = false;
if (!immutable_db_options_.best_efforts_recovery) {
s = versions_->Recover(column_families, read_only, &db_id_);
} else {
assert(!files_in_dbname.empty());
s = versions_->TryRecover(column_families, read_only, files_in_dbname,
&db_id_, &missing_table_file);
if (s.ok()) {
// TryRecover may delete previous column_family_set_.
column_family_memtables_.reset(
new ColumnFamilyMemTablesImpl(versions_->GetColumnFamilySet()));
s = FinishBestEffortsRecovery();
}
}
Status s = versions_->Recover(column_families, read_only, &db_id_);
if (!s.ok()) {
return s;
}
@@ -524,7 +472,6 @@ Status DBImpl::Recover(
s = InitPersistStatsColumnFamily();
}
std::vector<std::string> files_in_wal_dir;
if (s.ok()) {
// Initial max_total_in_memory_state_ before recovery logs. Log recovery
// may check this value to decide whether to flush.
@@ -551,9 +498,8 @@ Status DBImpl::Recover(
// Note that prev_log_number() is no longer used, but we pay
// attention to it in case we are recovering a database
// produced by an older version of rocksdb.
if (!immutable_db_options_.best_efforts_recovery) {
s = env_->GetChildren(immutable_db_options_.wal_dir, &files_in_wal_dir);
}
std::vector<std::string> filenames;
s = env_->GetChildren(immutable_db_options_.wal_dir, &filenames);
if (s.IsNotFound()) {
return Status::InvalidArgument("wal_dir not found",
immutable_db_options_.wal_dir);
@@ -562,15 +508,15 @@ Status DBImpl::Recover(
}
std::vector<uint64_t> logs;
for (const auto& file : files_in_wal_dir) {
for (size_t i = 0; i < filenames.size(); i++) {
uint64_t number;
FileType type;
if (ParseFileName(file, &number, &type) && type == kLogFile) {
if (ParseFileName(filenames[i], &number, &type) && type == kLogFile) {
if (is_new_db) {
return Status::Corruption(
"While creating a new Db, wal_dir contains "
"existing log file: ",
file);
filenames[i]);
} else {
logs.push_back(number);
}
@@ -622,24 +568,15 @@ Status DBImpl::Recover(
// to reflect the most recent OPTIONS file. It does not matter for regular
// read-write db instance because options_file_number_ will later be
// updated to versions_->NewFileNumber() in RenameTempFileToOptionsFile.
std::vector<std::string> filenames;
std::vector<std::string> file_names;
if (s.ok()) {
const std::string normalized_dbname = NormalizePath(dbname_);
const std::string normalized_wal_dir =
NormalizePath(immutable_db_options_.wal_dir);
if (immutable_db_options_.best_efforts_recovery) {
filenames = std::move(files_in_dbname);
} else if (normalized_dbname == normalized_wal_dir) {
filenames = std::move(files_in_wal_dir);
} else {
s = env_->GetChildren(GetName(), &filenames);
}
s = env_->GetChildren(GetName(), &file_names);
}
if (s.ok()) {
uint64_t number = 0;
uint64_t options_file_number = 0;
FileType type;
for (const auto& fname : filenames) {
for (const auto& fname : file_names) {
if (ParseFileName(fname, &number, &type) && type == kOptionsFile) {
options_file_number = std::max(number, options_file_number);
}
@@ -647,6 +584,7 @@ Status DBImpl::Recover(
versions_->options_file_number_ = options_file_number;
}
}
return s;
}
@@ -753,10 +691,10 @@ Status DBImpl::RecoverLogFiles(const std::vector<uint64_t>& log_numbers,
Status* status; // nullptr if immutable_db_options_.paranoid_checks==false
void Corruption(size_t bytes, const Status& s) override {
ROCKS_LOG_WARN(info_log, "%s%s: dropping %d bytes; %s",
(status == nullptr ? "(ignoring error) " : ""), fname,
static_cast<int>(bytes), s.ToString().c_str());
if (status != nullptr && status->ok()) {
*status = s;
(this->status == nullptr ? "(ignoring error) " : ""),
fname, static_cast<int>(bytes), s.ToString().c_str());
if (this->status != nullptr && this->status->ok()) {
*this->status = s;
}
}
};
@@ -879,8 +817,6 @@ Status DBImpl::RecoverLogFiles(const std::vector<uint64_t>& log_numbers,
Slice record;
WriteBatch batch;
TEST_SYNC_POINT_CALLBACK("DBImpl::RecoverLogFiles:BeforeReadWal",
/*arg=*/nullptr);
while (!stop_replay_by_wal_filter &&
reader.ReadRecord(&record, &scratch,
immutable_db_options_.wal_recovery_mode) &&
@@ -1045,16 +981,6 @@ Status DBImpl::RecoverLogFiles(const std::vector<uint64_t>& log_numbers,
status = Status::OK();
} else if (immutable_db_options_.wal_recovery_mode ==
WALRecoveryMode::kPointInTimeRecovery) {
if (status.IsIOError()) {
ROCKS_LOG_ERROR(immutable_db_options_.info_log,
"IOError during point-in-time reading log #%" PRIu64
" seq #%" PRIu64
". %s. This likely mean loss of synced WAL, "
"thus recovery fails.",
log_number, *next_sequence,
status.ToString().c_str());
return status;
}
// We should ignore the error but not continue replaying
status = Status::OK();
stop_replay_for_corruption = true;
@@ -1303,7 +1229,6 @@ Status DBImpl::WriteLevel0TableForRecovery(int job_id, ColumnFamilyData* cfd,
if (range_del_iter != nullptr) {
range_del_iters.emplace_back(range_del_iter);
}
IOStatus io_s;
s = BuildTable(
dbname_, env_, fs_.get(), *cfd->ioptions(), mutable_cf_options,
file_options_for_compaction_, cfd->table_cache(), iter.get(),
@@ -1312,11 +1237,10 @@ Status DBImpl::WriteLevel0TableForRecovery(int job_id, ColumnFamilyData* cfd,
snapshot_seqs, earliest_write_conflict_snapshot, snapshot_checker,
GetCompressionFlush(*cfd->ioptions(), mutable_cf_options),
mutable_cf_options.sample_for_compression,
mutable_cf_options.compression_opts, paranoid_file_checks,
cfd->internal_stats(), TableFileCreationReason::kRecovery, &io_s,
cfd->ioptions()->compression_opts, paranoid_file_checks,
cfd->internal_stats(), TableFileCreationReason::kRecovery,
&event_logger_, job_id, Env::IO_HIGH, nullptr /* table_properties */,
-1 /* level */, current_time, 0 /* oldest_key_time */, write_hint,
0 /* file_creation_time */, db_id_, db_session_id_);
-1 /* level */, current_time, write_hint);
LogFlush(immutable_db_options_.info_log);
ROCKS_LOG_DEBUG(immutable_db_options_.info_log,
"[%s] [WriteLevel0TableForRecovery]"
@@ -1388,10 +1312,9 @@ Status DB::Open(const DBOptions& db_options, const std::string& dbname,
!kSeqPerBatch, kBatchPerTxn);
}
IOStatus DBImpl::CreateWAL(uint64_t log_file_num, uint64_t recycle_log_number,
size_t preallocate_block_size,
log::Writer** new_log) {
IOStatus io_s;
Status DBImpl::CreateWAL(uint64_t log_file_num, uint64_t recycle_log_number,
size_t preallocate_block_size, log::Writer** new_log) {
Status s;
std::unique_ptr<FSWritableFile> lfile;
DBOptions db_options =
@@ -1409,13 +1332,13 @@ IOStatus DBImpl::CreateWAL(uint64_t log_file_num, uint64_t recycle_log_number,
LogFileName(immutable_db_options_.wal_dir, recycle_log_number);
TEST_SYNC_POINT("DBImpl::CreateWAL:BeforeReuseWritableFile1");
TEST_SYNC_POINT("DBImpl::CreateWAL:BeforeReuseWritableFile2");
io_s = fs_->ReuseWritableFile(log_fname, old_log_fname, opt_file_options,
&lfile, /*dbg=*/nullptr);
s = fs_->ReuseWritableFile(log_fname, old_log_fname, opt_file_options,
&lfile, /*dbg=*/nullptr);
} else {
io_s = NewWritableFile(fs_.get(), log_fname, &lfile, opt_file_options);
s = NewWritableFile(fs_.get(), log_fname, &lfile, opt_file_options);
}
if (io_s.ok()) {
if (s.ok()) {
lfile->SetWriteLifeTimeHint(CalculateWALWriteHint());
lfile->SetPreallocationBlockSize(preallocate_block_size);
@@ -1427,7 +1350,7 @@ IOStatus DBImpl::CreateWAL(uint64_t log_file_num, uint64_t recycle_log_number,
immutable_db_options_.recycle_log_file_num > 0,
immutable_db_options_.manual_wal_flush);
}
return io_s;
return s;
}
Status DBImpl::Open(const DBOptions& db_options, const std::string& dbname,
@@ -1632,12 +1555,6 @@ Status DBImpl::Open(const DBOptions& db_options, const std::string& dbname,
auto sfm = static_cast<SstFileManagerImpl*>(
impl->immutable_db_options_.sst_file_manager.get());
if (s.ok() && sfm) {
// Set Statistics ptr for SstFileManager to dump the stats of
// DeleteScheduler.
sfm->SetStatisticsPtr(impl->immutable_db_options_.statistics);
ROCKS_LOG_INFO(impl->immutable_db_options_.info_log,
"SstFileManager instance %p", sfm);
// Notify SstFileManager about all sst files that already exist in
// db_paths[0] and cf_paths[0] when the DB is opened.
+9 -55
View File
@@ -4,14 +4,13 @@
// (found in the LICENSE.Apache file in the root directory).
#include "db/db_impl/db_impl_readonly.h"
#include "db/arena_wrapped_db_iter.h"
#include "db/compacted_db_impl.h"
#include "db/db_impl/db_impl.h"
#include "db/db_iter.h"
#include "db/merge_context.h"
#include "monitoring/perf_context_imp.h"
#include "util/cast_util.h"
namespace ROCKSDB_NAMESPACE {
@@ -36,7 +35,7 @@ Status DBImplReadOnly::Get(const ReadOptions& read_options,
PERF_TIMER_GUARD(get_snapshot_time);
Status s;
SequenceNumber snapshot = versions_->LastSequence();
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
auto cfd = cfh->cfd();
if (tracer_) {
InstrumentedMutexLock lock(&trace_mutex_);
@@ -71,7 +70,7 @@ Status DBImplReadOnly::Get(const ReadOptions& read_options,
Iterator* DBImplReadOnly::NewIterator(const ReadOptions& read_options,
ColumnFamilyHandle* column_family) {
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
auto cfd = cfh->cfd();
SuperVersion* super_version = cfd->GetSuperVersion()->Ref();
SequenceNumber latest_snapshot = versions_->LastSequence();
@@ -88,8 +87,7 @@ Iterator* DBImplReadOnly::NewIterator(const ReadOptions& read_options,
super_version->version_number, read_callback);
auto internal_iter =
NewInternalIterator(read_options, cfd, super_version, db_iter->GetArena(),
db_iter->GetRangeDelAggregator(), read_seq,
/* allow_unprepared_value */ true);
db_iter->GetRangeDelAggregator(), read_seq);
db_iter->SetIterUnderDBIter(internal_iter);
return db_iter;
}
@@ -112,7 +110,7 @@ Status DBImplReadOnly::NewIterators(
: latest_snapshot;
for (auto cfh : column_families) {
auto* cfd = static_cast_with_check<ColumnFamilyHandleImpl>(cfh)->cfd();
auto* cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(cfh)->cfd();
auto* sv = cfd->GetSuperVersion()->Ref();
auto* db_iter = NewArenaWrappedDbIterator(
env_, read_options, *cfd->ioptions(), sv->mutable_cf_options, read_seq,
@@ -120,8 +118,7 @@ Status DBImplReadOnly::NewIterators(
sv->version_number, read_callback);
auto* internal_iter =
NewInternalIterator(read_options, cfd, sv, db_iter->GetArena(),
db_iter->GetRangeDelAggregator(), read_seq,
/* allow_unprepared_value */ true);
db_iter->GetRangeDelAggregator(), read_seq);
db_iter->SetIterUnderDBIter(internal_iter);
iterators->push_back(db_iter);
}
@@ -129,38 +126,12 @@ Status DBImplReadOnly::NewIterators(
return Status::OK();
}
namespace {
// Return OK if dbname exists in the file system
// or create_if_missing is false
Status OpenForReadOnlyCheckExistence(const DBOptions& db_options,
const std::string& dbname) {
Status s;
if (!db_options.create_if_missing) {
// Attempt to read "CURRENT" file
const std::shared_ptr<FileSystem>& fs = db_options.env->GetFileSystem();
std::string manifest_path;
uint64_t manifest_file_number;
s = VersionSet::GetCurrentManifestPath(dbname, fs.get(), &manifest_path,
&manifest_file_number);
if (!s.ok()) {
return Status::NotFound(CurrentFileName(dbname), "does not exist");
}
}
return s;
}
} // namespace
Status DB::OpenForReadOnly(const Options& options, const std::string& dbname,
DB** dbptr, bool /*error_if_log_file_exist*/) {
// If dbname does not exist in the file system, should not do anything
Status s = OpenForReadOnlyCheckExistence(options, dbname);
if (!s.ok()) {
return s;
}
*dbptr = nullptr;
// Try to first open DB as fully compacted DB
Status s;
s = CompactedDBImpl::Open(options, dbname, dbptr);
if (s.ok()) {
return s;
@@ -173,8 +144,7 @@ Status DB::OpenForReadOnly(const Options& options, const std::string& dbname,
ColumnFamilyDescriptor(kDefaultColumnFamilyName, cf_options));
std::vector<ColumnFamilyHandle*> handles;
s = DBImplReadOnly::OpenForReadOnlyWithoutCheck(
db_options, dbname, column_families, &handles, dbptr);
s = DB::OpenForReadOnly(db_options, dbname, column_families, &handles, dbptr);
if (s.ok()) {
assert(handles.size() == 1);
// i can delete the handle since DBImpl is always holding a
@@ -189,22 +159,6 @@ Status DB::OpenForReadOnly(
const std::vector<ColumnFamilyDescriptor>& column_families,
std::vector<ColumnFamilyHandle*>* handles, DB** dbptr,
bool error_if_log_file_exist) {
// If dbname does not exist in the file system, should not do anything
Status s = OpenForReadOnlyCheckExistence(db_options, dbname);
if (!s.ok()) {
return s;
}
return DBImplReadOnly::OpenForReadOnlyWithoutCheck(
db_options, dbname, column_families, handles, dbptr,
error_if_log_file_exist);
}
Status DBImplReadOnly::OpenForReadOnlyWithoutCheck(
const DBOptions& db_options, const std::string& dbname,
const std::vector<ColumnFamilyDescriptor>& column_families,
std::vector<ColumnFamilyHandle*>* handles, DB** dbptr,
bool error_if_log_file_exist) {
*dbptr = nullptr;
handles->clear();
@@ -237,7 +191,7 @@ Status DBImplReadOnly::OpenForReadOnlyWithoutCheck(
*dbptr = impl;
for (auto* h : *handles) {
impl->NewThreadStatusCfInfo(
static_cast_with_check<ColumnFamilyHandleImpl>(h)->cfd());
reinterpret_cast<ColumnFamilyHandleImpl*>(h)->cfd());
}
} else {
for (auto h : *handles) {
-9
View File
@@ -130,15 +130,6 @@ class DBImplReadOnly : public DBImpl {
}
private:
// A "helper" function for DB::OpenForReadOnly without column families
// to reduce unnecessary I/O
// It has the same functionality as DB::OpenForReadOnly with column families
// but does not check the existence of dbname in the file system
static Status OpenForReadOnlyWithoutCheck(
const DBOptions& db_options, const std::string& dbname,
const std::vector<ColumnFamilyDescriptor>& column_families,
std::vector<ColumnFamilyHandle*>* handles, DB** dbptr,
bool error_if_log_file_exist = false);
friend class DB;
};
} // namespace ROCKSDB_NAMESPACE
+3 -4
View File
@@ -388,7 +388,7 @@ Iterator* DBImplSecondary::NewIterator(const ReadOptions& read_options,
"ReadTier::kPersistedData is not yet supported in iterators."));
}
Iterator* result = nullptr;
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
auto cfd = cfh->cfd();
ReadCallback* read_callback = nullptr; // No read callback provided.
if (read_options.tailing) {
@@ -417,8 +417,7 @@ ArenaWrappedDBIter* DBImplSecondary::NewIteratorImpl(
super_version->version_number, read_callback);
auto internal_iter =
NewInternalIterator(read_options, cfd, super_version, db_iter->GetArena(),
db_iter->GetRangeDelAggregator(), snapshot,
/* allow_unprepared_value */ true);
db_iter->GetRangeDelAggregator(), snapshot);
db_iter->SetIterUnderDBIter(internal_iter);
return db_iter;
}
@@ -642,7 +641,7 @@ Status DB::OpenAsSecondary(
*dbptr = impl;
for (auto h : *handles) {
impl->NewThreadStatusCfInfo(
static_cast_with_check<ColumnFamilyHandleImpl>(h)->cfd());
reinterpret_cast<ColumnFamilyHandleImpl*>(h)->cfd());
}
} else {
for (auto h : *handles) {
+47 -111
View File
@@ -6,15 +6,14 @@
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
#include <cinttypes>
#include "db/db_impl/db_impl.h"
#include <cinttypes>
#include "db/error_handler.h"
#include "db/event_helpers.h"
#include "monitoring/perf_context_imp.h"
#include "options/options_helper.h"
#include "test_util/sync_point.h"
#include "util/cast_util.h"
namespace ROCKSDB_NAMESPACE {
// Convenience methods
@@ -25,7 +24,7 @@ Status DBImpl::Put(const WriteOptions& o, ColumnFamilyHandle* column_family,
Status DBImpl::Merge(const WriteOptions& o, ColumnFamilyHandle* column_family,
const Slice& key, const Slice& val) {
auto cfh = static_cast_with_check<ColumnFamilyHandleImpl>(column_family);
auto cfh = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family);
if (!cfh->cfd()->ioptions()->merge_operator) {
return Status::NotSupported("Provide a merge_operator when opening DB");
} else {
@@ -102,7 +101,6 @@ Status DBImpl::WriteImpl(const WriteOptions& write_options,
disable_memtable);
Status status;
IOStatus io_s;
if (write_options.low_pri) {
status = ThrottleLowPriWritesIfNeeded(write_options, my_batch);
if (!status.ok()) {
@@ -324,22 +322,21 @@ Status DBImpl::WriteImpl(const WriteOptions& write_options,
if (!two_write_queues_) {
if (status.ok() && !write_options.disableWAL) {
PERF_TIMER_GUARD(write_wal_time);
io_s = WriteToWAL(write_group, log_writer, log_used, need_log_sync,
need_log_dir_sync, last_sequence + 1);
status = WriteToWAL(write_group, log_writer, log_used, need_log_sync,
need_log_dir_sync, last_sequence + 1);
}
} else {
if (status.ok() && !write_options.disableWAL) {
PERF_TIMER_GUARD(write_wal_time);
// LastAllocatedSequence is increased inside WriteToWAL under
// wal_write_mutex_ to ensure ordered events in WAL
io_s = ConcurrentWriteToWAL(write_group, log_used, &last_sequence,
seq_inc);
status = ConcurrentWriteToWAL(write_group, log_used, &last_sequence,
seq_inc);
} else {
// Otherwise we inc seq number for memtable writes
last_sequence = versions_->FetchAddLastAllocatedSequence(seq_inc);
}
}
status = io_s;
assert(last_sequence != kMaxSequenceNumber);
const SequenceNumber current_sequence = last_sequence + 1;
last_sequence += seq_inc;
@@ -414,11 +411,7 @@ Status DBImpl::WriteImpl(const WriteOptions& write_options,
PERF_TIMER_START(write_pre_and_post_process_time);
if (!w.CallbackFailed()) {
if (!io_s.ok()) {
IOStatusCheck(io_s);
} else {
WriteStatusCheck(status);
}
WriteStatusCheck(status);
}
if (need_log_sync) {
@@ -522,7 +515,6 @@ Status DBImpl::PipelinedWriteImpl(const WriteOptions& write_options,
PERF_TIMER_STOP(write_pre_and_post_process_time);
IOStatus io_s;
if (w.status.ok() && !write_options.disableWAL) {
PERF_TIMER_GUARD(write_wal_time);
stats->AddDBStats(InternalStats::kIntStatsWriteDoneBySelf, 1);
@@ -532,17 +524,12 @@ Status DBImpl::PipelinedWriteImpl(const WriteOptions& write_options,
wal_write_group.size - 1);
RecordTick(stats_, WRITE_DONE_BY_OTHER, wal_write_group.size - 1);
}
io_s = WriteToWAL(wal_write_group, log_writer, log_used, need_log_sync,
need_log_dir_sync, current_sequence);
w.status = io_s;
w.status = WriteToWAL(wal_write_group, log_writer, log_used,
need_log_sync, need_log_dir_sync, current_sequence);
}
if (!w.CallbackFailed()) {
if (!io_s.ok()) {
IOStatusCheck(io_s);
} else {
WriteStatusCheck(w.status);
}
WriteStatusCheck(w.status);
}
if (need_log_sync) {
@@ -753,10 +740,9 @@ Status DBImpl::WriteImplWALOnly(
}
seq_inc = total_batch_cnt;
}
IOStatus io_s;
if (!write_options.disableWAL) {
io_s = ConcurrentWriteToWAL(write_group, log_used, &last_sequence, seq_inc);
status = io_s;
status =
ConcurrentWriteToWAL(write_group, log_used, &last_sequence, seq_inc);
} else {
// Otherwise we inc seq number to do solely the seq allocation
last_sequence = versions_->FetchAddLastAllocatedSequence(seq_inc);
@@ -791,11 +777,7 @@ Status DBImpl::WriteImplWALOnly(
PERF_TIMER_START(write_pre_and_post_process_time);
if (!w.CallbackFailed()) {
if (!io_s.ok()) {
IOStatusCheck(io_s);
} else {
WriteStatusCheck(status);
}
WriteStatusCheck(status);
}
if (status.ok()) {
size_t index = 0;
@@ -841,17 +823,6 @@ void DBImpl::WriteStatusCheck(const Status& status) {
}
}
void DBImpl::IOStatusCheck(const IOStatus& io_status) {
// Is setting bg_error_ enough here? This will at least stop
// compaction and fail any further writes.
if (immutable_db_options_.paranoid_checks && !io_status.ok() &&
!io_status.IsBusy() && !io_status.IsIncomplete()) {
mutex_.Lock();
error_handler_.SetBGError(io_status, BackgroundErrorReason::kWriteCallback);
mutex_.Unlock();
}
}
void DBImpl::MemTableInsertStatusCheck(const Status& status) {
// A non-OK status here indicates that the state implied by the
// WAL has diverged from the in-memory state. This could be
@@ -990,9 +961,9 @@ WriteBatch* DBImpl::MergeBatch(const WriteThread::WriteGroup& write_group,
// When two_write_queues_ is disabled, this function is called from the only
// write thread. Otherwise this must be called holding log_write_mutex_.
IOStatus DBImpl::WriteToWAL(const WriteBatch& merged_batch,
log::Writer* log_writer, uint64_t* log_used,
uint64_t* log_size) {
Status DBImpl::WriteToWAL(const WriteBatch& merged_batch,
log::Writer* log_writer, uint64_t* log_used,
uint64_t* log_size) {
assert(log_size != nullptr);
Slice log_entry = WriteBatchInternal::Contents(&merged_batch);
*log_size = log_entry.size();
@@ -1007,8 +978,7 @@ IOStatus DBImpl::WriteToWAL(const WriteBatch& merged_batch,
if (UNLIKELY(needs_locking)) {
log_write_mutex_.Lock();
}
IOStatus io_s = log_writer->AddRecord(log_entry);
Status status = log_writer->AddRecord(log_entry);
if (UNLIKELY(needs_locking)) {
log_write_mutex_.Unlock();
}
@@ -1020,14 +990,15 @@ IOStatus DBImpl::WriteToWAL(const WriteBatch& merged_batch,
// since alive_log_files_ might be modified concurrently
alive_log_files_.back().AddSize(log_entry.size());
log_empty_ = false;
return io_s;
return status;
}
IOStatus DBImpl::WriteToWAL(const WriteThread::WriteGroup& write_group,
log::Writer* log_writer, uint64_t* log_used,
bool need_log_sync, bool need_log_dir_sync,
SequenceNumber sequence) {
IOStatus io_s;
Status DBImpl::WriteToWAL(const WriteThread::WriteGroup& write_group,
log::Writer* log_writer, uint64_t* log_used,
bool need_log_sync, bool need_log_dir_sync,
SequenceNumber sequence) {
Status status;
assert(!write_group.leader->disable_wal);
// Same holds for all in the batch group
size_t write_with_wal = 0;
@@ -1045,13 +1016,13 @@ IOStatus DBImpl::WriteToWAL(const WriteThread::WriteGroup& write_group,
WriteBatchInternal::SetSequence(merged_batch, sequence);
uint64_t log_size;
io_s = WriteToWAL(*merged_batch, log_writer, log_used, &log_size);
status = WriteToWAL(*merged_batch, log_writer, log_used, &log_size);
if (to_be_cached_state) {
cached_recoverable_state_ = *to_be_cached_state;
cached_recoverable_state_empty_ = false;
}
if (io_s.ok() && need_log_sync) {
if (status.ok() && need_log_sync) {
StopWatch sw(env_, stats_, WAL_FILE_SYNC_MICROS);
// It's safe to access logs_ with unlocked mutex_ here because:
// - we've set getting_synced=true for all logs,
@@ -1061,24 +1032,23 @@ IOStatus DBImpl::WriteToWAL(const WriteThread::WriteGroup& write_group,
// - as long as other threads don't modify it, it's safe to read
// from std::deque from multiple threads concurrently.
for (auto& log : logs_) {
io_s = log.writer->file()->Sync(immutable_db_options_.use_fsync);
if (!io_s.ok()) {
status = log.writer->file()->Sync(immutable_db_options_.use_fsync);
if (!status.ok()) {
break;
}
}
if (io_s.ok() && need_log_dir_sync) {
if (status.ok() && need_log_dir_sync) {
// We only sync WAL directory the first time WAL syncing is
// requested, so that in case users never turn on WAL sync,
// we can avoid the disk I/O in the write code path.
io_s = directories_.GetWalDir()->Fsync(IOOptions(), nullptr);
status = directories_.GetWalDir()->Fsync(IOOptions(), nullptr);
}
}
if (merged_batch == &tmp_batch_) {
tmp_batch_.Clear();
}
if (io_s.ok()) {
if (status.ok()) {
auto stats = default_cf_internal_stats_;
if (need_log_sync) {
stats->AddDBStats(InternalStats::kIntStatsWalFileSynced, 1);
@@ -1089,13 +1059,14 @@ IOStatus DBImpl::WriteToWAL(const WriteThread::WriteGroup& write_group,
stats->AddDBStats(InternalStats::kIntStatsWriteWithWal, write_with_wal);
RecordTick(stats_, WRITE_WITH_WAL, write_with_wal);
}
return io_s;
return status;
}
IOStatus DBImpl::ConcurrentWriteToWAL(
const WriteThread::WriteGroup& write_group, uint64_t* log_used,
SequenceNumber* last_sequence, size_t seq_inc) {
IOStatus io_s;
Status DBImpl::ConcurrentWriteToWAL(const WriteThread::WriteGroup& write_group,
uint64_t* log_used,
SequenceNumber* last_sequence,
size_t seq_inc) {
Status status;
assert(!write_group.leader->disable_wal);
// Same holds for all in the batch group
@@ -1121,14 +1092,14 @@ IOStatus DBImpl::ConcurrentWriteToWAL(
log::Writer* log_writer = logs_.back().writer;
uint64_t log_size;
io_s = WriteToWAL(*merged_batch, log_writer, log_used, &log_size);
status = WriteToWAL(*merged_batch, log_writer, log_used, &log_size);
if (to_be_cached_state) {
cached_recoverable_state_ = *to_be_cached_state;
cached_recoverable_state_empty_ = false;
}
log_write_mutex_.Unlock();
if (io_s.ok()) {
if (status.ok()) {
const bool concurrent = true;
auto stats = default_cf_internal_stats_;
stats->AddDBStats(InternalStats::kIntStatsWalFileBytes, log_size,
@@ -1138,7 +1109,7 @@ IOStatus DBImpl::ConcurrentWriteToWAL(
concurrent);
RecordTick(stats_, WRITE_WITH_WAL, write_with_wal);
}
return io_s;
return status;
}
Status DBImpl::WriteRecoverableState() {
@@ -1638,7 +1609,6 @@ Status DBImpl::SwitchMemtable(ColumnFamilyData* cfd, WriteContext* context) {
std::unique_ptr<WritableFile> lfile;
log::Writer* new_log = nullptr;
MemTable* new_mem = nullptr;
IOStatus io_s;
// Recoverable state is persisted in WAL. After memtable switch, WAL might
// be deleted, so we write the state to memtable to be persisted as well.
@@ -1684,11 +1654,8 @@ Status DBImpl::SwitchMemtable(ColumnFamilyData* cfd, WriteContext* context) {
if (creating_new_log) {
// TODO: Write buffer size passed in should be max of all CF's instead
// of mutable_cf_options.write_buffer_size.
io_s = CreateWAL(new_log_number, recycle_log_number, preallocate_block_size,
&new_log);
if (s.ok()) {
s = io_s;
}
s = CreateWAL(new_log_number, recycle_log_number, preallocate_block_size,
&new_log);
}
if (s.ok()) {
SequenceNumber seq = versions_->LastSequence();
@@ -1714,10 +1681,7 @@ Status DBImpl::SwitchMemtable(ColumnFamilyData* cfd, WriteContext* context) {
if (!logs_.empty()) {
// Alway flush the buffer of the last log before switching to a new one
log::Writer* cur_log_writer = logs_.back().writer;
io_s = cur_log_writer->WriteBuffer();
if (s.ok()) {
s = io_s;
}
s = cur_log_writer->WriteBuffer();
if (!s.ok()) {
ROCKS_LOG_WARN(immutable_db_options_.info_log,
"[%s] Failed to switch from #%" PRIu64 " to #%" PRIu64
@@ -1752,11 +1716,7 @@ Status DBImpl::SwitchMemtable(ColumnFamilyData* cfd, WriteContext* context) {
}
// We may have lost data from the WritableFileBuffer in-memory buffer for
// the current log, so treat it as a fatal error and set bg_error
if (!io_s.ok()) {
error_handler_.SetBGError(io_s, BackgroundErrorReason::kMemTable);
} else {
error_handler_.SetBGError(s, BackgroundErrorReason::kMemTable);
}
error_handler_.SetBGError(s, BackgroundErrorReason::kMemTable);
// Read back bg_error in order to get the right severity
s = error_handler_.GetBGError();
return s;
@@ -1832,8 +1792,6 @@ Status DB::Put(const WriteOptions& opt, ColumnFamilyHandle* column_family,
const Slice* ts = opt.timestamp;
assert(nullptr != ts);
size_t ts_sz = ts->size();
assert(column_family->GetComparator());
assert(ts_sz == column_family->GetComparator()->timestamp_size());
WriteBatch batch(key.size() + ts_sz + value.size() + 24, /*max_bytes=*/0,
ts_sz);
Status s = batch.Put(column_family, key, value);
@@ -1849,30 +1807,8 @@ Status DB::Put(const WriteOptions& opt, ColumnFamilyHandle* column_family,
Status DB::Delete(const WriteOptions& opt, ColumnFamilyHandle* column_family,
const Slice& key) {
if (nullptr == opt.timestamp) {
WriteBatch batch;
Status s = batch.Delete(column_family, key);
if (!s.ok()) {
return s;
}
return Write(opt, &batch);
}
const Slice* ts = opt.timestamp;
assert(ts != nullptr);
const size_t ts_sz = ts->size();
constexpr size_t kKeyAndValueLenSize = 11;
constexpr size_t kWriteBatchOverhead =
WriteBatchInternal::kHeader + sizeof(ValueType) + kKeyAndValueLenSize;
WriteBatch batch(key.size() + ts_sz + kWriteBatchOverhead, /*max_bytes=*/0,
ts_sz);
Status s = batch.Delete(column_family, key);
if (!s.ok()) {
return s;
}
s = batch.AssignTimestamp(*ts);
if (!s.ok()) {
return s;
}
WriteBatch batch;
batch.Delete(column_family, key);
return Write(opt, &batch);
}
+2 -58
View File
@@ -10,8 +10,8 @@
#include "db/db_impl/db_impl_secondary.h"
#include "db/db_test_util.h"
#include "port/stack_trace.h"
#include "test_util/fault_injection_test_env.h"
#include "test_util/sync_point.h"
#include "utilities/fault_injection_env.h"
namespace ROCKSDB_NAMESPACE {
@@ -45,8 +45,6 @@ class DBSecondaryTest : public DBTestBase {
void OpenSecondary(const Options& options);
Status TryOpenSecondary(const Options& options);
void OpenSecondaryWithColumnFamilies(
const std::vector<std::string>& column_families, const Options& options);
@@ -72,13 +70,9 @@ class DBSecondaryTest : public DBTestBase {
};
void DBSecondaryTest::OpenSecondary(const Options& options) {
ASSERT_OK(TryOpenSecondary(options));
}
Status DBSecondaryTest::TryOpenSecondary(const Options& options) {
Status s =
DB::OpenAsSecondary(options, dbname_, secondary_path_, &db_secondary_);
return s;
ASSERT_OK(s);
}
void DBSecondaryTest::OpenSecondaryWithColumnFamilies(
@@ -864,56 +858,6 @@ TEST_F(DBSecondaryTest, CheckConsistencyWhenOpen) {
thread.join();
ASSERT_TRUE(called);
}
TEST_F(DBSecondaryTest, StartFromInconsistent) {
Options options = CurrentOptions();
DestroyAndReopen(options);
ASSERT_OK(Put("foo", "value"));
ASSERT_OK(Flush());
SyncPoint::GetInstance()->DisableProcessing();
SyncPoint::GetInstance()->ClearAllCallBacks();
SyncPoint::GetInstance()->SetCallBack(
"VersionBuilder::CheckConsistencyBeforeReturn", [&](void* arg) {
ASSERT_NE(nullptr, arg);
*(reinterpret_cast<Status*>(arg)) =
Status::Corruption("Inject corruption");
});
SyncPoint::GetInstance()->EnableProcessing();
Options options1;
Status s = TryOpenSecondary(options1);
ASSERT_TRUE(s.IsCorruption());
}
TEST_F(DBSecondaryTest, InconsistencyDuringCatchUp) {
Options options = CurrentOptions();
DestroyAndReopen(options);
ASSERT_OK(Put("foo", "value"));
ASSERT_OK(Flush());
Options options1;
OpenSecondary(options1);
{
std::string value;
ASSERT_OK(db_secondary_->Get(ReadOptions(), "foo", &value));
ASSERT_EQ("value", value);
}
ASSERT_OK(Put("bar", "value1"));
ASSERT_OK(Flush());
SyncPoint::GetInstance()->DisableProcessing();
SyncPoint::GetInstance()->ClearAllCallBacks();
SyncPoint::GetInstance()->SetCallBack(
"VersionBuilder::CheckConsistencyBeforeReturn", [&](void* arg) {
ASSERT_NE(nullptr, arg);
*(reinterpret_cast<Status*>(arg)) =
Status::Corruption("Inject corruption");
});
SyncPoint::GetInstance()->EnableProcessing();
Status s = db_secondary_->TryCatchUpWithPrimary();
ASSERT_TRUE(s.IsCorruption());
}
#endif //! ROCKSDB_LITE
} // namespace ROCKSDB_NAMESPACE
+1 -4
View File
@@ -17,8 +17,7 @@
namespace ROCKSDB_NAMESPACE {
void DumpDBFileSummary(const ImmutableDBOptions& options,
const std::string& dbname,
const std::string& session_id) {
const std::string& dbname) {
if (options.info_log == nullptr) {
return;
}
@@ -33,8 +32,6 @@ void DumpDBFileSummary(const ImmutableDBOptions& options,
std::string file_info, wal_info;
Header(options.info_log, "DB SUMMARY\n");
Header(options.info_log, "DB Session ID: %s\n", session_id.c_str());
// Get files in dbname dir
if (!env->GetChildren(dbname, &files).ok()) {
Error(options.info_log,
+1 -2
View File
@@ -10,6 +10,5 @@
namespace ROCKSDB_NAMESPACE {
void DumpDBFileSummary(const ImmutableDBOptions& options,
const std::string& dbname,
const std::string& session_id = "");
const std::string& dbname);
} // namespace ROCKSDB_NAMESPACE
+4 -5
View File
@@ -9,7 +9,6 @@
#include "db/db_test_util.h"
#include "port/stack_trace.h"
#include "util/random.h"
namespace ROCKSDB_NAMESPACE {
@@ -282,8 +281,8 @@ TEST_F(DBIOFailureTest, FlushSstRangeSyncError) {
Random rnd(301);
std::string rnd_str =
rnd.RandomString(static_cast<int>(options.bytes_per_sync / 2));
std::string rnd_str_512kb = rnd.RandomString(512 * 1024);
RandomString(&rnd, static_cast<int>(options.bytes_per_sync / 2));
std::string rnd_str_512kb = RandomString(&rnd, 512 * 1024);
ASSERT_OK(Put(1, "foo", "bar"));
// First 1MB doesn't get range synced
@@ -331,8 +330,8 @@ TEST_F(DBIOFailureTest, CompactSstRangeSyncError) {
Random rnd(301);
std::string rnd_str =
rnd.RandomString(static_cast<int>(options.bytes_per_sync / 2));
std::string rnd_str_512kb = rnd.RandomString(512 * 1024);
RandomString(&rnd, static_cast<int>(options.bytes_per_sync / 2));
std::string rnd_str_512kb = RandomString(&rnd, 512 * 1024);
ASSERT_OK(Put(1, "foo", "bar"));
// First 1MB doesn't get range synced
+26 -64
View File
@@ -73,7 +73,6 @@ DBIter::DBIter(Env* _env, const ReadOptions& read_options,
cfd_(cfd),
start_seqnum_(read_options.iter_start_seqnum),
timestamp_ub_(read_options.timestamp),
timestamp_lb_(read_options.iter_start_ts),
timestamp_size_(timestamp_ub_ ? timestamp_ub_->size() : 0) {
RecordTick(statistics_, NO_ITERATOR_CREATED);
if (pin_thru_lifetime_) {
@@ -247,36 +246,27 @@ bool DBIter::FindNextUserEntryInternal(bool skipping_saved_key,
assert(ikey_.user_key.size() >= timestamp_size_);
Slice ts;
bool more_recent = false;
if (timestamp_size_ > 0) {
ts = ExtractTimestampFromUserKey(ikey_.user_key, timestamp_size_);
}
if (IsVisible(ikey_.sequence, ts, &more_recent)) {
if (IsVisible(ikey_.sequence, ts)) {
// If the previous entry is of seqnum 0, the current entry will not
// possibly be skipped. This condition can potentially be relaxed to
// prev_key.seq <= ikey_.sequence. We are cautious because it will be more
// prone to bugs causing the same user key with the same sequence number.
// Note that with current timestamp implementation, the same user key can
// have different timestamps and zero sequence number on the bottommost
// level. This may change in the future.
if ((!is_prev_key_seqnum_zero || timestamp_size_ > 0) &&
skipping_saved_key &&
CompareKeyForSkip(ikey_.user_key, saved_key_.GetUserKey()) <= 0) {
if (!is_prev_key_seqnum_zero && skipping_saved_key &&
user_comparator_.CompareWithoutTimestamp(
ikey_.user_key, saved_key_.GetUserKey()) <= 0) {
num_skipped++; // skip this entry
PERF_COUNTER_ADD(internal_key_skipped_count, 1);
} else {
assert(!skipping_saved_key ||
CompareKeyForSkip(ikey_.user_key, saved_key_.GetUserKey()) > 0);
if (!iter_.PrepareValue()) {
assert(!iter_.status().ok());
valid_ = false;
return false;
}
user_comparator_.CompareWithoutTimestamp(
ikey_.user_key, saved_key_.GetUserKey()) > 0);
num_skipped = 0;
reseek_done = false;
switch (ikey_.type) {
case kTypeDeletion:
case kTypeDeletionWithTimestamp:
case kTypeSingleDeletion:
// Arrange to skip all upcoming entries for this key since
// they are hidden by this deletion.
@@ -373,13 +363,11 @@ bool DBIter::FindNextUserEntryInternal(bool skipping_saved_key,
}
}
} else {
if (more_recent) {
PERF_COUNTER_ADD(internal_recent_skipped_count, 1);
}
PERF_COUNTER_ADD(internal_recent_skipped_count, 1);
// This key was inserted after our snapshot was taken or skipped by
// timestamp range. If this happens too many times in a row for the same
// user key, we want to seek to the target sequence number.
// This key was inserted after our snapshot was taken.
// If this happens too many times in a row for the same user key, we want
// to seek to the target sequence number.
int cmp = user_comparator_.CompareWithoutTimestamp(
ikey_.user_key, saved_key_.GetUserKey());
if (cmp == 0 || (skipping_saved_key && cmp < 0)) {
@@ -458,7 +446,6 @@ bool DBIter::FindNextUserEntryInternal(bool skipping_saved_key,
// Scan from the newer entries to older entries.
// PRE: iter_.key() points to the first merge type entry
// saved_key_ stores the user key
// iter_.PrepareValue() has been called
// POST: saved_value_ has the merged value for the user key
// iter_ points to the next entry (or invalid)
bool DBIter::MergeValuesNewToOld() {
@@ -488,21 +475,14 @@ bool DBIter::MergeValuesNewToOld() {
if (!user_comparator_.Equal(ikey.user_key, saved_key_.GetUserKey())) {
// hit the next user key, stop right here
break;
}
if (kTypeDeletion == ikey.type || kTypeSingleDeletion == ikey.type ||
} else if (kTypeDeletion == ikey.type || kTypeSingleDeletion == ikey.type ||
range_del_agg_.ShouldDelete(
ikey, RangeDelPositioningMode::kForwardTraversal)) {
// hit a delete with the same user key, stop right here
// iter_ is positioned after delete
iter_.Next();
break;
}
if (!iter_.PrepareValue()) {
valid_ = false;
return false;
}
if (kTypeValue == ikey.type) {
} else if (kTypeValue == ikey.type) {
// hit a put, merge the put value with operands and store the
// final result in saved_value_. We are done!
const Slice val = iter_.value();
@@ -774,11 +754,6 @@ bool DBIter::FindValueForCurrentKey() {
return FindValueForCurrentKeyUsingSeek();
}
if (!iter_.PrepareValue()) {
valid_ = false;
return false;
}
last_key_entry_type = ikey.type;
switch (last_key_entry_type) {
case kTypeValue:
@@ -956,10 +931,6 @@ bool DBIter::FindValueForCurrentKeyUsingSeek() {
valid_ = false;
return false;
}
if (!iter_.PrepareValue()) {
valid_ = false;
return false;
}
if (ikey.type == kTypeValue || ikey.type == kTypeBlobIndex) {
assert(iter_.iter()->IsValuePinned());
pinned_value_ = iter_.value();
@@ -991,17 +962,12 @@ bool DBIter::FindValueForCurrentKeyUsingSeek() {
if (!user_comparator_.Equal(ikey.user_key, saved_key_.GetUserKey())) {
break;
}
if (ikey.type == kTypeDeletion || ikey.type == kTypeSingleDeletion ||
range_del_agg_.ShouldDelete(
ikey, RangeDelPositioningMode::kForwardTraversal)) {
break;
}
if (!iter_.PrepareValue()) {
valid_ = false;
return false;
}
if (ikey.type == kTypeValue) {
} else if (ikey.type == kTypeValue) {
const Slice val = iter_.value();
Status s = MergeHelper::TimedFullMerge(
merge_operator_, saved_key_.GetUserKey(), &val,
@@ -1135,24 +1101,20 @@ bool DBIter::TooManyInternalKeysSkipped(bool increment) {
return false;
}
bool DBIter::IsVisible(SequenceNumber sequence, const Slice& ts,
bool* more_recent) {
bool DBIter::IsVisible(SequenceNumber sequence, const Slice& ts) {
// Remember that comparator orders preceding timestamp as larger.
// TODO(yanqin): support timestamp in read_callback_.
bool visible_by_seq = (read_callback_ == nullptr)
? sequence <= sequence_
: read_callback_->IsVisible(sequence);
bool visible_by_ts =
(timestamp_ub_ == nullptr ||
user_comparator_.CompareTimestamp(ts, *timestamp_ub_) <= 0) &&
(timestamp_lb_ == nullptr ||
user_comparator_.CompareTimestamp(ts, *timestamp_lb_) >= 0);
if (more_recent) {
*more_recent = !visible_by_seq;
int cmp_ts = timestamp_ub_ != nullptr
? user_comparator_.CompareTimestamp(ts, *timestamp_ub_)
: 0;
if (cmp_ts > 0) {
return false;
}
if (read_callback_ == nullptr) {
return sequence <= sequence_;
} else {
// TODO(yanqin): support timestamp in read_callback_.
return read_callback_->IsVisible(sequence);
}
return visible_by_seq && visible_by_ts;
}
void DBIter::SetSavedKeyToSeekTarget(const Slice& target) {
+1 -12
View File
@@ -231,8 +231,7 @@ class DBIter final : public Iterator {
// entry can be found within the prefix.
void PrevInternal(const Slice* prefix);
bool TooManyInternalKeysSkipped(bool increment = true);
bool IsVisible(SequenceNumber sequence, const Slice& ts,
bool* more_recent = nullptr);
bool IsVisible(SequenceNumber sequence, const Slice& ts);
// Temporarily pin the blocks that we encounter until ReleaseTempPinnedData()
// is called
@@ -271,15 +270,6 @@ class DBIter final : public Iterator {
return expect_total_order_inner_iter_;
}
// If lower bound of timestamp is given by ReadOptions.iter_start_ts, we need
// to return versions of the same key. We cannot just skip if the key value
// is the same but timestamps are different but fall in timestamp range.
inline int CompareKeyForSkip(const Slice& a, const Slice& b) {
return timestamp_lb_ != nullptr
? user_comparator_.Compare(a, b)
: user_comparator_.CompareWithoutTimestamp(a, b);
}
const SliceTransform* prefix_extractor_;
Env* const env_;
Logger* logger_;
@@ -348,7 +338,6 @@ class DBIter final : public Iterator {
// if this value > 0 iterator will return internal keys
SequenceNumber start_seqnum_;
const Slice* const timestamp_ub_;
const Slice* const timestamp_lb_;
const size_t timestamp_size_;
};
+4 -7
View File
@@ -97,8 +97,7 @@ struct StressTestIterator : public InternalIterator {
bool MaybeFail() {
if (rnd->Next() >=
static_cast<double>(std::numeric_limits<uint64_t>::max()) *
error_probability) {
std::numeric_limits<uint64_t>::max() * error_probability) {
return false;
}
if (rnd->Next() % 2) {
@@ -115,8 +114,7 @@ struct StressTestIterator : public InternalIterator {
void MaybeMutate() {
if (rnd->Next() >=
static_cast<double>(std::numeric_limits<uint64_t>::max()) *
mutation_probability) {
std::numeric_limits<uint64_t>::max() * mutation_probability) {
return;
}
do {
@@ -128,9 +126,8 @@ struct StressTestIterator : public InternalIterator {
if (data->hidden.empty()) {
hide_probability = 1;
}
bool do_hide = rnd->Next() <
static_cast<double>(std::numeric_limits<uint64_t>::max()) *
hide_probability;
bool do_hide =
rnd->Next() < std::numeric_limits<uint64_t>::max() * hide_probability;
if (do_hide) {
// Hide a random entry.
size_t idx = rnd->Next() % data->entries.size();
+28 -60
View File
@@ -17,7 +17,6 @@
#include "rocksdb/iostats_context.h"
#include "rocksdb/perf_context.h"
#include "table/block_based/flush_block_policy.h"
#include "util/random.h"
namespace ROCKSDB_NAMESPACE {
@@ -41,8 +40,7 @@ class DBIteratorTest : public DBTestBase,
if (column_family == nullptr) {
column_family = db_->DefaultColumnFamily();
}
auto* cfd =
static_cast_with_check<ColumnFamilyHandleImpl>(column_family)->cfd();
auto* cfd = reinterpret_cast<ColumnFamilyHandleImpl*>(column_family)->cfd();
SequenceNumber seq = read_options.snapshot != nullptr
? read_options.snapshot->GetSequenceNumber()
: db_->GetLatestSequenceNumber();
@@ -195,10 +193,10 @@ TEST_P(DBIteratorTest, IterReseekNewUpperBound) {
options.compression = kNoCompression;
Reopen(options);
ASSERT_OK(Put("a", rnd.RandomString(400)));
ASSERT_OK(Put("aabb", rnd.RandomString(400)));
ASSERT_OK(Put("aaef", rnd.RandomString(400)));
ASSERT_OK(Put("b", rnd.RandomString(400)));
ASSERT_OK(Put("a", RandomString(&rnd, 400)));
ASSERT_OK(Put("aabb", RandomString(&rnd, 400)));
ASSERT_OK(Put("aaef", RandomString(&rnd, 400)));
ASSERT_OK(Put("b", RandomString(&rnd, 400)));
dbfull()->Flush(FlushOptions());
ReadOptions opts;
Slice ub = Slice("aa");
@@ -1169,62 +1167,32 @@ TEST_P(DBIteratorTest, IndexWithFirstKey) {
ropt.tailing = tailing;
std::unique_ptr<Iterator> iter(NewIterator(ropt));
ropt.read_tier = ReadTier::kBlockCacheTier;
std::unique_ptr<Iterator> nonblocking_iter(NewIterator(ropt));
iter->Seek("b10");
ASSERT_TRUE(iter->Valid());
EXPECT_EQ("b2", iter->key().ToString());
EXPECT_EQ("y2", iter->value().ToString());
EXPECT_EQ(1, stats->getTickerCount(BLOCK_CACHE_DATA_MISS));
// The cache-only iterator should succeed too, using the blocks pulled into
// the cache by the previous iterator.
nonblocking_iter->Seek("b10");
ASSERT_TRUE(nonblocking_iter->Valid());
EXPECT_EQ("b2", nonblocking_iter->key().ToString());
EXPECT_EQ("y2", nonblocking_iter->value().ToString());
EXPECT_EQ(1, stats->getTickerCount(BLOCK_CACHE_DATA_HIT));
// ... but it shouldn't be able to step forward since the next block is
// not in cache yet.
nonblocking_iter->Next();
ASSERT_FALSE(nonblocking_iter->Valid());
ASSERT_TRUE(nonblocking_iter->status().IsIncomplete());
// ... nor should a seek to the next key succeed.
nonblocking_iter->Seek("b20");
ASSERT_FALSE(nonblocking_iter->Valid());
ASSERT_TRUE(nonblocking_iter->status().IsIncomplete());
iter->Next();
ASSERT_TRUE(iter->Valid());
EXPECT_EQ("b3", iter->key().ToString());
EXPECT_EQ("y3", iter->value().ToString());
EXPECT_EQ(4, stats->getTickerCount(BLOCK_CACHE_DATA_MISS));
EXPECT_EQ(1, stats->getTickerCount(BLOCK_CACHE_DATA_HIT));
// After the blocking iterator loaded the next block, the nonblocking
// iterator's seek should succeed.
nonblocking_iter->Seek("b20");
ASSERT_TRUE(nonblocking_iter->Valid());
EXPECT_EQ("b3", nonblocking_iter->key().ToString());
EXPECT_EQ("y3", nonblocking_iter->value().ToString());
EXPECT_EQ(2, stats->getTickerCount(BLOCK_CACHE_DATA_HIT));
EXPECT_EQ(2, stats->getTickerCount(BLOCK_CACHE_DATA_MISS));
EXPECT_EQ(0, stats->getTickerCount(BLOCK_CACHE_DATA_HIT));
iter->Seek("c0");
ASSERT_TRUE(iter->Valid());
EXPECT_EQ("c0", iter->key().ToString());
EXPECT_EQ("z1,z2", iter->value().ToString());
EXPECT_EQ(2, stats->getTickerCount(BLOCK_CACHE_DATA_HIT));
EXPECT_EQ(6, stats->getTickerCount(BLOCK_CACHE_DATA_MISS));
EXPECT_EQ(0, stats->getTickerCount(BLOCK_CACHE_DATA_HIT));
EXPECT_EQ(4, stats->getTickerCount(BLOCK_CACHE_DATA_MISS));
iter->Next();
ASSERT_TRUE(iter->Valid());
EXPECT_EQ("c3", iter->key().ToString());
EXPECT_EQ("z3", iter->value().ToString());
EXPECT_EQ(2, stats->getTickerCount(BLOCK_CACHE_DATA_HIT));
EXPECT_EQ(7, stats->getTickerCount(BLOCK_CACHE_DATA_MISS));
EXPECT_EQ(0, stats->getTickerCount(BLOCK_CACHE_DATA_HIT));
EXPECT_EQ(5, stats->getTickerCount(BLOCK_CACHE_DATA_MISS));
iter.reset();
@@ -1239,13 +1207,13 @@ TEST_P(DBIteratorTest, IndexWithFirstKey) {
ASSERT_TRUE(iter->Valid());
EXPECT_EQ("b2", iter->key().ToString());
EXPECT_EQ("y2", iter->value().ToString());
EXPECT_EQ(3, stats->getTickerCount(BLOCK_CACHE_DATA_HIT));
EXPECT_EQ(7, stats->getTickerCount(BLOCK_CACHE_DATA_MISS));
EXPECT_EQ(1, stats->getTickerCount(BLOCK_CACHE_DATA_HIT));
EXPECT_EQ(5, stats->getTickerCount(BLOCK_CACHE_DATA_MISS));
iter->Next();
ASSERT_FALSE(iter->Valid());
EXPECT_EQ(3, stats->getTickerCount(BLOCK_CACHE_DATA_HIT));
EXPECT_EQ(7, stats->getTickerCount(BLOCK_CACHE_DATA_MISS));
EXPECT_EQ(1, stats->getTickerCount(BLOCK_CACHE_DATA_HIT));
EXPECT_EQ(5, stats->getTickerCount(BLOCK_CACHE_DATA_MISS));
}
}
@@ -1361,7 +1329,7 @@ class DBIteratorTestForPinnedData : public DBIteratorTest {
std::vector<std::string> generated_keys(key_pool);
for (int i = 0; i < key_pool; i++) {
generated_keys[i] = rnd.RandomString(key_size);
generated_keys[i] = RandomString(&rnd, key_size);
}
std::map<std::string, std::string> true_data;
@@ -1369,7 +1337,7 @@ class DBIteratorTestForPinnedData : public DBIteratorTest {
std::vector<std::string> deleted_keys;
for (int i = 0; i < puts; i++) {
auto& k = generated_keys[rnd.Next() % key_pool];
auto v = rnd.RandomString(val_size);
auto v = RandomString(&rnd, val_size);
// Insert data to true_data map and to DB
true_data[k] = v;
@@ -1532,7 +1500,7 @@ TEST_P(DBIteratorTest, PinnedDataIteratorMultipleFiles) {
Random rnd(301);
for (int i = 1; i <= 1000; i++) {
std::string k = Key(i * 3);
std::string v = rnd.RandomString(100);
std::string v = RandomString(&rnd, 100);
ASSERT_OK(Put(k, v));
true_data[k] = v;
if (i % 250 == 0) {
@@ -1546,7 +1514,7 @@ TEST_P(DBIteratorTest, PinnedDataIteratorMultipleFiles) {
// Generate 4 sst files in L0
for (int i = 1; i <= 1000; i++) {
std::string k = Key(i * 2);
std::string v = rnd.RandomString(100);
std::string v = RandomString(&rnd, 100);
ASSERT_OK(Put(k, v));
true_data[k] = v;
if (i % 250 == 0) {
@@ -1558,7 +1526,7 @@ TEST_P(DBIteratorTest, PinnedDataIteratorMultipleFiles) {
// Add some keys/values in memtables
for (int i = 1; i <= 1000; i++) {
std::string k = Key(i);
std::string v = rnd.RandomString(100);
std::string v = RandomString(&rnd, 100);
ASSERT_OK(Put(k, v));
true_data[k] = v;
}
@@ -1660,8 +1628,8 @@ TEST_P(DBIteratorTest, PinnedDataIteratorReadAfterUpdate) {
std::map<std::string, std::string> true_data;
for (int i = 0; i < 1000; i++) {
std::string k = rnd.RandomString(10);
std::string v = rnd.RandomString(1000);
std::string k = RandomString(&rnd, 10);
std::string v = RandomString(&rnd, 1000);
ASSERT_OK(Put(k, v));
true_data[k] = v;
}
@@ -1675,7 +1643,7 @@ TEST_P(DBIteratorTest, PinnedDataIteratorReadAfterUpdate) {
if (rnd.OneIn(2)) {
ASSERT_OK(Delete(kv.first));
} else {
std::string new_val = rnd.RandomString(1000);
std::string new_val = RandomString(&rnd, 1000);
ASSERT_OK(Put(kv.first, new_val));
}
}
@@ -1932,7 +1900,7 @@ TEST_P(DBIteratorTest, IterPrevKeyCrossingBlocksRandomized) {
for (int i = 0; i < kNumKeys; i++) {
gen_key = Key(i);
gen_val = rnd.RandomString(kValSize);
gen_val = RandomString(&rnd, kValSize);
ASSERT_OK(Put(gen_key, gen_val));
true_data[gen_key] = gen_val;
@@ -1950,7 +1918,7 @@ TEST_P(DBIteratorTest, IterPrevKeyCrossingBlocksRandomized) {
for (int j = 0; j < kNumMergeOperands; j++) {
gen_key = Key(i);
gen_val = rnd.RandomString(kValSize);
gen_val = RandomString(&rnd, kValSize);
ASSERT_OK(db_->Merge(WriteOptions(), gen_key, gen_val));
true_data[gen_key] += "," + gen_val;
@@ -2050,7 +2018,7 @@ TEST_P(DBIteratorTest, IteratorWithLocalStatistics) {
Random rnd(301);
for (int i = 0; i < 1000; i++) {
// Key 10 bytes / Value 10 bytes
ASSERT_OK(Put(rnd.RandomString(10), rnd.RandomString(10)));
ASSERT_OK(Put(RandomString(&rnd, 10), RandomString(&rnd, 10)));
}
std::atomic<uint64_t> total_next(0);
@@ -2706,7 +2674,7 @@ TEST_P(DBIteratorTest, AvoidReseekLevelIterator) {
Reopen(options);
Random rnd(301);
std::string random_str = rnd.RandomString(180);
std::string random_str = RandomString(&rnd, 180);
ASSERT_OK(Put("1", random_str));
ASSERT_OK(Put("2", random_str));
@@ -2913,7 +2881,7 @@ TEST_F(DBIteratorWithReadCallbackTest, ReadCallback) {
SequenceNumber seq2 = db_->GetLatestSequenceNumber();
auto* cfd =
static_cast_with_check<ColumnFamilyHandleImpl>(db_->DefaultColumnFamily())
reinterpret_cast<ColumnFamilyHandleImpl*>(db_->DefaultColumnFamily())
->cfd();
// The iterator are suppose to see data before seq1.
Iterator* iter =
+8 -6
View File
@@ -37,15 +37,17 @@ class DBLogicalBlockSizeCacheTest : public testing::Test {
data_path_1_(dbname_ + "/data_path_1"),
cf_path_0_(dbname_ + "/cf_path_0"),
cf_path_1_(dbname_ + "/cf_path_1") {
auto get_fd_block_size = [&](int fd) { return fd; };
auto get_fd_block_size = [&](int fd) {
return fd;
};
auto get_dir_block_size = [&](const std::string& /*dir*/, size_t* size) {
*size = 1024;
return Status::OK();
};
cache_.reset(
new LogicalBlockSizeCache(get_fd_block_size, get_dir_block_size));
env_.reset(
new EnvWithCustomLogicalBlockSizeCache(Env::Default(), cache_.get()));
cache_.reset(new LogicalBlockSizeCache(
get_fd_block_size, get_dir_block_size));
env_.reset(new EnvWithCustomLogicalBlockSizeCache(
Env::Default(), cache_.get()));
}
protected:
@@ -505,7 +507,7 @@ TEST_F(DBLogicalBlockSizeCacheTest, MultiDBWithSamePaths) {
}
} // namespace ROCKSDB_NAMESPACE
#endif // OS_LINUX
#endif // OS_LINUX
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);

Some files were not shown because too many files have changed in this diff Show More