Compare commits

..
32 Commits
Author SHA1 Message Date
Daniel Black ca97834b43 db_bench_tool: fix buffer size
Summary:
Found by gcc warning:

x86_64-pc-linux-gnu-g++ --version
x86_64-pc-linux-gnu-g++ (GCC) 7.1.1 20170710

tools/db_bench_tool.cc: In member function 'void rocksdb::Benchmark::RandomWithVerify(rocksdb::ThreadState*)':
tools/db_bench_tool.cc:4430:8: error: '%lu' directive output may be truncated writing between 1 and 19 bytes into a region of size between 0 and 66 [-Werror=format-truncation=]
   void RandomWithVerify(ThreadState* thread) {
        ^~~~~~~~~~~~~~~~
tools/db_bench_tool.cc:4430:8: note: directive argument in the range [0, 9223372036854775807]
tools/db_bench_tool.cc:4492:13: note: 'snprintf' output between 37 and 128 bytes into a destination of size 100
     snprintf(msg, sizeof(msg),
     ~~~~~~~~^~~~~~~~~~~~~~~~~~
              "( get:%" PRIu64 " put:%" PRIu64 " del:%" PRIu64 " total:%" \
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              PRIu64 " found:%" PRIu64 ")",
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
              gets_done, puts_done, deletes_done, readwrites_, found);
              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
cc1plus: all warnings being treated as errors
Makefile:1707: recipe for target 'tools/db_bench_tool.o' failed
Closes https://github.com/facebook/rocksdb/pull/2558

Differential Revision: D5398703

Pulled By: siying

fbshipit-source-id: 6ffa552bbd8b59cfc2c36289f86ff9b9acca8ca6
2019-10-30 14:19:18 -07:00
Daniel Black 393862895a table/block.h: change memset
Summary:
In gcc-7 the following is an error identified by -Werror=class-memaccess

In file included from ./table/get_context.h:14:0,
                 from db/version_set.cc:43:
./table/block.h: In constructor ‘rocksdb::BlockReadAmpBitmap::BlockReadAmpBitmap(size_t, size_t, rocksdb::Statistics*)’:
./table/block.h:73:53: error: ‘void* memset(void*, int, size_t)’ clearing an object of type ‘struct std::atomic<unsigned int>’ with no trivial copy-assignment; use value-initialization instead [-Werror=class-memaccess]
     memset(bitmap_, 0, bitmap_size * kBytesPersEntry);
                                                     ^
In file included from ./db/version_set.h:23:0,
                 from db/version_set.cc:12:
/toolchain/include/c++/8.0.0/atomic:684:12: note: ‘struct std::atomic<unsigned int>’ declared here
     struct atomic<unsigned int> : __atomic_base<unsigned int>
            ^~~~~~~~~~~~~~~~~~~~

As a solution the default initializer can be applied in list context.

Signed-off-by: Daniel Black <daniel.black@au.ibm.com>
Closes https://github.com/facebook/rocksdb/pull/2561

Differential Revision: D5398714

Pulled By: siying

fbshipit-source-id: d883fb88ec7535eee60d551038fe91f14488be36
2019-10-30 14:19:18 -07:00
przemyslaw.skibinski@percona.com ad2176a03e Fix GitHub issue #3716: gcc-8 warnings
Summary:
Fix the following gcc-8 warnings:
- conflicting C language linkage declaration [-Werror]
- writing to an object with no trivial copy-assignment [-Werror=class-memaccess]
- array subscript -1 is below array bounds [-Werror=array-bounds]

Solves https://github.com/facebook/rocksdb/issues/3716
Closes https://github.com/facebook/rocksdb/pull/3736

Differential Revision: D7684161

Pulled By: yiwu-arbug

fbshipit-source-id: 47c0423d26b74add251f1d3595211eee1e41e54a
2019-10-30 14:19:18 -07:00
Vijay Nadimpalli 4fc2709d51 Making platform 007 (gcc 7) default in build_detect_platform.sh (#5947)
Summary:
Making platform 007 (gcc 7) default in build_detect_platform.sh.
Pull Request resolved: https://github.com/facebook/rocksdb/pull/5947

Differential Revision: D18038837

Pulled By: vjnadimpalli

fbshipit-source-id: 9ac2ddaa93bf328a416faec028970e039886378e
2019-10-30 14:19:18 -07:00
Andrew Kryczka 9781ef438a Add latest toolchain (gcc-8, etc.) build support for fbcode users (#4923)
Summary:
- When building with internal dependencies, specify this toolchain by setting `ROCKSDB_FBCODE_BUILD_WITH_PLATFORM007=1`
- It is not enabled by default. However, it is enabled for TSAN builds in CI since there is a known problem with TSAN in gcc-5: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71090
- I did not add support for Lua since (1) we agreed to deprecate it, and (2) we only have an internal build for v5.3 with this toolchain while that has breaking changes compared to our current version (v5.2).
Pull Request resolved: https://github.com/facebook/rocksdb/pull/4923

Differential Revision: D13827226

Pulled By: ajkr

fbshipit-source-id: 9aa3388ed3679777cfb15ef8cbcb83c07f62f947
2019-10-30 14:19:18 -07:00
Andrew Kryczka 6720e96b40 release 5.5.6 2017-08-12 14:42:21 -07:00
Andrew Kryczka febc8ac904 fix deletion dropping in intra-L0
Summary:
`KeyNotExistsBeyondOutputLevel` didn't consider L0 files' key-ranges. So if a key only was covered by older L0 files' key-ranges, we would incorrectly drop deletions of that key. This PR just skips the deletion-dropping optimization when output level is L0.
Closes https://github.com/facebook/rocksdb/pull/2726

Differential Revision: D5617286

Pulled By: ajkr

fbshipit-source-id: 4bff1396b06d49a828ba4542f249191052915bce
2017-08-12 14:42:11 -07:00
sdong 2e98ac018f Bump up version to 5.5.5, update HISTORY.md and one more cleaning up 2017-07-18 12:54:12 -07:00
sdong 06bc381059 Update java/rocksjni.pom 2017-07-18 12:50:36 -07:00
sdong 8efefd19b8 Some more files. 2017-07-18 12:21:24 -07:00
sdong b5a99a72e4 Update HISTORY.md 2017-07-18 11:41:17 -07:00
sdong 832b052591 Remove some left-over BSD headers 2017-07-18 11:38:39 -07:00
sdong 64266e8282 Bump up version to 5.5.4 2017-07-18 10:46:24 -07:00
Siying Dong ed1ccaba8b Add back the LevelDB license file
Summary: Closes https://github.com/facebook/rocksdb/pull/2591

Differential Revision: D5432696

Pulled By: siying

fbshipit-source-id: a613230ab916de0b279a65ef429ede65460a8db2
2017-07-18 10:42:29 -07:00
Siying Dong 90b27c4439 Remove the licensing description in CONTRIBUTING.md
Summary: Closes https://github.com/facebook/rocksdb/pull/2590

Differential Revision: D5432539

Pulled By: siying

fbshipit-source-id: 49902453bba3c95c1fb8354441b2198649e52bf4
2017-07-18 10:42:18 -07:00
Siying Dong 5ed2f082d5 Change RocksDB License
Summary: Closes https://github.com/facebook/rocksdb/pull/2589

Differential Revision: D5431502

Pulled By: siying

fbshipit-source-id: 8ebf8c87883daa9daa54b2303d11ce01ab1f6f75
2017-07-18 10:41:51 -07:00
Yi Wu 7f5f0e0c03 Bump version to 5.5.3 2017-07-17 14:31:15 -07:00
Siying Dong 7778d2a467 Fix RocksDB Lite build with CLANG
Summary: Closes https://github.com/facebook/rocksdb/pull/2419

Differential Revision: D5193976

Pulled By: siying

fbshipit-source-id: 62d115edee6043237e9d6ad3c2a05481e162c9eb
2017-07-17 14:27:24 -07:00
Yi Wu 9c15f19c3f Fix db_bench build break with blob db
Summary:
Lite build does not recognize FLAGS_use_blob_db. Fixing it.
Closes https://github.com/facebook/rocksdb/pull/2372

Reviewed By: anirbanr-fb

Differential Revision: D5130773

Pulled By: yiwu-arbug

fbshipit-source-id: 43131d9d0be5811f2129af562be72cca26369cb3
2017-07-17 14:24:27 -07:00
Yi Wu b082e27120 Bump version to 5.5.2 2017-07-13 11:46:47 -07:00
sdong 72cf57d4b4 Apply CLANG Tidy 2017-06-26 17:47:20 -07:00
Aaron Gao 769778e2dc bump version to 5.5.1 2017-06-26 15:24:46 -07:00
Siying Dong e2f851e064 Fix bug that flush doesn't respond to fsync result
Summary:
With a regression bug was introduced two years ago, by https://github.com/facebook/rocksdb/commit/6e9fbeb27c38329f33ae541302c44c8db8374f8c , we fail to check return status of fsync call. This can cause we miss the information from the file system and can potentially cause corrupted data which we could have been detected.
Closes https://github.com/facebook/rocksdb/pull/2495

Reviewed By: ajkr

Differential Revision: D5321949

Pulled By: siying

fbshipit-source-id: c68117914bb40700198fc37d0e4c63163a8a1031
2017-06-26 12:59:48 -07:00
Aaron Gao 09fce6be70 update 5.5 change log
Summary:
update bug fixed.
Closes https://github.com/facebook/rocksdb/pull/2434

Differential Revision: D5218601

Pulled By: lightmark

fbshipit-source-id: 1f86b2c93345673612381081537d464e7d12e434
2017-06-09 11:46:37 -07:00
Adam Retter 343f70fe9b Switch from CentOS 5 to CentOS 6 for crossbuilding RocksJava
Summary:
Updates the statically linked libraries from linking against glibc 2.5, to linking against glibc 2.12.
Closes https://github.com/facebook/rocksdb/pull/2405

Differential Revision: D5184132

Pulled By: sagar0

fbshipit-source-id: 7a8ad4cf7e737ca62f29e58938bd49fa02114541
2017-06-05 16:32:19 -07:00
Aaron Gao cb60842d00 Revert "cross-platform compatibility improvements"
This reverts commit 11c5d4741a.
2017-05-24 18:18:51 -07:00
Aaron Gao a61e7b5f06 Revert "remove #include port/port.h in public header file"
This reverts commit 4c9d2b1046.
2017-05-24 18:18:24 -07:00
Aaron Gao 1182f63f92 update buckifer/TARGETS
Summary:
update targets file for release
Closes https://github.com/facebook/rocksdb/pull/2358

Differential Revision: D5115705

Pulled By: lightmark

fbshipit-source-id: 96a3c7e15b5807b5d0f5a9bb73850b92754b5794
2017-05-24 15:40:03 -07:00
Siying Dong 8fd7fb59e5 range sync should be enabled
Summary:
We forgot to add the new flag in internal build script. Add it.
Closes https://github.com/facebook/rocksdb/pull/2360

Differential Revision: D5121428

Pulled By: siying

fbshipit-source-id: af72d48cd855b37df1ce3c1fbb00c80377ba6e4f
2017-05-24 15:40:03 -07:00
Sagar Vemuri e519921b80 Fix errors in clang-analyzer builds
Summary:
Fix build error in db_iter.cc when running clang-analyzer.
```
  CC       db/db_iter.o
db/db_iter.cc:938:21: error: no matching constructor for initialization of 'rocksdb::ParsedInternalKey'
  ParsedInternalKey ikey(Slice(), 0, 0);
                    ^    ~~~~~~~~~~~~~
./db/dbformat.h:84:3: note: candidate constructor not viable: no known conversion from 'int' to 'rocksdb::ValueType' for 3rd argument
  ParsedInternalKey(const Slice& u, const SequenceNumber& seq, ValueType t)
  ^
./db/dbformat.h:78:8: note: candidate constructor (the implicit copy constructor) not viable: requires 1 argument, but 3 were provided
struct ParsedInternalKey {
       ^
./db/dbformat.h:78:8: note: candidate constructor (the implicit move constructor) not viable: requires 1 argument, but 3 were provided
./db/dbformat.h:83:3: note: candidate constructor not viable: requires 0 arguments, but 3 were provided
  ParsedInternalKey() { }  // Intentionally left uninitialized (for speed)
  ^
1 error generated.
```
Closes https://github.com/facebook/rocksdb/pull/2354

Differential Revision: D5115751

Pulled By: sagar0

fbshipit-source-id: b0e386d4e935e4725b07761c3ca5f7a8cbde3692
2017-05-24 15:40:03 -07:00
Sagar Vemuri a1c62c19cc Fix release build on Linux
Summary:
Release builds are failing on Linux with the error:
```
tools/db_stress.cc: In function ‘int main(int, char**)’:
tools/db_stress.cc:2365:12: error: ‘rocksdb::SyncPoint’ has not been declared
   rocksdb::SyncPoint::GetInstance()->SetCallBack(
            ^
tools/db_stress.cc:2370:12: error: ‘rocksdb::SyncPoint’ has not been declared
   rocksdb::SyncPoint::GetInstance()->SetCallBack(
            ^
tools/db_stress.cc:2375:12: error: ‘rocksdb::SyncPoint’ has not been declared
   rocksdb::SyncPoint::GetInstance()->EnableProcessing();
            ^
make[1]: *** [tools/db_stress.o] Error 1
make[1]: Leaving directory `/data/sandcastle/boxes/trunk-git-rocksdb-public'
make: *** [release] Error 2
```
Closes https://github.com/facebook/rocksdb/pull/2355

Differential Revision: D5113552

Pulled By: sagar0

fbshipit-source-id: 351df707277787da5633ba4a40e52edc7c895dc4
2017-05-24 15:40:03 -07:00
Yi Wu fba9d66416 Fix rocksdb.estimate-num-keys DB property underflow
Summary:
rocksdb.estimate-num-keys is compute from `estimate_num_keys - 2 * estimate_num_deletes`. If  `2 * estimate_num_deletes > estimate_num_keys` it will underflow. Fixing it.
Closes https://github.com/facebook/rocksdb/pull/2348

Differential Revision: D5109272

Pulled By: yiwu-arbug

fbshipit-source-id: e1bfb91346a59b7282a282b615002507e9d7c246
2017-05-23 13:15:10 -07:00
224 changed files with 3076 additions and 6687 deletions

No files matched your search

-1
View File
@@ -31,7 +31,6 @@ build/
ldb
manifest_dump
sst_dump
blob_dump
column_aware_encoding_exp
util/build_version.cc
build_tools/VALGRIND_LOGS/
+31 -31
View File
@@ -7,7 +7,6 @@ os:
compiler:
- clang
- gcc
osx_image: xcode8.3
jdk:
- oraclejdk7
cache:
@@ -16,55 +15,56 @@ cache:
addons:
apt:
packages: ['zlib1g-dev', 'libbz2-dev', 'libsnappy-dev', 'curl', 'libgflags-dev', 'mingw-w64']
sources: ['ubuntu-toolchain-r-test', 'llvm-toolchain-precise-3.6']
packages: ['clang-3.6' , 'g++-6', 'zlib1g-dev', 'libbz2-dev', 'libsnappy-dev', 'curl', 'libgflags-dev', 'mingw-w64']
env:
- TEST_GROUP=platform_dependent # 16-18 minutes
- TEST_GROUP=1 # 33-35 minutes
- TEST_GROUP=2 # 30-32 minutes
- TEST_GROUP=platform_dependent1
- TEST_GROUP=platform_dependent2
- TEST_GROUP=platform_dependent3
- TEST_GROUP=1
- TEST_GROUP=2
# Run java tests
- JOB_NAME=java_test # 4-11 minutes
- JOB_NAME=java_test
# Build ROCKSDB_LITE
- JOB_NAME=lite_build # 3-4 minutes
- JOB_NAME=lite_build
# Build examples
- JOB_NAME=examples # 5-7 minutes
- JOB_NAME=cmake # 3-5 minutes
- JOB_NAME=cmake-mingw # 3 minutes
- JOB_NAME=examples
- JOB_NAME=cmake
- JOB_NAME=cmake-mingw
matrix:
exclude:
- os: osx
compiler: gcc
- os: osx
env: TEST_GROUP=1
- os: osx
env: TEST_GROUP=2
- os : osx
env: JOB_NAME=cmake-mingw
- os : linux
- os: linux
env: JOB_NAME=cmake-mingw
compiler: clang
- os : osx
compiler: gcc
# https://docs.travis-ci.com/user/caching/#ccache-cache
install:
- if [ "${TRAVIS_OS_NAME}" == osx ]; then
brew install ccache;
PATH=$PATH:/usr/local/opt/ccache/libexec;
fi
before_script:
# Increase the maximum number of open file descriptors, since some tests use
# more FDs than the default limit.
- ulimit -n 8192
- if [[ "${TRAVIS_OS_NAME}" == 'linux' && "${CXX}" == 'clang++' ]]; then CXX=clang++-3.6; fi
# test one linux g++ build with g++-6
- if [[ "${TRAVIS_OS_NAME}" == 'linux' && "${CXX}" == 'g++' && "${JOB_NAME}" == 'unittests' ]]; then CXX=g++-6; fi
# Limit the maximum number of open file descriptors to 8192
- ulimit -n 8192 || true
script:
- ${CXX} --version
- if [ "${TEST_GROUP}" == 'platform_dependent' ]; then OPT=-DTRAVIS V=1 make -j4 all; OPT=-DTRAVIS V=1 ROCKSDBTESTS_END=db_block_cache_test make -j4 check_some; fi
- if [ "${TEST_GROUP}" == '1' ]; then OPT=-DTRAVIS V=1 ROCKSDBTESTS_START=db_block_cache_test ROCKSDBTESTS_END=comparator_db_test make -j4 check_some; fi
- if [ "${TEST_GROUP}" == '2' ]; then OPT=-DTRAVIS V=1 ROCKSDBTESTS_START=comparator_db_test make -j4 check_some; fi
- if [ "${JOB_NAME}" == 'java_test' ]; then OPT=-DTRAVIS V=1 make clean jclean && make rocksdbjava jtest; fi
- if [ "${JOB_NAME}" == 'lite_build' ]; then OPT="-DTRAVIS -DROCKSDB_LITE" V=1 make -j4 static_lib; fi
- if [ "${JOB_NAME}" == 'examples' ]; then OPT=-DTRAVIS V=1 make -j4 static_lib; cd examples; make -j4; fi
- if [ "${JOB_NAME}" == 'cmake' ]; then mkdir build && cd build && cmake .. && make -j4 rocksdb; fi
- if [ "${JOB_NAME}" == 'cmake-mingw' ]; then mkdir build && cd build && cmake .. -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++ -DCMAKE_SYSTEM_NAME=Windows && make -j4 rocksdb; fi
- if [[ "${TEST_GROUP}" == 'platform_dependent1' ]]; then OPT=-DTRAVIS V=1 ROCKSDBTESTS_END=external_sst_file_basic_test make -j4 check_some; fi
- if [[ "${TEST_GROUP}" == 'platform_dependent2' ]]; then OPT=-DTRAVIS V=1 ROCKSDBTESTS_START=external_sst_file_basic_test ROCKSDBTESTS_END=checkpoint_test make -j4 check_some; fi
- if [[ "${TEST_GROUP}" == 'platform_dependent3' ]]; then OPT=-DTRAVIS V=1 ROCKSDBTESTS_START=checkpoint_test ROCKSDBTESTS_END=db_block_cache_test make -j4 check_some; fi
- if [[ "${TEST_GROUP}" == '1' ]]; then OPT=-DTRAVIS V=1 ROCKSDBTESTS_START=db_block_cache_test ROCKSDBTESTS_END=comparator_db_test make -j4 check_some; fi
- if [[ "${TEST_GROUP}" == '2' ]]; then OPT=-DTRAVIS V=1 ROCKSDBTESTS_START=comparator_db_test make -j4 check_some; fi
- if [[ "${JOB_NAME}" == 'java_test' ]]; then OPT=-DTRAVIS V=1 make clean jclean && make rocksdbjava jtest; fi
- if [[ "${JOB_NAME}" == 'lite_build' ]]; then OPT="-DTRAVIS -DROCKSDB_LITE" V=1 make -j4 static_lib; fi
- if [[ "${JOB_NAME}" == 'examples' ]]; then OPT=-DTRAVIS V=1 make -j4 static_lib; cd examples; make -j4; fi
- if [[ "${JOB_NAME}" == 'cmake' ]]; then mkdir build && cd build && cmake .. && make -j4 rocksdb; fi
- if [[ "${JOB_NAME}" == 'cmake-mingw' ]]; then mkdir build && cd build && cmake .. -DCMAKE_C_COMPILER=x86_64-w64-mingw32-gcc -DCMAKE_CXX_COMPILER=x86_64-w64-mingw32-g++ -DCMAKE_SYSTEM_NAME=Windows && make -j4 rocksdb; fi
notifications:
email:
- leveldb@fb.com
+24 -63
View File
@@ -106,58 +106,31 @@ if(NOT WIN32)
string(STRIP "${ROCKSDB_VERSION_MAJOR}" ROCKSDB_VERSION_MAJOR)
endif()
option(WITH_MD_LIBRARY "build with MD" ON)
if(WIN32 AND MSVC)
if(WITH_MD_LIBRARY)
set(RUNTIME_LIBRARY "MD")
else()
set(RUNTIME_LIBRARY "MT")
if(WIN32)
option(WITH_AVX2 "build with AVX2" ON)
if(WITH_AVX2)
if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX2")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mavx2")
endif()
endif()
endif()
option(PORTABLE "build a portable binary" OFF)
option(FORCE_SSE42 "force building with SSE4.2, even when PORTABLE=ON" OFF)
if(PORTABLE)
# MSVC does not need a separate compiler flag to enable SSE4.2; if nmmintrin.h
# is available, it is available by default.
if(FORCE_SSE42 AND NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.2")
option(WITH_MD_LIBRARY "build with MD" ON)
if(MSVC)
if(WITH_MD_LIBRARY)
set(RUNTIME_LIBRARY "MD")
else()
set(RUNTIME_LIBRARY "MT")
endif()
endif()
else()
if(MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX2")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")
option(WITH_SSE42 "build with SSE4.2" ON)
if(WITH_SSE42)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msse4.2")
endif()
endif()
set(CMAKE_REQUIRED_FLAGS ${CMAKE_CXX_FLAGS})
include(CheckCXXSourceCompiles)
CHECK_CXX_SOURCE_COMPILES("
#include <cstdint>
#include <nmmintrin.h>
int main() {
volatile uint32_t x = _mm_crc32_u32(0, 0);
}
" HAVE_SSE42)
if(HAVE_SSE42)
add_definitions(-DHAVE_SSE42)
elseif(FORCE_SSE42)
message(FATAL_ERROR "FORCE_SSE42=ON but unable to compile with SSE4.2 enabled")
endif()
CHECK_CXX_SOURCE_COMPILES("
#if defined(_MSC_VER) && !defined(__thread)
#define __thread __declspec(thread)
#endif
int main() {
static __thread int tls;
}
" HAVE_THREAD_LOCAL)
if(HAVE_THREAD_LOCAL)
add_definitions(-DROCKSDB_SUPPORT_THREAD_LOCAL)
endif()
set(BUILD_VERSION_CC ${CMAKE_BINARY_DIR}/build_version.cc)
configure_file(util/build_version.cc.in ${BUILD_VERSION_CC} @ONLY)
add_library(build_version OBJECT ${BUILD_VERSION_CC})
@@ -195,6 +168,7 @@ endif()
option(WITH_ASAN "build with ASAN" OFF)
if(WITH_ASAN)
add_definitions(-DROCKSDB_TSAN_RUN)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=address")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=address")
@@ -206,6 +180,7 @@ endif()
option(WITH_TSAN "build with TSAN" OFF)
if(WITH_TSAN)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread -pie")
add_definitions(-DROCKSDB_TSAN_RUN)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=thread -fPIC")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=thread -fPIC")
if(WITH_JEMALLOC)
@@ -215,7 +190,6 @@ endif()
option(WITH_UBSAN "build with UBSAN" OFF)
if(WITH_UBSAN)
add_definitions(-DROCKSDB_UBSAN_RUN)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=undefined")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fsanitize=undefined")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fsanitize=undefined")
@@ -358,7 +332,6 @@ set(SOURCES
db/internal_stats.cc
db/log_reader.cc
db/log_writer.cc
db/malloc_stats.cc
db/managed_iterator.cc
db/memtable.cc
db/memtable_list.cc
@@ -381,14 +354,13 @@ set(SOURCES
env/env.cc
env/env_chroot.cc
env/env_hdfs.cc
env/mock_env.cc
memtable/alloc_tracker.cc
env/memenv.cc
memtable/hash_cuckoo_rep.cc
memtable/hash_linklist_rep.cc
memtable/hash_skiplist_rep.cc
memtable/memtable_allocator.cc
memtable/skiplistrep.cc
memtable/vectorrep.cc
memtable/write_buffer_manager.cc
monitoring/histogram.cc
monitoring/histogram_windowing.cc
monitoring/instrumented_mutex.cc
@@ -477,7 +449,6 @@ set(SOURCES
utilities/blob_db/blob_db.cc
utilities/blob_db/blob_db_impl.cc
utilities/blob_db/blob_db_options_impl.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
@@ -500,8 +471,6 @@ set(SOURCES
utilities/memory/memory_util.cc
utilities/merge_operators/max.cc
utilities/merge_operators/put.cc
utilities/merge_operators/cassandra/format.cc
utilities/merge_operators/cassandra/merge_operator.cc
utilities/merge_operators/string_append/stringappend.cc
utilities/merge_operators/string_append/stringappend2.cc
utilities/merge_operators/uint64add.cc
@@ -552,7 +521,7 @@ if(WIN32)
set(SYSTEM_LIBS ${SYSTEM_LIBS} Shlwapi.lib Rpcrt4.lib)
set(LIBS ${ROCKSDB_STATIC_LIB} ${THIRDPARTY_LIBS} ${SYSTEM_LIBS})
else()
set(SYSTEM_LIBS ${CMAKE_THREAD_LIBS_INIT})
set(SYSTEM_LIBS ${CMAKE_THREAD_LIBS_INIT} rt)
set(LIBS ${ROCKSDB_SHARED_LIB} ${THIRDPARTY_LIBS} ${SYSTEM_LIBS})
add_library(${ROCKSDB_SHARED_LIB} SHARED ${SOURCES})
@@ -636,7 +605,6 @@ set(TESTS
db/db_test2.cc
db/db_universal_compaction_test.cc
db/db_wal_test.cc
db/db_write_test.cc
db/dbformat_test.cc
db/deletefile_test.cc
db/external_sst_file_basic_test.cc
@@ -669,7 +637,6 @@ set(TESTS
env/mock_env_test.cc
memtable/inlineskiplist_test.cc
memtable/skiplist_test.cc
memtable/write_buffer_manager_test.cc
monitoring/histogram_test.cc
monitoring/iostats_context_test.cc
monitoring/statistics_test.cc
@@ -696,7 +663,6 @@ set(TESTS
util/event_logger_test.cc
util/file_reader_writer_test.cc
util/filelock_test.cc
util/hash_test.cc
util/heap_test.cc
util/rate_limiter_test.cc
util/slice_transform_test.cc
@@ -704,7 +670,6 @@ set(TESTS
util/thread_list_test.cc
util/thread_local_test.cc
utilities/backupable/backupable_db_test.cc
utilities/blob_db/blob_db_test.cc
utilities/checkpoint/checkpoint_test.cc
utilities/column_aware_encoding_test.cc
utilities/date_tiered/date_tiered_test.cc
@@ -713,10 +678,6 @@ set(TESTS
utilities/geodb/geodb_test.cc
utilities/lua/rocks_lua_test.cc
utilities/memory/memory_test.cc
utilities/merge_operators/cassandra/cassandra_merge_test.cc
utilities/merge_operators/cassandra/cassandra_format_test.cc
utilities/merge_operators/cassandra/cassandra_row_merge_test.cc
utilities/merge_operators/cassandra/cassandra_serialize_test.cc
utilities/merge_operators/string_append/stringappend_test.cc
utilities/object_registry_test.cc
utilities/option_change_migration/option_change_migration_test.cc
@@ -754,10 +715,10 @@ endforeach(sourcefile ${BENCHMARKS})
# and linked to tests. Add test only code that is not #ifdefed for Release here.
set(TESTUTIL_SOURCE
db/db_test_util.cc
env/mock_env.cc
monitoring/thread_status_updater_debug.cc
table/mock_table.cc
util/fault_injection_test_env.cc
utilities/merge_operators/cassandra/test_utils.cc
)
# test utilities are only build in debug
enable_testing()
-3
View File
@@ -1,8 +1,5 @@
# RocksDB default options change log
## Unreleased
* delayed_write_rate takes the rate given by rate_limiter if not specified.
## 5.2
* Change the default of delayed slowdown value to 16MB/s and further increase the L0 stop condition to 36 files.
## 5.0 (11/17/2016)
+13 -16
View File
@@ -1,26 +1,23 @@
# Rocksdb Change Log
## 5.6.2 (08/12/2017)
## 5.5.6 (08/12/2017)
### Bug Fixes
* Fix incorrect dropping of deletions during intra-L0 compaction.
## 5.6.1 (07/25/2017)
## 5.5.5 (07/18/2017)
* Change license section of java/rocksjni.pom
* Clear up some files still mentioning PATENTS file
## 5.5.4 (07/18/2017)
* Change License to Apache + GPLv2
## 5.5.3 (07/17/2017)
### Bug Fixes
* Fix lite build.
* Fix LITE build error.
## 5.6.0 (06/06/2017)
### Public API Change
* Scheduling flushes and compactions in the same thread pool is no longer supported by setting `max_background_flushes=0`. Instead, users can achieve this by configuring their high-pri thread pool to have zero threads.
* Replace `Options::max_background_flushes`, `Options::max_background_compactions`, and `Options::base_background_compactions` all with `Options::max_background_jobs`, which automatically decides how many threads to allocate towards flush/compaction.
* options.delayed_write_rate by default take the value of options.rate_limiter rate.
* Replace global variable `IOStatsContext iostats_context` with `IOStatsContext* get_iostats_context()`; replace global variable `PerfContext perf_context` with `PerfContext* get_perf_context()`.
### New Features
* Change ticker/histogram statistics implementations to use core-local storage. This improves aggregation speed compared to our previous thread-local approach, particularly for applications with many threads.
* Users can pass a cache object to write buffer manager, so that they can cap memory usage for memtable and block cache using one single limit.
* Flush will be triggered when 7/8 of the limit introduced by write_buffer_manager or db_write_buffer_size is triggered, so that the hard threshold is hard to hit.
* Introduce WriteOptions.low_pri. If it is true, low priority writes will be throttled if the compaction is behind.
* `DB::IngestExternalFile()` now supports ingesting files into a database containing range deletions.
## 5.5.2 (07/13/2017)
No change from 5.5.1.
## 5.5.1 (06/27/2017)
### Bug Fixes
* Shouldn't ignore return value of fsync() in flush.
+3 -5
View File
@@ -21,11 +21,9 @@ depend on gflags. You will need to have gflags installed to run `make all`. This
use binaries compiled by `make all` in production.
* By default the binary we produce is optimized for the platform you're compiling on
(`-march=native` or the equivalent). SSE4.2 will thus be enabled automatically if your
CPU supports it. To print a warning if your CPU does not support SSE4.2, build with
`USE_SSE=1 make static_lib` or, if using CMake, `cmake -DFORCE_SSE42=ON`. If you want
to build a portable binary, add `PORTABLE=1` before your make commands, like this:
`PORTABLE=1 make static_lib`.
(-march=native or the equivalent). If you want to build a portable binary, add 'PORTABLE=1' before
your make commands, like this: `PORTABLE=1 make static_lib`. If you want to build a binary that
makes use of SSE4, add 'USE_SSE=1' before your make commands, like this: `USE_SSE=1 make static_lib`.
## Dependencies
+6 -42
View File
@@ -193,8 +193,8 @@ endif
ifdef COMPILE_WITH_TSAN
DISABLE_JEMALLOC=1
EXEC_LDFLAGS += -fsanitize=thread
PLATFORM_CCFLAGS += -fsanitize=thread -fPIC
PLATFORM_CXXFLAGS += -fsanitize=thread -fPIC
PLATFORM_CCFLAGS += -fsanitize=thread -fPIC -DROCKSDB_TSAN_RUN
PLATFORM_CXXFLAGS += -fsanitize=thread -fPIC -DROCKSDB_TSAN_RUN
# Turn off -pg when enabling TSAN testing, because that induces
# a link failure. TODO: find the root cause
PROFILING_FLAGS =
@@ -211,8 +211,8 @@ endif
ifdef COMPILE_WITH_UBSAN
DISABLE_JEMALLOC=1
EXEC_LDFLAGS += -fsanitize=undefined
PLATFORM_CCFLAGS += -fsanitize=undefined -DROCKSDB_UBSAN_RUN
PLATFORM_CXXFLAGS += -fsanitize=undefined -DROCKSDB_UBSAN_RUN
PLATFORM_CCFLAGS += -fsanitize=undefined
PLATFORM_CXXFLAGS += -fsanitize=undefined
endif
ifndef DISABLE_JEMALLOC
@@ -335,7 +335,6 @@ TESTS = \
inlineskiplist_test \
env_basic_test \
env_test \
hash_test \
thread_local_test \
rate_limiter_test \
perf_context_test \
@@ -363,9 +362,7 @@ TESTS = \
db_properties_test \
db_table_properties_test \
db_statistics_test \
db_write_test \
autovector_test \
blob_db_test \
cleanable_test \
column_family_test \
table_properties_collector_test \
@@ -401,12 +398,7 @@ TESTS = \
external_sst_file_test \
prefix_test \
skiplist_test \
write_buffer_manager_test \
stringappend_test \
cassandra_format_test \
cassandra_merge_test \
cassandra_row_merge_test \
cassandra_serialize_test \
ttl_test \
date_tiered_test \
backupable_db_test \
@@ -493,8 +485,7 @@ TOOLS = \
ldb \
db_repl_stress \
rocksdb_dump \
rocksdb_undump \
blob_dump \
rocksdb_undump
TEST_LIBS = \
librocksdb_env_basic_test.a
@@ -910,7 +901,7 @@ clean:
rm -rf $(CLEAN_FILES) ios-x86 ios-arm scan_build_report
find . -name "*.[oda]" -exec rm -f {} \;
find . -type f -regex ".*\.\(\(gcda\)\|\(gcno\)\)" -exec rm {} \;
rm -rf bzip2* snappy* zlib* lz4* zstd*
rm -rf bzip2* snappy* zlib* lz4*
cd java; $(MAKE) clean
tags:
@@ -990,27 +981,12 @@ cache_test: cache/cache_test.o $(LIBOBJECTS) $(TESTHARNESS)
coding_test: util/coding_test.o $(LIBOBJECTS) $(TESTHARNESS)
$(AM_LINK)
hash_test: util/hash_test.o $(LIBOBJECTS) $(TESTHARNESS)
$(AM_LINK)
option_change_migration_test: utilities/option_change_migration/option_change_migration_test.o db/db_test_util.o $(LIBOBJECTS) $(TESTHARNESS)
$(AM_LINK)
stringappend_test: utilities/merge_operators/string_append/stringappend_test.o $(LIBOBJECTS) $(TESTHARNESS)
$(AM_LINK)
cassandra_format_test: utilities/merge_operators/cassandra/cassandra_format_test.o $(LIBOBJECTS) $(TESTHARNESS)
$(AM_LINK)
cassandra_merge_test: utilities/merge_operators/cassandra/cassandra_merge_test.o utilities/merge_operators/cassandra/test_utils.o $(LIBOBJECTS) $(TESTHARNESS)
$(AM_LINK)
cassandra_row_merge_test: utilities/merge_operators/cassandra/cassandra_row_merge_test.o utilities/merge_operators/cassandra/test_utils.o $(LIBOBJECTS) $(TESTHARNESS)
$(AM_LINK)
cassandra_serialize_test: utilities/merge_operators/cassandra/cassandra_serialize_test.o $(LIBOBJECTS) $(TESTHARNESS)
$(AM_LINK)
redis_test: utilities/redis/redis_lists_test.o $(LIBOBJECTS) $(TESTHARNESS)
$(AM_LINK)
@@ -1086,9 +1062,6 @@ db_sst_test: db/db_sst_test.o db/db_test_util.o $(LIBOBJECTS) $(TESTHARNESS)
db_statistics_test: db/db_statistics_test.o db/db_test_util.o $(LIBOBJECTS) $(TESTHARNESS)
$(AM_LINK)
db_write_test: db/db_write_test.o db/db_test_util.o $(LIBOBJECTS) $(TESTHARNESS)
$(AM_LINK)
external_sst_file_basic_test: db/external_sst_file_basic_test.o db/db_test_util.o $(LIBOBJECTS) $(TESTHARNESS)
$(AM_LINK)
@@ -1244,9 +1217,6 @@ inlineskiplist_test: memtable/inlineskiplist_test.o $(LIBOBJECTS) $(TESTHARNESS)
skiplist_test: memtable/skiplist_test.o $(LIBOBJECTS) $(TESTHARNESS)
$(AM_LINK)
write_buffer_manager_test: memtable/write_buffer_manager_test.o $(LIBOBJECTS) $(TESTHARNESS)
$(AM_LINK)
version_edit_test: db/version_edit_test.o $(LIBOBJECTS) $(TESTHARNESS)
$(AM_LINK)
@@ -1373,9 +1343,6 @@ transaction_test: utilities/transactions/transaction_test.o $(LIBOBJECTS) $(TEST
sst_dump: tools/sst_dump.o $(LIBOBJECTS)
$(AM_LINK)
blob_dump: tools/blob_dump.o $(LIBOBJECTS)
$(AM_LINK)
column_aware_encoding_exp: utilities/column_aware_encoding_exp.o $(EXPOBJECTS)
$(AM_LINK)
@@ -1406,9 +1373,6 @@ lua_test: utilities/lua/rocks_lua_test.o db/db_test_util.o $(LIBOBJECTS) $(TESTH
range_del_aggregator_test: db/range_del_aggregator_test.o db/db_test_util.o $(LIBOBJECTS) $(TESTHARNESS)
$(AM_LINK)
blob_db_test: utilities/blob_db/blob_db_test.o $(LIBOBJECTS) $(TESTHARNESS)
$(AM_LINK)
#-------------------------------------------------
# make install related stuff
INSTALL_PATH ?= /usr/local
+151 -192
View File
@@ -1,8 +1,4 @@
import os
TARGETS_PATH = os.path.dirname(__file__)
REPO_PATH = TARGETS_PATH[(TARGETS_PATH.find('fbcode/') + len('fbcode/')):] + "/"
REPO_PATH = "internal_repo_rocksdb/repo/"
BUCK_BINS = "buck-out/gen/" + REPO_PATH
TEST_RUNNER = REPO_PATH + "buckifier/rocks_test_runner.sh"
rocksdb_compiler_flags = [
@@ -15,8 +11,6 @@ rocksdb_compiler_flags = [
"-DROCKSDB_MALLOC_USABLE_SIZE",
"-DROCKSDB_RANGESYNC_PRESENT",
"-DROCKSDB_SCHED_GETCPU_PRESENT",
"-DROCKSDB_SUPPORT_THREAD_LOCAL",
"-DHAVE_SSE42",
"-DOS_LINUX",
# Flags to enable libs we include
"-DSNAPPY",
@@ -39,7 +33,7 @@ rocksdb_external_deps = [
('lz4', None, 'lz4'),
('zstd', None),
('tbb', None),
("numa", None, "numa"),
("numa", "2.0.8", "numa"),
("googletest", None, "gtest"),
]
@@ -88,7 +82,6 @@ cpp_library(
"db/internal_stats.cc",
"db/log_reader.cc",
"db/log_writer.cc",
"db/malloc_stats.cc",
"db/managed_iterator.cc",
"db/memtable.cc",
"db/memtable_list.cc",
@@ -113,14 +106,13 @@ cpp_library(
"env/env_hdfs.cc",
"env/env_posix.cc",
"env/io_posix.cc",
"env/mock_env.cc",
"memtable/alloc_tracker.cc",
"env/memenv.cc",
"memtable/hash_cuckoo_rep.cc",
"memtable/hash_linklist_rep.cc",
"memtable/hash_skiplist_rep.cc",
"memtable/memtable_allocator.cc",
"memtable/skiplistrep.cc",
"memtable/vectorrep.cc",
"memtable/write_buffer_manager.cc",
"monitoring/histogram.cc",
"monitoring/histogram_windowing.cc",
"monitoring/instrumented_mutex.cc",
@@ -225,8 +217,6 @@ cpp_library(
"utilities/leveldb_options/leveldb_options.cc",
"utilities/lua/rocks_lua_compaction_filter.cc",
"utilities/memory/memory_util.cc",
"utilities/merge_operators/cassandra/format.cc",
"utilities/merge_operators/cassandra/merge_operator.cc",
"utilities/merge_operators/max.cc",
"utilities/merge_operators/put.cc",
"utilities/merge_operators/string_append/stringappend.cc",
@@ -269,12 +259,12 @@ cpp_library(
name = "rocksdb_test_lib",
headers = AutoHeaders.RECURSIVE_GLOB,
srcs = [
"env/mock_env.cc",
"table/mock_table.cc",
"util/fault_injection_test_env.cc",
"util/testharness.cc",
"util/testutil.cc",
"db/db_test_util.cc",
"utilities/merge_operators/cassandra/test_utils.cc",
"utilities/col_buf_encoder.cc",
"utilities/col_buf_decoder.cc",
"utilities/column_aware_encoding_util.cc",
@@ -309,182 +299,163 @@ cpp_library(
)
# [test_name, test_src, test_type]
ROCKS_TESTS = [['arena_test', 'util/arena_test.cc', 'serial'],
['auto_roll_logger_test', 'util/auto_roll_logger_test.cc', 'serial'],
['autovector_test', 'util/autovector_test.cc', 'serial'],
['backupable_db_test',
'utilities/backupable/backupable_db_test.cc',
'parallel'],
['blob_db_test', 'utilities/blob_db/blob_db_test.cc', 'serial'],
['block_based_filter_block_test',
'table/block_based_filter_block_test.cc',
'serial'],
['block_test', 'table/block_test.cc', 'serial'],
['bloom_test', 'util/bloom_test.cc', 'serial'],
['c_test', 'db/c_test.c', 'serial'],
ROCKS_TESTS = [['merger_test', 'table/merger_test.cc', 'serial'],
['cache_test', 'cache/cache_test.cc', 'serial'],
['cassandra_format_test',
'utilities/merge_operators/cassandra/cassandra_format_test.cc',
'serial'],
['cassandra_merge_test',
'utilities/merge_operators/cassandra/cassandra_merge_test.cc',
'serial'],
['cassandra_row_merge_test',
'utilities/merge_operators/cassandra/cassandra_row_merge_test.cc',
'serial'],
['cassandra_serialize_test',
'utilities/merge_operators/cassandra/cassandra_serialize_test.cc',
'serial'],
['checkpoint_test', 'utilities/checkpoint/checkpoint_test.cc', 'serial'],
['cleanable_test', 'table/cleanable_test.cc', 'serial'],
['coding_test', 'util/coding_test.cc', 'serial'],
['column_aware_encoding_test',
'utilities/column_aware_encoding_test.cc',
'serial'],
['column_family_test', 'db/column_family_test.cc', 'serial'],
['compact_files_test', 'db/compact_files_test.cc', 'serial'],
['compact_on_deletion_collector_test',
'utilities/table_properties_collectors/compact_on_deletion_collector_test.cc',
'serial'],
['compaction_iterator_test', 'db/compaction_iterator_test.cc', 'serial'],
['compaction_job_stats_test', 'db/compaction_job_stats_test.cc', 'serial'],
['compaction_job_test', 'db/compaction_job_test.cc', 'serial'],
['compaction_picker_test', 'db/compaction_picker_test.cc', 'serial'],
['comparator_db_test', 'db/comparator_db_test.cc', 'serial'],
['corruption_test', 'db/corruption_test.cc', 'serial'],
['crc32c_test', 'util/crc32c_test.cc', 'serial'],
['cuckoo_table_builder_test', 'table/cuckoo_table_builder_test.cc', 'serial'],
['cuckoo_table_db_test', 'db/cuckoo_table_db_test.cc', 'serial'],
['cuckoo_table_reader_test', 'table/cuckoo_table_reader_test.cc', 'serial'],
['date_tiered_test', 'utilities/date_tiered/date_tiered_test.cc', 'serial'],
['db_basic_test', 'db/db_basic_test.cc', 'serial'],
['db_block_cache_test', 'db/db_block_cache_test.cc', 'serial'],
['db_bloom_filter_test', 'db/db_bloom_filter_test.cc', 'serial'],
['db_compaction_filter_test', 'db/db_compaction_filter_test.cc', 'parallel'],
['db_compaction_test', 'db/db_compaction_test.cc', 'parallel'],
['db_dynamic_level_test', 'db/db_dynamic_level_test.cc', 'serial'],
['db_encryption_test', 'db/db_encryption_test.cc', 'serial'],
['db_flush_test', 'db/db_flush_test.cc', 'serial'],
['db_inplace_update_test', 'db/db_inplace_update_test.cc', 'serial'],
['db_io_failure_test', 'db/db_io_failure_test.cc', 'serial'],
['db_iter_test', 'db/db_iter_test.cc', 'serial'],
['db_iterator_test', 'db/db_iterator_test.cc', 'serial'],
['db_log_iter_test', 'db/db_log_iter_test.cc', 'serial'],
['db_memtable_test', 'db/db_memtable_test.cc', 'serial'],
['db_merge_operator_test', 'db/db_merge_operator_test.cc', 'serial'],
['db_options_test', 'db/db_options_test.cc', 'serial'],
['db_properties_test', 'db/db_properties_test.cc', 'serial'],
['db_range_del_test', 'db/db_range_del_test.cc', 'serial'],
['db_sst_test', 'db/db_sst_test.cc', 'parallel'],
['db_statistics_test', 'db/db_statistics_test.cc', 'serial'],
['db_table_properties_test', 'db/db_table_properties_test.cc', 'serial'],
['db_tailing_iter_test', 'db/db_tailing_iter_test.cc', 'serial'],
['db_test', 'db/db_test.cc', 'parallel'],
['db_test2', 'db/db_test2.cc', 'serial'],
['db_universal_compaction_test',
'db/db_universal_compaction_test.cc',
'parallel'],
['db_wal_test', 'db/db_wal_test.cc', 'parallel'],
['db_write_test', 'db/db_write_test.cc', 'serial'],
['dbformat_test', 'db/dbformat_test.cc', 'serial'],
['delete_scheduler_test', 'util/delete_scheduler_test.cc', 'serial'],
['deletefile_test', 'db/deletefile_test.cc', 'serial'],
['document_db_test', 'utilities/document/document_db_test.cc', 'serial'],
['dynamic_bloom_test', 'util/dynamic_bloom_test.cc', 'serial'],
['env_basic_test', 'env/env_basic_test.cc', 'serial'],
['env_test', 'env/env_test.cc', 'serial'],
['env_timed_test', 'utilities/env_timed_test.cc', 'serial'],
['event_logger_test', 'util/event_logger_test.cc', 'serial'],
['external_sst_file_basic_test',
'db/external_sst_file_basic_test.cc',
'serial'],
['external_sst_file_test', 'db/external_sst_file_test.cc', 'parallel'],
['fault_injection_test', 'db/fault_injection_test.cc', 'parallel'],
['file_indexer_test', 'db/file_indexer_test.cc', 'serial'],
['file_reader_writer_test', 'util/file_reader_writer_test.cc', 'serial'],
['filelock_test', 'util/filelock_test.cc', 'serial'],
['filename_test', 'db/filename_test.cc', 'serial'],
['flush_job_test', 'db/flush_job_test.cc', 'serial'],
['full_filter_block_test', 'table/full_filter_block_test.cc', 'serial'],
['geodb_test', 'utilities/geodb/geodb_test.cc', 'serial'],
['hash_table_test',
'utilities/persistent_cache/hash_table_test.cc',
'serial'],
['hash_test', 'util/hash_test.cc', 'serial'],
['heap_test', 'util/heap_test.cc', 'serial'],
['histogram_test', 'monitoring/histogram_test.cc', 'serial'],
['inlineskiplist_test', 'memtable/inlineskiplist_test.cc', 'parallel'],
['iostats_context_test', 'monitoring/iostats_context_test.cc', 'serial'],
['json_document_test', 'utilities/document/json_document_test.cc', 'serial'],
['ldb_cmd_test', 'tools/ldb_cmd_test.cc', 'serial'],
['listener_test', 'db/listener_test.cc', 'serial'],
['log_test', 'db/log_test.cc', 'serial'],
['lru_cache_test', 'cache/lru_cache_test.cc', 'serial'],
['manual_compaction_test', 'db/manual_compaction_test.cc', 'parallel'],
['memory_test', 'utilities/memory/memory_test.cc', 'serial'],
['memtable_list_test', 'db/memtable_list_test.cc', 'serial'],
['merge_helper_test', 'db/merge_helper_test.cc', 'serial'],
['merge_test', 'db/merge_test.cc', 'serial'],
['merger_test', 'table/merger_test.cc', 'serial'],
['mock_env_test', 'env/mock_env_test.cc', 'serial'],
['object_registry_test', 'utilities/object_registry_test.cc', 'serial'],
['optimistic_transaction_test',
'utilities/transactions/optimistic_transaction_test.cc',
'serial'],
['option_change_migration_test',
'utilities/option_change_migration/option_change_migration_test.cc',
'serial'],
['options_file_test', 'db/options_file_test.cc', 'serial'],
['options_settable_test', 'options/options_settable_test.cc', 'serial'],
['options_test', 'options/options_test.cc', 'serial'],
['options_util_test', 'utilities/options/options_util_test.cc', 'serial'],
['partitioned_filter_block_test',
'table/partitioned_filter_block_test.cc',
'serial'],
['perf_context_test', 'db/perf_context_test.cc', 'serial'],
['persistent_cache_test',
'utilities/persistent_cache/persistent_cache_test.cc',
'parallel'],
['plain_table_db_test', 'db/plain_table_db_test.cc', 'serial'],
['prefix_test', 'db/prefix_test.cc', 'serial'],
['range_del_aggregator_test', 'db/range_del_aggregator_test.cc', 'serial'],
['rate_limiter_test', 'util/rate_limiter_test.cc', 'serial'],
['reduce_levels_test', 'tools/reduce_levels_test.cc', 'serial'],
['repair_test', 'db/repair_test.cc', 'serial'],
['sim_cache_test', 'utilities/simulator_cache/sim_cache_test.cc', 'serial'],
['skiplist_test', 'memtable/skiplist_test.cc', 'serial'],
['slice_transform_test', 'util/slice_transform_test.cc', 'serial'],
['spatial_db_test', 'utilities/spatialdb/spatial_db_test.cc', 'serial'],
['sst_dump_test', 'tools/sst_dump_test.cc', 'serial'],
['statistics_test', 'monitoring/statistics_test.cc', 'serial'],
['stringappend_test',
'utilities/merge_operators/string_append/stringappend_test.cc',
'serial'],
['compaction_picker_test', 'db/compaction_picker_test.cc', 'serial'],
['db_log_iter_test', 'db/db_log_iter_test.cc', 'serial'],
['thread_list_test', 'util/thread_list_test.cc', 'serial'],
['table_properties_collector_test',
'db/table_properties_collector_test.cc',
'serial'],
['table_test', 'table/table_test.cc', 'parallel'],
['thread_list_test', 'util/thread_list_test.cc', 'serial'],
['thread_local_test', 'util/thread_local_test.cc', 'serial'],
['timer_queue_test', 'util/timer_queue_test.cc', 'serial'],
['transaction_test', 'utilities/transactions/transaction_test.cc', 'serial'],
['ttl_test', 'utilities/ttl/ttl_test.cc', 'serial'],
['util_merge_operators_test',
'utilities/util_merge_operators_test.cc',
['document_db_test', 'utilities/document/document_db_test.cc', 'serial'],
['event_logger_test', 'util/event_logger_test.cc', 'serial'],
['coding_test', 'util/coding_test.cc', 'serial'],
['statistics_test', 'monitoring/statistics_test.cc', 'serial'],
['options_settable_test', 'options/options_settable_test.cc', 'serial'],
['sst_dump_test', 'tools/sst_dump_test.cc', 'serial'],
['column_aware_encoding_test',
'utilities/column_aware_encoding_test.cc',
'serial'],
['version_builder_test', 'db/version_builder_test.cc', 'serial'],
['version_edit_test', 'db/version_edit_test.cc', 'serial'],
['db_iterator_test', 'db/db_iterator_test.cc', 'serial'],
['db_sst_test', 'db/db_sst_test.cc', 'parallel'],
['geodb_test', 'utilities/geodb/geodb_test.cc', 'serial'],
['listener_test', 'db/listener_test.cc', 'serial'],
['write_callback_test', 'db/write_callback_test.cc', 'serial'],
['version_set_test', 'db/version_set_test.cc', 'serial'],
['wal_manager_test', 'db/wal_manager_test.cc', 'serial'],
['write_batch_test', 'db/write_batch_test.cc', 'serial'],
['full_filter_block_test', 'table/full_filter_block_test.cc', 'serial'],
['cleanable_test', 'table/cleanable_test.cc', 'serial'],
['checkpoint_test', 'utilities/checkpoint/checkpoint_test.cc', 'serial'],
['compact_files_test', 'db/compact_files_test.cc', 'serial'],
['db_options_test', 'db/db_options_test.cc', 'serial'],
['object_registry_test', 'utilities/object_registry_test.cc', 'serial'],
['auto_roll_logger_test', 'util/auto_roll_logger_test.cc', 'serial'],
['dbformat_test', 'db/dbformat_test.cc', 'serial'],
['write_batch_with_index_test',
'utilities/write_batch_with_index/write_batch_with_index_test.cc',
'serial'],
['write_buffer_manager_test',
'memtable/write_buffer_manager_test.cc',
['json_document_test', 'utilities/document/json_document_test.cc', 'serial'],
['file_reader_writer_test', 'util/file_reader_writer_test.cc', 'serial'],
['repair_test', 'db/repair_test.cc', 'serial'],
['persistent_cache_test',
'utilities/persistent_cache/persistent_cache_test.cc',
'parallel'],
['db_bloom_filter_test', 'db/db_bloom_filter_test.cc', 'serial'],
['external_sst_file_basic_test',
'db/external_sst_file_basic_test.cc',
'serial'],
['write_callback_test', 'db/write_callback_test.cc', 'serial'],
['write_controller_test', 'db/write_controller_test.cc', 'serial']]
['options_test', 'options/options_test.cc', 'serial'],
['perf_context_test', 'db/perf_context_test.cc', 'serial'],
['db_block_cache_test', 'db/db_block_cache_test.cc', 'serial'],
['heap_test', 'util/heap_test.cc', 'serial'],
['db_test2', 'db/db_test2.cc', 'serial'],
['filelock_test', 'util/filelock_test.cc', 'serial'],
['write_controller_test', 'db/write_controller_test.cc', 'serial'],
['compaction_iterator_test', 'db/compaction_iterator_test.cc', 'serial'],
['spatial_db_test', 'utilities/spatialdb/spatial_db_test.cc', 'serial'],
['c_test', 'db/c_test.c', 'serial'],
['range_del_aggregator_test', 'db/range_del_aggregator_test.cc', 'serial'],
['date_tiered_test', 'utilities/date_tiered/date_tiered_test.cc', 'serial'],
['ldb_cmd_test', 'tools/ldb_cmd_test.cc', 'serial'],
['db_test', 'db/db_test.cc', 'parallel'],
['block_based_filter_block_test',
'table/block_based_filter_block_test.cc',
'serial'],
['merge_test', 'db/merge_test.cc', 'serial'],
['bloom_test', 'util/bloom_test.cc', 'serial'],
['block_test', 'table/block_test.cc', 'serial'],
['cuckoo_table_builder_test', 'table/cuckoo_table_builder_test.cc', 'serial'],
['backupable_db_test',
'utilities/backupable/backupable_db_test.cc',
'parallel'],
['db_flush_test', 'db/db_flush_test.cc', 'serial'],
['filename_test', 'db/filename_test.cc', 'serial'],
['cuckoo_table_reader_test', 'table/cuckoo_table_reader_test.cc', 'serial'],
['slice_transform_test', 'util/slice_transform_test.cc', 'serial'],
['cuckoo_table_db_test', 'db/cuckoo_table_db_test.cc', 'serial'],
['inlineskiplist_test', 'memtable/inlineskiplist_test.cc', 'parallel'],
['optimistic_transaction_test',
'utilities/transactions/optimistic_transaction_test.cc',
'serial'],
['hash_table_test',
'utilities/persistent_cache/hash_table_test.cc',
'serial'],
['db_dynamic_level_test', 'db/db_dynamic_level_test.cc', 'serial'],
['option_change_migration_test',
'utilities/option_change_migration/option_change_migration_test.cc',
'serial'],
['db_inplace_update_test', 'db/db_inplace_update_test.cc', 'serial'],
['autovector_test', 'util/autovector_test.cc', 'serial'],
['db_iter_test', 'db/db_iter_test.cc', 'serial'],
['flush_job_test', 'db/flush_job_test.cc', 'serial'],
['wal_manager_test', 'db/wal_manager_test.cc', 'serial'],
['write_batch_test', 'db/write_batch_test.cc', 'serial'],
['crc32c_test', 'util/crc32c_test.cc', 'serial'],
['rate_limiter_test', 'util/rate_limiter_test.cc', 'serial'],
['external_sst_file_test', 'db/external_sst_file_test.cc', 'parallel'],
['compaction_job_test', 'db/compaction_job_test.cc', 'serial'],
['mock_env_test', 'env/mock_env_test.cc', 'serial'],
['db_table_properties_test', 'db/db_table_properties_test.cc', 'serial'],
['db_compaction_test', 'db/db_compaction_test.cc', 'parallel'],
['arena_test', 'util/arena_test.cc', 'serial'],
['stringappend_test',
'utilities/merge_operators/string_append/stringappend_test.cc',
'serial'],
['reduce_levels_test', 'tools/reduce_levels_test.cc', 'serial'],
['prefix_test', 'db/prefix_test.cc', 'serial'],
['ttl_test', 'utilities/ttl/ttl_test.cc', 'serial'],
['merge_helper_test', 'db/merge_helper_test.cc', 'serial'],
['file_indexer_test', 'db/file_indexer_test.cc', 'serial'],
['db_statistics_test', 'db/db_statistics_test.cc', 'serial'],
['memory_test', 'utilities/memory/memory_test.cc', 'serial'],
['log_test', 'db/log_test.cc', 'serial'],
['env_timed_test', 'utilities/env_timed_test.cc', 'serial'],
['deletefile_test', 'db/deletefile_test.cc', 'serial'],
['partitioned_filter_block_test',
'table/partitioned_filter_block_test.cc',
'serial'],
['comparator_db_test', 'db/comparator_db_test.cc', 'serial'],
['compaction_job_stats_test', 'db/compaction_job_stats_test.cc', 'serial'],
['thread_local_test', 'util/thread_local_test.cc', 'serial'],
['version_builder_test', 'db/version_builder_test.cc', 'serial'],
['db_range_del_test', 'db/db_range_del_test.cc', 'serial'],
['table_test', 'table/table_test.cc', 'parallel'],
['db_tailing_iter_test', 'db/db_tailing_iter_test.cc', 'serial'],
['db_compaction_filter_test', 'db/db_compaction_filter_test.cc', 'parallel'],
['options_util_test', 'utilities/options/options_util_test.cc', 'serial'],
['dynamic_bloom_test', 'util/dynamic_bloom_test.cc', 'serial'],
['db_basic_test', 'db/db_basic_test.cc', 'serial'],
['db_merge_operator_test', 'db/db_merge_operator_test.cc', 'serial'],
['manual_compaction_test', 'db/manual_compaction_test.cc', 'parallel'],
['delete_scheduler_test', 'util/delete_scheduler_test.cc', 'serial'],
['transaction_test', 'utilities/transactions/transaction_test.cc', 'serial'],
['db_io_failure_test', 'db/db_io_failure_test.cc', 'serial'],
['corruption_test', 'db/corruption_test.cc', 'serial'],
['compact_on_deletion_collector_test',
'utilities/table_properties_collectors/compact_on_deletion_collector_test.cc',
'serial'],
['env_test', 'env/env_test.cc', 'serial'],
['db_wal_test', 'db/db_wal_test.cc', 'parallel'],
['timer_queue_test', 'util/timer_queue_test.cc', 'serial'],
['sim_cache_test', 'utilities/simulator_cache/sim_cache_test.cc', 'serial'],
['db_memtable_test', 'db/db_memtable_test.cc', 'serial'],
['db_universal_compaction_test',
'db/db_universal_compaction_test.cc',
'parallel'],
['histogram_test', 'monitoring/histogram_test.cc', 'serial'],
['util_merge_operators_test',
'utilities/util_merge_operators_test.cc',
'serial'],
['fault_injection_test', 'db/fault_injection_test.cc', 'parallel'],
['env_basic_test', 'env/env_basic_test.cc', 'serial'],
['iostats_context_test', 'monitoring/iostats_context_test.cc', 'serial'],
['memtable_list_test', 'db/memtable_list_test.cc', 'serial'],
['column_family_test', 'db/column_family_test.cc', 'serial'],
['db_properties_test', 'db/db_properties_test.cc', 'serial'],
['version_edit_test', 'db/version_edit_test.cc', 'serial'],
['skiplist_test', 'memtable/skiplist_test.cc', 'serial'],
['lru_cache_test', 'cache/lru_cache_test.cc', 'serial'],
['plain_table_db_test', 'db/plain_table_db_test.cc', 'serial']]
# Generate a test rule for each entry in ROCKS_TESTS
@@ -509,15 +480,3 @@ for test_cfg in ROCKS_TESTS:
deps = [":" + test_bin],
command = [TEST_RUNNER, BUCK_BINS + test_bin]
)
custom_unittest(
name = "make_rocksdbjavastatic",
type = "simple",
command = ["internal_repo_rocksdb/make_rocksdbjavastatic.sh"],
)
custom_unittest(
name = "make_rocksdb_lite_release",
type = "simple",
command = ["internal_repo_rocksdb/make_rocksdb_lite_release.sh"],
)
-2
View File
@@ -1,2 +0,0 @@
arcanist_util are only used internaly, If you want to change it please check
<internal_rocksdb_repo>/arcanist_util
+2 -2
View File
@@ -84,7 +84,7 @@ def get_tests(repo_path):
else:
# we consumed all the parallel tests
break
return tests
@@ -122,7 +122,7 @@ def generate_targets(repo_path):
[":rocksdb_lib"])
# test for every test we found in the Makefile
for test in sorted(tests):
for test in 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))
+2 -7
View File
@@ -2,11 +2,7 @@ from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
rocksdb_target_header = """
import os
TARGETS_PATH = os.path.dirname(__file__)
REPO_PATH = TARGETS_PATH[(TARGETS_PATH.find('fbcode/') + len('fbcode/')):] + "/"
rocksdb_target_header = """REPO_PATH = "internal_repo_rocksdb/repo/"
BUCK_BINS = "buck-out/gen/" + REPO_PATH
TEST_RUNNER = REPO_PATH + "buckifier/rocks_test_runner.sh"
rocksdb_compiler_flags = [
@@ -20,7 +16,6 @@ rocksdb_compiler_flags = [
"-DROCKSDB_RANGESYNC_PRESENT",
"-DROCKSDB_SCHED_GETCPU_PRESENT",
"-DROCKSDB_SUPPORT_THREAD_LOCAL",
"-DHAVE_SSE42",
"-DOS_LINUX",
# Flags to enable libs we include
"-DSNAPPY",
@@ -43,7 +38,7 @@ rocksdb_external_deps = [
('lz4', None, 'lz4'),
('zstd', None),
('tbb', None),
("numa", None, "numa"),
("numa", "2.0.8", "numa"),
("googletest", None, "gtest"),
]
+7 -31
View File
@@ -444,8 +444,14 @@ if test "$USE_HDFS"; then
JAVA_LDFLAGS="$JAVA_LDFLAGS $HDFS_LDFLAGS"
fi
if [ "$TARGET_OS" = FreeBSD -a "$TARGET_ARCHITECTURE" = i386 ]; then
# Intel SSE instructions breaks compilation on FreeBSD i386
unset USE_SSE
fi
if test "$USE_SSE"; then
COMMON_FLAGS="$COMMON_FLAGS -msse4.2"
# if Intel SSE instruction set is supported, set USE_SSE=1
COMMON_FLAGS="$COMMON_FLAGS -msse -msse4.2 "
elif test -z "$PORTABLE"; then
if test -n "`echo $TARGET_ARCHITECTURE | grep ^ppc64`"; then
# Tune for this POWER processor, treating '+' models as base models
@@ -458,36 +464,6 @@ elif test -z "$PORTABLE"; then
fi
fi
$CXX $COMMON_FLAGS -x c++ - -o /dev/null 2>/dev/null <<EOF
#include <cstdint>
#include <nmmintrin.h>
int main() {
volatile uint32_t x = _mm_crc32_u32(0, 0);
}
EOF
if [ "$?" = 0 ]; then
COMMON_FLAGS="$COMMON_FLAGS -DHAVE_SSE42"
elif test "$USE_SSE"; then
echo "warning: USE_SSE specified but compiler could not use SSE intrinsics, disabling"
fi
# iOS doesn't support thread-local storage, but this check would erroneously
# succeed because the cross-compiler flags are added by the Makefile, not this
# script.
if [ "$PLATFORM" != IOS ]; then
$CXX $COMMON_FLAGS -x c++ - -o /dev/null 2>/dev/null <<EOF
#if defined(_MSC_VER) && !defined(__thread)
#define __thread __declspec(thread)
#endif
int main() {
static __thread int tls;
}
EOF
if [ "$?" = 0 ]; then
COMMON_FLAGS="$COMMON_FLAGS -DROCKSDB_SUPPORT_THREAD_LOCAL"
fi
fi
PLATFORM_CCFLAGS="$PLATFORM_CCFLAGS $COMMON_FLAGS"
PLATFORM_CXXFLAGS="$PLATFORM_CXXFLAGS $COMMON_FLAGS"
+1 -1
View File
@@ -128,7 +128,7 @@ else
fi
CFLAGS+=" $DEPS_INCLUDE"
CFLAGS+=" -DROCKSDB_PLATFORM_POSIX -DROCKSDB_LIB_IO_POSIX -DROCKSDB_FALLOCATE_PRESENT -DROCKSDB_MALLOC_USABLE_SIZE -DROCKSDB_RANGESYNC_PRESENT -DROCKSDB_SCHED_GETCPU_PRESENT -DROCKSDB_SUPPORT_THREAD_LOCAL -DHAVE_SSE42"
CFLAGS+=" -DROCKSDB_PLATFORM_POSIX -DROCKSDB_LIB_IO_POSIX -DROCKSDB_FALLOCATE_PRESENT -DROCKSDB_MALLOC_USABLE_SIZE -DROCKSDB_RANGESYNC_PRESENT -DROCKSDB_SCHED_GETCPU_PRESENT -DROCKSDB_SUPPORT_THREAD_LOCAL"
CXXFLAGS+=" $CFLAGS"
EXEC_LDFLAGS=" $SNAPPY_LIBS $ZLIB_LIBS $BZIP_LIBS $LZ4_LIBS $ZSTD_LIBS $GFLAGS_LIBS $NUMA_LIB $TBB_LIBS"
+1 -1
View File
@@ -93,7 +93,7 @@ else
fi
CFLAGS+=" $DEPS_INCLUDE"
CFLAGS+=" -DROCKSDB_PLATFORM_POSIX -DROCKSDB_LIB_IO_POSIX -DROCKSDB_FALLOCATE_PRESENT -DROCKSDB_MALLOC_USABLE_SIZE -DROCKSDB_RANGESYNC_PRESENT -DROCKSDB_SCHED_GETCPU_PRESENT -DROCKSDB_SUPPORT_THREAD_LOCAL -DHAVE_SSE42"
CFLAGS+=" -DROCKSDB_PLATFORM_POSIX -DROCKSDB_LIB_IO_POSIX -DROCKSDB_FALLOCATE_PRESENT -DROCKSDB_MALLOC_USABLE_SIZE -DROCKSDB_RANGESYNC_PRESENT -DROCKSDB_SCHED_GETCPU_PRESENT -DROCKSDB_SUPPORT_THREAD_LOCAL"
CFLAGS+=" -DSNAPPY -DGFLAGS=google -DZLIB -DBZIP2 -DLZ4 -DZSTD -DNUMA -DTBB"
CXXFLAGS+=" $CFLAGS"
+53
View File
@@ -0,0 +1,53 @@
#!/bin/bash
# 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).
set -e
if [ -z "$GIT" ]
then
GIT="git"
fi
# Print out the colored progress info so that it can be brainlessly
# distinguished by users.
function title() {
echo -e "\033[1;32m$*\033[0m"
}
usage="Create new RocksDB version and prepare it for the release process\n"
usage+="USAGE: ./make_new_version.sh <version> [<remote>]\n"
usage+=" version: specify a version without '.fb' suffix (e.g. 5.4).\n"
usage+=" remote: name of the remote to push the branch to (default: origin)."
# -- Pre-check
if [[ $# < 1 ]]; then
echo -e $usage
exit 1
fi
ROCKSDB_VERSION=$1
REMOTE="origin"
if [[ $# > 1 ]]; then
REMOTE=$2
fi
GIT_BRANCH=`git rev-parse --abbrev-ref HEAD`
echo $GIT_BRANCH
if [ $GIT_BRANCH != "master" ]; then
echo "Error: Current branch is '$GIT_BRANCH', Please switch to master branch."
exit 1
fi
title "Adding new tag for this release ..."
BRANCH="$ROCKSDB_VERSION.fb"
$GIT checkout -b $BRANCH
# Setting up the proxy for remote repo access
title "Pushing new branch to remote repo ..."
git push $REMOTE --set-upstream $BRANCH
title "Branch $BRANCH is pushed to github;"
+1 -1
View File
@@ -333,7 +333,7 @@ function RunJobs($Suites, $TestCmds, [int]$ConcurrencyVal)
$Cases = @{}
if($Suites.Count -gt 0) {
# Will the first one
# Will teh first one
ForEach($e in $Suites.Keys) {
$exe_name = $e
$Cases = $Suites[$e]
+1 -20
View File
@@ -2839,26 +2839,7 @@ void rocksdb_sstfilewriter_open(rocksdb_sstfilewriter_t* writer,
void rocksdb_sstfilewriter_add(rocksdb_sstfilewriter_t* writer, const char* key,
size_t keylen, const char* val, size_t vallen,
char** errptr) {
SaveError(errptr, writer->rep->Put(Slice(key, keylen), Slice(val, vallen)));
}
void rocksdb_sstfilewriter_put(rocksdb_sstfilewriter_t* writer, const char* key,
size_t keylen, const char* val, size_t vallen,
char** errptr) {
SaveError(errptr, writer->rep->Put(Slice(key, keylen), Slice(val, vallen)));
}
void rocksdb_sstfilewriter_merge(rocksdb_sstfilewriter_t* writer,
const char* key, size_t keylen,
const char* val, size_t vallen,
char** errptr) {
SaveError(errptr, writer->rep->Merge(Slice(key, keylen), Slice(val, vallen)));
}
void rocksdb_sstfilewriter_delete(rocksdb_sstfilewriter_t* writer,
const char* key, size_t keylen,
char** errptr) {
SaveError(errptr, writer->rep->Delete(Slice(key, keylen)));
SaveError(errptr, writer->rep->Add(Slice(key, keylen), Slice(val, vallen)));
}
void rocksdb_sstfilewriter_finish(rocksdb_sstfilewriter_t* writer,
+6 -6
View File
@@ -569,11 +569,11 @@ int main(int argc, char** argv) {
unlink(sstfilename);
rocksdb_sstfilewriter_open(writer, sstfilename, &err);
CheckNoError(err);
rocksdb_sstfilewriter_put(writer, "sstk1", 5, "v1", 2, &err);
rocksdb_sstfilewriter_add(writer, "sstk1", 5, "v1", 2, &err);
CheckNoError(err);
rocksdb_sstfilewriter_put(writer, "sstk2", 5, "v2", 2, &err);
rocksdb_sstfilewriter_add(writer, "sstk2", 5, "v2", 2, &err);
CheckNoError(err);
rocksdb_sstfilewriter_put(writer, "sstk3", 5, "v3", 2, &err);
rocksdb_sstfilewriter_add(writer, "sstk3", 5, "v3", 2, &err);
CheckNoError(err);
rocksdb_sstfilewriter_finish(writer, &err);
CheckNoError(err);
@@ -590,11 +590,11 @@ int main(int argc, char** argv) {
unlink(sstfilename);
rocksdb_sstfilewriter_open(writer, sstfilename, &err);
CheckNoError(err);
rocksdb_sstfilewriter_put(writer, "sstk2", 5, "v4", 2, &err);
rocksdb_sstfilewriter_add(writer, "sstk2", 5, "v4", 2, &err);
CheckNoError(err);
rocksdb_sstfilewriter_put(writer, "sstk22", 6, "v5", 2, &err);
rocksdb_sstfilewriter_add(writer, "sstk22", 6, "v5", 2, &err);
CheckNoError(err);
rocksdb_sstfilewriter_put(writer, "sstk3", 5, "v6", 2, &err);
rocksdb_sstfilewriter_add(writer, "sstk3", 5, "v6", 2, &err);
CheckNoError(err);
rocksdb_sstfilewriter_finish(writer, &err);
CheckNoError(err);
+4 -11
View File
@@ -347,7 +347,6 @@ ColumnFamilyData::ColumnFamilyData(
dummy_versions_(_dummy_versions),
current_(nullptr),
refs_(0),
initialized_(false),
dropped_(false),
internal_comparator_(cf_options.comparator),
initial_cf_options_(SanitizeOptions(db_options, cf_options)),
@@ -550,7 +549,7 @@ std::unique_ptr<WriteControllerToken> SetupDelay(
// If DB just falled into the stop condition, we need to further reduce
// the write rate to avoid the stop condition.
if (penalize_stop) {
// Penalize the near stop or stop condition by more aggressive slowdown.
// Penalize the near stop or stop condition by more agressive slowdown.
// This is to provide the long term slowdown increase signal.
// The penalty is more than the reward of recovering to the normal
// condition.
@@ -728,7 +727,7 @@ void ColumnFamilyData::RecalculateWriteStallConditions(
mutable_cf_options.level0_slowdown_writes_trigger)) {
write_controller_token_ =
write_controller->GetCompactionPressureToken();
ROCKS_LOG_INFO(
ROCKS_LOG_WARN(
ioptions_.info_log,
"[%s] Increasing compaction threads because we have %d level-0 "
"files ",
@@ -742,7 +741,7 @@ void ColumnFamilyData::RecalculateWriteStallConditions(
write_controller_token_ =
write_controller->GetCompactionPressureToken();
if (mutable_cf_options.soft_pending_compaction_bytes_limit > 0) {
ROCKS_LOG_INFO(
ROCKS_LOG_WARN(
ioptions_.info_log,
"[%s] Increasing compaction threads because of estimated pending "
"compaction "
@@ -759,12 +758,6 @@ void ColumnFamilyData::RecalculateWriteStallConditions(
uint64_t write_rate = write_controller->delayed_write_rate();
write_controller->set_delayed_write_rate(static_cast<uint64_t>(
static_cast<double>(write_rate) * kDelayRecoverSlowdownRatio));
// Set the low pri limit to be 1/4 the delayed write rate.
// Note we don't reset this value even after delay condition is relased.
// Low-pri rate will continue to apply if there is a compaction
// pressure.
write_controller->low_pri_rate_limiter()->SetBytesPerSecond(write_rate /
4);
}
}
prev_compaction_needed_bytes_ = compaction_needed_bytes;
@@ -790,7 +783,7 @@ uint64_t ColumnFamilyData::GetTotalSstFilesSize() const {
MemTable* ColumnFamilyData::ConstructNewMemtable(
const MutableCFOptions& mutable_cf_options, SequenceNumber earliest_seq) {
return new MemTable(internal_comparator_, ioptions_, mutable_cf_options,
write_buffer_manager_, earliest_seq, id_);
write_buffer_manager_, earliest_seq);
}
void ColumnFamilyData::CreateNewMemtable(
-5
View File
@@ -333,10 +333,6 @@ class ColumnFamilyData {
void RecalculateWriteStallConditions(
const MutableCFOptions& mutable_cf_options);
void set_initialized() { initialized_.store(true); }
bool initialized() const { return initialized_.load(); }
private:
friend class ColumnFamilySet;
ColumnFamilyData(uint32_t id, const std::string& name,
@@ -353,7 +349,6 @@ class ColumnFamilyData {
Version* current_; // == dummy_versions->prev_
std::atomic<int> refs_; // outstanding references to ColumnFamilyData
std::atomic<bool> initialized_;
bool dropped_; // true if client dropped it
const InternalKeyComparator internal_comparator_;
+29 -55
View File
@@ -520,30 +520,6 @@ TEST_F(ColumnFamilyTest, DontReuseColumnFamilyID) {
}
}
#ifndef ROCKSDB_LITE
TEST_F(ColumnFamilyTest, CreateCFRaceWithGetAggProperty) {
Open();
rocksdb::SyncPoint::GetInstance()->LoadDependency(
{{"DBImpl::WriteOptionsFile:1",
"ColumnFamilyTest.CreateCFRaceWithGetAggProperty:1"},
{"ColumnFamilyTest.CreateCFRaceWithGetAggProperty:2",
"DBImpl::WriteOptionsFile:2"}});
rocksdb::SyncPoint::GetInstance()->EnableProcessing();
rocksdb::port::Thread thread([&] { CreateColumnFamilies({"one"}); });
TEST_SYNC_POINT("ColumnFamilyTest.CreateCFRaceWithGetAggProperty:1");
uint64_t pv;
db_->GetAggregatedIntProperty(DB::Properties::kEstimateTableReadersMem, &pv);
TEST_SYNC_POINT("ColumnFamilyTest.CreateCFRaceWithGetAggProperty:2");
thread.join();
rocksdb::SyncPoint::GetInstance()->DisableProcessing();
}
#endif // !ROCKSDB_LITE
class FlushEmptyCFTestWithParam : public ColumnFamilyTest,
public testing::WithParamInterface<bool> {
public:
@@ -1403,6 +1379,7 @@ TEST_F(ColumnFamilyTest, AutomaticAndManualCompactions) {
ColumnFamilyOptions default_cf, one, two;
db_options_.max_open_files = 20; // only 10 files in file cache
db_options_.max_background_compactions = 3;
db_options_.base_background_compactions = 3;
default_cf.compaction_style = kCompactionStyleLevel;
default_cf.num_levels = 3;
@@ -1426,9 +1403,6 @@ TEST_F(ColumnFamilyTest, AutomaticAndManualCompactions) {
two.write_buffer_size = 100000;
Reopen({default_cf, one, two});
// make sure all background compaction jobs can be scheduled
auto stop_token =
dbfull()->TEST_write_controler().GetCompactionPressureToken();
bool cf_1_1 = true;
rocksdb::SyncPoint::GetInstance()->LoadDependency(
@@ -1488,6 +1462,7 @@ TEST_F(ColumnFamilyTest, AutomaticAndManualCompactions) {
ASSERT_NE("NOT_FOUND", Get(1, *key_iter));
key_iter++;
}
Close();
}
TEST_F(ColumnFamilyTest, ManualAndAutomaticCompactions) {
@@ -1496,6 +1471,7 @@ TEST_F(ColumnFamilyTest, ManualAndAutomaticCompactions) {
ColumnFamilyOptions default_cf, one, two;
db_options_.max_open_files = 20; // only 10 files in file cache
db_options_.max_background_compactions = 3;
db_options_.base_background_compactions = 3;
default_cf.compaction_style = kCompactionStyleLevel;
default_cf.num_levels = 3;
@@ -1519,9 +1495,6 @@ TEST_F(ColumnFamilyTest, ManualAndAutomaticCompactions) {
two.write_buffer_size = 100000;
Reopen({default_cf, one, two});
// make sure all background compaction jobs can be scheduled
auto stop_token =
dbfull()->TEST_write_controler().GetCompactionPressureToken();
// SETUP column family "one" -- universal style
for (int i = 0; i < one.level0_file_num_compaction_trigger - 2; ++i) {
@@ -1584,6 +1557,7 @@ TEST_F(ColumnFamilyTest, ManualAndAutomaticCompactions) {
ASSERT_NE("NOT_FOUND", Get(1, *key_iter));
key_iter++;
}
Close();
}
TEST_F(ColumnFamilyTest, SameCFManualManualCompactions) {
@@ -1592,6 +1566,7 @@ TEST_F(ColumnFamilyTest, SameCFManualManualCompactions) {
ColumnFamilyOptions default_cf, one;
db_options_.max_open_files = 20; // only 10 files in file cache
db_options_.max_background_compactions = 3;
db_options_.base_background_compactions = 3;
default_cf.compaction_style = kCompactionStyleLevel;
default_cf.num_levels = 3;
@@ -1610,9 +1585,6 @@ TEST_F(ColumnFamilyTest, SameCFManualManualCompactions) {
one.write_buffer_size = 120000;
Reopen({default_cf, one});
// make sure all background compaction jobs can be scheduled
auto stop_token =
dbfull()->TEST_write_controler().GetCompactionPressureToken();
// SETUP column family "one" -- universal style
for (int i = 0; i < one.level0_file_num_compaction_trigger - 2; ++i) {
@@ -1683,6 +1655,7 @@ TEST_F(ColumnFamilyTest, SameCFManualManualCompactions) {
ASSERT_NE("NOT_FOUND", Get(1, *key_iter));
key_iter++;
}
Close();
}
TEST_F(ColumnFamilyTest, SameCFManualAutomaticCompactions) {
@@ -1691,6 +1664,7 @@ TEST_F(ColumnFamilyTest, SameCFManualAutomaticCompactions) {
ColumnFamilyOptions default_cf, one;
db_options_.max_open_files = 20; // only 10 files in file cache
db_options_.max_background_compactions = 3;
db_options_.base_background_compactions = 3;
default_cf.compaction_style = kCompactionStyleLevel;
default_cf.num_levels = 3;
@@ -1709,9 +1683,6 @@ TEST_F(ColumnFamilyTest, SameCFManualAutomaticCompactions) {
one.write_buffer_size = 120000;
Reopen({default_cf, one});
// make sure all background compaction jobs can be scheduled
auto stop_token =
dbfull()->TEST_write_controler().GetCompactionPressureToken();
// SETUP column family "one" -- universal style
for (int i = 0; i < one.level0_file_num_compaction_trigger - 2; ++i) {
@@ -1773,6 +1744,7 @@ TEST_F(ColumnFamilyTest, SameCFManualAutomaticCompactions) {
ASSERT_NE("NOT_FOUND", Get(1, *key_iter));
key_iter++;
}
Close();
}
TEST_F(ColumnFamilyTest, SameCFManualAutomaticCompactionsLevel) {
@@ -1781,6 +1753,7 @@ TEST_F(ColumnFamilyTest, SameCFManualAutomaticCompactionsLevel) {
ColumnFamilyOptions default_cf, one;
db_options_.max_open_files = 20; // only 10 files in file cache
db_options_.max_background_compactions = 3;
db_options_.base_background_compactions = 3;
default_cf.compaction_style = kCompactionStyleLevel;
default_cf.num_levels = 3;
@@ -1799,9 +1772,6 @@ TEST_F(ColumnFamilyTest, SameCFManualAutomaticCompactionsLevel) {
one.write_buffer_size = 120000;
Reopen({default_cf, one});
// make sure all background compaction jobs can be scheduled
auto stop_token =
dbfull()->TEST_write_controler().GetCompactionPressureToken();
// SETUP column family "one" -- level style
for (int i = 0; i < one.level0_file_num_compaction_trigger - 2; ++i) {
@@ -1863,6 +1833,7 @@ TEST_F(ColumnFamilyTest, SameCFManualAutomaticCompactionsLevel) {
ASSERT_NE("NOT_FOUND", Get(1, *key_iter));
key_iter++;
}
Close();
}
// This test checks for automatic getting a conflict if there is a
@@ -1878,6 +1849,7 @@ TEST_F(ColumnFamilyTest, SameCFManualAutomaticConflict) {
ColumnFamilyOptions default_cf, one;
db_options_.max_open_files = 20; // only 10 files in file cache
db_options_.max_background_compactions = 3;
db_options_.base_background_compactions = 3;
default_cf.compaction_style = kCompactionStyleLevel;
default_cf.num_levels = 3;
@@ -1896,9 +1868,6 @@ TEST_F(ColumnFamilyTest, SameCFManualAutomaticConflict) {
one.write_buffer_size = 120000;
Reopen({default_cf, one});
// make sure all background compaction jobs can be scheduled
auto stop_token =
dbfull()->TEST_write_controler().GetCompactionPressureToken();
// SETUP column family "one" -- universal style
for (int i = 0; i < one.level0_file_num_compaction_trigger - 2; ++i) {
@@ -1983,6 +1952,8 @@ TEST_F(ColumnFamilyTest, SameCFManualAutomaticConflict) {
ASSERT_NE("NOT_FOUND", Get(1, *key_iter));
key_iter++;
}
Close();
}
// In this test, we generate enough files to trigger automatic compactions.
@@ -1997,6 +1968,7 @@ TEST_F(ColumnFamilyTest, SameCFAutomaticManualCompactions) {
ColumnFamilyOptions default_cf, one;
db_options_.max_open_files = 20; // only 10 files in file cache
db_options_.max_background_compactions = 3;
db_options_.base_background_compactions = 3;
default_cf.compaction_style = kCompactionStyleLevel;
default_cf.num_levels = 3;
@@ -2015,9 +1987,6 @@ TEST_F(ColumnFamilyTest, SameCFAutomaticManualCompactions) {
one.write_buffer_size = 120000;
Reopen({default_cf, one});
// make sure all background compaction jobs can be scheduled
auto stop_token =
dbfull()->TEST_write_controler().GetCompactionPressureToken();
bool cf_1_1 = true;
bool cf_1_2 = true;
@@ -2072,6 +2041,8 @@ TEST_F(ColumnFamilyTest, SameCFAutomaticManualCompactions) {
ASSERT_NE("NOT_FOUND", Get(1, *key_iter));
key_iter++;
}
Close();
}
#endif // !ROCKSDB_LITE
@@ -2524,6 +2495,7 @@ TEST_F(ColumnFamilyTest, CreateAndDropRace) {
TEST_F(ColumnFamilyTest, WriteStallSingleColumnFamily) {
const uint64_t kBaseRate = 800000u;
db_options_.delayed_write_rate = kBaseRate;
db_options_.base_background_compactions = 2;
db_options_.max_background_compactions = 6;
Open({"default"});
@@ -2704,6 +2676,7 @@ TEST_F(ColumnFamilyTest, WriteStallSingleColumnFamily) {
}
TEST_F(ColumnFamilyTest, CompactionSpeedupSingleColumnFamily) {
db_options_.base_background_compactions = 2;
db_options_.max_background_compactions = 6;
Open({"default"});
ColumnFamilyData* cfd =
@@ -2723,7 +2696,7 @@ TEST_F(ColumnFamilyTest, CompactionSpeedupSingleColumnFamily) {
vstorage->TEST_set_estimated_compaction_needed_bytes(40);
cfd->RecalculateWriteStallConditions(mutable_cf_options);
ASSERT_EQ(1, dbfull()->TEST_BGCompactionsAllowed());
ASSERT_EQ(2, dbfull()->TEST_BGCompactionsAllowed());
vstorage->TEST_set_estimated_compaction_needed_bytes(50);
cfd->RecalculateWriteStallConditions(mutable_cf_options);
@@ -2735,11 +2708,11 @@ TEST_F(ColumnFamilyTest, CompactionSpeedupSingleColumnFamily) {
vstorage->TEST_set_estimated_compaction_needed_bytes(45);
cfd->RecalculateWriteStallConditions(mutable_cf_options);
ASSERT_EQ(1, dbfull()->TEST_BGCompactionsAllowed());
ASSERT_EQ(2, dbfull()->TEST_BGCompactionsAllowed());
vstorage->set_l0_delay_trigger_count(7);
cfd->RecalculateWriteStallConditions(mutable_cf_options);
ASSERT_EQ(1, dbfull()->TEST_BGCompactionsAllowed());
ASSERT_EQ(2, dbfull()->TEST_BGCompactionsAllowed());
vstorage->set_l0_delay_trigger_count(9);
cfd->RecalculateWriteStallConditions(mutable_cf_options);
@@ -2747,7 +2720,7 @@ TEST_F(ColumnFamilyTest, CompactionSpeedupSingleColumnFamily) {
vstorage->set_l0_delay_trigger_count(6);
cfd->RecalculateWriteStallConditions(mutable_cf_options);
ASSERT_EQ(1, dbfull()->TEST_BGCompactionsAllowed());
ASSERT_EQ(2, dbfull()->TEST_BGCompactionsAllowed());
// Speed up threshold = min(4 * 2, 4 + (12 - 4)/4) = 6
mutable_cf_options.level0_file_num_compaction_trigger = 4;
@@ -2756,7 +2729,7 @@ TEST_F(ColumnFamilyTest, CompactionSpeedupSingleColumnFamily) {
vstorage->set_l0_delay_trigger_count(5);
cfd->RecalculateWriteStallConditions(mutable_cf_options);
ASSERT_EQ(1, dbfull()->TEST_BGCompactionsAllowed());
ASSERT_EQ(2, dbfull()->TEST_BGCompactionsAllowed());
vstorage->set_l0_delay_trigger_count(7);
cfd->RecalculateWriteStallConditions(mutable_cf_options);
@@ -2764,7 +2737,7 @@ TEST_F(ColumnFamilyTest, CompactionSpeedupSingleColumnFamily) {
vstorage->set_l0_delay_trigger_count(3);
cfd->RecalculateWriteStallConditions(mutable_cf_options);
ASSERT_EQ(1, dbfull()->TEST_BGCompactionsAllowed());
ASSERT_EQ(2, dbfull()->TEST_BGCompactionsAllowed());
}
TEST_F(ColumnFamilyTest, WriteStallTwoColumnFamilies) {
@@ -2843,6 +2816,7 @@ TEST_F(ColumnFamilyTest, WriteStallTwoColumnFamilies) {
}
TEST_F(ColumnFamilyTest, CompactionSpeedupTwoColumnFamilies) {
db_options_.base_background_compactions = 2;
db_options_.max_background_compactions = 6;
column_family_options_.soft_pending_compaction_bytes_limit = 200;
column_family_options_.hard_pending_compaction_bytes_limit = 2000;
@@ -2870,11 +2844,11 @@ TEST_F(ColumnFamilyTest, CompactionSpeedupTwoColumnFamilies) {
vstorage->TEST_set_estimated_compaction_needed_bytes(40);
cfd->RecalculateWriteStallConditions(mutable_cf_options);
ASSERT_EQ(1, dbfull()->TEST_BGCompactionsAllowed());
ASSERT_EQ(2, dbfull()->TEST_BGCompactionsAllowed());
vstorage->TEST_set_estimated_compaction_needed_bytes(60);
cfd1->RecalculateWriteStallConditions(mutable_cf_options);
ASSERT_EQ(1, dbfull()->TEST_BGCompactionsAllowed());
ASSERT_EQ(2, dbfull()->TEST_BGCompactionsAllowed());
cfd->RecalculateWriteStallConditions(mutable_cf_options);
ASSERT_EQ(6, dbfull()->TEST_BGCompactionsAllowed());
@@ -2892,7 +2866,7 @@ TEST_F(ColumnFamilyTest, CompactionSpeedupTwoColumnFamilies) {
vstorage1->TEST_set_estimated_compaction_needed_bytes(3);
cfd1->RecalculateWriteStallConditions(mutable_cf_options);
ASSERT_EQ(1, dbfull()->TEST_BGCompactionsAllowed());
ASSERT_EQ(2, dbfull()->TEST_BGCompactionsAllowed());
vstorage->set_l0_delay_trigger_count(9);
cfd->RecalculateWriteStallConditions(mutable_cf_options);
@@ -2904,7 +2878,7 @@ TEST_F(ColumnFamilyTest, CompactionSpeedupTwoColumnFamilies) {
vstorage->set_l0_delay_trigger_count(0);
cfd->RecalculateWriteStallConditions(mutable_cf_options);
ASSERT_EQ(1, dbfull()->TEST_BGCompactionsAllowed());
ASSERT_EQ(2, dbfull()->TEST_BGCompactionsAllowed());
}
#ifndef ROCKSDB_LITE
+2
View File
@@ -654,6 +654,7 @@ TEST_P(CompactionJobStatsTest, CompactionJobStatsTest) {
Options options;
options.listeners.emplace_back(stats_checker);
options.create_if_missing = true;
options.max_background_flushes = 0;
// just enough setting to hold off auto-compaction.
options.level0_file_num_compaction_trigger = kTestScale + 1;
options.num_levels = 3;
@@ -875,6 +876,7 @@ TEST_P(CompactionJobStatsTest, DeletionStatsTest) {
Options options;
options.listeners.emplace_back(stats_checker);
options.create_if_missing = true;
options.max_background_flushes = 0;
options.level0_file_num_compaction_trigger = kTestScale+1;
options.num_levels = 3;
options.compression = kNoCompression;
+1 -1
View File
@@ -950,7 +950,7 @@ TEST_F(CompactionPickerTest, NotScheduleL1IfL0WithHigherPri3) {
TEST_F(CompactionPickerTest, EstimateCompactionBytesNeeded1) {
int num_levels = ioptions_.num_levels;
ioptions_.level_compaction_dynamic_level_bytes = false;
mutable_cf_options_.level0_file_num_compaction_trigger = 4;
mutable_cf_options_.level0_file_num_compaction_trigger = 3;
mutable_cf_options_.max_bytes_for_level_base = 1000;
mutable_cf_options_.max_bytes_for_level_multiplier = 10;
NewVersionStorage(num_levels, kCompactionStyleLevel);
+1 -1
View File
@@ -619,7 +619,7 @@ Compaction* UniversalCompactionPicker::PickCompactionToReduceSizeAmp(
const std::string& cf_name, const MutableCFOptions& mutable_cf_options,
VersionStorageInfo* vstorage, double score,
const std::vector<SortedRun>& sorted_runs, LogBuffer* log_buffer) {
// percentage flexibility while reducing size amplification
// percentage flexibilty while reducing size amplification
uint64_t ratio =
ioptions_.compaction_options_universal.max_size_amplification_percent;
+4 -4
View File
@@ -364,9 +364,9 @@ TEST_F(DBBasicTest, FLUSH) {
ASSERT_OK(Flush(1));
ASSERT_OK(dbfull()->Put(writeOpt, handles_[1], "bar", "v1"));
get_perf_context()->Reset();
perf_context.Reset();
Get(1, "foo");
ASSERT_TRUE((int)get_perf_context()->get_from_output_files_time > 0);
ASSERT_TRUE((int)perf_context.get_from_output_files_time > 0);
ReopenWithColumnFamilies({"default", "pikachu"}, CurrentOptions());
ASSERT_EQ("v1", Get(1, "foo"));
@@ -379,9 +379,9 @@ TEST_F(DBBasicTest, FLUSH) {
ReopenWithColumnFamilies({"default", "pikachu"}, CurrentOptions());
ASSERT_EQ("v2", Get(1, "bar"));
get_perf_context()->Reset();
perf_context.Reset();
ASSERT_EQ("v2", Get(1, "foo"));
ASSERT_TRUE((int)get_perf_context()->get_from_output_files_time > 0);
ASSERT_TRUE((int)perf_context.get_from_output_files_time > 0);
writeOpt.disableWAL = false;
ASSERT_OK(dbfull()->Put(writeOpt, handles_[1], "bar", "v3"));
+24 -24
View File
@@ -686,12 +686,12 @@ class BloomStatsTestWithParam
}
options_.env = env_;
get_perf_context()->Reset();
perf_context.Reset();
DestroyAndReopen(options_);
}
~BloomStatsTestWithParam() {
get_perf_context()->Reset();
perf_context.Reset();
Destroy(options_);
}
@@ -724,33 +724,33 @@ TEST_P(BloomStatsTestWithParam, BloomStatsTest) {
// check memtable bloom stats
ASSERT_EQ(value1, Get(key1));
ASSERT_EQ(1, get_perf_context()->bloom_memtable_hit_count);
ASSERT_EQ(1, perf_context.bloom_memtable_hit_count);
ASSERT_EQ(value3, Get(key3));
ASSERT_EQ(2, get_perf_context()->bloom_memtable_hit_count);
ASSERT_EQ(0, get_perf_context()->bloom_memtable_miss_count);
ASSERT_EQ(2, perf_context.bloom_memtable_hit_count);
ASSERT_EQ(0, perf_context.bloom_memtable_miss_count);
ASSERT_EQ("NOT_FOUND", Get(key2));
ASSERT_EQ(1, get_perf_context()->bloom_memtable_miss_count);
ASSERT_EQ(2, get_perf_context()->bloom_memtable_hit_count);
ASSERT_EQ(1, perf_context.bloom_memtable_miss_count);
ASSERT_EQ(2, perf_context.bloom_memtable_hit_count);
// sanity checks
ASSERT_EQ(0, get_perf_context()->bloom_sst_hit_count);
ASSERT_EQ(0, get_perf_context()->bloom_sst_miss_count);
ASSERT_EQ(0, perf_context.bloom_sst_hit_count);
ASSERT_EQ(0, perf_context.bloom_sst_miss_count);
Flush();
// sanity checks
ASSERT_EQ(0, get_perf_context()->bloom_sst_hit_count);
ASSERT_EQ(0, get_perf_context()->bloom_sst_miss_count);
ASSERT_EQ(0, perf_context.bloom_sst_hit_count);
ASSERT_EQ(0, perf_context.bloom_sst_miss_count);
// check SST bloom stats
ASSERT_EQ(value1, Get(key1));
ASSERT_EQ(1, get_perf_context()->bloom_sst_hit_count);
ASSERT_EQ(1, perf_context.bloom_sst_hit_count);
ASSERT_EQ(value3, Get(key3));
ASSERT_EQ(2, get_perf_context()->bloom_sst_hit_count);
ASSERT_EQ(2, perf_context.bloom_sst_hit_count);
ASSERT_EQ("NOT_FOUND", Get(key2));
ASSERT_EQ(1, get_perf_context()->bloom_sst_miss_count);
ASSERT_EQ(1, perf_context.bloom_sst_miss_count);
}
// Same scenario as in BloomStatsTest but using an iterator
@@ -771,21 +771,21 @@ TEST_P(BloomStatsTestWithParam, BloomStatsTestWithIter) {
ASSERT_OK(iter->status());
ASSERT_TRUE(iter->Valid());
ASSERT_EQ(value1, iter->value().ToString());
ASSERT_EQ(1, get_perf_context()->bloom_memtable_hit_count);
ASSERT_EQ(0, get_perf_context()->bloom_memtable_miss_count);
ASSERT_EQ(1, perf_context.bloom_memtable_hit_count);
ASSERT_EQ(0, perf_context.bloom_memtable_miss_count);
iter->Seek(key3);
ASSERT_OK(iter->status());
ASSERT_TRUE(iter->Valid());
ASSERT_EQ(value3, iter->value().ToString());
ASSERT_EQ(2, get_perf_context()->bloom_memtable_hit_count);
ASSERT_EQ(0, get_perf_context()->bloom_memtable_miss_count);
ASSERT_EQ(2, perf_context.bloom_memtable_hit_count);
ASSERT_EQ(0, perf_context.bloom_memtable_miss_count);
iter->Seek(key2);
ASSERT_OK(iter->status());
ASSERT_TRUE(!iter->Valid());
ASSERT_EQ(1, get_perf_context()->bloom_memtable_miss_count);
ASSERT_EQ(2, get_perf_context()->bloom_memtable_hit_count);
ASSERT_EQ(1, perf_context.bloom_memtable_miss_count);
ASSERT_EQ(2, perf_context.bloom_memtable_hit_count);
Flush();
@@ -796,19 +796,19 @@ TEST_P(BloomStatsTestWithParam, BloomStatsTestWithIter) {
ASSERT_OK(iter->status());
ASSERT_TRUE(iter->Valid());
ASSERT_EQ(value1, iter->value().ToString());
ASSERT_EQ(1, get_perf_context()->bloom_sst_hit_count);
ASSERT_EQ(1, perf_context.bloom_sst_hit_count);
iter->Seek(key3);
ASSERT_OK(iter->status());
ASSERT_TRUE(iter->Valid());
ASSERT_EQ(value3, iter->value().ToString());
ASSERT_EQ(2, get_perf_context()->bloom_sst_hit_count);
ASSERT_EQ(2, perf_context.bloom_sst_hit_count);
iter->Seek(key2);
ASSERT_OK(iter->status());
ASSERT_TRUE(!iter->Valid());
ASSERT_EQ(1, get_perf_context()->bloom_sst_miss_count);
ASSERT_EQ(2, get_perf_context()->bloom_sst_hit_count);
ASSERT_EQ(1, perf_context.bloom_sst_miss_count);
ASSERT_EQ(2, perf_context.bloom_sst_hit_count);
}
INSTANTIATE_TEST_CASE_P(BloomStatsTestWithParam, BloomStatsTestWithParam,
+1 -38
View File
@@ -778,7 +778,7 @@ TEST_F(DBTestCompactionFilter, SkipUntil) {
cfilter_skips = 0;
ASSERT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
// Number of skips in tables: 2, 3, 3, 3.
// Numberof skips in tables: 2, 3, 3, 3.
ASSERT_EQ(11, cfilter_skips);
for (int table = 0; table < 4; ++table) {
@@ -799,43 +799,6 @@ TEST_F(DBTestCompactionFilter, SkipUntil) {
}
}
TEST_F(DBTestCompactionFilter, SkipUntilWithBloomFilter) {
BlockBasedTableOptions table_options;
table_options.whole_key_filtering = false;
table_options.filter_policy.reset(NewBloomFilterPolicy(100, false));
Options options = CurrentOptions();
options.table_factory.reset(NewBlockBasedTableFactory(table_options));
options.prefix_extractor.reset(NewCappedPrefixTransform(9));
options.compaction_filter_factory = std::make_shared<SkipEvenFilterFactory>();
options.disable_auto_compactions = true;
options.create_if_missing = true;
DestroyAndReopen(options);
Put("0000000010", "v10");
Put("0000000020", "v20"); // skipped
Put("0000000050", "v50");
Flush();
cfilter_skips = 0;
EXPECT_OK(db_->CompactRange(CompactRangeOptions(), nullptr, nullptr));
EXPECT_EQ(1, cfilter_skips);
Status s;
std::string val;
s = db_->Get(ReadOptions(), "0000000010", &val);
ASSERT_OK(s);
EXPECT_EQ("v10", val);
s = db_->Get(ReadOptions(), "0000000020", &val);
EXPECT_TRUE(s.IsNotFound());
s = db_->Get(ReadOptions(), "0000000050", &val);
ASSERT_OK(s);
EXPECT_EQ("v50", val);
}
} // namespace rocksdb
int main(int argc, char** argv) {
+5 -3
View File
@@ -519,6 +519,7 @@ TEST_F(DBCompactionTest, BGCompactionsAllowed) {
options.level0_file_num_compaction_trigger = 2;
options.level0_slowdown_writes_trigger = 20;
options.soft_pending_compaction_bytes_limit = 1 << 30; // Infinitely large
options.base_background_compactions = 1;
options.max_background_compactions = 3;
options.memtable_factory.reset(new SpecialSkipListFactory(kNumKeysPerFile));
@@ -1227,9 +1228,6 @@ TEST_F(DBCompactionTest, DISABLED_ManualPartialFill) {
options.max_background_compactions = 3;
DestroyAndReopen(options);
// make sure all background compaction jobs can be scheduled
auto stop_token =
dbfull()->TEST_write_controler().GetCompactionPressureToken();
int32_t value_size = 10 * 1024; // 10 KB
// Add 2 non-overlapping files
@@ -1977,6 +1975,7 @@ TEST_P(DBCompactionTestWithParam, ManualCompaction) {
if (iter == 0) {
options = CurrentOptions();
options.max_background_flushes = 0;
options.num_levels = 3;
options.create_if_missing = true;
options.statistics = rocksdb::CreateDBStatistics();
@@ -2422,12 +2421,15 @@ TEST_F(DBCompactionTest, SanitizeCompactionOptionsTest) {
options.hard_pending_compaction_bytes_limit = 100;
options.create_if_missing = true;
DestroyAndReopen(options);
ASSERT_EQ(5, db_->GetOptions().base_background_compactions);
ASSERT_EQ(100, db_->GetOptions().soft_pending_compaction_bytes_limit);
options.base_background_compactions = 4;
options.max_background_compactions = 3;
options.soft_pending_compaction_bytes_limit = 200;
options.hard_pending_compaction_bytes_limit = 150;
DestroyAndReopen(options);
ASSERT_EQ(3, db_->GetOptions().base_background_compactions);
ASSERT_EQ(150, db_->GetOptions().soft_pending_compaction_bytes_limit);
}
+5 -1
View File
@@ -57,6 +57,7 @@ TEST_F(DBTestDynamicLevel, DynamicLevelMaxBytesBase) {
Options options;
options.env = env.get();
options.create_if_missing = true;
options.db_write_buffer_size = 2048;
options.write_buffer_size = 2048;
options.max_write_buffer_number = 2;
options.level0_file_num_compaction_trigger = 2;
@@ -126,6 +127,7 @@ TEST_F(DBTestDynamicLevel, DynamicLevelMaxBytesBase2) {
Options options = CurrentOptions();
options.create_if_missing = true;
options.db_write_buffer_size = 204800;
options.write_buffer_size = 20480;
options.max_write_buffer_number = 2;
options.level0_file_num_compaction_trigger = 2;
@@ -282,6 +284,7 @@ TEST_F(DBTestDynamicLevel, DynamicLevelMaxBytesCompactRange) {
Options options = CurrentOptions();
options.create_if_missing = true;
options.db_write_buffer_size = 2048;
options.write_buffer_size = 2048;
options.max_write_buffer_number = 2;
options.level0_file_num_compaction_trigger = 2;
@@ -359,6 +362,7 @@ TEST_F(DBTestDynamicLevel, DynamicLevelMaxBytesCompactRange) {
TEST_F(DBTestDynamicLevel, DynamicLevelMaxBytesBaseInc) {
Options options = CurrentOptions();
options.create_if_missing = true;
options.db_write_buffer_size = 2048;
options.write_buffer_size = 2048;
options.max_write_buffer_number = 2;
options.level0_file_num_compaction_trigger = 2;
@@ -371,7 +375,6 @@ TEST_F(DBTestDynamicLevel, DynamicLevelMaxBytesBaseInc) {
options.soft_rate_limit = 1.1;
options.max_background_compactions = 2;
options.num_levels = 5;
options.max_compaction_bytes = 100000000;
DestroyAndReopen(options);
@@ -411,6 +414,7 @@ TEST_F(DBTestDynamicLevel, DISABLED_MigrateToDynamicLevelMaxBytesBase) {
Options options;
options.create_if_missing = true;
options.db_write_buffer_size = 2048;
options.write_buffer_size = 2048;
options.max_write_buffer_number = 8;
options.level0_file_num_compaction_trigger = 4;
-37
View File
@@ -89,43 +89,6 @@ TEST_F(DBFlushTest, SyncFail) {
Destroy(options);
}
TEST_F(DBFlushTest, FlushInLowPriThreadPool) {
// Verify setting an empty high-pri (flush) thread pool causes flushes to be
// scheduled in the low-pri (compaction) thread pool.
Options options = CurrentOptions();
options.level0_file_num_compaction_trigger = 4;
options.memtable_factory.reset(new SpecialSkipListFactory(1));
Reopen(options);
env_->SetBackgroundThreads(0, Env::HIGH);
std::thread::id tid;
int num_flushes = 0, num_compactions = 0;
SyncPoint::GetInstance()->SetCallBack(
"DBImpl::BGWorkFlush", [&](void* arg) {
if (tid == std::thread::id()) {
tid = std::this_thread::get_id();
} else {
ASSERT_EQ(tid, std::this_thread::get_id());
}
++num_flushes;
});
SyncPoint::GetInstance()->SetCallBack(
"DBImpl::BGWorkCompaction", [&](void* arg) {
ASSERT_EQ(tid, std::this_thread::get_id());
++num_compactions;
});
SyncPoint::GetInstance()->EnableProcessing();
ASSERT_OK(Put("key", "val"));
for (int i = 0; i < 4; ++i) {
ASSERT_OK(Put("key", "val"));
dbfull()->TEST_WaitForFlushMemTable();
}
dbfull()->TEST_WaitForCompact();
ASSERT_EQ(4, num_flushes);
ASSERT_EQ(1, num_compactions);
}
TEST_P(DBFlushDirectIOTest, DirectIO) {
Options options;
options.create_if_missing = true;
+43 -30
View File
@@ -16,6 +16,9 @@
#ifdef OS_SOLARIS
#include <alloca.h>
#endif
#ifdef ROCKSDB_JEMALLOC
#include "jemalloc/jemalloc.h"
#endif
#include <algorithm>
#include <climits>
@@ -41,7 +44,6 @@
#include "db/job_context.h"
#include "db/log_reader.h"
#include "db/log_writer.h"
#include "db/malloc_stats.h"
#include "db/managed_iterator.h"
#include "db/memtable.h"
#include "db/memtable_list.h"
@@ -132,8 +134,6 @@ void DumpSupportInfo(Logger* logger) {
ROCKS_LOG_HEADER(logger, "Fast CRC32 supported: %d",
crc32c::IsFastCrc32Supported());
}
int64_t kDefaultLowPriThrottledRate = 2 * 1024 * 1024;
} // namespace
DBImpl::DBImpl(const DBOptions& options, const std::string& dbname)
@@ -159,11 +159,6 @@ DBImpl::DBImpl(const DBOptions& options, const std::string& dbname)
write_buffer_manager_(immutable_db_options_.write_buffer_manager.get()),
write_thread_(immutable_db_options_),
write_controller_(mutable_db_options_.delayed_write_rate),
// Use delayed_write_rate as a base line to determine the initial
// low pri write rate limit. It may be adjusted later.
low_pri_write_rate_limiter_(NewGenericRateLimiter(std::min(
static_cast<int64_t>(mutable_db_options_.delayed_write_rate / 8),
kDefaultLowPriThrottledRate))),
last_batch_group_size_(0),
unscheduled_flushes_(0),
unscheduled_compactions_(0),
@@ -222,7 +217,7 @@ void DBImpl::CancelAllBackgroundWork(bool wait) {
has_unpersisted_data_.load(std::memory_order_relaxed) &&
!mutable_db_options_.avoid_flush_during_shutdown) {
for (auto cfd : *versions_->GetColumnFamilySet()) {
if (!cfd->IsDropped() && cfd->initialized() && !cfd->mem()->IsEmpty()) {
if (!cfd->IsDropped() && !cfd->mem()->IsEmpty()) {
cfd->Ref();
mutex_.Unlock();
FlushMemTable(cfd, FlushOptions());
@@ -373,6 +368,39 @@ void DBImpl::PrintStatistics() {
}
}
#ifndef ROCKSDB_LITE
#ifdef ROCKSDB_JEMALLOC
typedef struct {
char* cur;
char* end;
} MallocStatus;
static void GetJemallocStatus(void* mstat_arg, const char* status) {
MallocStatus* mstat = reinterpret_cast<MallocStatus*>(mstat_arg);
size_t status_len = status ? strlen(status) : 0;
size_t buf_size = (size_t)(mstat->end - mstat->cur);
if (!status_len || status_len > buf_size) {
return;
}
snprintf(mstat->cur, buf_size, "%s", status);
mstat->cur += status_len;
}
#endif // ROCKSDB_JEMALLOC
static void DumpMallocStats(std::string* stats) {
#ifdef ROCKSDB_JEMALLOC
MallocStatus mstat;
const unsigned int kMallocStatusLen = 1000000;
std::unique_ptr<char[]> buf{new char[kMallocStatusLen + 1]};
mstat.cur = buf.get();
mstat.end = buf.get() + kMallocStatusLen;
je_malloc_stats_print(GetJemallocStatus, &mstat, "");
stats->append(buf.get());
#endif // ROCKSDB_JEMALLOC
}
#endif // !ROCKSDB_LITE
void DBImpl::MaybeDumpStats() {
mutex_.Lock();
unsigned int stats_dump_period_sec =
@@ -404,17 +432,12 @@ void DBImpl::MaybeDumpStats() {
default_cf_internal_stats_->GetStringProperty(
*db_property_info, DB::Properties::kDBStats, &stats);
for (auto cfd : *versions_->GetColumnFamilySet()) {
if (cfd->initialized()) {
cfd->internal_stats()->GetStringProperty(
*cf_property_info, DB::Properties::kCFStatsNoFileHistogram,
&stats);
}
cfd->internal_stats()->GetStringProperty(
*cf_property_info, DB::Properties::kCFStatsNoFileHistogram, &stats);
}
for (auto cfd : *versions_->GetColumnFamilySet()) {
if (cfd->initialized()) {
cfd->internal_stats()->GetStringProperty(
*cf_property_info, DB::Properties::kCFFileHistogram, &stats);
}
cfd->internal_stats()->GetStringProperty(
*cf_property_info, DB::Properties::kCFFileHistogram, &stats);
}
}
ROCKS_LOG_WARN(immutable_db_options_.info_log,
@@ -1211,8 +1234,6 @@ Status DBImpl::CreateColumnFamilyImpl(const ColumnFamilyOptions& cf_options,
is_snapshot_supported_ = false;
}
cfd->set_initialized();
*handle = new ColumnFamilyHandleImpl(cfd, this, &mutex_);
ROCKS_LOG_INFO(immutable_db_options_.info_log,
"Created column family [%s] (ID %u)",
@@ -1714,9 +1735,7 @@ bool DBImpl::GetIntPropertyInternal(ColumnFamilyData* cfd,
Status DBImpl::ResetStats() {
InstrumentedMutexLock l(&mutex_);
for (auto* cfd : *versions_->GetColumnFamilySet()) {
if (cfd->initialized()) {
cfd->internal_stats()->Clear();
}
cfd->internal_stats()->Clear();
}
return Status::OK();
}
@@ -1735,9 +1754,6 @@ bool DBImpl::GetAggregatedIntProperty(const Slice& property,
InstrumentedMutexLock l(&mutex_);
uint64_t value;
for (auto* cfd : *versions_->GetColumnFamilySet()) {
if (!cfd->initialized()) {
continue;
}
if (GetIntPropertyInternal(cfd, *property_info, true, &value)) {
sum += value;
} else {
@@ -2330,9 +2346,6 @@ Status DBImpl::WriteOptionsFile(bool need_mutex_lock,
BuildDBOptions(immutable_db_options_, mutable_db_options_);
mutex_.Unlock();
TEST_SYNC_POINT("DBImpl::WriteOptionsFile:1");
TEST_SYNC_POINT("DBImpl::WriteOptionsFile:2");
std::string file_name =
TempOptionsFileName(GetName(), versions_->NewFileNumber());
Status s =
@@ -2468,7 +2481,7 @@ void DBImpl::EraseThreadStatusDbInfo() const {
// A global method that can dump out the build version
void DumpRocksDBBuildVersion(Logger * log) {
#if !defined(IOS_CROSS_COMPILE)
// if we compile with Xcode, we don't run build_detect_version, so we don't
// if we compile with Xcode, we don't run build_detect_vesion, so we don't
// generate util/build_version.cc
ROCKS_LOG_HEADER(log, "RocksDB version: %d.%d.%d\n", ROCKSDB_MAJOR,
ROCKSDB_MINOR, ROCKSDB_PATCH);
+4 -18
View File
@@ -399,21 +399,12 @@ class DBImpl : public DB {
uint64_t TEST_FindMinPrepLogReferencedByMemTable();
int TEST_BGCompactionsAllowed() const;
int TEST_BGFlushesAllowed() const;
#endif // NDEBUG
struct BGJobLimits {
int max_flushes;
int max_compactions;
};
// Returns maximum background flushes and compactions allowed to be scheduled
BGJobLimits GetBGJobLimits() const;
// Need a static version that can be called during SanitizeOptions().
static BGJobLimits GetBGJobLimits(int max_background_flushes,
int max_background_compactions,
int max_background_jobs,
bool parallelize_compactions);
// Return maximum background compaction allowed to be scheduled based on
// compaction status.
int BGCompactionsAllowed() const;
// move logs pending closing from job_context to the DB queue and
// schedule a purge
@@ -720,9 +711,6 @@ class DBImpl : public DB {
// `num_bytes` going through.
Status DelayWrite(uint64_t num_bytes, const WriteOptions& write_options);
Status ThrottleLowPriWritesIfNeeded(const WriteOptions& write_options,
WriteBatch* my_batch);
Status ScheduleFlushes(WriteContext* context);
Status SwitchMemtable(ColumnFamilyData* cfd, WriteContext* context);
@@ -942,8 +930,6 @@ class DBImpl : public DB {
WriteController write_controller_;
unique_ptr<RateLimiter> low_pri_write_rate_limiter_;
// Size of the last batch group. In slowdown mode, next write needs to
// sleep if it uses up the quota.
uint64_t last_batch_group_size_;
@@ -1198,7 +1184,7 @@ extern DBOptions SanitizeOptions(const std::string& db, const DBOptions& src);
extern CompressionType GetCompressionFlush(
const ImmutableCFOptions& ioptions,
const MutableCFOptions& mutable_cf_options);
// Fix user-supplied options to be reasonable
template <class T, class V>
static void ClipToRange(T* ptr, V minvalue, V maxvalue) {
+18 -42
View File
@@ -981,22 +981,22 @@ void DBImpl::MaybeScheduleFlushOrCompaction() {
// DB is being deleted; no more background compactions
return;
}
auto bg_job_limits = GetBGJobLimits();
bool is_flush_pool_empty =
env_->GetBackgroundThreads(Env::Priority::HIGH) == 0;
while (!is_flush_pool_empty && unscheduled_flushes_ > 0 &&
bg_flush_scheduled_ < bg_job_limits.max_flushes) {
while (unscheduled_flushes_ > 0 &&
bg_flush_scheduled_ < immutable_db_options_.max_background_flushes) {
unscheduled_flushes_--;
bg_flush_scheduled_++;
env_->Schedule(&DBImpl::BGWorkFlush, this, Env::Priority::HIGH, this);
}
// special case -- if high-pri (flush) thread pool is empty, then schedule
// flushes in low-pri (compaction) thread pool.
if (is_flush_pool_empty) {
auto bg_compactions_allowed = BGCompactionsAllowed();
// special case -- if max_background_flushes == 0, then schedule flush on a
// compaction thread
if (immutable_db_options_.max_background_flushes == 0) {
while (unscheduled_flushes_ > 0 &&
bg_flush_scheduled_ + bg_compaction_scheduled_ <
bg_job_limits.max_flushes) {
bg_compactions_allowed) {
unscheduled_flushes_--;
bg_flush_scheduled_++;
env_->Schedule(&DBImpl::BGWorkFlush, this, Env::Priority::LOW, this);
@@ -1014,7 +1014,7 @@ void DBImpl::MaybeScheduleFlushOrCompaction() {
return;
}
while (bg_compaction_scheduled_ < bg_job_limits.max_compactions &&
while (bg_compaction_scheduled_ < bg_compactions_allowed &&
unscheduled_compactions_ > 0) {
CompactionArg* ca = new CompactionArg;
ca->db = this;
@@ -1026,35 +1026,13 @@ void DBImpl::MaybeScheduleFlushOrCompaction() {
}
}
DBImpl::BGJobLimits DBImpl::GetBGJobLimits() const {
int DBImpl::BGCompactionsAllowed() const {
mutex_.AssertHeld();
return GetBGJobLimits(immutable_db_options_.max_background_flushes,
mutable_db_options_.max_background_compactions,
mutable_db_options_.max_background_jobs,
write_controller_.NeedSpeedupCompaction());
}
DBImpl::BGJobLimits DBImpl::GetBGJobLimits(int max_background_flushes,
int max_background_compactions,
int max_background_jobs,
bool parallelize_compactions) {
BGJobLimits res;
if (max_background_flushes == -1 && max_background_compactions == -1) {
// for our first stab implementing max_background_jobs, simply allocate a
// quarter of the threads to flushes.
res.max_flushes = std::max(1, max_background_jobs / 4);
res.max_compactions = std::max(1, max_background_jobs - res.max_flushes);
if (write_controller_.NeedSpeedupCompaction()) {
return mutable_db_options_.max_background_compactions;
} else {
// compatibility code in case users haven't migrated to max_background_jobs,
// which automatically computes flush/compaction limits
res.max_flushes = std::max(1, max_background_flushes);
res.max_compactions = std::max(1, max_background_compactions);
return mutable_db_options_.base_background_compactions;
}
if (!parallelize_compactions) {
// throttle background compactions until we deem necessary
res.max_compactions = 1;
}
return res;
}
void DBImpl::AddToCompactionQueue(ColumnFamilyData* cfd) {
@@ -1176,15 +1154,13 @@ Status DBImpl::BackgroundFlush(bool* made_progress, JobContext* job_context,
if (cfd != nullptr) {
const MutableCFOptions mutable_cf_options =
*cfd->GetLatestMutableCFOptions();
auto bg_job_limits = GetBGJobLimits();
ROCKS_LOG_BUFFER(
log_buffer,
"Calling FlushMemTableToOutputFile with column "
"family [%s], flush slots available %d, compaction slots available %d, "
"flush slots scheduled %d, compaction slots scheduled %d",
cfd->GetName().c_str(), bg_job_limits.max_flushes,
bg_job_limits.max_compactions, bg_flush_scheduled_,
bg_compaction_scheduled_);
"family [%s], flush slots available %d, compaction slots allowed %d, "
"compaction slots scheduled %d",
cfd->GetName().c_str(), immutable_db_options_.max_background_flushes -
bg_flush_scheduled_, BGCompactionsAllowed(), bg_compaction_scheduled_);
status = FlushMemTableToOutputFile(cfd, mutable_cf_options, made_progress,
job_context, log_buffer);
if (cfd->Unref()) {
+1 -6
View File
@@ -186,12 +186,7 @@ Status DBImpl::TEST_GetLatestMutableCFOptions(
int DBImpl::TEST_BGCompactionsAllowed() const {
InstrumentedMutexLock l(&mutex_);
return GetBGJobLimits().max_compactions;
}
int DBImpl::TEST_BGFlushesAllowed() const {
InstrumentedMutexLock l(&mutex_);
return GetBGJobLimits().max_flushes;
return BGCompactionsAllowed();
}
} // namespace rocksdb
+9 -17
View File
@@ -16,7 +16,6 @@
#include "db/builder.h"
#include "options/options_helper.h"
#include "rocksdb/wal_filter.h"
#include "util/rate_limiter.h"
#include "util/sst_file_manager_impl.h"
#include "util/sync_point.h"
@@ -54,13 +53,15 @@ DBOptions SanitizeOptions(const std::string& dbname, const DBOptions& src) {
result.write_buffer_manager.reset(
new WriteBufferManager(result.db_write_buffer_size));
}
auto bg_job_limits = DBImpl::GetBGJobLimits(result.max_background_flushes,
result.max_background_compactions,
result.max_background_jobs,
true /* parallelize_compactions */);
result.env->IncBackgroundThreadsIfNeeded(bg_job_limits.max_compactions,
if (result.base_background_compactions == -1) {
result.base_background_compactions = result.max_background_compactions;
}
if (result.base_background_compactions > result.max_background_compactions) {
result.base_background_compactions = result.max_background_compactions;
}
result.env->IncBackgroundThreadsIfNeeded(src.max_background_compactions,
Env::Priority::LOW);
result.env->IncBackgroundThreadsIfNeeded(bg_job_limits.max_flushes,
result.env->IncBackgroundThreadsIfNeeded(src.max_background_flushes,
Env::Priority::HIGH);
if (result.rate_limiter.get() != nullptr) {
@@ -69,15 +70,6 @@ DBOptions SanitizeOptions(const std::string& dbname, const DBOptions& src) {
}
}
if (result.delayed_write_rate == 0) {
if (result.rate_limiter.get() != nullptr) {
result.delayed_write_rate = result.rate_limiter->GetBytesPerSecond();
}
if (result.delayed_write_rate == 0) {
result.delayed_write_rate = 16 * 1024 * 1024;
}
}
if (result.WAL_ttl_seconds > 0 || result.WAL_size_limit_MB > 0) {
result.recycle_log_file_num = false;
}
@@ -898,7 +890,7 @@ Status DB::Open(const Options& options, const std::string& dbname, DB** dbptr) {
}
return s;
}
Status DB::Open(const DBOptions& db_options, const std::string& dbname,
const std::vector<ColumnFamilyDescriptor>& column_families,
std::vector<ColumnFamilyHandle*>* handles, DB** dbptr) {
+8 -39
View File
@@ -64,19 +64,13 @@ Status DBImpl::WriteImpl(const WriteOptions& write_options,
return Status::Corruption("Batch is nullptr!");
}
Status status;
if (write_options.low_pri) {
status = ThrottleLowPriWritesIfNeeded(write_options, my_batch);
if (!status.ok()) {
return status;
}
}
if (immutable_db_options_.enable_pipelined_write) {
return PipelinedWriteImpl(write_options, my_batch, callback, log_used,
log_ref, disable_memtable);
}
Status status;
PERF_TIMER_GUARD(write_pre_and_post_process_time);
WriteThread::Writer w(write_options, my_batch, callback, log_ref,
disable_memtable);
@@ -95,8 +89,9 @@ Status DBImpl::WriteImpl(const WriteOptions& write_options,
if (w.ShouldWriteToMemtable()) {
ColumnFamilyMemTablesImpl column_family_memtables(
versions_->GetColumnFamilySet());
WriteBatchInternal::SetSequence(w.batch, w.sequence);
w.status = WriteBatchInternal::InsertInto(
&w, w.sequence, &column_family_memtables, &flush_scheduler_,
&w, &column_family_memtables, &flush_scheduler_,
write_options.ignore_missing_column_families, 0 /*log_number*/, this,
true /*concurrent_memtable_writes*/);
}
@@ -242,8 +237,9 @@ Status DBImpl::WriteImpl(const WriteOptions& write_options,
ColumnFamilyMemTablesImpl column_family_memtables(
versions_->GetColumnFamilySet());
assert(w.sequence == current_sequence);
WriteBatchInternal::SetSequence(w.batch, w.sequence);
w.status = WriteBatchInternal::InsertInto(
&w, w.sequence, &column_family_memtables, &flush_scheduler_,
&w, &column_family_memtables, &flush_scheduler_,
write_options.ignore_missing_column_families, 0 /*log_number*/,
this, true /*concurrent_memtable_writes*/);
}
@@ -386,10 +382,11 @@ Status DBImpl::PipelinedWriteImpl(const WriteOptions& write_options,
if (w.state == WriteThread::STATE_PARALLEL_MEMTABLE_WRITER) {
assert(w.ShouldWriteToMemtable());
WriteBatchInternal::SetSequence(w.batch, w.sequence);
ColumnFamilyMemTablesImpl column_family_memtables(
versions_->GetColumnFamilySet());
w.status = WriteBatchInternal::InsertInto(
&w, w.sequence, &column_family_memtables, &flush_scheduler_,
&w, &column_family_memtables, &flush_scheduler_,
write_options.ignore_missing_column_families, 0 /*log_number*/, this,
true /*concurrent_memtable_writes*/);
if (write_thread_.CompleteParallelMemTableWriter(&w)) {
@@ -746,34 +743,6 @@ Status DBImpl::DelayWrite(uint64_t num_bytes,
return bg_error_;
}
Status DBImpl::ThrottleLowPriWritesIfNeeded(const WriteOptions& write_options,
WriteBatch* my_batch) {
assert(write_options.low_pri);
// This is called outside the DB mutex. Although it is safe to make the call,
// the consistency condition is not guaranteed to hold. It's OK to live with
// it in this case.
// If we need to speed compaction, it means the compaction is left behind
// and we start to limit low pri writes to a limit.
if (write_controller_.NeedSpeedupCompaction()) {
if (allow_2pc() && (my_batch->HasCommit() || my_batch->HasRollback())) {
// For 2PC, we only rate limit prepare, not commit.
return Status::OK();
}
if (write_options.no_slowdown) {
return Status::Incomplete();
} else {
assert(my_batch != nullptr);
// Rate limit those writes. The reason that we don't completely wait
// is that in case the write is heavy, low pri writes may never have
// a chance to run. Now we guarantee we are still slowly making
// progress.
write_controller_.low_pri_rate_limiter()->Request(my_batch->GetDataSize(),
Env::IO_HIGH, nullptr);
}
}
return Status::OK();
}
Status DBImpl::ScheduleFlushes(WriteContext* context) {
ColumnFamilyData* cfd;
while ((cfd = flush_scheduler_.TakeNextColumnFamily()) != nullptr) {
+6 -6
View File
@@ -560,7 +560,7 @@ void DBIter::MergeValuesNewToOld() {
const Slice val = iter_->value();
s = MergeHelper::TimedFullMerge(
merge_operator_, ikey.user_key, &val, merge_context_.GetOperands(),
&saved_value_, logger_, statistics_, env_, &pinned_value_, true);
&saved_value_, logger_, statistics_, env_, &pinned_value_);
if (!s.ok()) {
status_ = s;
}
@@ -585,7 +585,7 @@ void DBIter::MergeValuesNewToOld() {
s = MergeHelper::TimedFullMerge(merge_operator_, saved_key_.GetUserKey(),
nullptr, merge_context_.GetOperands(),
&saved_value_, logger_, statistics_, env_,
&pinned_value_, true);
&pinned_value_);
if (!s.ok()) {
status_ = s;
}
@@ -804,13 +804,13 @@ bool DBIter::FindValueForCurrentKey() {
s = MergeHelper::TimedFullMerge(
merge_operator_, saved_key_.GetUserKey(), nullptr,
merge_context_.GetOperands(), &saved_value_, logger_, statistics_,
env_, &pinned_value_, true);
env_, &pinned_value_);
} else {
assert(last_not_merge_type == kTypeValue);
s = MergeHelper::TimedFullMerge(
merge_operator_, saved_key_.GetUserKey(), &pinned_value_,
merge_context_.GetOperands(), &saved_value_, logger_, statistics_,
env_, &pinned_value_, true);
env_, &pinned_value_);
}
break;
case kTypeValue:
@@ -882,7 +882,7 @@ bool DBIter::FindValueForCurrentKeyUsingSeek() {
s = MergeHelper::TimedFullMerge(merge_operator_, saved_key_.GetUserKey(),
nullptr, merge_context_.GetOperands(),
&saved_value_, logger_, statistics_, env_,
&pinned_value_, true);
&pinned_value_);
// Make iter_ valid and point to saved_key_
if (!iter_->Valid() ||
!user_comparator_->Equal(ikey.user_key, saved_key_.GetUserKey())) {
@@ -900,7 +900,7 @@ bool DBIter::FindValueForCurrentKeyUsingSeek() {
s = MergeHelper::TimedFullMerge(merge_operator_, saved_key_.GetUserKey(),
&val, merge_context_.GetOperands(),
&saved_value_, logger_, statistics_, env_,
&pinned_value_, true);
&pinned_value_);
valid_ = true;
if (!s.ok()) {
status_ = s;
+4 -4
View File
@@ -352,11 +352,11 @@ TEST_F(DBIteratorTest, DBIteratorPrevNext) {
SetPerfLevel(kEnableCount);
ASSERT_TRUE(GetPerfLevel() == kEnableCount);
get_perf_context()->Reset();
perf_context.Reset();
db_iter->SeekToLast();
ASSERT_TRUE(db_iter->Valid());
ASSERT_EQ(static_cast<int>(get_perf_context()->internal_key_skipped_count), 7);
ASSERT_EQ(static_cast<int>(perf_context.internal_key_skipped_count), 7);
ASSERT_EQ(db_iter->key().ToString(), "b");
SetPerfLevel(kDisable);
@@ -471,11 +471,11 @@ TEST_F(DBIteratorTest, DBIteratorPrevNext) {
SetPerfLevel(kEnableCount);
ASSERT_TRUE(GetPerfLevel() == kEnableCount);
get_perf_context()->Reset();
perf_context.Reset();
db_iter->SeekToLast();
ASSERT_TRUE(db_iter->Valid());
ASSERT_EQ(static_cast<int>(get_perf_context()->internal_delete_skipped_count), 1);
ASSERT_EQ(static_cast<int>(perf_context.internal_delete_skipped_count), 1);
ASSERT_EQ(db_iter->key().ToString(), "b");
SetPerfLevel(kDisable);
+14 -14
View File
@@ -972,11 +972,11 @@ TEST_F(DBIteratorTest, DBIteratorBoundTest) {
ASSERT_TRUE(iter->Valid());
ASSERT_EQ(iter->key().compare(("b1")), 0);
get_perf_context()->Reset();
perf_context.Reset();
iter->Next();
ASSERT_TRUE(iter->Valid());
ASSERT_EQ(static_cast<int>(get_perf_context()->internal_delete_skipped_count), 2);
ASSERT_EQ(static_cast<int>(perf_context.internal_delete_skipped_count), 2);
// now testing with iterate_bound
Slice prefix("c");
@@ -984,7 +984,7 @@ TEST_F(DBIteratorTest, DBIteratorBoundTest) {
iter.reset(db_->NewIterator(ro));
get_perf_context()->Reset();
perf_context.Reset();
iter->Seek("b");
ASSERT_TRUE(iter->Valid());
@@ -999,7 +999,7 @@ TEST_F(DBIteratorTest, DBIteratorBoundTest) {
// even though the key is deleted
// hence internal_delete_skipped_count should be 0
ASSERT_TRUE(!iter->Valid());
ASSERT_EQ(static_cast<int>(get_perf_context()->internal_delete_skipped_count), 0);
ASSERT_EQ(static_cast<int>(perf_context.internal_delete_skipped_count), 0);
}
}
@@ -1886,7 +1886,7 @@ TEST_F(DBIteratorTest, DBIteratorSkipRecentDuplicatesTest) {
#endif
// Seek iterator to a smaller key.
get_perf_context()->Reset();
perf_context.Reset();
iter->Seek("a");
ASSERT_TRUE(iter->Valid());
EXPECT_EQ("b", iter->key().ToString());
@@ -1894,17 +1894,17 @@ TEST_F(DBIteratorTest, DBIteratorSkipRecentDuplicatesTest) {
// Check that the seek didn't do too much work.
// Checks are not tight, just make sure that everything is well below 100.
EXPECT_LT(get_perf_context()->internal_key_skipped_count, 4);
EXPECT_LT(get_perf_context()->internal_recent_skipped_count, 8);
EXPECT_LT(get_perf_context()->seek_on_memtable_count, 10);
EXPECT_LT(get_perf_context()->next_on_memtable_count, 10);
EXPECT_LT(get_perf_context()->prev_on_memtable_count, 10);
EXPECT_LT(perf_context.internal_key_skipped_count, 4);
EXPECT_LT(perf_context.internal_recent_skipped_count, 8);
EXPECT_LT(perf_context.seek_on_memtable_count, 10);
EXPECT_LT(perf_context.next_on_memtable_count, 10);
EXPECT_LT(perf_context.prev_on_memtable_count, 10);
// Check that iterator did something like what we expect.
EXPECT_EQ(get_perf_context()->internal_delete_skipped_count, 0);
EXPECT_EQ(get_perf_context()->internal_merge_count, 0);
EXPECT_GE(get_perf_context()->internal_recent_skipped_count, 2);
EXPECT_GE(get_perf_context()->seek_on_memtable_count, 2);
EXPECT_EQ(perf_context.internal_delete_skipped_count, 0);
EXPECT_EQ(perf_context.internal_merge_count, 0);
EXPECT_GE(perf_context.internal_recent_skipped_count, 2);
EXPECT_GE(perf_context.seek_on_memtable_count, 2);
EXPECT_EQ(1, options.statistics->getTickerCount(
NUMBER_OF_RESEEKS_IN_ITERATION));
}
+2 -33
View File
@@ -21,7 +21,7 @@ class DBMemTableTest : public DBTestBase {
class MockMemTableRep : public MemTableRep {
public:
explicit MockMemTableRep(Allocator* allocator, MemTableRep* rep)
explicit MockMemTableRep(MemTableAllocator* allocator, MemTableRep* rep)
: MemTableRep(allocator), rep_(rep), num_insert_with_hint_(0) {}
virtual KeyHandle Allocate(const size_t len, char** buf) override {
@@ -72,7 +72,7 @@ class MockMemTableRep : public MemTableRep {
class MockMemTableRepFactory : public MemTableRepFactory {
public:
virtual MemTableRep* CreateMemTableRep(const MemTableRep::KeyComparator& cmp,
Allocator* allocator,
MemTableAllocator* allocator,
const SliceTransform* transform,
Logger* logger) override {
SkipListFactory factory;
@@ -82,27 +82,14 @@ class MockMemTableRepFactory : public MemTableRepFactory {
return mock_rep_;
}
virtual MemTableRep* CreateMemTableRep(const MemTableRep::KeyComparator& cmp,
Allocator* allocator,
const SliceTransform* transform,
Logger* logger,
uint32_t column_family_id) override {
last_column_family_id_ = column_family_id;
return CreateMemTableRep(cmp, allocator, transform, logger);
}
virtual const char* Name() const override { return "MockMemTableRepFactory"; }
MockMemTableRep* rep() { return mock_rep_; }
bool IsInsertConcurrentlySupported() const override { return false; }
uint32_t GetLastColumnFamilyId() { return last_column_family_id_; }
private:
MockMemTableRep* mock_rep_;
// workaround since there's no port::kMaxUint32 yet.
uint32_t last_column_family_id_ = static_cast<uint32_t>(-1);
};
class TestPrefixExtractor : public SliceTransform {
@@ -168,24 +155,6 @@ TEST_F(DBMemTableTest, InsertWithHint) {
ASSERT_EQ("vvv", Get("whitelisted"));
}
TEST_F(DBMemTableTest, ColumnFamilyId) {
// Verifies MemTableRepFactory is told the right column family id.
Options options;
options.allow_concurrent_memtable_write = false;
options.create_if_missing = true;
options.memtable_factory.reset(new MockMemTableRepFactory());
DestroyAndReopen(options);
CreateAndReopenWithCF({"pikachu"}, options);
for (int cf = 0; cf < 2; ++cf) {
ASSERT_OK(Put(cf, "key", "val"));
ASSERT_OK(Flush(cf));
ASSERT_EQ(
cf, static_cast<MockMemTableRepFactory*>(options.memtable_factory.get())
->GetLastColumnFamilyId());
}
}
} // namespace rocksdb
int main(int argc, char** argv) {
+22
View File
@@ -18,6 +18,28 @@ class DBMergeOperatorTest : public DBTestBase {
DBMergeOperatorTest() : DBTestBase("/db_merge_operator_test") {}
};
// A test merge operator mimics put but also fails if one of merge operands is
// "corrupted".
class TestPutOperator : public MergeOperator {
public:
virtual bool FullMergeV2(const MergeOperationInput& merge_in,
MergeOperationOutput* merge_out) const override {
if (merge_in.existing_value != nullptr &&
*(merge_in.existing_value) == "corrupted") {
return false;
}
for (auto value : merge_in.operand_list) {
if (value == "corrupted") {
return false;
}
}
merge_out->existing_operand = merge_in.operand_list.back();
return true;
}
virtual const char* Name() const override { return "TestPutOperator"; }
};
TEST_F(DBMergeOperatorTest, MergeErrorOnRead) {
Options options;
options.create_if_missing = true;
+4 -42
View File
@@ -17,7 +17,6 @@
#include "port/stack_trace.h"
#include "rocksdb/cache.h"
#include "rocksdb/convenience.h"
#include "rocksdb/rate_limiter.h"
#include "util/random.h"
#include "util/sync_point.h"
#include "util/testutil.h"
@@ -253,44 +252,18 @@ TEST_F(DBOptionsTest, SetOptionsMayTriggerCompaction) {
TEST_F(DBOptionsTest, SetBackgroundCompactionThreads) {
Options options;
options.create_if_missing = true;
options.base_background_compactions = 1; // default value
options.max_background_compactions = 1; // default value
options.env = env_;
Reopen(options);
ASSERT_EQ(1, dbfull()->TEST_BGCompactionsAllowed());
ASSERT_OK(dbfull()->SetDBOptions({{"max_background_compactions", "3"}}));
ASSERT_EQ(1, dbfull()->TEST_BGCompactionsAllowed());
ASSERT_OK(dbfull()->SetDBOptions({{"base_background_compactions", "2"},
{"max_background_compactions", "3"}}));
ASSERT_EQ(2, dbfull()->TEST_BGCompactionsAllowed());
auto stop_token = dbfull()->TEST_write_controler().GetStopToken();
ASSERT_EQ(3, dbfull()->TEST_BGCompactionsAllowed());
}
TEST_F(DBOptionsTest, SetBackgroundJobs) {
Options options;
options.create_if_missing = true;
options.max_background_jobs = 8;
options.env = env_;
Reopen(options);
for (int i = 0; i < 2; ++i) {
if (i > 0) {
options.max_background_jobs = 12;
ASSERT_OK(dbfull()->SetDBOptions(
{{"max_background_jobs",
std::to_string(options.max_background_jobs)}}));
}
ASSERT_EQ(options.max_background_jobs / 4,
dbfull()->TEST_BGFlushesAllowed());
ASSERT_EQ(1, dbfull()->TEST_BGCompactionsAllowed());
auto stop_token = dbfull()->TEST_write_controler().GetStopToken();
ASSERT_EQ(options.max_background_jobs / 4,
dbfull()->TEST_BGFlushesAllowed());
ASSERT_EQ(3 * options.max_background_jobs / 4,
dbfull()->TEST_BGCompactionsAllowed());
}
}
TEST_F(DBOptionsTest, AvoidFlushDuringShutdown) {
Options options;
options.create_if_missing = true;
@@ -429,17 +402,6 @@ TEST_F(DBOptionsTest, MaxOpenFilesChange) {
Close();
}
TEST_F(DBOptionsTest, SanitizeDelayedWriteRate) {
Options options;
options.delayed_write_rate = 0;
Reopen(options);
ASSERT_EQ(16 * 1024 * 1024, dbfull()->GetDBOptions().delayed_write_rate);
options.rate_limiter.reset(NewGenericRateLimiter(31 * 1024 * 1024));
Reopen(options);
ASSERT_EQ(31 * 1024 * 1024, dbfull()->GetDBOptions().delayed_write_rate);
}
#endif // ROCKSDB_LITE
} // namespace rocksdb
+23 -20
View File
@@ -533,9 +533,9 @@ TEST_F(DBPropertiesTest, NumImmutableMemTable) {
ASSERT_TRUE(dbfull()->GetProperty(
handles_[1], "rocksdb.num-entries-active-mem-table", &num));
ASSERT_EQ(num, "1");
get_perf_context()->Reset();
perf_context.Reset();
Get(1, "k1");
ASSERT_EQ(1, static_cast<int>(get_perf_context()->get_from_memtable_count));
ASSERT_EQ(1, static_cast<int>(perf_context.get_from_memtable_count));
ASSERT_OK(dbfull()->Put(writeOpt, handles_[1], "k2", big_value));
ASSERT_TRUE(dbfull()->GetProperty(handles_[1],
@@ -548,12 +548,12 @@ TEST_F(DBPropertiesTest, NumImmutableMemTable) {
handles_[1], "rocksdb.num-entries-imm-mem-tables", &num));
ASSERT_EQ(num, "1");
get_perf_context()->Reset();
perf_context.Reset();
Get(1, "k1");
ASSERT_EQ(2, static_cast<int>(get_perf_context()->get_from_memtable_count));
get_perf_context()->Reset();
ASSERT_EQ(2, static_cast<int>(perf_context.get_from_memtable_count));
perf_context.Reset();
Get(1, "k2");
ASSERT_EQ(1, static_cast<int>(get_perf_context()->get_from_memtable_count));
ASSERT_EQ(1, static_cast<int>(perf_context.get_from_memtable_count));
ASSERT_OK(dbfull()->Put(writeOpt, handles_[1], "k3", big_value));
ASSERT_TRUE(dbfull()->GetProperty(
@@ -567,15 +567,15 @@ TEST_F(DBPropertiesTest, NumImmutableMemTable) {
ASSERT_TRUE(dbfull()->GetProperty(
handles_[1], "rocksdb.num-entries-imm-mem-tables", &num));
ASSERT_EQ(num, "2");
get_perf_context()->Reset();
perf_context.Reset();
Get(1, "k2");
ASSERT_EQ(2, static_cast<int>(get_perf_context()->get_from_memtable_count));
get_perf_context()->Reset();
ASSERT_EQ(2, static_cast<int>(perf_context.get_from_memtable_count));
perf_context.Reset();
Get(1, "k3");
ASSERT_EQ(1, static_cast<int>(get_perf_context()->get_from_memtable_count));
get_perf_context()->Reset();
ASSERT_EQ(1, static_cast<int>(perf_context.get_from_memtable_count));
perf_context.Reset();
Get(1, "k1");
ASSERT_EQ(3, static_cast<int>(get_perf_context()->get_from_memtable_count));
ASSERT_EQ(3, static_cast<int>(perf_context.get_from_memtable_count));
ASSERT_OK(Flush(1));
ASSERT_TRUE(dbfull()->GetProperty(handles_[1],
@@ -670,7 +670,7 @@ TEST_F(DBPropertiesTest, DISABLED_GetProperty) {
ASSERT_EQ(num, "0");
ASSERT_TRUE(dbfull()->GetProperty("rocksdb.estimate-num-keys", &num));
ASSERT_EQ(num, "1");
get_perf_context()->Reset();
perf_context.Reset();
ASSERT_OK(dbfull()->Put(writeOpt, "k2", big_value));
ASSERT_TRUE(dbfull()->GetProperty("rocksdb.num-immutable-mem-table", &num));
@@ -913,7 +913,7 @@ TEST_F(DBPropertiesTest, EstimatePendingCompBytes) {
Flush();
ASSERT_TRUE(dbfull()->GetIntProperty(
"rocksdb.estimate-pending-compaction-bytes", &int_num));
ASSERT_GT(int_num, 0U);
ASSERT_EQ(int_num, 0U);
ASSERT_OK(dbfull()->Put(writeOpt, "k3", big_value));
Flush();
@@ -940,6 +940,7 @@ TEST_F(DBPropertiesTest, EstimateCompressionRatio) {
Options options = CurrentOptions();
options.compression_per_level = {kNoCompression, kSnappyCompression};
options.disable_auto_compactions = true;
options.max_background_flushes = 0;
options.num_levels = 2;
Reopen(options);
@@ -1067,6 +1068,7 @@ class CountingDeleteTabPropCollectorFactory
TEST_F(DBPropertiesTest, GetUserDefinedTableProperties) {
Options options = CurrentOptions();
options.level0_file_num_compaction_trigger = (1 << 30);
options.max_background_flushes = 0;
options.table_properties_collector_factories.resize(1);
std::shared_ptr<CountingUserTblPropCollectorFactory> collector_factory =
std::make_shared<CountingUserTblPropCollectorFactory>(0);
@@ -1107,6 +1109,7 @@ TEST_F(DBPropertiesTest, GetUserDefinedTableProperties) {
TEST_F(DBPropertiesTest, UserDefinedTablePropertiesContext) {
Options options = CurrentOptions();
options.level0_file_num_compaction_trigger = 3;
options.max_background_flushes = 0;
options.table_properties_collector_factories.resize(1);
std::shared_ptr<CountingUserTblPropCollectorFactory> collector_factory =
std::make_shared<CountingUserTblPropCollectorFactory>(1);
@@ -1228,7 +1231,7 @@ TEST_F(DBPropertiesTest, TablePropertiesNeedCompactTest) {
{
SetPerfLevel(kEnableCount);
get_perf_context()->Reset();
perf_context.Reset();
int c = 0;
std::unique_ptr<Iterator> iter(db_->NewIterator(ReadOptions()));
iter->Seek(Key(kMaxKey - 100));
@@ -1236,8 +1239,8 @@ TEST_F(DBPropertiesTest, TablePropertiesNeedCompactTest) {
iter->Next();
}
ASSERT_EQ(c, 0);
ASSERT_LT(get_perf_context()->internal_delete_skipped_count, 30u);
ASSERT_LT(get_perf_context()->internal_key_skipped_count, 30u);
ASSERT_LT(perf_context.internal_delete_skipped_count, 30u);
ASSERT_LT(perf_context.internal_key_skipped_count, 30u);
SetPerfLevel(kDisable);
}
}
@@ -1284,16 +1287,16 @@ TEST_F(DBPropertiesTest, NeedCompactHintPersistentTest) {
ASSERT_EQ(NumTableFilesAtLevel(0), 0);
{
SetPerfLevel(kEnableCount);
get_perf_context()->Reset();
perf_context.Reset();
int c = 0;
std::unique_ptr<Iterator> iter(db_->NewIterator(ReadOptions()));
for (iter->Seek(Key(0)); iter->Valid(); iter->Next()) {
c++;
}
ASSERT_EQ(c, 2);
ASSERT_EQ(get_perf_context()->internal_delete_skipped_count, 0);
ASSERT_EQ(perf_context.internal_delete_skipped_count, 0);
// We iterate every key twice. Is it a bug?
ASSERT_LE(get_perf_context()->internal_key_skipped_count, 2);
ASSERT_LE(perf_context.internal_key_skipped_count, 2);
SetPerfLevel(kDisable);
}
}
-3
View File
@@ -789,7 +789,6 @@ TEST_F(DBRangeDelTest, IteratorIgnoresRangeDeletions) {
db_->ReleaseSnapshot(snapshot);
}
#ifndef ROCKSDB_UBSAN_RUN
TEST_F(DBRangeDelTest, TailingIteratorRangeTombstoneUnsupported) {
db_->Put(WriteOptions(), "key", "val");
// snapshot prevents key from being deleted during flush
@@ -816,8 +815,6 @@ TEST_F(DBRangeDelTest, TailingIteratorRangeTombstoneUnsupported) {
}
db_->ReleaseSnapshot(snapshot);
}
#endif // !ROCKSDB_UBSAN_RUN
#endif // ROCKSDB_LITE
} // namespace rocksdb
+20 -11
View File
@@ -60,6 +60,7 @@
#include "util/file_reader_writer.h"
#include "util/filename.h"
#include "util/hash.h"
#include "util/logging.h"
#include "util/mutexlock.h"
#include "util/rate_limiter.h"
#include "util/string_util.h"
@@ -1438,6 +1439,7 @@ TEST_F(DBTest, UnremovableSingleDelete) {
#ifndef ROCKSDB_LITE
TEST_F(DBTest, DeletionMarkers1) {
Options options = CurrentOptions();
options.max_background_flushes = 0;
CreateAndReopenWithCF({"pikachu"}, options);
Put(1, "foo", "v1");
ASSERT_OK(Flush(1));
@@ -3071,9 +3073,9 @@ TEST_F(DBTest, DynamicMemtableOptions) {
Env::Priority::LOW);
// Start from scratch and disable compaction/flush. Flush can only happen
// during compaction but trigger is pretty high
options.max_background_flushes = 0;
options.disable_auto_compactions = true;
DestroyAndReopen(options);
env_->SetBackgroundThreads(0, Env::HIGH);
// Put until writes are stopped, bounded by 256 puts. We should see stop at
// ~128KB
@@ -3350,6 +3352,7 @@ TEST_P(DBTestWithParam, ThreadStatusSingleCompaction) {
TEST_P(DBTestWithParam, PreShutdownManualCompaction) {
Options options = CurrentOptions();
options.max_background_flushes = 0;
options.max_subcompactions = max_subcompactions_;
CreateAndReopenWithCF({"pikachu"}, options);
@@ -3388,6 +3391,7 @@ TEST_P(DBTestWithParam, PreShutdownManualCompaction) {
if (iter == 0) {
options = CurrentOptions();
options.max_background_flushes = 0;
options.num_levels = 3;
options.create_if_missing = true;
DestroyAndReopen(options);
@@ -3398,6 +3402,7 @@ TEST_P(DBTestWithParam, PreShutdownManualCompaction) {
TEST_F(DBTest, PreShutdownFlush) {
Options options = CurrentOptions();
options.max_background_flushes = 0;
CreateAndReopenWithCF({"pikachu"}, options);
ASSERT_OK(Put(1, "key", "value"));
CancelAllBackgroundWork(db_);
@@ -3689,14 +3694,19 @@ TEST_F(DBTest, DynamicLevelCompressionPerLevel2) {
Random rnd(301);
Options options;
options.create_if_missing = true;
options.db_write_buffer_size = 6000000;
options.write_buffer_size = 600000;
options.db_write_buffer_size = 6000;
options.write_buffer_size = 6000;
options.max_write_buffer_number = 2;
options.level0_file_num_compaction_trigger = 2;
options.level0_slowdown_writes_trigger = 2;
options.level0_stop_writes_trigger = 2;
options.soft_pending_compaction_bytes_limit = 1024 * 1024;
options.target_file_size_base = 20;
// Use file size to distinguish levels
// L1: 10, L2: 20, L3 40, L4 80
// L0 is less than 30
options.target_file_size_base = 10;
options.target_file_size_multiplier = 2;
options.level_compaction_dynamic_level_bytes = true;
options.max_bytes_for_level_base = 200;
@@ -3733,11 +3743,10 @@ TEST_F(DBTest, DynamicLevelCompressionPerLevel2) {
rocksdb::SyncPoint::GetInstance()->EnableProcessing();
for (int i = 0; i < 100; i++) {
std::string value = RandomString(&rnd, 200);
ASSERT_OK(Put(Key(keys[i]), value));
if (i % 25 == 24) {
Flush();
dbfull()->TEST_WaitForCompact();
ASSERT_OK(Put(Key(keys[i]), RandomString(&rnd, 200)));
if (i % 25 == 0) {
dbfull()->TEST_WaitForFlushMemTable();
}
}
@@ -3778,8 +3787,7 @@ TEST_F(DBTest, DynamicLevelCompressionPerLevel2) {
rocksdb::SyncPoint::GetInstance()->EnableProcessing();
for (int i = 101; i < 500; i++) {
std::string value = RandomString(&rnd, 200);
ASSERT_OK(Put(Key(keys[i]), value));
ASSERT_OK(Put(Key(keys[i]), RandomString(&rnd, 200)));
if (i % 100 == 99) {
Flush();
dbfull()->TEST_WaitForCompact();
@@ -5153,6 +5161,7 @@ TEST_F(DBTest, PauseBackgroundWorkTest) {
// now it's done
ASSERT_TRUE(done.load());
}
} // namespace rocksdb
int main(int argc, char** argv) {
+36 -166
View File
@@ -165,48 +165,20 @@ TEST_F(DBTest2, MaxSuccessiveMergesChangeWithDBRecovery) {
#ifndef ROCKSDB_LITE
class DBTestSharedWriteBufferAcrossCFs
: public DBTestBase,
public testing::WithParamInterface<std::tuple<bool, bool>> {
public testing::WithParamInterface<bool> {
public:
DBTestSharedWriteBufferAcrossCFs()
: DBTestBase("/db_test_shared_write_buffer") {}
void SetUp() override {
use_old_interface_ = std::get<0>(GetParam());
cost_cache_ = std::get<1>(GetParam());
}
void SetUp() override { use_old_interface_ = GetParam(); }
bool use_old_interface_;
bool cost_cache_;
};
TEST_P(DBTestSharedWriteBufferAcrossCFs, SharedWriteBufferAcrossCFs) {
Options options = CurrentOptions();
options.arena_block_size = 4096;
// Avoid undeterministic value by malloc_usable_size();
// Force arena block size to 1
rocksdb::SyncPoint::GetInstance()->SetCallBack(
"Arena::Arena:0", [&](void* arg) {
size_t* block_size = static_cast<size_t*>(arg);
*block_size = 1;
});
rocksdb::SyncPoint::GetInstance()->SetCallBack(
"Arena::AllocateNewBlock:0", [&](void* arg) {
std::pair<size_t*, size_t*>* pair =
static_cast<std::pair<size_t*, size_t*>*>(arg);
*std::get<0>(*pair) = *std::get<1>(*pair);
});
rocksdb::SyncPoint::GetInstance()->EnableProcessing();
// The total soft write buffer size is about 105000
std::shared_ptr<Cache> cache = NewLRUCache(4 * 1024 * 1024, 2);
ASSERT_LT(cache->GetUsage(), 1024 * 1024);
if (use_old_interface_) {
options.db_write_buffer_size = 120000; // this is the real limit
} else if (!cost_cache_) {
options.write_buffer_manager.reset(new WriteBufferManager(114285));
options.db_write_buffer_size = 100000; // this is the real limit
} else {
options.write_buffer_manager.reset(new WriteBufferManager(114285, cache));
options.write_buffer_manager.reset(new WriteBufferManager(100000));
}
options.write_buffer_size = 500000; // this is never hit
CreateAndReopenWithCF({"pikachu", "dobrynia", "nikitich"}, options);
@@ -214,13 +186,6 @@ TEST_P(DBTestSharedWriteBufferAcrossCFs, SharedWriteBufferAcrossCFs) {
WriteOptions wo;
wo.disableWAL = true;
std::function<void()> wait_flush = [&]() {
dbfull()->TEST_WaitForFlushMemTable(handles_[0]);
dbfull()->TEST_WaitForFlushMemTable(handles_[1]);
dbfull()->TEST_WaitForFlushMemTable(handles_[2]);
dbfull()->TEST_WaitForFlushMemTable(handles_[3]);
};
// Create some data and flush "default" and "nikitich" so that they
// are newer CFs created.
ASSERT_OK(Put(3, Key(1), DummyString(1), wo));
@@ -234,20 +199,13 @@ TEST_P(DBTestSharedWriteBufferAcrossCFs, SharedWriteBufferAcrossCFs) {
static_cast<uint64_t>(1));
ASSERT_OK(Put(3, Key(1), DummyString(30000), wo));
if (cost_cache_) {
ASSERT_GE(cache->GetUsage(), 1024 * 1024);
ASSERT_LE(cache->GetUsage(), 2 * 1024 * 1024);
}
wait_flush();
ASSERT_OK(Put(0, Key(1), DummyString(60000), wo));
if (cost_cache_) {
ASSERT_GE(cache->GetUsage(), 1024 * 1024);
ASSERT_LE(cache->GetUsage(), 2 * 1024 * 1024);
}
wait_flush();
ASSERT_OK(Put(2, Key(1), DummyString(1), wo));
// No flush should trigger
wait_flush();
dbfull()->TEST_WaitForFlushMemTable(handles_[0]);
dbfull()->TEST_WaitForFlushMemTable(handles_[1]);
dbfull()->TEST_WaitForFlushMemTable(handles_[2]);
dbfull()->TEST_WaitForFlushMemTable(handles_[3]);
{
ASSERT_EQ(GetNumberOfSstFilesForColumnFamily(db_, "default"),
static_cast<uint64_t>(1));
@@ -261,9 +219,11 @@ TEST_P(DBTestSharedWriteBufferAcrossCFs, SharedWriteBufferAcrossCFs) {
// Trigger a flush. Flushing "nikitich".
ASSERT_OK(Put(3, Key(2), DummyString(30000), wo));
wait_flush();
ASSERT_OK(Put(0, Key(1), DummyString(1), wo));
wait_flush();
dbfull()->TEST_WaitForFlushMemTable(handles_[0]);
dbfull()->TEST_WaitForFlushMemTable(handles_[1]);
dbfull()->TEST_WaitForFlushMemTable(handles_[2]);
dbfull()->TEST_WaitForFlushMemTable(handles_[3]);
{
ASSERT_EQ(GetNumberOfSstFilesForColumnFamily(db_, "default"),
static_cast<uint64_t>(1));
@@ -277,11 +237,12 @@ TEST_P(DBTestSharedWriteBufferAcrossCFs, SharedWriteBufferAcrossCFs) {
// Without hitting the threshold, no flush should trigger.
ASSERT_OK(Put(2, Key(1), DummyString(30000), wo));
wait_flush();
ASSERT_OK(Put(2, Key(1), DummyString(1), wo));
wait_flush();
ASSERT_OK(Put(2, Key(1), DummyString(1), wo));
wait_flush();
dbfull()->TEST_WaitForFlushMemTable(handles_[0]);
dbfull()->TEST_WaitForFlushMemTable(handles_[1]);
dbfull()->TEST_WaitForFlushMemTable(handles_[2]);
dbfull()->TEST_WaitForFlushMemTable(handles_[3]);
{
ASSERT_EQ(GetNumberOfSstFilesForColumnFamily(db_, "default"),
static_cast<uint64_t>(1));
@@ -296,15 +257,14 @@ TEST_P(DBTestSharedWriteBufferAcrossCFs, SharedWriteBufferAcrossCFs) {
// Hit the write buffer limit again. "default"
// will have been flushed.
ASSERT_OK(Put(2, Key(2), DummyString(10000), wo));
wait_flush();
ASSERT_OK(Put(3, Key(1), DummyString(1), wo));
wait_flush();
ASSERT_OK(Put(0, Key(1), DummyString(1), wo));
wait_flush();
ASSERT_OK(Put(0, Key(1), DummyString(1), wo));
wait_flush();
ASSERT_OK(Put(0, Key(1), DummyString(1), wo));
wait_flush();
dbfull()->TEST_WaitForFlushMemTable(handles_[0]);
dbfull()->TEST_WaitForFlushMemTable(handles_[1]);
dbfull()->TEST_WaitForFlushMemTable(handles_[2]);
dbfull()->TEST_WaitForFlushMemTable(handles_[3]);
{
ASSERT_EQ(GetNumberOfSstFilesForColumnFamily(db_, "default"),
static_cast<uint64_t>(2));
@@ -319,14 +279,13 @@ TEST_P(DBTestSharedWriteBufferAcrossCFs, SharedWriteBufferAcrossCFs) {
// Trigger another flush. This time "dobrynia". "pikachu" should not
// be flushed, althrough it was never flushed.
ASSERT_OK(Put(1, Key(1), DummyString(1), wo));
wait_flush();
ASSERT_OK(Put(2, Key(1), DummyString(80000), wo));
wait_flush();
ASSERT_OK(Put(1, Key(1), DummyString(1), wo));
wait_flush();
ASSERT_OK(Put(2, Key(1), DummyString(1), wo));
wait_flush();
dbfull()->TEST_WaitForFlushMemTable(handles_[0]);
dbfull()->TEST_WaitForFlushMemTable(handles_[1]);
dbfull()->TEST_WaitForFlushMemTable(handles_[2]);
dbfull()->TEST_WaitForFlushMemTable(handles_[3]);
{
ASSERT_EQ(GetNumberOfSstFilesForColumnFamily(db_, "default"),
static_cast<uint64_t>(2));
@@ -337,45 +296,16 @@ TEST_P(DBTestSharedWriteBufferAcrossCFs, SharedWriteBufferAcrossCFs) {
ASSERT_EQ(GetNumberOfSstFilesForColumnFamily(db_, "nikitich"),
static_cast<uint64_t>(2));
}
if (cost_cache_) {
ASSERT_GE(cache->GetUsage(), 1024 * 1024);
Close();
options.write_buffer_manager.reset();
ASSERT_LT(cache->GetUsage(), 1024 * 1024);
}
rocksdb::SyncPoint::GetInstance()->DisableProcessing();
}
INSTANTIATE_TEST_CASE_P(DBTestSharedWriteBufferAcrossCFs,
DBTestSharedWriteBufferAcrossCFs,
::testing::Values(std::make_tuple(true, false),
std::make_tuple(false, false),
std::make_tuple(false, true)));
DBTestSharedWriteBufferAcrossCFs, ::testing::Bool());
TEST_F(DBTest2, SharedWriteBufferLimitAcrossDB) {
std::string dbname2 = test::TmpDir(env_) + "/db_shared_wb_db2";
Options options = CurrentOptions();
options.arena_block_size = 4096;
// Avoid undeterministic value by malloc_usable_size();
// Force arena block size to 1
rocksdb::SyncPoint::GetInstance()->SetCallBack(
"Arena::Arena:0", [&](void* arg) {
size_t* block_size = static_cast<size_t*>(arg);
*block_size = 1;
});
rocksdb::SyncPoint::GetInstance()->SetCallBack(
"Arena::AllocateNewBlock:0", [&](void* arg) {
std::pair<size_t*, size_t*>* pair =
static_cast<std::pair<size_t*, size_t*>*>(arg);
*std::get<0>(*pair) = *std::get<1>(*pair);
});
rocksdb::SyncPoint::GetInstance()->EnableProcessing();
options.write_buffer_size = 500000; // this is never hit
// Use a write buffer total size so that the soft limit is about
// 105000.
options.write_buffer_manager.reset(new WriteBufferManager(120000));
options.write_buffer_manager.reset(new WriteBufferManager(100000));
CreateAndReopenWithCF({"cf1", "cf2"}, options);
ASSERT_OK(DestroyDB(dbname2, options));
@@ -385,25 +315,17 @@ TEST_F(DBTest2, SharedWriteBufferLimitAcrossDB) {
WriteOptions wo;
wo.disableWAL = true;
std::function<void()> wait_flush = [&]() {
dbfull()->TEST_WaitForFlushMemTable(handles_[0]);
dbfull()->TEST_WaitForFlushMemTable(handles_[1]);
dbfull()->TEST_WaitForFlushMemTable(handles_[2]);
static_cast<DBImpl*>(db2)->TEST_WaitForFlushMemTable();
};
// Trigger a flush on cf2
ASSERT_OK(Put(2, Key(1), DummyString(70000), wo));
wait_flush();
ASSERT_OK(Put(0, Key(1), DummyString(20000), wo));
wait_flush();
// Insert to DB2
ASSERT_OK(db2->Put(wo, Key(2), DummyString(20000)));
wait_flush();
ASSERT_OK(Put(2, Key(1), DummyString(1), wo));
wait_flush();
dbfull()->TEST_WaitForFlushMemTable(handles_[0]);
dbfull()->TEST_WaitForFlushMemTable(handles_[1]);
dbfull()->TEST_WaitForFlushMemTable(handles_[2]);
static_cast<DBImpl*>(db2)->TEST_WaitForFlushMemTable();
{
ASSERT_EQ(GetNumberOfSstFilesForColumnFamily(db_, "default") +
@@ -416,9 +338,10 @@ TEST_F(DBTest2, SharedWriteBufferLimitAcrossDB) {
// Triggering to flush another CF in DB1
ASSERT_OK(db2->Put(wo, Key(2), DummyString(70000)));
wait_flush();
ASSERT_OK(Put(2, Key(1), DummyString(1), wo));
wait_flush();
dbfull()->TEST_WaitForFlushMemTable(handles_[0]);
dbfull()->TEST_WaitForFlushMemTable(handles_[1]);
dbfull()->TEST_WaitForFlushMemTable(handles_[2]);
{
ASSERT_EQ(GetNumberOfSstFilesForColumnFamily(db_, "default"),
static_cast<uint64_t>(1));
@@ -432,9 +355,10 @@ TEST_F(DBTest2, SharedWriteBufferLimitAcrossDB) {
// Triggering flush in DB2.
ASSERT_OK(db2->Put(wo, Key(3), DummyString(40000)));
wait_flush();
ASSERT_OK(db2->Put(wo, Key(1), DummyString(1)));
wait_flush();
dbfull()->TEST_WaitForFlushMemTable(handles_[0]);
dbfull()->TEST_WaitForFlushMemTable(handles_[1]);
dbfull()->TEST_WaitForFlushMemTable(handles_[2]);
static_cast<DBImpl*>(db2)->TEST_WaitForFlushMemTable();
{
ASSERT_EQ(GetNumberOfSstFilesForColumnFamily(db_, "default"),
@@ -449,8 +373,6 @@ TEST_F(DBTest2, SharedWriteBufferLimitAcrossDB) {
delete db2;
ASSERT_OK(DestroyDB(dbname2, options));
rocksdb::SyncPoint::GetInstance()->DisableProcessing();
}
namespace {
@@ -1158,6 +1080,7 @@ TEST_F(DBTest2, CompressionOptions) {
options.max_bytes_for_level_multiplier = 2;
options.num_levels = 7;
options.max_background_compactions = 1;
options.base_background_compactions = 1;
CompactionCompressionListener* listener =
new CompactionCompressionListener(&options);
@@ -1234,9 +1157,6 @@ TEST_F(DBTest2, CompactionStall) {
CompactionStallTestListener* listener = new CompactionStallTestListener();
options.listeners.emplace_back(listener);
DestroyAndReopen(options);
// make sure all background compaction jobs can be scheduled
auto stop_token =
dbfull()->TEST_write_controler().GetCompactionPressureToken();
Random rnd(301);
@@ -2184,56 +2104,6 @@ TEST_F(DBTest2, MemtableOnlyIterator) {
ASSERT_EQ(1, count);
delete it;
}
TEST_F(DBTest2, LowPriWrite) {
Options options = CurrentOptions();
// Compaction pressure should trigger since 6 files
options.level0_file_num_compaction_trigger = 4;
options.level0_slowdown_writes_trigger = 12;
options.level0_stop_writes_trigger = 30;
options.delayed_write_rate = 8 * 1024 * 1024;
Reopen(options);
std::atomic<int> rate_limit_count(0);
rocksdb::SyncPoint::GetInstance()->SetCallBack(
"GenericRateLimiter::Request:1", [&](void* arg) {
rate_limit_count.fetch_add(1);
int64_t* rate_bytes_per_sec = static_cast<int64_t*>(arg);
ASSERT_EQ(1024 * 1024, *rate_bytes_per_sec);
});
// Block compaction
rocksdb::SyncPoint::GetInstance()->LoadDependency({
{"DBTest.LowPriWrite:0", "DBImpl::BGWorkCompaction"},
});
rocksdb::SyncPoint::GetInstance()->EnableProcessing();
WriteOptions wo;
for (int i = 0; i < 6; i++) {
wo.low_pri = false;
Put("", "", wo);
wo.low_pri = true;
Put("", "", wo);
Flush();
}
ASSERT_EQ(0, rate_limit_count.load());
wo.low_pri = true;
Put("", "", wo);
ASSERT_EQ(1, rate_limit_count.load());
wo.low_pri = false;
Put("", "", wo);
ASSERT_EQ(1, rate_limit_count.load());
TEST_SYNC_POINT("DBTest.LowPriWrite:0");
rocksdb::SyncPoint::GetInstance()->DisableProcessing();
dbfull()->TEST_WaitForCompact();
wo.low_pri = true;
Put("", "", wo);
ASSERT_EQ(1, rate_limit_count.load());
wo.low_pri = false;
Put("", "", wo);
ASSERT_EQ(1, rate_limit_count.load());
}
} // namespace rocksdb
int main(int argc, char** argv) {
+12 -24
View File
@@ -43,9 +43,9 @@ SpecialEnv::SpecialEnv(Env* base)
}
DBTestBase::DBTestBase(const std::string path)
: mem_env_(!getenv("MEM_ENV") ? nullptr : new MockEnv(Env::Default())),
env_(new SpecialEnv(mem_env_ ? mem_env_ : Env::Default())),
option_config_(kDefault) {
: option_config_(kDefault),
mem_env_(!getenv("MEM_ENV") ? nullptr : new MockEnv(Env::Default())),
env_(new SpecialEnv(mem_env_ ? mem_env_ : Env::Default())) {
env_->SetBackgroundThreads(1, Env::LOW);
env_->SetBackgroundThreads(1, Env::HIGH);
dbname_ = test::TmpDir(env_) + path;
@@ -245,32 +245,24 @@ bool DBTestBase::ChangeFilterOptions() {
// Return the current option configuration.
Options DBTestBase::CurrentOptions(
const anon::OptionsOverride& options_override) const {
return GetOptions(option_config_, GetDefaultOptions(), options_override);
}
Options DBTestBase::CurrentOptions(
const Options& default_options,
const anon::OptionsOverride& options_override) const {
return GetOptions(option_config_, default_options, options_override);
}
Options DBTestBase::GetDefaultOptions() {
const anon::OptionsOverride& options_override) {
Options options;
options.write_buffer_size = 4090 * 4096;
options.target_file_size_base = 2 * 1024 * 1024;
options.max_bytes_for_level_base = 10 * 1024 * 1024;
options.max_open_files = 5000;
options.base_background_compactions = -1;
options.wal_recovery_mode = WALRecoveryMode::kTolerateCorruptedTailRecords;
options.compaction_pri = CompactionPri::kByCompensatedSize;
return options;
return CurrentOptions(options, options_override);
}
Options DBTestBase::GetOptions(
int option_config, const Options& default_options,
const anon::OptionsOverride& options_override) const {
Options DBTestBase::CurrentOptions(
const Options& defaultOptions,
const anon::OptionsOverride& options_override) {
// this redundant copy is to minimize code change w/o having lint error.
Options options = default_options;
Options options = defaultOptions;
BlockBasedTableOptions table_options;
bool set_block_based_table_factory = true;
#if !defined(OS_MACOSX) && !defined(OS_WIN) && !defined(OS_SOLARIS) && \
@@ -281,7 +273,7 @@ Options DBTestBase::GetOptions(
"NewWritableFile:O_DIRECT");
#endif
switch (option_config) {
switch (option_config_) {
#ifndef ROCKSDB_LITE
case kHashSkipList:
options.prefix_extractor.reset(NewFixedPrefixTransform(1));
@@ -465,10 +457,6 @@ Options DBTestBase::GetOptions(
#endif
break;
}
case kPipelinedWrite: {
options.enable_pipelined_write = true;
break;
}
default:
break;
+20 -48
View File
@@ -49,7 +49,10 @@
#include "util/mutexlock.h"
#include "util/string_util.h"
// SyncPoint is not supported in Released Windows Mode.
#if !(defined NDEBUG) || !defined(OS_WIN)
#include "util/sync_point.h"
#endif // !(defined NDEBUG) || !defined(OS_WIN)
#include "util/testharness.h"
#include "util/testutil.h"
#include "utilities/merge_operators.h"
@@ -123,8 +126,8 @@ enum SkipPolicy { kSkipNone = 0, kSkipNoSnapshot = 1, kSkipNoPrefix = 2 };
// A hacky skip list mem table that triggers flush after number of entries.
class SpecialMemTableRep : public MemTableRep {
public:
explicit SpecialMemTableRep(Allocator* allocator, MemTableRep* memtable,
int num_entries_flush)
explicit SpecialMemTableRep(MemTableAllocator* allocator,
MemTableRep* memtable, int num_entries_flush)
: MemTableRep(allocator),
memtable_(memtable),
num_entries_flush_(num_entries_flush),
@@ -184,9 +187,8 @@ class SpecialSkipListFactory : public MemTableRepFactory {
explicit SpecialSkipListFactory(int num_entries_flush)
: num_entries_flush_(num_entries_flush) {}
using MemTableRepFactory::CreateMemTableRep;
virtual MemTableRep* CreateMemTableRep(
const MemTableRep::KeyComparator& compare, Allocator* allocator,
const MemTableRep::KeyComparator& compare, MemTableAllocator* allocator,
const SliceTransform* transform, Logger* logger) override {
return new SpecialMemTableRep(
allocator, factory_.CreateMemTableRep(compare, allocator, transform, 0),
@@ -584,32 +586,10 @@ class OnFileDeletionListener : public EventListener {
};
#endif
// A test merge operator mimics put but also fails if one of merge operands is
// "corrupted".
class TestPutOperator : public MergeOperator {
public:
virtual bool FullMergeV2(const MergeOperationInput& merge_in,
MergeOperationOutput* merge_out) const override {
if (merge_in.existing_value != nullptr &&
*(merge_in.existing_value) == "corrupted") {
return false;
}
for (auto value : merge_in.operand_list) {
if (value == "corrupted") {
return false;
}
}
merge_out->existing_operand = merge_in.operand_list.back();
return true;
}
virtual const char* Name() const override { return "TestPutOperator"; }
};
class DBTestBase : public testing::Test {
public:
protected:
// Sequence of option configurations to try
enum OptionConfig : int {
enum OptionConfig {
kDefault = 0,
kBlockBasedTableWithPrefixHashIndex = 1,
kBlockBasedTableWithWholeKeyHashIndex = 2,
@@ -640,15 +620,15 @@ class DBTestBase : public testing::Test {
kRowCache = 27,
kRecycleLogFiles = 28,
kConcurrentSkipList = 29,
kPipelinedWrite = 30,
kDirectIO = 30,
kEnd = 31,
kDirectIO = 32,
kLevelSubcompactions = 33,
kUniversalSubcompactions = 34,
kBlockBasedTableWithIndexRestartInterval = 35,
kBlockBasedTableWithPartitionedIndex = 36,
kPartitionedFilterWithNewTableReaderForCompactions = 37,
kLevelSubcompactions = 32,
kUniversalSubcompactions = 33,
kBlockBasedTableWithIndexRestartInterval = 34,
kBlockBasedTableWithPartitionedIndex = 35,
kPartitionedFilterWithNewTableReaderForCompactions = 36,
};
int option_config_;
public:
std::string dbname_;
@@ -659,7 +639,6 @@ class DBTestBase : public testing::Test {
DB* db_;
std::vector<ColumnFamilyHandle*> handles_;
int option_config_;
Options last_options_;
// Skip some options, as they may not be applicable to a specific test.
@@ -710,19 +689,12 @@ class DBTestBase : public testing::Test {
bool ChangeFilterOptions();
// Return the current option configuration.
Options CurrentOptions(const anon::OptionsOverride& options_override =
anon::OptionsOverride()) const;
Options CurrentOptions(
const anon::OptionsOverride& options_override = anon::OptionsOverride());
Options CurrentOptions(const Options& default_options,
const anon::OptionsOverride& options_override =
anon::OptionsOverride()) const;
static Options GetDefaultOptions();
Options GetOptions(int option_config,
const Options& default_options = GetDefaultOptions(),
const anon::OptionsOverride& options_override =
anon::OptionsOverride()) const;
Options CurrentOptions(
const Options& defaultOptions,
const anon::OptionsOverride& options_override = anon::OptionsOverride());
DBImpl* dbfull() { return reinterpret_cast<DBImpl*>(db_); }
-80
View File
@@ -1,80 +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 <memory>
#include <thread>
#include <vector>
#include "db/db_test_util.h"
#include "db/write_batch_internal.h"
#include "port/stack_trace.h"
#include "util/sync_point.h"
namespace rocksdb {
// Test variations of WriteImpl.
class DBWriteTest : public DBTestBase, public testing::WithParamInterface<int> {
public:
DBWriteTest() : DBTestBase("/db_write_test") {}
void Open() { DBTestBase::Reopen(GetOptions(GetParam())); }
};
// Sequence number should be return through input write batch.
TEST_P(DBWriteTest, ReturnSeuqneceNumber) {
Random rnd(4422);
Open();
for (int i = 0; i < 100; i++) {
WriteBatch batch;
batch.Put("key" + ToString(i), test::RandomHumanReadableString(&rnd, 10));
ASSERT_OK(dbfull()->Write(WriteOptions(), &batch));
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(),
WriteBatchInternal::Sequence(&batch));
}
}
TEST_P(DBWriteTest, ReturnSeuqneceNumberMultiThreaded) {
constexpr size_t kThreads = 16;
constexpr size_t kNumKeys = 1000;
Open();
ASSERT_EQ(0, dbfull()->GetLatestSequenceNumber());
// Check each sequence is used once and only once.
std::vector<std::atomic_flag> flags(kNumKeys * kThreads + 1);
for (size_t i = 0; i < flags.size(); i++) {
flags[i].clear();
}
auto writer = [&](size_t id) {
Random rnd(4422 + static_cast<uint32_t>(id));
for (size_t k = 0; k < kNumKeys; k++) {
WriteBatch batch;
batch.Put("key" + ToString(id) + "-" + ToString(k),
test::RandomHumanReadableString(&rnd, 10));
ASSERT_OK(dbfull()->Write(WriteOptions(), &batch));
SequenceNumber sequence = WriteBatchInternal::Sequence(&batch);
ASSERT_GT(sequence, 0);
ASSERT_LE(sequence, kNumKeys * kThreads);
// The sequence isn't consumed by someone else.
ASSERT_FALSE(flags[sequence].test_and_set());
}
};
std::vector<port::Thread> threads;
for (size_t i = 0; i < kThreads; i++) {
threads.emplace_back(writer, i);
}
for (size_t i = 0; i < kThreads; i++) {
threads[i].join();
}
}
INSTANTIATE_TEST_CASE_P(DBWriteTestInstance, DBWriteTest,
testing::Values(DBTestBase::kDefault,
DBTestBase::kPipelinedWrite));
} // namespace rocksdb
int main(int argc, char** argv) {
rocksdb::port::InstallStackTraceHandler();
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
+38 -331
View File
@@ -38,10 +38,8 @@ class ExternalSSTFileBasicTest : public DBTestBase {
}
Status GenerateAndAddExternalFile(
const Options options, std::vector<int> keys,
const std::vector<ValueType>& value_types, int file_id,
const Options options, std::vector<int> keys, int file_id,
std::map<std::string, std::string>* true_data) {
assert(value_types.size() == 1 || keys.size() == value_types.size());
std::string file_path = sst_files_dir_ + ToString(file_id);
SstFileWriter sst_file_writer(EnvOptions(), options);
@@ -49,28 +47,11 @@ class ExternalSSTFileBasicTest : public DBTestBase {
if (!s.ok()) {
return s;
}
for (size_t i = 0; i < keys.size(); i++) {
std::string key = Key(keys[i]);
std::string value = Key(keys[i]) + ToString(file_id);
ValueType value_type =
(value_types.size() == 1 ? value_types[0] : value_types[i]);
switch (value_type) {
case ValueType::kTypeValue:
s = sst_file_writer.Put(key, value);
(*true_data)[key] = value;
break;
case ValueType::kTypeMerge:
s = sst_file_writer.Merge(key, value);
// we only use TestPutOperator in this test
(*true_data)[key] = value;
break;
case ValueType::kTypeDeletion:
s = sst_file_writer.Delete(key);
true_data->erase(key);
break;
default:
return Status::InvalidArgument("Value type is not supported");
}
for (int k : keys) {
std::string key = Key(k);
std::string value = Key(k) + ToString(file_id);
s = sst_file_writer.Add(key, value);
(*true_data)[key] = value;
if (!s.ok()) {
sst_file_writer.Finish();
return s;
@@ -83,15 +64,8 @@ class ExternalSSTFileBasicTest : public DBTestBase {
ifo.allow_global_seqno = true;
s = db_->IngestExternalFile({file_path}, ifo);
}
return s;
}
Status GenerateAndAddExternalFile(
const Options options, std::vector<int> keys, const ValueType value_type,
int file_id, std::map<std::string, std::string>* true_data) {
return GenerateAndAddExternalFile(options, keys,
std::vector<ValueType>(1, value_type),
file_id, true_data);
return s;
}
~ExternalSSTFileBasicTest() { test::DestroyDir(env_, sst_files_dir_); }
@@ -113,7 +87,7 @@ TEST_F(ExternalSSTFileBasicTest, Basic) {
std::string file1 = sst_files_dir_ + "file1.sst";
ASSERT_OK(sst_file_writer.Open(file1));
for (int k = 0; k < 100; k++) {
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
ASSERT_OK(sst_file_writer.Add(Key(k), Key(k) + "_val"));
}
ExternalSstFileInfo file1_info;
Status s = sst_file_writer.Finish(&file1_info);
@@ -127,7 +101,7 @@ TEST_F(ExternalSSTFileBasicTest, Basic) {
ASSERT_EQ(file1_info.smallest_key, Key(0));
ASSERT_EQ(file1_info.largest_key, Key(99));
// sst_file_writer already finished, cannot add this value
s = sst_file_writer.Put(Key(100), "bad_val");
s = sst_file_writer.Add(Key(100), "bad_val");
ASSERT_FALSE(s.ok()) << s.ToString();
DestroyAndReopen(options);
@@ -152,7 +126,7 @@ TEST_F(ExternalSSTFileBasicTest, NoCopy) {
std::string file1 = sst_files_dir_ + "file1.sst";
ASSERT_OK(sst_file_writer.Open(file1));
for (int k = 0; k < 100; k++) {
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
ASSERT_OK(sst_file_writer.Add(Key(k), Key(k) + "_val"));
}
ExternalSstFileInfo file1_info;
Status s = sst_file_writer.Finish(&file1_info);
@@ -166,7 +140,7 @@ TEST_F(ExternalSSTFileBasicTest, NoCopy) {
std::string file2 = sst_files_dir_ + "file2.sst";
ASSERT_OK(sst_file_writer.Open(file2));
for (int k = 100; k < 300; k++) {
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
ASSERT_OK(sst_file_writer.Add(Key(k), Key(k) + "_val"));
}
ExternalSstFileInfo file2_info;
s = sst_file_writer.Finish(&file2_info);
@@ -180,7 +154,7 @@ TEST_F(ExternalSSTFileBasicTest, NoCopy) {
std::string file3 = sst_files_dir_ + "file3.sst";
ASSERT_OK(sst_file_writer.Open(file3));
for (int k = 110; k < 125; k++) {
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val_overlap"));
ASSERT_OK(sst_file_writer.Add(Key(k), Key(k) + "_val_overlap"));
}
ExternalSstFileInfo file3_info;
s = sst_file_writer.Finish(&file3_info);
@@ -215,36 +189,33 @@ TEST_F(ExternalSSTFileBasicTest, IngestFileWithGlobalSeqnoPickedSeqno) {
int file_id = 1;
ASSERT_OK(GenerateAndAddExternalFile(options, {1, 2, 3, 4, 5, 6},
ValueType::kTypeValue, file_id++,
ASSERT_OK(GenerateAndAddExternalFile(options, {1, 2, 3, 4, 5, 6}, file_id++,
&true_data));
// File dont overwrite any keys, No seqno needed
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), 0);
ASSERT_OK(GenerateAndAddExternalFile(options, {10, 11, 12, 13},
ValueType::kTypeValue, file_id++,
ASSERT_OK(GenerateAndAddExternalFile(options, {10, 11, 12, 13}, file_id++,
&true_data));
// File dont overwrite any keys, No seqno needed
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), 0);
ASSERT_OK(GenerateAndAddExternalFile(
options, {1, 4, 6}, ValueType::kTypeValue, file_id++, &true_data));
ASSERT_OK(
GenerateAndAddExternalFile(options, {1, 4, 6}, file_id++, &true_data));
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), 1);
ASSERT_OK(GenerateAndAddExternalFile(
options, {11, 15, 19}, ValueType::kTypeValue, file_id++, &true_data));
ASSERT_OK(GenerateAndAddExternalFile(options, {11, 15, 19}, file_id++,
&true_data));
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), 2);
ASSERT_OK(GenerateAndAddExternalFile(
options, {120, 130}, ValueType::kTypeValue, file_id++, &true_data));
ASSERT_OK(
GenerateAndAddExternalFile(options, {120, 130}, file_id++, &true_data));
// File dont overwrite any keys, No seqno needed
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), 2);
ASSERT_OK(GenerateAndAddExternalFile(
options, {1, 130}, ValueType::kTypeValue, file_id++, &true_data));
ASSERT_OK(
GenerateAndAddExternalFile(options, {1, 130}, file_id++, &true_data));
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), 3);
@@ -255,18 +226,18 @@ TEST_F(ExternalSSTFileBasicTest, IngestFileWithGlobalSeqnoPickedSeqno) {
}
SequenceNumber last_seqno = dbfull()->GetLatestSequenceNumber();
ASSERT_OK(GenerateAndAddExternalFile(
options, {60, 61, 62}, ValueType::kTypeValue, file_id++, &true_data));
ASSERT_OK(GenerateAndAddExternalFile(options, {60, 61, 62}, file_id++,
&true_data));
// File dont overwrite any keys, No seqno needed
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), last_seqno);
ASSERT_OK(GenerateAndAddExternalFile(
options, {40, 41, 42}, ValueType::kTypeValue, file_id++, &true_data));
ASSERT_OK(GenerateAndAddExternalFile(options, {40, 41, 42}, file_id++,
&true_data));
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), last_seqno + 1);
ASSERT_OK(GenerateAndAddExternalFile(
options, {20, 30, 40}, ValueType::kTypeValue, file_id++, &true_data));
ASSERT_OK(GenerateAndAddExternalFile(options, {20, 30, 40}, file_id++,
&true_data));
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), last_seqno + 2);
@@ -274,241 +245,25 @@ TEST_F(ExternalSSTFileBasicTest, IngestFileWithGlobalSeqnoPickedSeqno) {
// We will need a seqno for the file regardless if the file overwrite
// keys in the DB or not because we have a snapshot
ASSERT_OK(GenerateAndAddExternalFile(
options, {1000, 1002}, ValueType::kTypeValue, file_id++, &true_data));
ASSERT_OK(GenerateAndAddExternalFile(options, {1000, 1002}, file_id++,
&true_data));
// A global seqno will be assigned anyway because of the snapshot
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), last_seqno + 3);
ASSERT_OK(GenerateAndAddExternalFile(
options, {2000, 3002}, ValueType::kTypeValue, file_id++, &true_data));
ASSERT_OK(GenerateAndAddExternalFile(options, {2000, 3002}, file_id++,
&true_data));
// A global seqno will be assigned anyway because of the snapshot
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), last_seqno + 4);
ASSERT_OK(GenerateAndAddExternalFile(options, {1, 20, 40, 100, 150},
ValueType::kTypeValue, file_id++,
&true_data));
file_id++, &true_data));
// A global seqno will be assigned anyway because of the snapshot
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), last_seqno + 5);
db_->ReleaseSnapshot(snapshot);
ASSERT_OK(GenerateAndAddExternalFile(
options, {5000, 5001}, ValueType::kTypeValue, file_id++, &true_data));
// No snapshot anymore, no need to assign a seqno
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), last_seqno + 5);
size_t kcnt = 0;
VerifyDBFromMap(true_data, &kcnt, false);
} while (ChangeCompactOptions());
}
TEST_F(ExternalSSTFileBasicTest, IngestFileWithMultipleValueType) {
do {
Options options = CurrentOptions();
options.merge_operator.reset(new TestPutOperator());
DestroyAndReopen(options);
std::map<std::string, std::string> true_data;
int file_id = 1;
ASSERT_OK(GenerateAndAddExternalFile(options, {1, 2, 3, 4, 5, 6},
ValueType::kTypeValue, file_id++,
ASSERT_OK(GenerateAndAddExternalFile(options, {5000, 5001}, file_id++,
&true_data));
// File dont overwrite any keys, No seqno needed
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), 0);
ASSERT_OK(GenerateAndAddExternalFile(options, {10, 11, 12, 13},
ValueType::kTypeValue, file_id++,
&true_data));
// File dont overwrite any keys, No seqno needed
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), 0);
ASSERT_OK(GenerateAndAddExternalFile(
options, {1, 4, 6}, ValueType::kTypeMerge, file_id++, &true_data));
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), 1);
ASSERT_OK(GenerateAndAddExternalFile(options, {11, 15, 19},
ValueType::kTypeDeletion, file_id++,
&true_data));
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), 2);
ASSERT_OK(GenerateAndAddExternalFile(
options, {120, 130}, ValueType::kTypeMerge, file_id++, &true_data));
// File dont overwrite any keys, No seqno needed
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), 2);
ASSERT_OK(GenerateAndAddExternalFile(
options, {1, 130}, ValueType::kTypeDeletion, file_id++, &true_data));
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), 3);
// Write some keys through normal write path
for (int i = 0; i < 50; i++) {
ASSERT_OK(Put(Key(i), "memtable"));
true_data[Key(i)] = "memtable";
}
SequenceNumber last_seqno = dbfull()->GetLatestSequenceNumber();
ASSERT_OK(GenerateAndAddExternalFile(
options, {60, 61, 62}, ValueType::kTypeValue, file_id++, &true_data));
// File dont overwrite any keys, No seqno needed
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), last_seqno);
ASSERT_OK(GenerateAndAddExternalFile(
options, {40, 41, 42}, ValueType::kTypeMerge, file_id++, &true_data));
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), last_seqno + 1);
ASSERT_OK(GenerateAndAddExternalFile(options, {20, 30, 40},
ValueType::kTypeDeletion, file_id++,
&true_data));
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), last_seqno + 2);
const Snapshot* snapshot = db_->GetSnapshot();
// We will need a seqno for the file regardless if the file overwrite
// keys in the DB or not because we have a snapshot
ASSERT_OK(GenerateAndAddExternalFile(
options, {1000, 1002}, ValueType::kTypeMerge, file_id++, &true_data));
// A global seqno will be assigned anyway because of the snapshot
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), last_seqno + 3);
ASSERT_OK(GenerateAndAddExternalFile(
options, {2000, 3002}, ValueType::kTypeMerge, file_id++, &true_data));
// A global seqno will be assigned anyway because of the snapshot
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), last_seqno + 4);
ASSERT_OK(GenerateAndAddExternalFile(options, {1, 20, 40, 100, 150},
ValueType::kTypeMerge, file_id++,
&true_data));
// A global seqno will be assigned anyway because of the snapshot
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), last_seqno + 5);
db_->ReleaseSnapshot(snapshot);
ASSERT_OK(GenerateAndAddExternalFile(
options, {5000, 5001}, ValueType::kTypeValue, file_id++, &true_data));
// No snapshot anymore, no need to assign a seqno
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), last_seqno + 5);
size_t kcnt = 0;
VerifyDBFromMap(true_data, &kcnt, false);
} while (ChangeCompactOptions());
}
TEST_F(ExternalSSTFileBasicTest, IngestFileWithMixedValueType) {
do {
Options options = CurrentOptions();
options.merge_operator.reset(new TestPutOperator());
DestroyAndReopen(options);
std::map<std::string, std::string> true_data;
int file_id = 1;
ASSERT_OK(GenerateAndAddExternalFile(
options, {1, 2, 3, 4, 5, 6},
{ValueType::kTypeValue, ValueType::kTypeMerge, ValueType::kTypeValue,
ValueType::kTypeMerge, ValueType::kTypeValue, ValueType::kTypeMerge},
file_id++, &true_data));
// File dont overwrite any keys, No seqno needed
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), 0);
ASSERT_OK(GenerateAndAddExternalFile(
options, {10, 11, 12, 13},
{ValueType::kTypeValue, ValueType::kTypeMerge, ValueType::kTypeValue,
ValueType::kTypeMerge},
file_id++, &true_data));
// File dont overwrite any keys, No seqno needed
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), 0);
ASSERT_OK(GenerateAndAddExternalFile(
options, {1, 4, 6}, {ValueType::kTypeDeletion, ValueType::kTypeValue,
ValueType::kTypeMerge},
file_id++, &true_data));
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), 1);
ASSERT_OK(GenerateAndAddExternalFile(
options, {11, 15, 19}, {ValueType::kTypeDeletion, ValueType::kTypeMerge,
ValueType::kTypeValue},
file_id++, &true_data));
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), 2);
ASSERT_OK(GenerateAndAddExternalFile(
options, {120, 130}, {ValueType::kTypeValue, ValueType::kTypeMerge},
file_id++, &true_data));
// File dont overwrite any keys, No seqno needed
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), 2);
ASSERT_OK(GenerateAndAddExternalFile(
options, {1, 130}, {ValueType::kTypeMerge, ValueType::kTypeDeletion},
file_id++, &true_data));
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), 3);
// Write some keys through normal write path
for (int i = 0; i < 50; i++) {
ASSERT_OK(Put(Key(i), "memtable"));
true_data[Key(i)] = "memtable";
}
SequenceNumber last_seqno = dbfull()->GetLatestSequenceNumber();
ASSERT_OK(GenerateAndAddExternalFile(
options, {60, 61, 62},
{ValueType::kTypeValue, ValueType::kTypeMerge, ValueType::kTypeValue},
file_id++, &true_data));
// File dont overwrite any keys, No seqno needed
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), last_seqno);
ASSERT_OK(GenerateAndAddExternalFile(
options, {40, 41, 42}, {ValueType::kTypeValue, ValueType::kTypeDeletion,
ValueType::kTypeDeletion},
file_id++, &true_data));
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), last_seqno + 1);
ASSERT_OK(GenerateAndAddExternalFile(
options, {20, 30, 40},
{ValueType::kTypeDeletion, ValueType::kTypeDeletion,
ValueType::kTypeDeletion},
file_id++, &true_data));
// File overwrite some keys, a seqno will be assigned
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), last_seqno + 2);
const Snapshot* snapshot = db_->GetSnapshot();
// We will need a seqno for the file regardless if the file overwrite
// keys in the DB or not because we have a snapshot
ASSERT_OK(GenerateAndAddExternalFile(
options, {1000, 1002}, {ValueType::kTypeValue, ValueType::kTypeMerge},
file_id++, &true_data));
// A global seqno will be assigned anyway because of the snapshot
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), last_seqno + 3);
ASSERT_OK(GenerateAndAddExternalFile(
options, {2000, 3002}, {ValueType::kTypeValue, ValueType::kTypeMerge},
file_id++, &true_data));
// A global seqno will be assigned anyway because of the snapshot
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), last_seqno + 4);
ASSERT_OK(GenerateAndAddExternalFile(
options, {1, 20, 40, 100, 150},
{ValueType::kTypeDeletion, ValueType::kTypeDeletion,
ValueType::kTypeValue, ValueType::kTypeMerge, ValueType::kTypeMerge},
file_id++, &true_data));
// A global seqno will be assigned anyway because of the snapshot
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), last_seqno + 5);
db_->ReleaseSnapshot(snapshot);
ASSERT_OK(GenerateAndAddExternalFile(
options, {5000, 5001}, {ValueType::kTypeValue, ValueType::kTypeMerge},
file_id++, &true_data));
// No snapshot anymore, no need to assign a seqno
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), last_seqno + 5);
@@ -523,7 +278,7 @@ TEST_F(ExternalSSTFileBasicTest, FadviseTrigger) {
size_t total_fadvised_bytes = 0;
rocksdb::SyncPoint::GetInstance()->SetCallBack(
"SstFileWriter::Rep::InvalidatePageCache", [&](void* arg) {
"SstFileWriter::InvalidatePageCache", [&](void* arg) {
size_t fadvise_size = *(reinterpret_cast<size_t*>(arg));
total_fadvised_bytes += fadvise_size;
});
@@ -536,18 +291,19 @@ TEST_F(ExternalSSTFileBasicTest, FadviseTrigger) {
new SstFileWriter(EnvOptions(), options, nullptr, false));
ASSERT_OK(sst_file_writer->Open(sst_file_path));
for (int i = 0; i < kNumKeys; i++) {
ASSERT_OK(sst_file_writer->Put(Key(i), Key(i)));
ASSERT_OK(sst_file_writer->Add(Key(i), Key(i)));
}
ASSERT_OK(sst_file_writer->Finish());
// fadvise disabled
ASSERT_EQ(total_fadvised_bytes, 0);
sst_file_path = sst_files_dir_ + "file_fadvise_enable.sst";
sst_file_writer.reset(
new SstFileWriter(EnvOptions(), options, nullptr, true));
ASSERT_OK(sst_file_writer->Open(sst_file_path));
for (int i = 0; i < kNumKeys; i++) {
ASSERT_OK(sst_file_writer->Put(Key(i), Key(i)));
ASSERT_OK(sst_file_writer->Add(Key(i), Key(i)));
}
ASSERT_OK(sst_file_writer->Finish());
// fadvise enabled
@@ -557,55 +313,6 @@ TEST_F(ExternalSSTFileBasicTest, FadviseTrigger) {
rocksdb::SyncPoint::GetInstance()->DisableProcessing();
}
TEST_F(ExternalSSTFileBasicTest, IngestionWithRangeDeletions) {
Options options = CurrentOptions();
options.disable_auto_compactions = true;
Reopen(options);
std::map<std::string, std::string> true_data;
int file_id = 1;
// prevent range deletions from being dropped due to becoming obsolete.
const Snapshot* snapshot = db_->GetSnapshot();
// range del [0, 50) in L0 file, [50, 100) in memtable
for (int i = 0; i < 2; i++) {
if (i == 1) {
db_->Flush(FlushOptions());
}
ASSERT_OK(db_->DeleteRange(WriteOptions(), db_->DefaultColumnFamily(),
Key(50 * i), Key(50 * (i + 1))));
}
ASSERT_EQ(1, NumTableFilesAtLevel(0));
// overlaps with L0 file but not memtable, so flush is skipped
SequenceNumber last_seqno = dbfull()->GetLatestSequenceNumber();
ASSERT_OK(GenerateAndAddExternalFile(
options, {10, 40}, {ValueType::kTypeValue, ValueType::kTypeValue},
file_id++, &true_data));
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), ++last_seqno);
ASSERT_EQ(2, NumTableFilesAtLevel(0));
// overlaps with memtable, so flush is triggered (thus file count increases by
// two at this step).
ASSERT_OK(GenerateAndAddExternalFile(
options, {50, 90}, {ValueType::kTypeValue, ValueType::kTypeValue},
file_id++, &true_data));
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), ++last_seqno);
ASSERT_EQ(4, NumTableFilesAtLevel(0));
// snapshot unneeded now that both range deletions are persisted
db_->ReleaseSnapshot(snapshot);
// overlaps with nothing, so places at bottom level and skips incrementing
// seqnum.
ASSERT_OK(GenerateAndAddExternalFile(
options, {101, 125}, {ValueType::kTypeValue, ValueType::kTypeValue},
file_id++, &true_data));
ASSERT_EQ(dbfull()->GetLatestSequenceNumber(), last_seqno);
ASSERT_EQ(4, NumTableFilesAtLevel(0));
ASSERT_EQ(1, NumTableFilesAtLevel(options.num_levels - 1));
}
#endif // ROCKSDB_LITE
} // namespace rocksdb
+10 -62
View File
@@ -379,17 +379,6 @@ Status ExternalSstFileIngestionJob::IngestedFilesOverlapWithMemtables(
sv->imm->AddIterators(ro, &merge_iter_builder);
ScopedArenaIterator memtable_iter(merge_iter_builder.Finish());
std::vector<InternalIterator*> memtable_range_del_iters;
auto* active_range_del_iter = sv->mem->NewRangeTombstoneIterator(ro);
if (active_range_del_iter != nullptr) {
memtable_range_del_iters.push_back(active_range_del_iter);
}
sv->imm->AddRangeTombstoneIterators(ro, &memtable_range_del_iters);
std::unique_ptr<InternalIterator> memtable_range_del_iter(NewMergingIterator(
&cfd_->internal_comparator(),
memtable_range_del_iters.empty() ? nullptr : &memtable_range_del_iters[0],
static_cast<int>(memtable_range_del_iters.size())));
Status status;
*overlap = false;
for (IngestedFileInfo& f : files_to_ingest_) {
@@ -398,11 +387,6 @@ Status ExternalSstFileIngestionJob::IngestedFilesOverlapWithMemtables(
if (!status.ok() || *overlap == true) {
break;
}
status = IngestedFileOverlapWithRangeDeletions(
&f, memtable_range_del_iter.get(), overlap);
if (!status.ok() || *overlap == true) {
break;
}
}
return status;
@@ -569,34 +553,6 @@ Status ExternalSstFileIngestionJob::IngestedFileOverlapWithIteratorRange(
return iter->status();
}
Status ExternalSstFileIngestionJob::IngestedFileOverlapWithRangeDeletions(
const IngestedFileInfo* file_to_ingest, InternalIterator* range_del_iter,
bool* overlap) {
auto* vstorage = cfd_->current()->storage_info();
auto* ucmp = vstorage->InternalComparator()->user_comparator();
*overlap = false;
if (range_del_iter != nullptr) {
for (range_del_iter->SeekToFirst(); range_del_iter->Valid();
range_del_iter->Next()) {
ParsedInternalKey parsed_key;
if (!ParseInternalKey(range_del_iter->key(), &parsed_key)) {
return Status::Corruption("corrupted range deletion key: " +
range_del_iter->key().ToString());
}
RangeTombstone range_del(parsed_key, range_del_iter->value());
if (ucmp->Compare(range_del.start_key_,
file_to_ingest->largest_user_key) <= 0 &&
ucmp->Compare(file_to_ingest->smallest_user_key,
range_del.end_key_) <= 0) {
*overlap = true;
break;
}
}
}
return Status::OK();
}
bool ExternalSstFileIngestionJob::IngestedFileFitInLevel(
const IngestedFileInfo* file_to_ingest, int level) {
if (level == 0) {
@@ -633,25 +589,17 @@ Status ExternalSstFileIngestionJob::IngestedFileOverlapWithLevel(
ro.total_order_seek = true;
MergeIteratorBuilder merge_iter_builder(&cfd_->internal_comparator(),
&arena);
sv->current->AddIteratorsForLevel(ro, env_options_, &merge_iter_builder, lvl,
nullptr /* range_del_agg */);
ScopedArenaIterator level_iter(merge_iter_builder.Finish());
std::vector<InternalIterator*> level_range_del_iters;
sv->current->AddRangeDelIteratorsForLevel(ro, env_options_, lvl,
&level_range_del_iters);
std::unique_ptr<InternalIterator> level_range_del_iter(NewMergingIterator(
&cfd_->internal_comparator(),
level_range_del_iters.empty() ? nullptr : &level_range_del_iters[0],
static_cast<int>(level_range_del_iters.size())));
Status status = IngestedFileOverlapWithIteratorRange(
file_to_ingest, level_iter.get(), overlap_with_level);
if (status.ok() && *overlap_with_level == false) {
status = IngestedFileOverlapWithRangeDeletions(
file_to_ingest, level_range_del_iter.get(), overlap_with_level);
RangeDelAggregator range_del_agg(cfd_->internal_comparator(),
{} /* snapshots */);
sv->current->AddIteratorsForLevel(ro, env_options_, &merge_iter_builder,
lvl, &range_del_agg);
if (!range_del_agg.IsEmpty()) {
return Status::NotSupported(
"file ingestion with range tombstones is currently unsupported");
}
return status;
ScopedArenaIterator level_iter(merge_iter_builder.Finish());
return IngestedFileOverlapWithIteratorRange(
file_to_ingest, level_iter.get(), overlap_with_level);
}
} // namespace rocksdb
+1 -8
View File
@@ -95,7 +95,7 @@ class ExternalSstFileIngestionJob {
// REQUIRES: Mutex held
void UpdateStats();
// Cleanup after successful/failed job
// Cleanup after successfull/failed job
void Cleanup(const Status& status);
VersionEdit* edit() { return &edit_; }
@@ -139,13 +139,6 @@ class ExternalSstFileIngestionJob {
const IngestedFileInfo* file_to_ingest, InternalIterator* iter,
bool* overlap);
// Check if `file_to_ingest` key range overlaps with any range deletions
// specified by `iter`.
// REQUIRES: Mutex held
Status IngestedFileOverlapWithRangeDeletions(
const IngestedFileInfo* file_to_ingest, InternalIterator* range_del_iter,
bool* overlap);
// Check if `file_to_ingest` key range overlap with level
// REQUIRES: Mutex held
Status IngestedFileOverlapWithLevel(SuperVersion* sv,
+37 -37
View File
@@ -61,7 +61,7 @@ class ExternalSSTFileTest : public DBTestBase {
return s;
}
for (auto& entry : data) {
s = sst_file_writer.Put(entry.first, entry.second);
s = sst_file_writer.Add(entry.first, entry.second);
if (!s.ok()) {
sst_file_writer.Finish();
return s;
@@ -123,7 +123,7 @@ class ExternalSSTFileTest : public DBTestBase {
return s;
}
for (auto& entry : data) {
s = sst_file_writer.Put(entry.first, entry.second);
s = sst_file_writer.Add(entry.first, entry.second);
if (!s.ok()) {
sst_file_writer.Finish();
return s;
@@ -209,7 +209,7 @@ TEST_F(ExternalSSTFileTest, Basic) {
std::string file1 = sst_files_dir_ + "file1.sst";
ASSERT_OK(sst_file_writer.Open(file1));
for (int k = 0; k < 100; k++) {
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
ASSERT_OK(sst_file_writer.Add(Key(k), Key(k) + "_val"));
}
ExternalSstFileInfo file1_info;
Status s = sst_file_writer.Finish(&file1_info);
@@ -223,17 +223,17 @@ TEST_F(ExternalSSTFileTest, Basic) {
ASSERT_EQ(file1_info.smallest_key, Key(0));
ASSERT_EQ(file1_info.largest_key, Key(99));
// sst_file_writer already finished, cannot add this value
s = sst_file_writer.Put(Key(100), "bad_val");
s = sst_file_writer.Add(Key(100), "bad_val");
ASSERT_FALSE(s.ok()) << s.ToString();
// file2.sst (100 => 199)
std::string file2 = sst_files_dir_ + "file2.sst";
ASSERT_OK(sst_file_writer.Open(file2));
for (int k = 100; k < 200; k++) {
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
ASSERT_OK(sst_file_writer.Add(Key(k), Key(k) + "_val"));
}
// Cannot add this key because it's not after last added key
s = sst_file_writer.Put(Key(99), "bad_val");
s = sst_file_writer.Add(Key(99), "bad_val");
ASSERT_FALSE(s.ok()) << s.ToString();
ExternalSstFileInfo file2_info;
s = sst_file_writer.Finish(&file2_info);
@@ -248,7 +248,7 @@ TEST_F(ExternalSSTFileTest, Basic) {
std::string file3 = sst_files_dir_ + "file3.sst";
ASSERT_OK(sst_file_writer.Open(file3));
for (int k = 195; k < 300; k++) {
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val_overlap"));
ASSERT_OK(sst_file_writer.Add(Key(k), Key(k) + "_val_overlap"));
}
ExternalSstFileInfo file3_info;
s = sst_file_writer.Finish(&file3_info);
@@ -266,7 +266,7 @@ TEST_F(ExternalSSTFileTest, Basic) {
std::string file4 = sst_files_dir_ + "file4.sst";
ASSERT_OK(sst_file_writer.Open(file4));
for (int k = 30; k < 40; k++) {
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val_overlap"));
ASSERT_OK(sst_file_writer.Add(Key(k), Key(k) + "_val_overlap"));
}
ExternalSstFileInfo file4_info;
s = sst_file_writer.Finish(&file4_info);
@@ -280,7 +280,7 @@ TEST_F(ExternalSSTFileTest, Basic) {
std::string file5 = sst_files_dir_ + "file5.sst";
ASSERT_OK(sst_file_writer.Open(file5));
for (int k = 400; k < 500; k++) {
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
ASSERT_OK(sst_file_writer.Add(Key(k), Key(k) + "_val"));
}
ExternalSstFileInfo file5_info;
s = sst_file_writer.Finish(&file5_info);
@@ -442,7 +442,7 @@ TEST_F(ExternalSSTFileTest, AddList) {
std::string file1 = sst_files_dir_ + "file1.sst";
ASSERT_OK(sst_file_writer.Open(file1));
for (int k = 0; k < 100; k++) {
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
ASSERT_OK(sst_file_writer.Add(Key(k), Key(k) + "_val"));
}
ExternalSstFileInfo file1_info;
Status s = sst_file_writer.Finish(&file1_info);
@@ -452,17 +452,17 @@ TEST_F(ExternalSSTFileTest, AddList) {
ASSERT_EQ(file1_info.smallest_key, Key(0));
ASSERT_EQ(file1_info.largest_key, Key(99));
// sst_file_writer already finished, cannot add this value
s = sst_file_writer.Put(Key(100), "bad_val");
s = sst_file_writer.Add(Key(100), "bad_val");
ASSERT_FALSE(s.ok()) << s.ToString();
// file2.sst (100 => 199)
std::string file2 = sst_files_dir_ + "file2.sst";
ASSERT_OK(sst_file_writer.Open(file2));
for (int k = 100; k < 200; k++) {
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
ASSERT_OK(sst_file_writer.Add(Key(k), Key(k) + "_val"));
}
// Cannot add this key because it's not after last added key
s = sst_file_writer.Put(Key(99), "bad_val");
s = sst_file_writer.Add(Key(99), "bad_val");
ASSERT_FALSE(s.ok()) << s.ToString();
ExternalSstFileInfo file2_info;
s = sst_file_writer.Finish(&file2_info);
@@ -477,7 +477,7 @@ TEST_F(ExternalSSTFileTest, AddList) {
std::string file3 = sst_files_dir_ + "file3.sst";
ASSERT_OK(sst_file_writer.Open(file3));
for (int k = 195; k < 200; k++) {
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val_overlap"));
ASSERT_OK(sst_file_writer.Add(Key(k), Key(k) + "_val_overlap"));
}
ExternalSstFileInfo file3_info;
s = sst_file_writer.Finish(&file3_info);
@@ -492,7 +492,7 @@ TEST_F(ExternalSSTFileTest, AddList) {
std::string file4 = sst_files_dir_ + "file4.sst";
ASSERT_OK(sst_file_writer.Open(file4));
for (int k = 30; k < 40; k++) {
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val_overlap"));
ASSERT_OK(sst_file_writer.Add(Key(k), Key(k) + "_val_overlap"));
}
ExternalSstFileInfo file4_info;
s = sst_file_writer.Finish(&file4_info);
@@ -506,7 +506,7 @@ TEST_F(ExternalSSTFileTest, AddList) {
std::string file5 = sst_files_dir_ + "file5.sst";
ASSERT_OK(sst_file_writer.Open(file5));
for (int k = 200; k < 300; k++) {
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
ASSERT_OK(sst_file_writer.Add(Key(k), Key(k) + "_val"));
}
ExternalSstFileInfo file5_info;
s = sst_file_writer.Finish(&file5_info);
@@ -637,7 +637,7 @@ TEST_F(ExternalSSTFileTest, AddListAtomicity) {
files[i] = sst_files_dir_ + "file" + std::to_string(i) + ".sst";
ASSERT_OK(sst_file_writer.Open(files[i]));
for (int k = i * 100; k < (i + 1) * 100; k++) {
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
ASSERT_OK(sst_file_writer.Add(Key(k), Key(k) + "_val"));
}
Status s = sst_file_writer.Finish(&files_info[i]);
ASSERT_TRUE(s.ok()) << s.ToString();
@@ -674,7 +674,7 @@ TEST_F(ExternalSSTFileTest, PurgeObsoleteFilesBug) {
ASSERT_OK(s);
for (int i = 0; i < 500; i++) {
std::string k = Key(i);
s = sst_file_writer.Put(k, k + "_val");
s = sst_file_writer.Add(k, k + "_val");
ASSERT_OK(s);
}
@@ -717,7 +717,7 @@ TEST_F(ExternalSSTFileTest, SkipSnapshot) {
std::string file1 = sst_files_dir_ + "file1.sst";
ASSERT_OK(sst_file_writer.Open(file1));
for (int k = 0; k < 100; k++) {
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
ASSERT_OK(sst_file_writer.Add(Key(k), Key(k) + "_val"));
}
ExternalSstFileInfo file1_info;
Status s = sst_file_writer.Finish(&file1_info);
@@ -731,7 +731,7 @@ TEST_F(ExternalSSTFileTest, SkipSnapshot) {
std::string file2 = sst_files_dir_ + "file2.sst";
ASSERT_OK(sst_file_writer.Open(file2));
for (int k = 100; k < 300; k++) {
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
ASSERT_OK(sst_file_writer.Add(Key(k), Key(k) + "_val"));
}
ExternalSstFileInfo file2_info;
s = sst_file_writer.Finish(&file2_info);
@@ -761,7 +761,7 @@ TEST_F(ExternalSSTFileTest, SkipSnapshot) {
std::string file3 = sst_files_dir_ + "file3.sst";
ASSERT_OK(sst_file_writer.Open(file3));
for (int k = 300; k < 400; k++) {
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k) + "_val"));
ASSERT_OK(sst_file_writer.Add(Key(k), Key(k) + "_val"));
}
ExternalSstFileInfo file3_info;
s = sst_file_writer.Finish(&file3_info);
@@ -807,7 +807,7 @@ TEST_F(ExternalSSTFileTest, MultiThreaded) {
ASSERT_OK(sst_file_writer.Open(file_names[file_idx]));
for (int k = range_start; k < range_end; k++) {
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k)));
ASSERT_OK(sst_file_writer.Add(Key(k), Key(k)));
}
Status s = sst_file_writer.Finish();
@@ -958,7 +958,7 @@ TEST_F(ExternalSSTFileTest, OverlappingRanges) {
std::string file_name = sst_files_dir_ + env_->GenerateUniqueId();
ASSERT_OK(sst_file_writer.Open(file_name));
for (int k = range_start; k <= range_end; k++) {
s = sst_file_writer.Put(Key(k), range_val);
s = sst_file_writer.Add(Key(k), range_val);
ASSERT_OK(s);
}
ExternalSstFileInfo file_info;
@@ -1356,7 +1356,7 @@ TEST_F(ExternalSSTFileTest, AddExternalSstFileWithCustomCompartor) {
int range_end = i * 10;
int range_start = range_end + 15;
for (int k = (range_start - 1); k >= range_end; k--) {
ASSERT_OK(sst_file_writer.Put(Key(k), Key(k)));
ASSERT_OK(sst_file_writer.Add(Key(k), Key(k)));
}
ExternalSstFileInfo file_info;
ASSERT_OK(sst_file_writer.Finish(&file_info));
@@ -1446,12 +1446,12 @@ TEST_F(ExternalSSTFileTest, SstFileWriterNonSharedKeys) {
std::string suffix(100, 'X');
ASSERT_OK(sst_file_writer.Open(file_path));
ASSERT_OK(sst_file_writer.Put("A" + suffix, "VAL"));
ASSERT_OK(sst_file_writer.Put("BB" + suffix, "VAL"));
ASSERT_OK(sst_file_writer.Put("CC" + suffix, "VAL"));
ASSERT_OK(sst_file_writer.Put("CXD" + suffix, "VAL"));
ASSERT_OK(sst_file_writer.Put("CZZZ" + suffix, "VAL"));
ASSERT_OK(sst_file_writer.Put("ZAAAX" + suffix, "VAL"));
ASSERT_OK(sst_file_writer.Add("A" + suffix, "VAL"));
ASSERT_OK(sst_file_writer.Add("BB" + suffix, "VAL"));
ASSERT_OK(sst_file_writer.Add("CC" + suffix, "VAL"));
ASSERT_OK(sst_file_writer.Add("CXD" + suffix, "VAL"));
ASSERT_OK(sst_file_writer.Add("CZZZ" + suffix, "VAL"));
ASSERT_OK(sst_file_writer.Add("ZAAAX" + suffix, "VAL"));
ASSERT_OK(sst_file_writer.Finish());
ASSERT_OK(DeprecatedAddFile({file_path}));
@@ -1746,22 +1746,22 @@ TEST_F(ExternalSSTFileTest, FileWithCFInfo) {
// default_cf.sst
const std::string cf_default_sst = sst_files_dir_ + "/default_cf.sst";
ASSERT_OK(sfw_default.Open(cf_default_sst));
ASSERT_OK(sfw_default.Put("K1", "V1"));
ASSERT_OK(sfw_default.Put("K2", "V2"));
ASSERT_OK(sfw_default.Add("K1", "V1"));
ASSERT_OK(sfw_default.Add("K2", "V2"));
ASSERT_OK(sfw_default.Finish());
// cf1.sst
const std::string cf1_sst = sst_files_dir_ + "/cf1.sst";
ASSERT_OK(sfw_cf1.Open(cf1_sst));
ASSERT_OK(sfw_cf1.Put("K3", "V1"));
ASSERT_OK(sfw_cf1.Put("K4", "V2"));
ASSERT_OK(sfw_cf1.Add("K3", "V1"));
ASSERT_OK(sfw_cf1.Add("K4", "V2"));
ASSERT_OK(sfw_cf1.Finish());
// cf_unknown.sst
const std::string unknown_sst = sst_files_dir_ + "/cf_unknown.sst";
ASSERT_OK(sfw_unknown.Open(unknown_sst));
ASSERT_OK(sfw_unknown.Put("K5", "V1"));
ASSERT_OK(sfw_unknown.Put("K6", "V2"));
ASSERT_OK(sfw_unknown.Add("K5", "V1"));
ASSERT_OK(sfw_unknown.Add("K6", "V2"));
ASSERT_OK(sfw_unknown.Finish());
IngestExternalFileOptions ifo;
@@ -1862,7 +1862,7 @@ TEST_F(ExternalSSTFileTest, SnapshotInconsistencyBug) {
SstFileWriter sst_file_writer(EnvOptions(), options);
ASSERT_OK(sst_file_writer.Open(sst_file_path));
for (int i = 0; i < kNumKeys; i++) {
ASSERT_OK(sst_file_writer.Put(Key(i), Key(i) + "_V2"));
ASSERT_OK(sst_file_writer.Add(Key(i), Key(i) + "_V2"));
}
ASSERT_OK(sst_file_writer.Finish());
+3 -5
View File
@@ -228,12 +228,10 @@ class FaultInjectionTest : public testing::Test,
return Status::OK();
}
#ifdef ROCKSDB_UBSAN_RUN
#if defined(__clang__)
__attribute__((__no_sanitize__("shift"), no_sanitize("signed-integer-overflow")))
#elif defined(__GNUC__)
#if __clang_major__ > 3 || (__clang_major__ == 3 && __clang_minor__ >= 9)
__attribute__((__no_sanitize__("undefined")))
#elif __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9)
__attribute__((__no_sanitize_undefined__))
#endif
#endif
// Return the ith key
Slice Key(int i, std::string* storage) const {
-1
View File
@@ -1137,7 +1137,6 @@ void InternalStats::DumpCFStatsNoFileHistogram(std::string* value) {
total_stall_count - cf_stats_snapshot_.stall_count);
value->append(buf);
cf_stats_snapshot_.seconds_up = seconds_up;
cf_stats_snapshot_.ingest_bytes_flush = flush_ingest;
cf_stats_snapshot_.ingest_bytes_addfile = add_file_ingest;
cf_stats_snapshot_.ingest_files_addfile = ingest_files_addfile;
-52
View File
@@ -1,52 +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 "db/malloc_stats.h"
#ifndef ROCKSDB_LITE
#include <memory>
#include <string.h>
namespace rocksdb {
#ifdef ROCKSDB_JEMALLOC
#include "jemalloc/jemalloc.h"
typedef struct {
char* cur;
char* end;
} MallocStatus;
static void GetJemallocStatus(void* mstat_arg, const char* status) {
MallocStatus* mstat = reinterpret_cast<MallocStatus*>(mstat_arg);
size_t status_len = status ? strlen(status) : 0;
size_t buf_size = (size_t)(mstat->end - mstat->cur);
if (!status_len || status_len > buf_size) {
return;
}
snprintf(mstat->cur, buf_size, "%s", status);
mstat->cur += status_len;
}
#endif // ROCKSDB_JEMALLOC
void DumpMallocStats(std::string* stats) {
#ifdef ROCKSDB_JEMALLOC
MallocStatus mstat;
const unsigned int kMallocStatusLen = 1000000;
std::unique_ptr<char[]> buf{new char[kMallocStatusLen + 1]};
mstat.cur = buf.get();
mstat.end = buf.get() + kMallocStatusLen;
je_malloc_stats_print(GetJemallocStatus, &mstat, "");
stats->append(buf.get());
#endif // ROCKSDB_JEMALLOC
}
}
#endif // !ROCKSDB_LITE
-22
View File
@@ -1,22 +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.
#pragma once
#ifndef ROCKSDB_LITE
#include <string>
namespace rocksdb {
void DumpMallocStats(std::string*);
}
#endif // !ROCKSDB_LITE
+16 -21
View File
@@ -11,6 +11,7 @@
#include <memory>
#include <algorithm>
#include <limits>
#include "db/dbformat.h"
#include "db/merge_context.h"
@@ -34,6 +35,7 @@
#include "util/memory_usage.h"
#include "util/murmurhash.h"
#include "util/mutexlock.h"
#include "util/stop_watch.h"
namespace rocksdb {
@@ -59,24 +61,20 @@ MemTable::MemTable(const InternalKeyComparator& cmp,
const ImmutableCFOptions& ioptions,
const MutableCFOptions& mutable_cf_options,
WriteBufferManager* write_buffer_manager,
SequenceNumber latest_seq, uint32_t column_family_id)
SequenceNumber latest_seq)
: comparator_(cmp),
moptions_(ioptions, mutable_cf_options),
refs_(0),
kArenaBlockSize(OptimizeBlockSize(moptions_.arena_block_size)),
mem_tracker_(write_buffer_manager),
arena_(
moptions_.arena_block_size,
(write_buffer_manager != nullptr && write_buffer_manager->enabled())
? &mem_tracker_
: nullptr,
mutable_cf_options.memtable_huge_page_size),
arena_(moptions_.arena_block_size,
mutable_cf_options.memtable_huge_page_size),
allocator_(&arena_, write_buffer_manager),
table_(ioptions.memtable_factory->CreateMemTableRep(
comparator_, &arena_, ioptions.prefix_extractor, ioptions.info_log,
column_family_id)),
comparator_, &allocator_, ioptions.prefix_extractor,
ioptions.info_log)),
range_del_table_(SkipListFactory().CreateMemTableRep(
comparator_, &arena_, nullptr /* transform */, ioptions.info_log,
column_family_id)),
comparator_, &allocator_, nullptr /* transform */,
ioptions.info_log)),
is_range_del_table_empty_(true),
data_size_(0),
num_entries_(0),
@@ -103,16 +101,13 @@ MemTable::MemTable(const InternalKeyComparator& cmp,
if (prefix_extractor_ && moptions_.memtable_prefix_bloom_bits > 0) {
prefix_bloom_.reset(new DynamicBloom(
&arena_, moptions_.memtable_prefix_bloom_bits, ioptions.bloom_locality,
6 /* hard coded 6 probes */, nullptr, moptions_.memtable_huge_page_size,
ioptions.info_log));
&allocator_, moptions_.memtable_prefix_bloom_bits,
ioptions.bloom_locality, 6 /* hard coded 6 probes */, nullptr,
moptions_.memtable_huge_page_size, ioptions.info_log));
}
}
MemTable::~MemTable() {
mem_tracker_.FreeMem();
assert(refs_ == 0);
}
MemTable::~MemTable() { assert(refs_ == 0); }
size_t MemTable::ApproximateMemoryUsage() {
autovector<size_t> usages = {arena_.ApproximateMemoryUsage(),
@@ -581,7 +576,7 @@ static bool SaveValue(void* arg, const char* entry) {
*(s->status) = MergeHelper::TimedFullMerge(
merge_operator, s->key->user_key(), &v,
merge_context->GetOperands(), s->value, s->logger, s->statistics,
s->env_, nullptr /* result_operand */, true);
s->env_);
} else if (s->value != nullptr) {
s->value->assign(v.data(), v.size());
}
@@ -598,7 +593,7 @@ static bool SaveValue(void* arg, const char* entry) {
*(s->status) = MergeHelper::TimedFullMerge(
merge_operator, s->key->user_key(), nullptr,
merge_context->GetOperands(), s->value, s->logger, s->statistics,
s->env_, nullptr /* result_operand */, true);
s->env_);
} else {
*(s->status) = Status::NotFound();
}
+4 -4
View File
@@ -18,12 +18,12 @@
#include "db/dbformat.h"
#include "db/range_del_aggregator.h"
#include "db/version_edit.h"
#include "memtable/memtable_allocator.h"
#include "monitoring/instrumented_mutex.h"
#include "options/cf_options.h"
#include "rocksdb/db.h"
#include "rocksdb/env.h"
#include "rocksdb/memtablerep.h"
#include "util/allocator.h"
#include "util/concurrent_arena.h"
#include "util/dynamic_bloom.h"
#include "util/hash.h"
@@ -101,7 +101,7 @@ class MemTable {
const ImmutableCFOptions& ioptions,
const MutableCFOptions& mutable_cf_options,
WriteBufferManager* write_buffer_manager,
SequenceNumber earliest_seq, uint32_t column_family_id);
SequenceNumber earliest_seq);
// Do not delete this MemTable unless Unref() indicates it not in use.
~MemTable();
@@ -317,7 +317,7 @@ class MemTable {
// write anything to this MemTable(). (Ie. do not call Add() or Update()).
void MarkImmutable() {
table_->MarkReadOnly();
mem_tracker_.DoneAllocating();
allocator_.DoneAllocating();
}
// return true if the current MemTableRep supports merge operator.
@@ -359,8 +359,8 @@ class MemTable {
const MemTableOptions moptions_;
int refs_;
const size_t kArenaBlockSize;
AllocTracker mem_tracker_;
ConcurrentArena arena_;
MemTableAllocator allocator_;
unique_ptr<MemTableRep> table_;
unique_ptr<MemTableRep> range_del_table_;
bool is_range_del_table_empty_;
-12
View File
@@ -166,18 +166,6 @@ Status MemTableListVersion::AddRangeTombstoneIterators(
return Status::OK();
}
Status MemTableListVersion::AddRangeTombstoneIterators(
const ReadOptions& read_opts,
std::vector<InternalIterator*>* range_del_iters) {
for (auto& m : memlist_) {
auto* range_del_iter = m->NewRangeTombstoneIterator(read_opts);
if (range_del_iter != nullptr) {
range_del_iters->push_back(range_del_iter);
}
}
return Status::OK();
}
void MemTableListVersion::AddIterators(
const ReadOptions& options, std::vector<InternalIterator*>* iterator_list,
Arena* arena) {
-3
View File
@@ -82,9 +82,6 @@ class MemTableListVersion {
Status AddRangeTombstoneIterators(const ReadOptions& read_opts, Arena* arena,
RangeDelAggregator* range_del_agg);
Status AddRangeTombstoneIterators(
const ReadOptions& read_opts,
std::vector<InternalIterator*>* range_del_iters);
void AddIterators(const ReadOptions& options,
std::vector<InternalIterator*>* iterator_list,
+6 -6
View File
@@ -134,7 +134,7 @@ TEST_F(MemTableListTest, GetTest) {
WriteBufferManager wb(options.db_write_buffer_size);
MemTable* mem = new MemTable(cmp, ioptions, MutableCFOptions(options), &wb,
kMaxSequenceNumber, 0 /* column_family_id */);
kMaxSequenceNumber);
mem->Ref();
// Write some keys to this memtable.
@@ -173,7 +173,7 @@ TEST_F(MemTableListTest, GetTest) {
// Create another memtable and write some keys to it
WriteBufferManager wb2(options.db_write_buffer_size);
MemTable* mem2 = new MemTable(cmp, ioptions, MutableCFOptions(options), &wb2,
kMaxSequenceNumber, 0 /* column_family_id */);
kMaxSequenceNumber);
mem2->Ref();
mem2->Add(++seq, kTypeDeletion, "key1", "");
@@ -241,7 +241,7 @@ TEST_F(MemTableListTest, GetFromHistoryTest) {
WriteBufferManager wb(options.db_write_buffer_size);
MemTable* mem = new MemTable(cmp, ioptions, MutableCFOptions(options), &wb,
kMaxSequenceNumber, 0 /* column_family_id */);
kMaxSequenceNumber);
mem->Ref();
// Write some keys to this memtable.
@@ -319,7 +319,7 @@ TEST_F(MemTableListTest, GetFromHistoryTest) {
// Create another memtable and write some keys to it
WriteBufferManager wb2(options.db_write_buffer_size);
MemTable* mem2 = new MemTable(cmp, ioptions, MutableCFOptions(options), &wb2,
kMaxSequenceNumber, 0 /* column_family_id */);
kMaxSequenceNumber);
mem2->Ref();
mem2->Add(++seq, kTypeDeletion, "key1", "");
@@ -344,7 +344,7 @@ TEST_F(MemTableListTest, GetFromHistoryTest) {
// Add a third memtable to push the first memtable out of the history
WriteBufferManager wb3(options.db_write_buffer_size);
MemTable* mem3 = new MemTable(cmp, ioptions, MutableCFOptions(options), &wb3,
kMaxSequenceNumber, 0 /* column_family_id */);
kMaxSequenceNumber);
mem3->Ref();
list.Add(mem3, &to_delete);
ASSERT_EQ(1, list.NumNotFlushed());
@@ -418,7 +418,7 @@ TEST_F(MemTableListTest, FlushPendingTest) {
MutableCFOptions mutable_cf_options(options);
for (int i = 0; i < num_tables; i++) {
MemTable* mem = new MemTable(cmp, ioptions, mutable_cf_options, &wb,
kMaxSequenceNumber, 0 /* column_family_id */);
kMaxSequenceNumber);
mem->Ref();
std::string value;
+1 -7
View File
@@ -23,8 +23,7 @@ Status MergeHelper::TimedFullMerge(const MergeOperator* merge_operator,
const std::vector<Slice>& operands,
std::string* result, Logger* logger,
Statistics* statistics, Env* env,
Slice* result_operand,
bool update_num_ops_stats) {
Slice* result_operand) {
assert(merge_operator != nullptr);
if (operands.size() == 0) {
@@ -33,11 +32,6 @@ Status MergeHelper::TimedFullMerge(const MergeOperator* merge_operator,
return Status::OK();
}
if (update_num_ops_stats) {
MeasureTime(statistics, READ_NUM_MERGE_OPERANDS,
static_cast<uint64_t>(operands.size()));
}
bool success;
Slice tmp_result_operand(nullptr, 0);
const MergeOperator::MergeOperationInput merge_in(key, value, operands,
+1 -4
View File
@@ -54,8 +54,6 @@ class MergeHelper {
// Wrapper around MergeOperator::FullMergeV2() that records perf statistics.
// Result of merge will be written to result if status returned is OK.
// If operands is empty, the value will simply be copied to result.
// Set `update_num_ops_stats` to true if it is from a user read, so that
// the latency is sensitive.
// Returns one of the following statuses:
// - OK: Entries were successfully merged.
// - Corruption: Merge operator reported unsuccessful merge.
@@ -64,8 +62,7 @@ class MergeHelper {
const std::vector<Slice>& operands,
std::string* result, Logger* logger,
Statistics* statistics, Env* env,
Slice* result_operand = nullptr,
bool update_num_ops_stats = false);
Slice* result_operand = nullptr);
// Merge entries until we hit
// - a corrupted key
+71 -71
View File
@@ -87,13 +87,13 @@ TEST_F(PerfContextTest, SeekIntoDeletion) {
std::string key = "k" + ToString(i);
std::string value;
get_perf_context()->Reset();
perf_context.Reset();
StopWatchNano timer(Env::Default());
timer.Start();
auto status = db->Get(read_options, key, &value);
auto elapsed_nanos = timer.ElapsedNanos();
ASSERT_TRUE(status.IsNotFound());
hist_get.Add(get_perf_context()->user_key_comparison_count);
hist_get.Add(perf_context.user_key_comparison_count);
hist_get_time.Add(elapsed_nanos);
}
@@ -106,19 +106,19 @@ TEST_F(PerfContextTest, SeekIntoDeletion) {
HistogramImpl hist_seek_to_first;
std::unique_ptr<Iterator> iter(db->NewIterator(read_options));
get_perf_context()->Reset();
perf_context.Reset();
StopWatchNano timer(Env::Default(), true);
iter->SeekToFirst();
hist_seek_to_first.Add(get_perf_context()->user_key_comparison_count);
hist_seek_to_first.Add(perf_context.user_key_comparison_count);
auto elapsed_nanos = timer.ElapsedNanos();
if (FLAGS_verbose) {
std::cout << "SeekToFirst uesr key comparison: \n"
<< hist_seek_to_first.ToString()
<< "ikey skipped: " << get_perf_context()->internal_key_skipped_count
<< "ikey skipped: " << perf_context.internal_key_skipped_count
<< "\n"
<< "idelete skipped: "
<< get_perf_context()->internal_delete_skipped_count << "\n"
<< perf_context.internal_delete_skipped_count << "\n"
<< "elapsed: " << elapsed_nanos << "\n";
}
}
@@ -128,26 +128,26 @@ TEST_F(PerfContextTest, SeekIntoDeletion) {
std::unique_ptr<Iterator> iter(db->NewIterator(read_options));
std::string key = "k" + ToString(i);
get_perf_context()->Reset();
perf_context.Reset();
StopWatchNano timer(Env::Default(), true);
iter->Seek(key);
auto elapsed_nanos = timer.ElapsedNanos();
hist_seek.Add(get_perf_context()->user_key_comparison_count);
hist_seek.Add(perf_context.user_key_comparison_count);
if (FLAGS_verbose) {
std::cout << "seek cmp: " << get_perf_context()->user_key_comparison_count
<< " ikey skipped " << get_perf_context()->internal_key_skipped_count
std::cout << "seek cmp: " << perf_context.user_key_comparison_count
<< " ikey skipped " << perf_context.internal_key_skipped_count
<< " idelete skipped "
<< get_perf_context()->internal_delete_skipped_count
<< perf_context.internal_delete_skipped_count
<< " elapsed: " << elapsed_nanos << "ns\n";
}
get_perf_context()->Reset();
perf_context.Reset();
ASSERT_TRUE(iter->Valid());
StopWatchNano timer2(Env::Default(), true);
iter->Next();
auto elapsed_nanos2 = timer2.ElapsedNanos();
if (FLAGS_verbose) {
std::cout << "next cmp: " << get_perf_context()->user_key_comparison_count
std::cout << "next cmp: " << perf_context.user_key_comparison_count
<< "elapsed: " << elapsed_nanos2 << "ns\n";
}
}
@@ -263,18 +263,18 @@ void ProfileQueries(bool enabled_time = false) {
std::vector<std::string> values;
get_perf_context()->Reset();
perf_context.Reset();
db->Put(write_options, key, value);
if (++num_mutex_waited > 3) {
#ifndef NDEBUG
ThreadStatusUtil::TEST_SetStateDelay(ThreadStatus::STATE_MUTEX_WAIT, 0U);
#endif
}
hist_write_pre_post.Add(get_perf_context()->write_pre_and_post_process_time);
hist_write_wal_time.Add(get_perf_context()->write_wal_time);
hist_write_memtable_time.Add(get_perf_context()->write_memtable_time);
hist_put.Add(get_perf_context()->user_key_comparison_count);
total_db_mutex_nanos += get_perf_context()->db_mutex_lock_nanos;
hist_write_pre_post.Add(perf_context.write_pre_and_post_process_time);
hist_write_wal_time.Add(perf_context.write_wal_time);
hist_write_memtable_time.Add(perf_context.write_memtable_time);
hist_put.Add(perf_context.user_key_comparison_count);
total_db_mutex_nanos += perf_context.db_mutex_lock_nanos;
}
#ifndef NDEBUG
ThreadStatusUtil::TEST_SetStateDelay(ThreadStatus::STATE_MUTEX_WAIT, 0U);
@@ -291,24 +291,24 @@ void ProfileQueries(bool enabled_time = false) {
std::vector<Slice> multiget_keys = {Slice(key)};
std::vector<std::string> values;
get_perf_context()->Reset();
perf_context.Reset();
ASSERT_OK(db->Get(read_options, key, &value));
ASSERT_EQ(expected_value, value);
hist_get_snapshot.Add(get_perf_context()->get_snapshot_time);
hist_get_memtable.Add(get_perf_context()->get_from_memtable_time);
hist_get_files.Add(get_perf_context()->get_from_output_files_time);
hist_num_memtable_checked.Add(get_perf_context()->get_from_memtable_count);
hist_get_post_process.Add(get_perf_context()->get_post_process_time);
hist_get.Add(get_perf_context()->user_key_comparison_count);
hist_get_snapshot.Add(perf_context.get_snapshot_time);
hist_get_memtable.Add(perf_context.get_from_memtable_time);
hist_get_files.Add(perf_context.get_from_output_files_time);
hist_num_memtable_checked.Add(perf_context.get_from_memtable_count);
hist_get_post_process.Add(perf_context.get_post_process_time);
hist_get.Add(perf_context.user_key_comparison_count);
get_perf_context()->Reset();
perf_context.Reset();
db->MultiGet(read_options, multiget_keys, &values);
hist_mget_snapshot.Add(get_perf_context()->get_snapshot_time);
hist_mget_memtable.Add(get_perf_context()->get_from_memtable_time);
hist_mget_files.Add(get_perf_context()->get_from_output_files_time);
hist_mget_num_memtable_checked.Add(get_perf_context()->get_from_memtable_count);
hist_mget_post_process.Add(get_perf_context()->get_post_process_time);
hist_mget.Add(get_perf_context()->user_key_comparison_count);
hist_mget_snapshot.Add(perf_context.get_snapshot_time);
hist_mget_memtable.Add(perf_context.get_from_memtable_time);
hist_mget_files.Add(perf_context.get_from_output_files_time);
hist_mget_num_memtable_checked.Add(perf_context.get_from_memtable_count);
hist_mget_post_process.Add(perf_context.get_post_process_time);
hist_mget.Add(perf_context.user_key_comparison_count);
}
if (FLAGS_verbose) {
@@ -392,24 +392,24 @@ void ProfileQueries(bool enabled_time = false) {
std::vector<Slice> multiget_keys = {Slice(key)};
std::vector<std::string> values;
get_perf_context()->Reset();
perf_context.Reset();
ASSERT_OK(db->Get(read_options, key, &value));
ASSERT_EQ(expected_value, value);
hist_get_snapshot.Add(get_perf_context()->get_snapshot_time);
hist_get_memtable.Add(get_perf_context()->get_from_memtable_time);
hist_get_files.Add(get_perf_context()->get_from_output_files_time);
hist_num_memtable_checked.Add(get_perf_context()->get_from_memtable_count);
hist_get_post_process.Add(get_perf_context()->get_post_process_time);
hist_get.Add(get_perf_context()->user_key_comparison_count);
hist_get_snapshot.Add(perf_context.get_snapshot_time);
hist_get_memtable.Add(perf_context.get_from_memtable_time);
hist_get_files.Add(perf_context.get_from_output_files_time);
hist_num_memtable_checked.Add(perf_context.get_from_memtable_count);
hist_get_post_process.Add(perf_context.get_post_process_time);
hist_get.Add(perf_context.user_key_comparison_count);
get_perf_context()->Reset();
perf_context.Reset();
db->MultiGet(read_options, multiget_keys, &values);
hist_mget_snapshot.Add(get_perf_context()->get_snapshot_time);
hist_mget_memtable.Add(get_perf_context()->get_from_memtable_time);
hist_mget_files.Add(get_perf_context()->get_from_output_files_time);
hist_mget_num_memtable_checked.Add(get_perf_context()->get_from_memtable_count);
hist_mget_post_process.Add(get_perf_context()->get_post_process_time);
hist_mget.Add(get_perf_context()->user_key_comparison_count);
hist_mget_snapshot.Add(perf_context.get_snapshot_time);
hist_mget_memtable.Add(perf_context.get_from_memtable_time);
hist_mget_files.Add(perf_context.get_from_output_files_time);
hist_mget_num_memtable_checked.Add(perf_context.get_from_memtable_count);
hist_mget_post_process.Add(perf_context.get_post_process_time);
hist_mget.Add(perf_context.user_key_comparison_count);
}
if (FLAGS_verbose) {
@@ -512,13 +512,13 @@ TEST_F(PerfContextTest, SeekKeyComparison) {
std::string key = "k" + ToString(i);
std::string value = "v" + ToString(i);
get_perf_context()->Reset();
perf_context.Reset();
timer.Start();
db->Put(write_options, key, value);
auto put_time = timer.ElapsedNanos();
hist_put_time.Add(put_time);
hist_wal_time.Add(get_perf_context()->write_wal_time);
hist_time_diff.Add(put_time - get_perf_context()->write_wal_time);
hist_wal_time.Add(perf_context.write_wal_time);
hist_time_diff.Add(put_time - perf_context.write_wal_time);
}
if (FLAGS_verbose) {
@@ -535,18 +535,18 @@ TEST_F(PerfContextTest, SeekKeyComparison) {
std::string value = "v" + ToString(i);
std::unique_ptr<Iterator> iter(db->NewIterator(read_options));
get_perf_context()->Reset();
perf_context.Reset();
iter->Seek(key);
ASSERT_TRUE(iter->Valid());
ASSERT_EQ(iter->value().ToString(), value);
hist_seek.Add(get_perf_context()->user_key_comparison_count);
hist_seek.Add(perf_context.user_key_comparison_count);
}
std::unique_ptr<Iterator> iter(db->NewIterator(read_options));
for (iter->SeekToFirst(); iter->Valid();) {
get_perf_context()->Reset();
perf_context.Reset();
iter->Next();
hist_next.Add(get_perf_context()->user_key_comparison_count);
hist_next.Add(perf_context.user_key_comparison_count);
}
if (FLAGS_verbose) {
@@ -564,16 +564,16 @@ TEST_F(PerfContextTest, DBMutexLockCounter) {
mutex.Lock();
rocksdb::port::Thread child_thread([&] {
SetPerfLevel(perf_level);
get_perf_context()->Reset();
ASSERT_EQ(get_perf_context()->db_mutex_lock_nanos, 0);
perf_context.Reset();
ASSERT_EQ(perf_context.db_mutex_lock_nanos, 0);
mutex.Lock();
mutex.Unlock();
if (perf_level == PerfLevel::kEnableTimeExceptForMutex ||
stats_code[c] != DB_MUTEX_WAIT_MICROS) {
ASSERT_EQ(get_perf_context()->db_mutex_lock_nanos, 0);
ASSERT_EQ(perf_context.db_mutex_lock_nanos, 0);
} else {
// increment the counter only when it's a DB Mutex
ASSERT_GT(get_perf_context()->db_mutex_lock_nanos, 0);
ASSERT_GT(perf_context.db_mutex_lock_nanos, 0);
}
});
Env::Default()->SleepForMicroseconds(100);
@@ -589,28 +589,28 @@ TEST_F(PerfContextTest, FalseDBMutexWait) {
for (int c = 0; c < 2; ++c) {
InstrumentedMutex mutex(nullptr, Env::Default(), stats_code[c]);
InstrumentedCondVar lock(&mutex);
get_perf_context()->Reset();
perf_context.Reset();
mutex.Lock();
lock.TimedWait(100);
mutex.Unlock();
if (stats_code[c] == static_cast<int>(DB_MUTEX_WAIT_MICROS)) {
// increment the counter only when it's a DB Mutex
ASSERT_GT(get_perf_context()->db_condition_wait_nanos, 0);
ASSERT_GT(perf_context.db_condition_wait_nanos, 0);
} else {
ASSERT_EQ(get_perf_context()->db_condition_wait_nanos, 0);
ASSERT_EQ(perf_context.db_condition_wait_nanos, 0);
}
}
}
TEST_F(PerfContextTest, ToString) {
get_perf_context()->Reset();
get_perf_context()->block_read_count = 12345;
perf_context.Reset();
perf_context.block_read_count = 12345;
std::string zero_included = get_perf_context()->ToString();
std::string zero_included = perf_context.ToString();
ASSERT_NE(std::string::npos, zero_included.find("= 0"));
ASSERT_NE(std::string::npos, zero_included.find("= 12345"));
std::string zero_excluded = get_perf_context()->ToString(true);
std::string zero_excluded = perf_context.ToString(true);
ASSERT_EQ(std::string::npos, zero_excluded.find("= 0"));
ASSERT_NE(std::string::npos, zero_excluded.find("= 12345"));
}
@@ -631,36 +631,36 @@ TEST_F(PerfContextTest, MergeOperatorTime) {
ASSERT_OK(db->Merge(WriteOptions(), "k1", "val4"));
SetPerfLevel(kEnableTime);
get_perf_context()->Reset();
perf_context.Reset();
ASSERT_OK(db->Get(ReadOptions(), "k1", &val));
#ifdef OS_SOLARIS
for (int i = 0; i < 100; i++) {
ASSERT_OK(db->Get(ReadOptions(), "k1", &val));
}
#endif
EXPECT_GT(get_perf_context()->merge_operator_time_nanos, 0);
EXPECT_GT(perf_context.merge_operator_time_nanos, 0);
ASSERT_OK(db->Flush(FlushOptions()));
get_perf_context()->Reset();
perf_context.Reset();
ASSERT_OK(db->Get(ReadOptions(), "k1", &val));
#ifdef OS_SOLARIS
for (int i = 0; i < 100; i++) {
ASSERT_OK(db->Get(ReadOptions(), "k1", &val));
}
#endif
EXPECT_GT(get_perf_context()->merge_operator_time_nanos, 0);
EXPECT_GT(perf_context.merge_operator_time_nanos, 0);
ASSERT_OK(db->CompactRange(CompactRangeOptions(), nullptr, nullptr));
get_perf_context()->Reset();
perf_context.Reset();
ASSERT_OK(db->Get(ReadOptions(), "k1", &val));
#ifdef OS_SOLARIS
for (int i = 0; i < 100; i++) {
ASSERT_OK(db->Get(ReadOptions(), "k1", &val));
}
#endif
EXPECT_GT(get_perf_context()->merge_operator_time_nanos, 0);
EXPECT_GT(perf_context.merge_operator_time_nanos, 0);
delete db;
}
+6 -6
View File
@@ -603,11 +603,11 @@ TEST_F(PrefixTest, DynamicPrefixIterator) {
Slice key = TestKeyToSlice(s, test_key);
std::string value(FLAGS_value_size, 0);
get_perf_context()->Reset();
perf_context.Reset();
StopWatchNano timer(Env::Default(), true);
ASSERT_OK(db->Put(write_options, key, value));
hist_put_time.Add(timer.ElapsedNanos());
hist_put_comparison.Add(get_perf_context()->user_key_comparison_count);
hist_put_comparison.Add(perf_context.user_key_comparison_count);
}
}
@@ -626,7 +626,7 @@ TEST_F(PrefixTest, DynamicPrefixIterator) {
Slice key = TestKeyToSlice(s, test_key);
std::string value = "v" + ToString(0);
get_perf_context()->Reset();
perf_context.Reset();
StopWatchNano timer(Env::Default(), true);
auto key_prefix = options.prefix_extractor->Transform(key);
uint64_t total_keys = 0;
@@ -640,7 +640,7 @@ TEST_F(PrefixTest, DynamicPrefixIterator) {
total_keys++;
}
hist_seek_time.Add(timer.ElapsedNanos());
hist_seek_comparison.Add(get_perf_context()->user_key_comparison_count);
hist_seek_comparison.Add(perf_context.user_key_comparison_count);
ASSERT_EQ(total_keys, FLAGS_items_per_prefix - FLAGS_items_per_prefix/2);
}
@@ -660,11 +660,11 @@ TEST_F(PrefixTest, DynamicPrefixIterator) {
std::string s;
Slice key = TestKeyToSlice(s, test_key);
get_perf_context()->Reset();
perf_context.Reset();
StopWatchNano timer(Env::Default(), true);
iter->Seek(key);
hist_no_seek_time.Add(timer.ElapsedNanos());
hist_no_seek_comparison.Add(get_perf_context()->user_key_comparison_count);
hist_no_seek_comparison.Add(perf_context.user_key_comparison_count);
ASSERT_TRUE(!iter->Valid());
}
-38
View File
@@ -260,44 +260,6 @@ InternalIterator* TableCache::NewIterator(
return result;
}
InternalIterator* TableCache::NewRangeTombstoneIterator(
const ReadOptions& options, const EnvOptions& env_options,
const InternalKeyComparator& icomparator, const FileDescriptor& fd,
HistogramImpl* file_read_hist, bool skip_filters, int level) {
Status s;
TableReader* table_reader = nullptr;
Cache::Handle* handle = nullptr;
table_reader = fd.table_reader;
if (table_reader == nullptr) {
s = FindTable(env_options, icomparator, fd, &handle,
options.read_tier == kBlockCacheTier /* no_io */,
true /* record read_stats */, file_read_hist, skip_filters,
level);
if (s.ok()) {
table_reader = GetTableReaderFromHandle(handle);
}
}
InternalIterator* result = nullptr;
if (s.ok()) {
result = table_reader->NewRangeTombstoneIterator(options);
if (result != nullptr) {
if (handle != nullptr) {
result->RegisterCleanup(&UnrefEntry, cache_, handle);
}
}
}
if (result == nullptr && handle != nullptr) {
// the range deletion block didn't exist, or there was a failure between
// getting handle and getting iterator.
ReleaseHandle(handle);
}
if (!s.ok()) {
assert(result == nullptr);
result = NewErrorInternalIterator(s);
}
return result;
}
Status TableCache::Get(const ReadOptions& options,
const InternalKeyComparator& internal_comparator,
const FileDescriptor& fd, const Slice& k,
-6
View File
@@ -58,12 +58,6 @@ class TableCache {
HistogramImpl* file_read_hist = nullptr, bool for_compaction = false,
Arena* arena = nullptr, bool skip_filters = false, int level = -1);
InternalIterator* NewRangeTombstoneIterator(
const ReadOptions& options, const EnvOptions& toptions,
const InternalKeyComparator& internal_comparator,
const FileDescriptor& file_fd, HistogramImpl* file_read_hist,
bool skip_filters, int level);
// If a seek to internal key "k" in specified file finds an entry,
// call (*handle_result)(arg, found_key, found_value) repeatedly until
// it returns false.
+14 -52
View File
@@ -134,8 +134,8 @@ class FilePicker {
// Do key range filtering of files or/and fractional cascading if:
// (1) not all the files are in level 0, or
// (2) there are more than 3 current level files
// If there are only 3 or less current level files in the system, we skip
// (2) there are more than 3 Level 0 files
// If there are only 3 or less level 0 files in the system, we skip
// the key range filtering. In this case, more likely, the system is
// highly tuned to minimize number of tables queried by each query,
// so it is unlikely that key range filtering is more efficient than
@@ -863,22 +863,6 @@ void Version::AddIteratorsForLevel(const ReadOptions& read_options,
}
}
void Version::AddRangeDelIteratorsForLevel(
const ReadOptions& read_options, const EnvOptions& soptions, int level,
std::vector<InternalIterator*>* range_del_iters) {
range_del_iters->clear();
for (size_t i = 0; i < storage_info_.LevelFilesBrief(level).num_files; i++) {
const auto& file = storage_info_.LevelFilesBrief(level).files[i];
auto* range_del_iter = cfd_->table_cache()->NewRangeTombstoneIterator(
read_options, soptions, cfd_->internal_comparator(), file.fd,
cfd_->internal_stats()->GetFileReadHist(level),
false /* skip_filters */, level);
if (range_del_iter != nullptr) {
range_del_iters->push_back(range_del_iter);
}
}
}
VersionStorageInfo::VersionStorageInfo(
const InternalKeyComparator* internal_comparator,
const Comparator* user_comparator, int levels,
@@ -1030,8 +1014,7 @@ void Version::Get(const ReadOptions& read_options, const LookupKey& k,
std::string* str_value = value != nullptr ? value->GetSelf() : nullptr;
*status = MergeHelper::TimedFullMerge(
merge_operator_, user_key, nullptr, merge_context->GetOperands(),
str_value, info_log_, db_statistics_, env_,
nullptr /* result_operand */, true);
str_value, info_log_, db_statistics_, env_);
if (LIKELY(value != nullptr)) {
value->PinSelf();
}
@@ -1231,18 +1214,15 @@ void VersionStorageInfo::EstimateCompactionBytesNeeded(
// accumulated bytes.
uint64_t bytes_compact_to_next_level = 0;
uint64_t level_size = 0;
for (auto* f : files_[0]) {
level_size += f->fd.GetFileSize();
}
// Level 0
bool level0_compact_triggered = false;
if (static_cast<int>(files_[0].size()) >=
mutable_cf_options.level0_file_num_compaction_trigger ||
level_size >= mutable_cf_options.max_bytes_for_level_base) {
if (static_cast<int>(files_[0].size()) >
mutable_cf_options.level0_file_num_compaction_trigger) {
level0_compact_triggered = true;
estimated_compaction_needed_bytes_ = level_size;
bytes_compact_to_next_level = level_size;
for (auto* f : files_[0]) {
bytes_compact_to_next_level += f->fd.GetFileSize();
}
estimated_compaction_needed_bytes_ = bytes_compact_to_next_level;
} else {
estimated_compaction_needed_bytes_ = 0;
}
@@ -1250,7 +1230,7 @@ void VersionStorageInfo::EstimateCompactionBytesNeeded(
// Level 1 and up.
uint64_t bytes_next_level = 0;
for (int level = base_level(); level <= MaxInputLevel(); level++) {
level_size = 0;
uint64_t level_size = 0;
if (bytes_next_level > 0) {
#ifndef NDEBUG
uint64_t level_size2 = 0;
@@ -2689,9 +2669,6 @@ Status VersionSet::Recover(
default_cf_edit.SetColumnFamily(0);
ColumnFamilyData* default_cfd =
CreateColumnFamily(default_cf_iter->second, &default_cf_edit);
// In recovery, nobody else can access it, so it's fine to set it to be
// initialized earlier.
default_cfd->set_initialized();
builders.insert({0, new BaseReferencedVersionBuilder(default_cfd)});
{
@@ -2738,7 +2715,6 @@ Status VersionSet::Recover(
{edit.column_family_, edit.column_family_name_});
} else {
cfd = CreateColumnFamily(cf_options->second, &edit);
cfd->set_initialized();
builders.insert(
{edit.column_family_, new BaseReferencedVersionBuilder(cfd)});
}
@@ -2866,7 +2842,6 @@ Status VersionSet::Recover(
if (cfd->IsDropped()) {
continue;
}
assert(cfd->initialized());
auto builders_iter = builders.find(cfd->GetID());
assert(builders_iter != builders.end());
auto* builder = builders_iter->second->version_builder();
@@ -3151,7 +3126,6 @@ Status VersionSet::DumpManifest(Options& options, std::string& dscname,
break;
}
cfd = CreateColumnFamily(ColumnFamilyOptions(options), &edit);
cfd->set_initialized();
builders.insert(
{edit.column_family_, new BaseReferencedVersionBuilder(cfd)});
} else if (edit.is_column_family_drop_) {
@@ -3295,7 +3269,6 @@ Status VersionSet::WriteSnapshot(log::Writer* log) {
if (cfd->IsDropped()) {
continue;
}
assert(cfd->initialized());
{
// Store column family info
VersionEdit edit;
@@ -3462,9 +3435,6 @@ void VersionSet::AddLiveFiles(std::vector<FileDescriptor>* live_list) {
// pre-calculate space requirement
int64_t total_files = 0;
for (auto cfd : *column_family_set_) {
if (!cfd->initialized()) {
continue;
}
Version* dummy_versions = cfd->dummy_versions();
for (Version* v = dummy_versions->next_; v != dummy_versions;
v = v->next_) {
@@ -3479,9 +3449,6 @@ void VersionSet::AddLiveFiles(std::vector<FileDescriptor>* live_list) {
live_list->reserve(live_list->size() + static_cast<size_t>(total_files));
for (auto cfd : *column_family_set_) {
if (!cfd->initialized()) {
continue;
}
auto* current = cfd->current();
bool found_current = false;
Version* dummy_versions = cfd->dummy_versions();
@@ -3506,11 +3473,9 @@ InternalIterator* VersionSet::MakeInputIterator(
ReadOptions read_options;
read_options.verify_checksums = true;
read_options.fill_cache = false;
// Compaction iterators shouldn't be confined to a single prefix.
// Compactions use Seek() for
// (a) concurrent compactions,
// (b) CompactionFilter::Decision::kRemoveAndSkipUntil.
read_options.total_order_seek = true;
if (c->ShouldFormSubcompactions()) {
read_options.total_order_seek = true;
}
// Level-0 files have to be merged together. For other levels,
// we will make a concatenating iterator per level.
@@ -3609,9 +3574,6 @@ Status VersionSet::GetMetadataForFile(uint64_t number, int* filelevel,
FileMetaData** meta,
ColumnFamilyData** cfd) {
for (auto cfd_iter : *column_family_set_) {
if (!cfd_iter->initialized()) {
continue;
}
Version* version = cfd_iter->current();
const auto* vstorage = version->storage_info();
for (int level = 0; level < vstorage->num_levels(); level++) {
@@ -3630,7 +3592,7 @@ Status VersionSet::GetMetadataForFile(uint64_t number, int* filelevel,
void VersionSet::GetLiveFilesMetaData(std::vector<LiveFileMetaData>* metadata) {
for (auto cfd : *column_family_set_) {
if (cfd->IsDropped() || !cfd->initialized()) {
if (cfd->IsDropped()) {
continue;
}
for (int level = 0; level < cfd->NumberLevels(); level++) {
-4
View File
@@ -461,10 +461,6 @@ class Version {
MergeIteratorBuilder* merger_iter_builder,
int level, RangeDelAggregator* range_del_agg);
void AddRangeDelIteratorsForLevel(
const ReadOptions& read_options, const EnvOptions& soptions, int level,
std::vector<InternalIterator*>* range_del_iters);
// Lookup the value for key. If found, store it in *val and
// return OK. Else return a non-OK status.
// Uses *operands to store merge_operator operations to apply later.
+27 -28
View File
@@ -850,24 +850,24 @@ class MemTableInserter : public WriteBatch::Handler {
public:
// cf_mems should not be shared with concurrent inserters
MemTableInserter(SequenceNumber _sequence, ColumnFamilyMemTables* cf_mems,
FlushScheduler* flush_scheduler,
bool ignore_missing_column_families,
uint64_t recovering_log_number, DB* db,
bool concurrent_memtable_writes,
bool* has_valid_writes = nullptr)
: sequence_(_sequence),
cf_mems_(cf_mems),
flush_scheduler_(flush_scheduler),
ignore_missing_column_families_(ignore_missing_column_families),
recovering_log_number_(recovering_log_number),
log_number_ref_(0),
db_(reinterpret_cast<DBImpl*>(db)),
concurrent_memtable_writes_(concurrent_memtable_writes),
post_info_created_(false),
has_valid_writes_(has_valid_writes),
rebuilding_trx_(nullptr) {
assert(cf_mems_);
MemTableInserter(SequenceNumber sequence, ColumnFamilyMemTables* cf_mems,
FlushScheduler* flush_scheduler,
bool ignore_missing_column_families,
uint64_t recovering_log_number, DB* db,
bool concurrent_memtable_writes,
bool* has_valid_writes = nullptr)
: sequence_(sequence),
cf_mems_(cf_mems),
flush_scheduler_(flush_scheduler),
ignore_missing_column_families_(ignore_missing_column_families),
recovering_log_number_(recovering_log_number),
log_number_ref_(0),
db_(reinterpret_cast<DBImpl*>(db)),
concurrent_memtable_writes_(concurrent_memtable_writes),
post_info_created_(false),
has_valid_writes_(has_valid_writes),
rebuilding_trx_(nullptr) {
assert(cf_mems_);
}
~MemTableInserter() {
@@ -882,7 +882,7 @@ public:
void set_log_number_ref(uint64_t log) { log_number_ref_ = log; }
SequenceNumber sequence() const { return sequence_; }
SequenceNumber get_final_sequence() const { return sequence_; }
void PostProcess() {
assert(concurrent_memtable_writes_);
@@ -1302,7 +1302,6 @@ Status WriteBatchInternal::InsertInto(WriteThread::WriteGroup& write_group,
if (!w->ShouldWriteToMemtable()) {
continue;
}
SetSequence(w->batch, inserter.sequence());
inserter.set_log_number_ref(w->log_ref);
w->status = w->batch->Iterate(&inserter);
if (!w->status.ok()) {
@@ -1313,17 +1312,16 @@ Status WriteBatchInternal::InsertInto(WriteThread::WriteGroup& write_group,
}
Status WriteBatchInternal::InsertInto(WriteThread::Writer* writer,
SequenceNumber sequence,
ColumnFamilyMemTables* memtables,
FlushScheduler* flush_scheduler,
bool ignore_missing_column_families,
uint64_t log_number, DB* db,
bool concurrent_memtable_writes) {
assert(writer->ShouldWriteToMemtable());
MemTableInserter inserter(sequence, memtables, flush_scheduler,
MemTableInserter inserter(WriteBatchInternal::Sequence(writer->batch),
memtables, flush_scheduler,
ignore_missing_column_families, log_number, db,
concurrent_memtable_writes);
SetSequence(writer->batch, sequence);
assert(writer->ShouldWriteToMemtable());
inserter.set_log_number_ref(writer->log_ref);
Status s = writer->batch->Iterate(&inserter);
if (concurrent_memtable_writes) {
@@ -1337,12 +1335,13 @@ Status WriteBatchInternal::InsertInto(
FlushScheduler* flush_scheduler, bool ignore_missing_column_families,
uint64_t log_number, DB* db, bool concurrent_memtable_writes,
SequenceNumber* last_seq_used, bool* has_valid_writes) {
MemTableInserter inserter(Sequence(batch), memtables, flush_scheduler,
ignore_missing_column_families, log_number, db,
concurrent_memtable_writes, has_valid_writes);
MemTableInserter inserter(WriteBatchInternal::Sequence(batch), memtables,
flush_scheduler, ignore_missing_column_families,
log_number, db, concurrent_memtable_writes,
has_valid_writes);
Status s = batch->Iterate(&inserter);
if (last_seq_used != nullptr) {
*last_seq_used = inserter.sequence();
*last_seq_used = inserter.get_final_sequence();
}
if (concurrent_memtable_writes) {
inserter.PostProcess();
+1 -1
View File
@@ -170,7 +170,7 @@ class WriteBatchInternal {
SequenceNumber* last_seq_used = nullptr,
bool* has_valid_writes = nullptr);
static Status InsertInto(WriteThread::Writer* writer, SequenceNumber sequence,
static Status InsertInto(WriteThread::Writer* writer,
ColumnFamilyMemTables* memtables,
FlushScheduler* flush_scheduler,
bool ignore_missing_column_families = false,
+1 -1
View File
@@ -32,7 +32,7 @@ static std::string PrintContents(WriteBatch* b) {
ImmutableCFOptions ioptions(options);
WriteBufferManager wb(options.db_write_buffer_size);
MemTable* mem = new MemTable(cmp, ioptions, MutableCFOptions(options), &wb,
kMaxSequenceNumber, 0 /* column_family_id */);
kMaxSequenceNumber);
mem->Ref();
std::string state;
ColumnFamilyMemTablesDefault cf_mems_default(mem);
+3 -5
View File
@@ -34,19 +34,17 @@ WriteController::GetCompactionPressureToken() {
new CompactionPressureToken(this));
}
bool WriteController::IsStopped() const {
return total_stopped_.load(std::memory_order_relaxed) > 0;
}
bool WriteController::IsStopped() const { return total_stopped_ > 0; }
// This is inside DB mutex, so we can't sleep and need to minimize
// frequency to get time.
// If it turns out to be a performance issue, we can redesign the thread
// synchronization model here.
// The function trust caller will sleep micros returned.
uint64_t WriteController::GetDelay(Env* env, uint64_t num_bytes) {
if (total_stopped_.load(std::memory_order_relaxed) > 0) {
if (total_stopped_ > 0) {
return 0;
}
if (total_delayed_.load(std::memory_order_relaxed) == 0) {
if (total_delayed_.load() == 0) {
return 0;
}
+4 -12
View File
@@ -9,7 +9,6 @@
#include <atomic>
#include <memory>
#include "rocksdb/rate_limiter.h"
namespace rocksdb {
@@ -22,15 +21,12 @@ class WriteControllerToken;
// to be called while holding DB mutex
class WriteController {
public:
explicit WriteController(uint64_t _delayed_write_rate = 1024u * 1024u * 32u,
int64_t low_pri_rate_bytes_per_sec = 1024 * 1024)
explicit WriteController(uint64_t _delayed_write_rate = 1024u * 1024u * 32u)
: total_stopped_(0),
total_delayed_(0),
total_compaction_pressure_(0),
bytes_left_(0),
last_refill_time_(0),
low_pri_rate_limiter_(
NewGenericRateLimiter(low_pri_rate_bytes_per_sec)) {
last_refill_time_(0) {
set_max_delayed_write_rate(_delayed_write_rate);
}
~WriteController() = default;
@@ -82,8 +78,6 @@ class WriteController {
uint64_t max_delayed_write_rate() const { return max_delayed_write_rate_; }
RateLimiter* low_pri_rate_limiter() { return low_pri_rate_limiter_.get(); }
private:
uint64_t NowMicrosMonotonic(Env* env);
@@ -92,17 +86,15 @@ class WriteController {
friend class DelayWriteToken;
friend class CompactionPressureToken;
std::atomic<int> total_stopped_;
int total_stopped_;
std::atomic<int> total_delayed_;
std::atomic<int> total_compaction_pressure_;
int total_compaction_pressure_;
uint64_t bytes_left_;
uint64_t last_refill_time_;
// write rate set when initialization or by `DBImpl::SetDBOptions`
uint64_t max_delayed_write_rate_;
// current write rate
uint64_t delayed_write_rate_;
std::unique_ptr<RateLimiter> low_pri_rate_limiter_;
};
class WriteControllerToken {
-4
View File
@@ -52,7 +52,3 @@ IslamAbdelRahman:
ajkr:
full_name: Andrew Kryczka
fbid: 100010829806660
sagar0:
full_name: Sagar Vemuri
fbid: 2419111
@@ -1,39 +0,0 @@
---
title: RocksDB 5.4.5 Released!
layout: post
author: sagar0
category: blog
---
### Public API Change
* Support dynamically changing `stats_dump_period_sec` option via SetDBOptions().
* Added ReadOptions::max_skippable_internal_keys to set a threshold to fail a request as incomplete when too many keys are being skipped while using iterators.
* DB::Get in place of std::string accepts PinnableSlice, which avoids the extra memcpy of value to std::string in most of cases.
* PinnableSlice releases the pinned resources that contain the value when it is destructed or when ::Reset() is called on it.
* The old API that accepts std::string, although discouraged, is still supported.
* Replace Options::use_direct_writes with Options::use_direct_io_for_flush_and_compaction. See Direct IO wiki for details.
### New Features
* Memtable flush can be avoided during checkpoint creation if total log file size is smaller than a threshold specified by the user.
* Introduce level-based L0->L0 compactions to reduce file count, so write delays are incurred less often.
* (Experimental) Partitioning filters which creates an index on the partitions. The feature can be enabled by setting partition_filters when using kFullFilter. Currently the feature also requires two-level indexing to be enabled. Number of partitions is the same as the number of partitions for indexes, which is controlled by metadata_block_size.
* DB::ResetStats() to reset internal stats.
* Added CompactionEventListener and EventListener::OnFlushBegin interfaces.
* Added DB::CreateColumnFamilie() and DB::DropColumnFamilies() to bulk create/drop column families.
* Facility for cross-building RocksJava using Docker.
### Bug Fixes
* Fix WriteBatchWithIndex address use after scope error.
* Fix WritableFile buffer size in direct IO.
* Add prefetch to PosixRandomAccessFile in buffered io.
* Fix PinnableSlice access invalid address when row cache is enabled.
* Fix huge fallocate calls fail and make XFS unhappy.
* Fix memory alignment with logical sector size.
* Fix alignment in ReadaheadRandomAccessFile.
* Fix bias with read amplification stats (READ_AMP_ESTIMATE_USEFUL_BYTES and READ_AMP_TOTAL_READ_BYTES).
* Fix a manual / auto compaction data race.
* Fix CentOS 5 cross-building of RocksJava.
* Build and link with ZStd when creating the static RocksJava build.
* Fix snprintf's usage to be cross-platform.
* Fix build errors with blob DB.
* Fix readamp test type inconsistency.
+30 -39
View File
@@ -169,8 +169,7 @@ class PosixEnv : public Env {
fd = open(fname.c_str(), flags, 0644);
} while (fd < 0 && errno == EINTR);
if (fd < 0) {
return IOError("While opening a file for sequentially reading", fname,
errno);
return IOError(fname, errno);
}
SetFD_CLOEXEC(fd, &options);
@@ -179,7 +178,7 @@ class PosixEnv : public Env {
#ifdef OS_MACOSX
if (fcntl(fd, F_NOCACHE, 1) == -1) {
close(fd);
return IOError("While fcntl NoCache", fname, errno);
return IOError(fname, errno);
}
#endif
} else {
@@ -189,8 +188,7 @@ class PosixEnv : public Env {
} while (file == nullptr && errno == EINTR);
if (file == nullptr) {
close(fd);
return IOError("While opening file for sequentially read", fname,
errno);
return IOError(fname, errno);
}
}
result->reset(new PosixSequentialFile(fname, file, fd, options));
@@ -219,7 +217,7 @@ class PosixEnv : public Env {
fd = open(fname.c_str(), flags, 0644);
} while (fd < 0 && errno == EINTR);
if (fd < 0) {
return IOError("While open a file for random read", fname, errno);
return IOError(fname, errno);
}
SetFD_CLOEXEC(fd, &options);
@@ -235,7 +233,7 @@ class PosixEnv : public Env {
result->reset(new PosixMmapReadableFile(fd, fname, base,
size, options));
} else {
s = IOError("while mmap file for read", fname, errno);
s = IOError(fname, errno);
}
}
close(fd);
@@ -244,7 +242,7 @@ class PosixEnv : public Env {
#ifdef OS_MACOSX
if (fcntl(fd, F_NOCACHE, 1) == -1) {
close(fd);
return IOError("while fcntl NoCache", fname, errno);
return IOError(fname, errno);
}
#endif
}
@@ -291,7 +289,7 @@ class PosixEnv : public Env {
} while (fd < 0 && errno == EINTR);
if (fd < 0) {
s = IOError("While open a file for appending", fname, errno);
s = IOError(fname, errno);
return s;
}
SetFD_CLOEXEC(fd, &options);
@@ -312,15 +310,14 @@ class PosixEnv : public Env {
#ifdef OS_MACOSX
if (fcntl(fd, F_NOCACHE, 1) == -1) {
close(fd);
s = IOError("While fcntl NoCache an opened file for appending", fname,
errno);
s = IOError(fname, errno);
return s;
}
#elif defined(OS_SOLARIS)
if (directio(fd, DIRECTIO_ON) == -1) {
if (errno != ENOTTY) { // ZFS filesystems don't support DIRECTIO_ON
close(fd);
s = IOError("While calling directio()", fname, errno);
s = IOError(fname, errno);
return s;
}
}
@@ -378,14 +375,14 @@ class PosixEnv : public Env {
fd = open(old_fname.c_str(), flags, 0644);
} while (fd < 0 && errno == EINTR);
if (fd < 0) {
s = IOError("while reopen file for write", fname, errno);
s = IOError(fname, errno);
return s;
}
SetFD_CLOEXEC(fd, &options);
// rename into place
if (rename(old_fname.c_str(), fname.c_str()) != 0) {
s = IOError("while rename file to " + fname, old_fname, errno);
s = IOError(old_fname, errno);
close(fd);
return s;
}
@@ -406,15 +403,14 @@ class PosixEnv : public Env {
#ifdef OS_MACOSX
if (fcntl(fd, F_NOCACHE, 1) == -1) {
close(fd);
s = IOError("while fcntl NoCache for reopened file for append", fname,
errno);
s = IOError(fname, errno);
return s;
}
#elif defined(OS_SOLARIS)
if (directio(fd, DIRECTIO_ON) == -1) {
if (errno != ENOTTY) { // ZFS filesystems don't support DIRECTIO_ON
close(fd);
s = IOError("while calling directio()", fname, errno);
s = IOError(fname, errno);
return s;
}
}
@@ -443,7 +439,7 @@ class PosixEnv : public Env {
if (errno == EINTR) {
continue;
}
return IOError("While open file for random read/write", fname, errno);
return IOError(fname, errno);
}
}
@@ -461,7 +457,7 @@ class PosixEnv : public Env {
fd = open(name.c_str(), 0);
}
if (fd < 0) {
return IOError("While open directory", name, errno);
return IOError(name, errno);
} else {
result->reset(new PosixDirectory(fd));
}
@@ -500,7 +496,7 @@ class PosixEnv : public Env {
case ENOTDIR:
return Status::NotFound();
default:
return IOError("While opendir", dir, errno);
return IOError(dir, errno);
}
}
struct dirent* entry;
@@ -514,7 +510,7 @@ class PosixEnv : public Env {
virtual Status DeleteFile(const std::string& fname) override {
Status result;
if (unlink(fname.c_str()) != 0) {
result = IOError("while unlink() file", fname, errno);
result = IOError(fname, errno);
}
return result;
};
@@ -522,7 +518,7 @@ class PosixEnv : public Env {
virtual Status CreateDir(const std::string& name) override {
Status result;
if (mkdir(name.c_str(), 0755) != 0) {
result = IOError("While mkdir", name, errno);
result = IOError(name, errno);
}
return result;
};
@@ -531,7 +527,7 @@ class PosixEnv : public Env {
Status result;
if (mkdir(name.c_str(), 0755) != 0) {
if (errno != EEXIST) {
result = IOError("While mkdir if missing", name, errno);
result = IOError(name, errno);
} else if (!DirExists(name)) { // Check that name is actually a
// directory.
// Message is taken from mkdir
@@ -544,7 +540,7 @@ class PosixEnv : public Env {
virtual Status DeleteDir(const std::string& name) override {
Status result;
if (rmdir(name.c_str()) != 0) {
result = IOError("file rmdir", name, errno);
result = IOError(name, errno);
}
return result;
};
@@ -555,7 +551,7 @@ class PosixEnv : public Env {
struct stat sbuf;
if (stat(fname.c_str(), &sbuf) != 0) {
*size = 0;
s = IOError("while stat a file for size", fname, errno);
s = IOError(fname, errno);
} else {
*size = sbuf.st_size;
}
@@ -566,7 +562,7 @@ class PosixEnv : public Env {
uint64_t* file_mtime) override {
struct stat s;
if (stat(fname.c_str(), &s) !=0) {
return IOError("while stat a file for modification time", fname, errno);
return IOError(fname, errno);
}
*file_mtime = static_cast<uint64_t>(s.st_mtime);
return Status::OK();
@@ -575,7 +571,7 @@ class PosixEnv : public Env {
const std::string& target) override {
Status result;
if (rename(src.c_str(), target.c_str()) != 0) {
result = IOError("While renaming a file to " + target, src, errno);
result = IOError(src, errno);
}
return result;
}
@@ -587,7 +583,7 @@ class PosixEnv : public Env {
if (errno == EXDEV) {
return Status::NotSupported("No cross FS links allowed");
}
result = IOError("while link file to " + target, src, errno);
result = IOError(src, errno);
}
return result;
}
@@ -601,9 +597,9 @@ class PosixEnv : public Env {
fd = open(fname.c_str(), O_RDWR | O_CREAT, 0644);
}
if (fd < 0) {
result = IOError("while open a file for lock", fname, errno);
result = IOError(fname, errno);
} else if (LockOrUnlock(fname, fd, true) == -1) {
result = IOError("While lock file", fname, errno);
result = IOError("lock " + fname, errno);
close(fd);
} else {
SetFD_CLOEXEC(fd, nullptr);
@@ -619,7 +615,7 @@ class PosixEnv : public Env {
PosixFileLock* my_lock = reinterpret_cast<PosixFileLock*>(lock);
Status result;
if (LockOrUnlock(my_lock->filename, my_lock->fd_, false) == -1) {
result = IOError("unlock", my_lock->filename, errno);
result = IOError("unlock", errno);
}
close(my_lock->fd_);
delete my_lock;
@@ -682,7 +678,7 @@ class PosixEnv : public Env {
}
if (f == nullptr) {
result->reset();
return IOError("when fopen a file for new logger", fname, errno);
return IOError(fname, errno);
} else {
int fd = fileno(f);
#ifdef ROCKSDB_FALLOCATE_PRESENT
@@ -728,7 +724,7 @@ class PosixEnv : public Env {
if (errno == EFAULT || errno == EINVAL)
return Status::InvalidArgument(strerror(errno));
else
return IOError("GetHostName", name, errno);
return IOError("GetHostName", errno);
}
return Status::OK();
}
@@ -736,7 +732,7 @@ class PosixEnv : public Env {
virtual Status GetCurrentTime(int64_t* unix_time) override {
time_t ret = time(nullptr);
if (ret == (time_t) -1) {
return IOError("GetCurrentTime", "", errno);
return IOError("GetCurrentTime", errno);
}
*unix_time = (int64_t) ret;
return Status::OK();
@@ -765,11 +761,6 @@ class PosixEnv : public Env {
thread_pools_[pri].SetBackgroundThreads(num);
}
virtual int GetBackgroundThreads(Priority pri) override {
assert(pri >= Priority::LOW && pri <= Priority::HIGH);
return thread_pools_[pri].GetBackgroundThreads();
}
// Allow increasing the number of worker threads.
virtual void IncBackgroundThreadsIfNeeded(int num, Priority pri) override {
assert(pri >= Priority::LOW && pri <= Priority::HIGH);
+35 -64
View File
@@ -167,7 +167,7 @@ Status PosixSequentialFile::Read(size_t n, Slice* result, char* scratch) {
clearerr(file_);
} else {
// A partial read with an error: return a non-ok status
s = IOError("While reading file sequentially", filename_, errno);
s = IOError(filename_, errno);
}
}
// we need to fadvise away the entire range of pages because
@@ -207,9 +207,7 @@ Status PosixSequentialFile::PositionedRead(uint64_t offset, size_t n,
}
if (r < 0) {
// An error: return a non-ok status
s = IOError(
"While pread " + ToString(n) + " bytes from offset " + ToString(offset),
filename_, errno);
s = IOError(filename_, errno);
}
*result = Slice(scratch, (r < 0) ? 0 : n - left);
return s;
@@ -217,8 +215,7 @@ Status PosixSequentialFile::PositionedRead(uint64_t offset, size_t n,
Status PosixSequentialFile::Skip(uint64_t n) {
if (fseek(file_, static_cast<long int>(n), SEEK_CUR)) {
return IOError("While fseek to skip " + ToString(n) + " bytes", filename_,
errno);
return IOError(filename_, errno);
}
return Status::OK();
}
@@ -231,9 +228,7 @@ Status PosixSequentialFile::InvalidateCache(size_t offset, size_t length) {
// free OS pages
int ret = Fadvise(fd_, offset, length, POSIX_FADV_DONTNEED);
if (ret != 0) {
return IOError("While fadvise NotNeeded offset " + ToString(offset) +
" len " + ToString(length),
filename_, errno);
return IOError(filename_, errno);
}
}
return Status::OK();
@@ -341,9 +336,7 @@ Status PosixRandomAccessFile::Read(uint64_t offset, size_t n, Slice* result,
}
if (r < 0) {
// An error: return a non-ok status
s = IOError(
"While pread offset " + ToString(offset) + " len " + ToString(n),
filename_, errno);
s = IOError(filename_, errno);
}
*result = Slice(scratch, (r < 0) ? 0 : n - left);
return s;
@@ -363,9 +356,7 @@ Status PosixRandomAccessFile::Prefetch(uint64_t offset, size_t n) {
r = fcntl(fd_, F_RDADVISE, &advice);
#endif
if (r == -1) {
s = IOError("While prefetching offset " + ToString(offset) + " len " +
ToString(n),
filename_, errno);
s = IOError(filename_, errno);
}
}
return s;
@@ -415,9 +406,7 @@ Status PosixRandomAccessFile::InvalidateCache(size_t offset, size_t length) {
if (ret == 0) {
return Status::OK();
}
return IOError("While fadvise NotNeeded offset " + ToString(offset) +
" len " + ToString(length),
filename_, errno);
return IOError(filename_, errno);
#endif
}
@@ -450,9 +439,7 @@ Status PosixMmapReadableFile::Read(uint64_t offset, size_t n, Slice* result,
Status s;
if (offset > length_) {
*result = Slice();
return IOError("While mmap read offset " + ToString(offset) +
" larger than file length " + ToString(length_),
filename_, EINVAL);
return IOError(filename_, EINVAL);
} else if (offset + n > length_) {
n = static_cast<size_t>(length_ - offset);
}
@@ -469,9 +456,7 @@ Status PosixMmapReadableFile::InvalidateCache(size_t offset, size_t length) {
if (ret == 0) {
return Status::OK();
}
return IOError("While fadvise not needed. Offset " + ToString(offset) +
" len" + ToString(length),
filename_, errno);
return IOError(filename_, errno);
#endif
}
@@ -488,7 +473,7 @@ Status PosixMmapFile::UnmapCurrentRegion() {
if (base_ != nullptr) {
int munmap_status = munmap(base_, limit_ - base_);
if (munmap_status != 0) {
return IOError("While munmap", filename_, munmap_status);
return IOError(filename_, munmap_status);
}
file_offset_ += limit_ - base_;
base_ = nullptr;
@@ -551,7 +536,7 @@ Status PosixMmapFile::Msync() {
last_sync_ = dst_;
TEST_KILL_RANDOM("PosixMmapFile::Msync:0", rocksdb_kill_odds);
if (msync(base_ + p1, p2 - p1 + page_size_, MS_SYNC) < 0) {
return IOError("While msync", filename_, errno);
return IOError(filename_, errno);
}
return Status::OK();
}
@@ -602,7 +587,6 @@ Status PosixMmapFile::Append(const Slice& data) {
}
size_t n = (left <= avail) ? left : avail;
assert(dst_);
memcpy(dst_, src, n);
dst_ += n;
src += n;
@@ -617,17 +601,17 @@ Status PosixMmapFile::Close() {
s = UnmapCurrentRegion();
if (!s.ok()) {
s = IOError("While closing mmapped file", filename_, errno);
s = IOError(filename_, errno);
} else if (unused > 0) {
// Trim the extra space at the end of the file
if (ftruncate(fd_, file_offset_ - unused) < 0) {
s = IOError("While ftruncating mmaped file", filename_, errno);
s = IOError(filename_, errno);
}
}
if (close(fd_) < 0) {
if (s.ok()) {
s = IOError("While closing mmapped file", filename_, errno);
s = IOError(filename_, errno);
}
}
@@ -641,7 +625,7 @@ Status PosixMmapFile::Flush() { return Status::OK(); }
Status PosixMmapFile::Sync() {
if (fdatasync(fd_) < 0) {
return IOError("While fdatasync mmapped file", filename_, errno);
return IOError(filename_, errno);
}
return Msync();
@@ -652,7 +636,7 @@ Status PosixMmapFile::Sync() {
*/
Status PosixMmapFile::Fsync() {
if (fsync(fd_) < 0) {
return IOError("While fsync mmaped file", filename_, errno);
return IOError(filename_, errno);
}
return Msync();
@@ -677,7 +661,7 @@ Status PosixMmapFile::InvalidateCache(size_t offset, size_t length) {
if (ret == 0) {
return Status::OK();
}
return IOError("While fadvise NotNeeded mmapped file", filename_, errno);
return IOError(filename_, errno);
#endif
}
@@ -695,9 +679,7 @@ Status PosixMmapFile::Allocate(uint64_t offset, uint64_t len) {
if (alloc_status == 0) {
return Status::OK();
} else {
return IOError(
"While fallocate offset " + ToString(offset) + " len " + ToString(len),
filename_, errno);
return IOError(filename_, errno);
}
}
#endif
@@ -740,7 +722,7 @@ Status PosixWritableFile::Append(const Slice& data) {
if (errno == EINTR) {
continue;
}
return IOError("While appending to file", filename_, errno);
return IOError(filename_, errno);
}
left -= done;
src += done;
@@ -764,8 +746,7 @@ Status PosixWritableFile::PositionedAppend(const Slice& data, uint64_t offset) {
if (errno == EINTR) {
continue;
}
return IOError("While pwrite to file at offset " + ToString(offset),
filename_, errno);
return IOError(filename_, errno);
}
left -= done;
offset += done;
@@ -779,8 +760,7 @@ Status PosixWritableFile::Truncate(uint64_t size) {
Status s;
int r = ftruncate(fd_, size);
if (r < 0) {
s = IOError("While ftruncate file to size " + ToString(size), filename_,
errno);
s = IOError(filename_, errno);
} else {
filesize_ = size;
}
@@ -817,11 +797,10 @@ Status PosixWritableFile::Close() {
// While we work with Travis-CI team to figure out if this is a
// quirk of Docker/AUFS, we will comment this out.
struct stat file_stats;
int result = fstat(fd_, &file_stats);
fstat(fd_, &file_stats);
// After ftruncate, we check whether ftruncate has the correct behavior.
// If not, we should hack it with FALLOC_FL_PUNCH_HOLE
if (result == 0 &&
(file_stats.st_size + file_stats.st_blksize - 1) /
if ((file_stats.st_size + file_stats.st_blksize - 1) /
file_stats.st_blksize !=
file_stats.st_blocks / (file_stats.st_blksize / 512)) {
IOSTATS_TIMER_GUARD(allocate_nanos);
@@ -834,7 +813,7 @@ Status PosixWritableFile::Close() {
}
if (close(fd_) < 0) {
s = IOError("While closing file after writing", filename_, errno);
s = IOError(filename_, errno);
}
fd_ = -1;
return s;
@@ -845,14 +824,14 @@ Status PosixWritableFile::Flush() { return Status::OK(); }
Status PosixWritableFile::Sync() {
if (fdatasync(fd_) < 0) {
return IOError("While fdatasync", filename_, errno);
return IOError(filename_, errno);
}
return Status::OK();
}
Status PosixWritableFile::Fsync() {
if (fsync(fd_) < 0) {
return IOError("While fsync", filename_, errno);
return IOError(filename_, errno);
}
return Status::OK();
}
@@ -873,7 +852,7 @@ Status PosixWritableFile::InvalidateCache(size_t offset, size_t length) {
if (ret == 0) {
return Status::OK();
}
return IOError("While fadvise NotNeeded", filename_, errno);
return IOError(filename_, errno);
#endif
}
@@ -892,9 +871,7 @@ Status PosixWritableFile::Allocate(uint64_t offset, uint64_t len) {
if (alloc_status == 0) {
return Status::OK();
} else {
return IOError(
"While fallocate offset " + ToString(offset) + " len " + ToString(len),
filename_, errno);
return IOError(filename_, errno);
}
}
#endif
@@ -907,9 +884,7 @@ Status PosixWritableFile::RangeSync(uint64_t offset, uint64_t nbytes) {
static_cast<off_t>(nbytes), SYNC_FILE_RANGE_WRITE) == 0) {
return Status::OK();
} else {
return IOError("While sync_file_range offset " + ToString(offset) +
" bytes " + ToString(nbytes),
filename_, errno);
return IOError(filename_, errno);
}
}
#endif
@@ -945,9 +920,7 @@ Status PosixRandomRWFile::Write(uint64_t offset, const Slice& data) {
// write was interrupted, try again.
continue;
}
return IOError(
"While write random read/write file at offset " + ToString(offset),
filename_, errno);
return IOError(filename_, errno);
}
// Wrote `done` bytes
@@ -971,9 +944,7 @@ Status PosixRandomRWFile::Read(uint64_t offset, size_t n, Slice* result,
// read was interrupted, try again.
continue;
}
return IOError("While reading random read/write file offset " +
ToString(offset) + " len " + ToString(n),
filename_, errno);
return IOError(filename_, errno);
} else if (done == 0) {
// Nothing more to read
break;
@@ -993,21 +964,21 @@ Status PosixRandomRWFile::Flush() { return Status::OK(); }
Status PosixRandomRWFile::Sync() {
if (fdatasync(fd_) < 0) {
return IOError("While fdatasync random read/write file", filename_, errno);
return IOError(filename_, errno);
}
return Status::OK();
}
Status PosixRandomRWFile::Fsync() {
if (fsync(fd_) < 0) {
return IOError("While fsync random read/write file", filename_, errno);
return IOError(filename_, errno);
}
return Status::OK();
}
Status PosixRandomRWFile::Close() {
if (close(fd_) < 0) {
return IOError("While close random read/write file", filename_, errno);
return IOError(filename_, errno);
}
fd_ = -1;
return Status::OK();
@@ -1022,7 +993,7 @@ PosixDirectory::~PosixDirectory() { close(fd_); }
Status PosixDirectory::Fsync() {
#ifndef OS_AIX
if (fsync(fd_) == -1) {
return IOError("While fsync", "a directory", errno);
return IOError("directory", errno);
}
#endif
return Status::OK();
+3 -14
View File
@@ -24,26 +24,15 @@
#endif
namespace rocksdb {
static std::string IOErrorMsg(const std::string& context,
const std::string& file_name) {
if (file_name.empty()) {
return context;
}
return context + ": " + file_name;
}
// file_name can be left empty if it is not unkown.
static Status IOError(const std::string& context, const std::string& file_name,
int err_number) {
static Status IOError(const std::string& context, int err_number) {
switch (err_number) {
case ENOSPC:
return Status::NoSpace(IOErrorMsg(context, file_name),
strerror(err_number));
return Status::NoSpace(context, strerror(err_number));
case ESTALE:
return Status::IOError(Status::kStaleFile);
default:
return Status::IOError(IOErrorMsg(context, file_name),
strerror(err_number));
return Status::IOError(context, strerror(err_number));
}
}
+451
View File
@@ -0,0 +1,451 @@
// 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 <string.h>
#include <algorithm>
#include <map>
#include <string>
#include <vector>
#include "rocksdb/env.h"
#include "rocksdb/status.h"
#include "port/port.h"
#include "util/mutexlock.h"
namespace rocksdb {
#ifndef ROCKSDB_LITE
namespace {
std::string NormalizeFileName(const std::string fname) {
if (fname.find("//") == std::string::npos) {
return fname;
}
std::string out_name = "";
bool is_slash = false;
for (char c : fname) {
if (c == '/' && is_slash) {
continue;
}
out_name.append(1, c);
if (c == '/') {
is_slash = true;
} else {
is_slash = false;
}
}
return out_name;
}
class FileState {
public:
// FileStates are reference counted. The initial reference count is zero
// and the caller must call Ref() at least once.
FileState() : refs_(0), size_(0) {}
// Increase the reference count.
void Ref() {
MutexLock lock(&refs_mutex_);
++refs_;
}
// Decrease the reference count. Delete if this is the last reference.
void Unref() {
bool do_delete = false;
{
MutexLock lock(&refs_mutex_);
--refs_;
assert(refs_ >= 0);
if (refs_ <= 0) {
do_delete = true;
}
}
if (do_delete) {
delete this;
}
}
uint64_t Size() const { return size_; }
Status Read(uint64_t offset, size_t n, Slice* result, char* scratch) const {
const uint64_t available = size_ - std::min(size_, offset);
if (n > available) {
n = available;
}
if (n == 0) {
*result = Slice();
return Status::OK();
}
size_t block = offset / kBlockSize;
size_t block_offset = offset % kBlockSize;
if (n <= kBlockSize - block_offset) {
// The requested bytes are all in the first block.
*result = Slice(blocks_[block] + block_offset, n);
return Status::OK();
}
size_t bytes_to_copy = n;
char* dst = scratch;
while (bytes_to_copy > 0) {
size_t avail = kBlockSize - block_offset;
if (avail > bytes_to_copy) {
avail = bytes_to_copy;
}
memcpy(dst, blocks_[block] + block_offset, avail);
bytes_to_copy -= avail;
dst += avail;
block++;
block_offset = 0;
}
*result = Slice(scratch, n);
return Status::OK();
}
Status Append(const Slice& data) {
const char* src = data.data();
size_t src_len = data.size();
while (src_len > 0) {
size_t avail;
size_t offset = size_ % kBlockSize;
if (offset != 0) {
// There is some room in the last block.
avail = kBlockSize - offset;
} else {
// No room in the last block; push new one.
blocks_.push_back(new char[kBlockSize]);
avail = kBlockSize;
}
if (avail > src_len) {
avail = src_len;
}
memcpy(blocks_.back() + offset, src, avail);
src_len -= avail;
src += avail;
size_ += avail;
}
return Status::OK();
}
private:
// Private since only Unref() should be used to delete it.
~FileState() {
for (std::vector<char*>::iterator i = blocks_.begin(); i != blocks_.end();
++i) {
delete [] *i;
}
}
// No copying allowed.
FileState(const FileState&);
void operator=(const FileState&);
port::Mutex refs_mutex_;
int refs_; // Protected by refs_mutex_;
// The following fields are not protected by any mutex. They are only mutable
// while the file is being written, and concurrent access is not allowed
// to writable files.
std::vector<char*> blocks_;
uint64_t size_;
enum { kBlockSize = 8 * 1024 };
};
class SequentialFileImpl : public SequentialFile {
public:
explicit SequentialFileImpl(FileState* file) : file_(file), pos_(0) {
file_->Ref();
}
~SequentialFileImpl() {
file_->Unref();
}
virtual Status Read(size_t n, Slice* result, char* scratch) override {
Status s = file_->Read(pos_, n, result, scratch);
if (s.ok()) {
pos_ += result->size();
}
return s;
}
virtual Status Skip(uint64_t n) override {
if (pos_ > file_->Size()) {
return Status::IOError("pos_ > file_->Size()");
}
const size_t available = file_->Size() - pos_;
if (n > available) {
n = available;
}
pos_ += n;
return Status::OK();
}
private:
FileState* file_;
size_t pos_;
};
class RandomAccessFileImpl : public RandomAccessFile {
public:
explicit RandomAccessFileImpl(FileState* file) : file_(file) {
file_->Ref();
}
~RandomAccessFileImpl() {
file_->Unref();
}
virtual Status Read(uint64_t offset, size_t n, Slice* result,
char* scratch) const override {
return file_->Read(offset, n, result, scratch);
}
private:
FileState* file_;
};
class WritableFileImpl : public WritableFile {
public:
explicit WritableFileImpl(FileState* file) : file_(file) { file_->Ref(); }
~WritableFileImpl() {
file_->Unref();
}
virtual Status Append(const Slice& data) override {
return file_->Append(data);
}
virtual Status Truncate(uint64_t size) override {
return Status::OK();
}
virtual Status Close() override { return Status::OK(); }
virtual Status Flush() override { return Status::OK(); }
virtual Status Sync() override { return Status::OK(); }
private:
FileState* file_;
};
class InMemoryDirectory : public Directory {
public:
virtual Status Fsync() override { return Status::OK(); }
};
class InMemoryEnv : public EnvWrapper {
public:
explicit InMemoryEnv(Env* base_env) : EnvWrapper(base_env) { }
virtual ~InMemoryEnv() {
for (FileSystem::iterator i = file_map_.begin(); i != file_map_.end(); ++i){
i->second->Unref();
}
}
// Partial implementation of the Env interface.
virtual Status NewSequentialFile(const std::string& fname,
unique_ptr<SequentialFile>* result,
const EnvOptions& soptions) override {
std::string nfname = NormalizeFileName(fname);
MutexLock lock(&mutex_);
if (file_map_.find(fname) == file_map_.end()) {
*result = NULL;
return Status::IOError(fname, "File not found");
}
result->reset(new SequentialFileImpl(file_map_[nfname]));
return Status::OK();
}
virtual Status NewRandomAccessFile(const std::string& fname,
unique_ptr<RandomAccessFile>* result,
const EnvOptions& soptions) override {
std::string nfname = NormalizeFileName(fname);
MutexLock lock(&mutex_);
if (file_map_.find(nfname) == file_map_.end()) {
*result = NULL;
return Status::IOError(fname, "File not found");
}
result->reset(new RandomAccessFileImpl(file_map_[nfname]));
return Status::OK();
}
virtual Status NewWritableFile(const std::string& fname,
unique_ptr<WritableFile>* result,
const EnvOptions& soptions) override {
std::string nfname = NormalizeFileName(fname);
MutexLock lock(&mutex_);
if (file_map_.find(nfname) != file_map_.end()) {
DeleteFileInternal(nfname);
}
FileState* file = new FileState();
file->Ref();
file_map_[nfname] = file;
result->reset(new WritableFileImpl(file));
return Status::OK();
}
virtual Status NewDirectory(const std::string& name,
unique_ptr<Directory>* result) override {
result->reset(new InMemoryDirectory());
return Status::OK();
}
virtual Status FileExists(const std::string& fname) override {
std::string nfname = NormalizeFileName(fname);
MutexLock lock(&mutex_);
if (file_map_.find(nfname) != file_map_.end()) {
return Status::OK();
} else {
return Status::NotFound();
}
}
virtual Status GetChildren(const std::string& dir,
std::vector<std::string>* result) override {
MutexLock lock(&mutex_);
result->clear();
bool found_dir = false;
for (FileSystem::iterator i = file_map_.begin(); i != file_map_.end(); ++i){
const std::string& filename = i->first;
if (dir == filename) {
found_dir = true;
} else if (filename.size() >= dir.size() + 1 &&
filename[dir.size()] == '/' &&
Slice(filename).starts_with(Slice(dir))) {
found_dir = true;
result->push_back(filename.substr(dir.size() + 1));
}
}
return found_dir ? Status::OK() : Status::NotFound();
}
void DeleteFileInternal(const std::string& fname) {
if (file_map_.find(fname) == file_map_.end()) {
return;
}
file_map_[fname]->Unref();
file_map_.erase(fname);
}
virtual Status DeleteFile(const std::string& fname) override {
std::string nfname = NormalizeFileName(fname);
MutexLock lock(&mutex_);
if (file_map_.find(nfname) == file_map_.end()) {
return Status::IOError(fname, "File not found");
}
DeleteFileInternal(nfname);
return Status::OK();
}
virtual Status CreateDir(const std::string& dirname) override {
auto ndirname = NormalizeFileName(dirname);
if (file_map_.find(ndirname) == file_map_.end()) {
FileState* file = new FileState();
file->Ref();
file_map_[ndirname] = file;
} else {
return Status::IOError();
}
return Status::OK();
}
virtual Status CreateDirIfMissing(const std::string& dirname) override {
CreateDir(dirname);
return Status::OK();
}
virtual Status DeleteDir(const std::string& dirname) override {
return DeleteFile(dirname);
}
virtual Status GetFileSize(const std::string& fname,
uint64_t* file_size) override {
std::string nfname = NormalizeFileName(fname);
MutexLock lock(&mutex_);
if (file_map_.find(nfname) == file_map_.end()) {
return Status::IOError(fname, "File not found");
}
*file_size = file_map_[nfname]->Size();
return Status::OK();
}
virtual Status GetFileModificationTime(const std::string& fname,
uint64_t* time) override {
return Status::NotSupported("getFileMTime", "Not supported in MemEnv");
}
virtual Status RenameFile(const std::string& src,
const std::string& dest) override {
std::string nsrc = NormalizeFileName(src);
std::string ndest = NormalizeFileName(dest);
MutexLock lock(&mutex_);
if (file_map_.find(nsrc) == file_map_.end()) {
return Status::IOError(src, "File not found");
}
DeleteFileInternal(dest);
file_map_[ndest] = file_map_[nsrc];
file_map_.erase(nsrc);
return Status::OK();
}
virtual Status LockFile(const std::string& fname, FileLock** lock) override {
*lock = new FileLock;
return Status::OK();
}
virtual Status UnlockFile(FileLock* lock) override {
delete lock;
return Status::OK();
}
virtual Status GetTestDirectory(std::string* path) override {
*path = "/test";
return Status::OK();
}
private:
// Map from filenames to FileState objects, representing a simple file system.
typedef std::map<std::string, FileState*> FileSystem;
port::Mutex mutex_;
FileSystem file_map_; // Protected by mutex_.
};
} // namespace
Env* NewMemEnv(Env* base_env) {
return new InMemoryEnv(base_env);
}
#else // ROCKSDB_LITE
Env* NewMemEnv(Env* base_env) { return nullptr; }
#endif // !ROCKSDB_LITE
} // namespace rocksdb
+2 -13
View File
@@ -376,9 +376,8 @@ class TestMemLogger : public Logger {
struct timeval now_tv;
gettimeofday(&now_tv, nullptr);
const time_t seconds = now_tv.tv_sec;
struct tm t{0, 0, 0, 0, 0, 0, 0, 0, 0};
auto ret __attribute__((__unused__)) = localtime_r(&seconds, &t);
assert(ret);
struct tm t;
localtime_r(&seconds, &t);
p += snprintf(p, limit - p,
"%04d/%02d/%02d-%02d:%02d:%02d.%06d ",
t.tm_year + 1900,
@@ -781,14 +780,4 @@ void MockEnv::FakeSleepForMicroseconds(int64_t micros) {
fake_sleep_micros_.fetch_add(micros);
}
#ifndef ROCKSDB_LITE
// This is to maintain the behavior before swithcing from InMemoryEnv to MockEnv
Env* NewMemEnv(Env* base_env) { return new MockEnv(base_env); }
#else // ROCKSDB_LITE
Env* NewMemEnv(Env* base_env) { return nullptr; }
#endif // !ROCKSDB_LITE
} // namespace rocksdb
-5
View File
@@ -149,10 +149,6 @@ class HdfsEnv : public Env {
posixEnv->SetBackgroundThreads(number, pri);
}
virtual int GetBackgroundThreads(Priority pri = LOW) {
return posixEnv->GetBackgroundThreads(pri);
}
virtual void IncBackgroundThreadsIfNeeded(int number, Priority pri) override {
posixEnv->IncBackgroundThreadsIfNeeded(number, pri);
}
@@ -360,7 +356,6 @@ class HdfsEnv : public Env {
}
virtual void SetBackgroundThreads(int number, Priority pri = LOW) override {}
virtual int GetBackgroundThreads(Priority pri = LOW) override { return 0; }
virtual void IncBackgroundThreadsIfNeeded(int number, Priority pri) override {
}
virtual std::string TimeToString(uint64_t number) override { return ""; }
+1 -1
View File
@@ -72,7 +72,7 @@ struct CompactionOptionsFIFO {
CompactionOptionsFIFO() : max_table_files_size(1 * 1024 * 1024 * 1024) {}
CompactionOptionsFIFO(uint64_t _max_table_files_size,
bool _allow_compaction)
uint64_t _allow_compaction)
: max_table_files_size(_max_table_files_size),
allow_compaction(_allow_compaction) {}
};
-10
View File
@@ -639,7 +639,6 @@ extern ROCKSDB_LIBRARY_API void rocksdb_block_based_options_set_format_version(
enum {
rocksdb_block_based_table_index_type_binary_search = 0,
rocksdb_block_based_table_index_type_hash_search = 1,
rocksdb_block_based_table_index_type_two_level_index_search = 2,
};
extern ROCKSDB_LIBRARY_API void rocksdb_block_based_options_set_index_type(
rocksdb_block_based_table_options_t*, int); // uses one of the above enums
@@ -1119,15 +1118,6 @@ extern ROCKSDB_LIBRARY_API void rocksdb_sstfilewriter_open(
extern ROCKSDB_LIBRARY_API void rocksdb_sstfilewriter_add(
rocksdb_sstfilewriter_t* writer, const char* key, size_t keylen,
const char* val, size_t vallen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_sstfilewriter_put(
rocksdb_sstfilewriter_t* writer, const char* key, size_t keylen,
const char* val, size_t vallen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_sstfilewriter_merge(
rocksdb_sstfilewriter_t* writer, const char* key, size_t keylen,
const char* val, size_t vallen, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_sstfilewriter_delete(
rocksdb_sstfilewriter_t* writer, const char* key, size_t keylen,
char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_sstfilewriter_finish(
rocksdb_sstfilewriter_t* writer, char** errptr);
extern ROCKSDB_LIBRARY_API void rocksdb_sstfilewriter_destroy(
+13 -13
View File
@@ -135,19 +135,19 @@ class CompactionFilter {
// *skip_until <= key is treated the same as Decision::kKeep
// (since the range [key, *skip_until) is empty).
//
// Caveats:
// - The keys are skipped even if there are snapshots containing them,
// as if IgnoreSnapshots() was true; i.e. values removed
// by kRemoveAndSkipUntil can disappear from a snapshot - beware
// if you're using TransactionDB or DB::GetSnapshot().
// - If value for a key was overwritten or merged into (multiple Put()s
// or Merge()s), and compaction filter skips this key with
// kRemoveAndSkipUntil, it's possible that it will remove only
// the new value, exposing the old value that was supposed to be
// overwritten.
// - Doesn't work with PlainTableFactory in prefix mode.
// - If you use kRemoveAndSkipUntil, consider also reducing
// compaction_readahead_size option.
// The keys are skipped even if there are snapshots containing them,
// as if IgnoreSnapshots() was true; i.e. values removed
// by kRemoveAndSkipUntil can disappear from a snapshot - beware
// if you're using TransactionDB or DB::GetSnapshot().
//
// Another warning: if value for a key was overwritten or merged into
// (multiple Put()s or Merge()s), and compaction filter skips this key
// with kRemoveAndSkipUntil, it's possible that it will remove only
// the new value, exposing the old value that was supposed to be
// overwritten.
//
// If you use kRemoveAndSkipUntil, consider also reducing
// compaction_readahead_size option.
//
// Note: If you are using a TransactionDB, it is not recommended to filter
// out or modify merge operands (ValueType::kMergeOperand).
+5 -15
View File
@@ -161,15 +161,12 @@ namespace rocksdb {
// @param input_strings_escaped when set to true, each escaped characters
// prefixed by '\' in the values of the opts_map will be further converted
// back to the raw string before assigning to the associated options.
// @param ignore_unknown_options when set to true, unknown options are ignored
// instead of resulting in an unknown-option error.
// @return Status::OK() on success. Otherwise, a non-ok status indicating
// error will be returned, and "new_options" will be set to "base_options".
Status GetColumnFamilyOptionsFromMap(
const ColumnFamilyOptions& base_options,
const std::unordered_map<std::string, std::string>& opts_map,
ColumnFamilyOptions* new_options, bool input_strings_escaped = false,
bool ignore_unknown_options = false);
ColumnFamilyOptions* new_options, bool input_strings_escaped = false);
// Take a default DBOptions "base_options" in addition to a
// map "opts_map" of option name to option value to construct the new
@@ -192,15 +189,12 @@ Status GetColumnFamilyOptionsFromMap(
// @param input_strings_escaped when set to true, each escaped characters
// prefixed by '\' in the values of the opts_map will be further converted
// back to the raw string before assigning to the associated options.
// @param ignore_unknown_options when set to true, unknown options are ignored
// instead of resulting in an unknown-option error.
// @return Status::OK() on success. Otherwise, a non-ok status indicating
// error will be returned, and "new_options" will be set to "base_options".
Status GetDBOptionsFromMap(
const DBOptions& base_options,
const std::unordered_map<std::string, std::string>& opts_map,
DBOptions* new_options, bool input_strings_escaped = false,
bool ignore_unknown_options = false);
DBOptions* new_options, bool input_strings_escaped = false);
// Take a default BlockBasedTableOptions "table_options" in addition to a
// map "opts_map" of option name to option value to construct the new
@@ -235,8 +229,6 @@ Status GetDBOptionsFromMap(
// @param input_strings_escaped when set to true, each escaped characters
// prefixed by '\' in the values of the opts_map will be further converted
// back to the raw string before assigning to the associated options.
// @param ignore_unknown_options when set to true, unknown options are ignored
// instead of resulting in an unknown-option error.
// @return Status::OK() on success. Otherwise, a non-ok status indicating
// error will be returned, and "new_table_options" will be set to
// "table_options".
@@ -244,7 +236,7 @@ Status GetBlockBasedTableOptionsFromMap(
const BlockBasedTableOptions& table_options,
const std::unordered_map<std::string, std::string>& opts_map,
BlockBasedTableOptions* new_table_options,
bool input_strings_escaped = false, bool ignore_unknown_options = false);
bool input_strings_escaped = false);
// Take a default PlainTableOptions "table_options" in addition to a
// map "opts_map" of option name to option value to construct the new
@@ -258,16 +250,14 @@ Status GetBlockBasedTableOptionsFromMap(
// @param input_strings_escaped when set to true, each escaped characters
// prefixed by '\' in the values of the opts_map will be further converted
// back to the raw string before assigning to the associated options.
// @param ignore_unknown_options when set to true, unknown options are ignored
// instead of resulting in an unknown-option error.
// @return Status::OK() on success. Otherwise, a non-ok status indicating
// error will be returned, and "new_table_options" will be set to
// "table_options".
Status GetPlainTableOptionsFromMap(
const PlainTableOptions& table_options,
const std::unordered_map<std::string, std::string>& opts_map,
PlainTableOptions* new_table_options, bool input_strings_escaped = false,
bool ignore_unknown_options = false);
PlainTableOptions* new_table_options,
bool input_strings_escaped = false);
// Take a string representation of option names and values, apply them into the
// base_options, and return the new options as a result. The string has the
+10 -13
View File
@@ -57,10 +57,10 @@ const size_t kDefaultPageSize = 4 * 1024;
// Options while opening a file to read/write
struct EnvOptions {
// Construct with default Options
// construct with default Options
EnvOptions();
// Construct from Options
// construct from Options
explicit EnvOptions(const DBOptions& options);
// If true, then use mmap to read data
@@ -95,10 +95,10 @@ struct EnvOptions {
// WAL writes
bool fallocate_with_keep_size = true;
// See DBOptions doc
// See DBOPtions doc
size_t compaction_readahead_size;
// See DBOptions doc
// See DBOPtions doc
size_t random_access_max_buffer_size;
// See DBOptions doc
@@ -173,7 +173,8 @@ class Env {
virtual Status ReopenWritableFile(const std::string& fname,
unique_ptr<WritableFile>* result,
const EnvOptions& options) {
return Status::NotSupported();
Status s;
return s;
}
// Reuse an existing file by renaming it and opening it as writable.
@@ -363,7 +364,6 @@ class Env {
// for this environment. 'LOW' is the default pool.
// default number: 1
virtual void SetBackgroundThreads(int number, Priority pri = LOW) = 0;
virtual int GetBackgroundThreads(Priority pri = LOW) = 0;
// Enlarge number of background worker threads of a specific thread pool
// for this environment if it is smaller than specified. 'LOW' is the default
@@ -935,8 +935,8 @@ class EnvWrapper : public Env {
const EnvOptions& options) override {
return target_->NewRandomRWFile(fname, result, options);
}
Status NewDirectory(const std::string& name,
unique_ptr<Directory>* result) override {
Status NewDirectory(const std::string& name, unique_ptr<Directory>* result)
override {
return target_->NewDirectory(name, result);
}
Status FileExists(const std::string& f) override {
@@ -1004,8 +1004,8 @@ class EnvWrapper : public Env {
Status GetTestDirectory(std::string* path) override {
return target_->GetTestDirectory(path);
}
Status NewLogger(const std::string& fname,
shared_ptr<Logger>* result) override {
Status NewLogger(const std::string& fname, shared_ptr<Logger>* result)
override {
return target_->NewLogger(fname, result);
}
uint64_t NowMicros() override { return target_->NowMicros(); }
@@ -1026,9 +1026,6 @@ class EnvWrapper : public Env {
void SetBackgroundThreads(int num, Priority pri) override {
return target_->SetBackgroundThreads(num, pri);
}
int GetBackgroundThreads(Priority pri) override {
return target_->GetBackgroundThreads(pri);
}
void IncBackgroundThreadsIfNeeded(int num, Priority pri) override {
return target_->IncBackgroundThreadsIfNeeded(num, pri);
+3 -1
View File
@@ -48,7 +48,9 @@ class FlushBlockBySizePolicyFactory : public FlushBlockPolicyFactory {
public:
FlushBlockBySizePolicyFactory() {}
const char* Name() const override { return "FlushBlockBySizePolicyFactory"; }
const char* Name() const override {
return "FlushBlockBySizePolicyFactory";
}
FlushBlockPolicy* NewFlushBlockPolicy(
const BlockBasedTableOptions& table_options,
+7 -2
View File
@@ -46,7 +46,12 @@ struct IOStatsContext {
uint64_t logger_nanos;
};
// Get Thread-local IOStatsContext object pointer
IOStatsContext* get_iostats_context();
#ifndef IOS_CROSS_COMPILE
# ifdef _MSC_VER
extern __declspec(thread) IOStatsContext iostats_context;
# else
extern __thread IOStatsContext iostats_context;
# endif
#endif // IOS_CROSS_COMPILE
} // namespace rocksdb
+9 -18
View File
@@ -43,7 +43,7 @@
namespace rocksdb {
class Arena;
class Allocator;
class MemTableAllocator;
class LookupKey;
class Slice;
class SliceTransform;
@@ -68,7 +68,7 @@ class MemTableRep {
virtual ~KeyComparator() { }
};
explicit MemTableRep(Allocator* allocator) : allocator_(allocator) {}
explicit MemTableRep(MemTableAllocator* allocator) : allocator_(allocator) {}
// Allocate a buf of len size for storing key. The idea is that a
// specific memtable representation knows its underlying data structure
@@ -208,7 +208,7 @@ class MemTableRep {
// user key.
virtual Slice UserKey(const char* key) const;
Allocator* allocator_;
MemTableAllocator* allocator_;
};
// This is the base class for all factories that are used by RocksDB to create
@@ -216,17 +216,10 @@ class MemTableRep {
class MemTableRepFactory {
public:
virtual ~MemTableRepFactory() {}
virtual MemTableRep* CreateMemTableRep(const MemTableRep::KeyComparator&,
Allocator*, const SliceTransform*,
MemTableAllocator*,
const SliceTransform*,
Logger* logger) = 0;
virtual MemTableRep* CreateMemTableRep(
const MemTableRep::KeyComparator& key_cmp, Allocator* allocator,
const SliceTransform* slice_transform, Logger* logger,
uint32_t /* column_family_id */) {
return CreateMemTableRep(key_cmp, allocator, slice_transform, logger);
}
virtual const char* Name() const = 0;
// Return true if the current MemTableRep supports concurrent inserts
@@ -245,9 +238,9 @@ class SkipListFactory : public MemTableRepFactory {
public:
explicit SkipListFactory(size_t lookahead = 0) : lookahead_(lookahead) {}
using MemTableRepFactory::CreateMemTableRep;
virtual MemTableRep* CreateMemTableRep(const MemTableRep::KeyComparator&,
Allocator*, const SliceTransform*,
MemTableAllocator*,
const SliceTransform*,
Logger* logger) override;
virtual const char* Name() const override { return "SkipListFactory"; }
@@ -271,12 +264,10 @@ class VectorRepFactory : public MemTableRepFactory {
public:
explicit VectorRepFactory(size_t count = 0) : count_(count) { }
using MemTableRepFactory::CreateMemTableRep;
virtual MemTableRep* CreateMemTableRep(const MemTableRep::KeyComparator&,
Allocator*, const SliceTransform*,
MemTableAllocator*,
const SliceTransform*,
Logger* logger) override;
virtual const char* Name() const override {
return "VectorRepFactory";
}
+9 -5
View File
@@ -212,12 +212,16 @@ class AssociativeMergeOperator : public MergeOperator {
private:
// Default implementations of the MergeOperator functions
bool FullMergeV2(const MergeOperationInput& merge_in,
MergeOperationOutput* merge_out) const override;
bool FullMergeV2(
const MergeOperationInput& merge_in,
MergeOperationOutput* merge_out) const override;
bool PartialMerge(const Slice& key, const Slice& left_operand,
const Slice& right_operand, std::string* new_value,
Logger* logger) const override;
bool PartialMerge(
const Slice& key,
const Slice& left_operand,
const Slice& right_operand,
std::string* new_value,
Logger* logger) const override;
};
} // namespace rocksdb
+56 -72
View File
@@ -463,27 +463,24 @@ struct DBOptions {
// regardless of this setting
uint64_t delete_obsolete_files_period_micros = 6ULL * 60 * 60 * 1000000;
// Maximum number of concurrent background jobs (compactions and flushes).
int max_background_jobs = 2;
// NOT SUPPORTED ANYMORE: RocksDB automatically decides this based on the
// value of max_background_jobs. This option is ignored.
int base_background_compactions = -1;
// NOT SUPPORTED ANYMORE: RocksDB automatically decides this based on the
// value of max_background_jobs. For backwards compatibility we will set
// `max_background_jobs = max_background_compactions + max_background_flushes`
// in the case where user sets at least one of `max_background_compactions` or
// `max_background_flushes` (we replace -1 by 1 in case one option is unset).
// Suggested number of concurrent background compaction jobs, submitted to
// the default LOW priority thread pool.
//
// Default: 1
int base_background_compactions = 1;
// Maximum number of concurrent background compaction jobs, submitted to
// the default LOW priority thread pool.
// We first try to schedule compactions based on
// `base_background_compactions`. If the compaction cannot catch up , we
// will increase number of compaction threads up to
// `max_background_compactions`.
//
// If you're increasing this, also consider increasing number of threads in
// LOW priority thread pool. For more information, see
// Env::SetBackgroundThreads
// Default: -1
int max_background_compactions = -1;
// Default: 1
int max_background_compactions = 1;
// This value represents the maximum number of threads that will
// concurrently perform a compaction job by breaking it into multiple,
@@ -491,27 +488,22 @@ struct DBOptions {
// Default: 1 (i.e. no subcompactions)
uint32_t max_subcompactions = 1;
// NOT SUPPORTED ANYMORE: RocksDB automatically decides this based on the
// value of max_background_jobs. For backwards compatibility we will set
// `max_background_jobs = max_background_compactions + max_background_flushes`
// in the case where user sets at least one of `max_background_compactions` or
// `max_background_flushes`.
// Maximum number of concurrent background memtable flush jobs, submitted to
// the HIGH priority thread pool.
//
// Maximum number of concurrent background memtable flush jobs, submitted by
// default to the HIGH priority thread pool. If the HIGH priority thread pool
// is configured to have zero threads, flush jobs will share the LOW priority
// thread pool with compaction jobs.
//
// It is important to use both thread pools when the same Env is shared by
// multiple db instances. Without a separate pool, long running compaction
// jobs could potentially block memtable flush jobs of other db instances,
// leading to unnecessary Put stalls.
// By default, all background jobs (major compaction and memtable flush) go
// to the LOW priority pool. If this option is set to a positive number,
// memtable flush jobs will be submitted to the HIGH priority pool.
// It is important when the same Env is shared by multiple db instances.
// Without a separate pool, long running major compaction jobs could
// potentially block memtable flush jobs of other db instances, leading to
// unnecessary Put stalls.
//
// If you're increasing this, also consider increasing number of threads in
// HIGH priority thread pool. For more information, see
// Env::SetBackgroundThreads
// Default: -1
int max_background_flushes = -1;
// Default: 1
int max_background_flushes = 1;
// Specify the maximal size of the info log file. If the log file
// is larger than `max_log_file_size`, a new info log file will
@@ -754,15 +746,10 @@ struct DBOptions {
// calculated using size of user write requests before compression.
// RocksDB may decide to slow down more if the compaction still
// gets behind further.
// If the value is 0, we will infer a value from `rater_limiter` value
// if it is not empty, or 16MB if `rater_limiter` is empty. Note that
// if users change the rate in `rate_limiter` after DB is opened,
// `delayed_write_rate` won't be adjusted.
//
// Unit: byte per second.
//
// Default: 0
uint64_t delayed_write_rate = 0;
// Default: 16MB/s
uint64_t delayed_write_rate = 16 * 1024U * 1024U;
// By default, a single write thread queue is maintained. The thread gets
// to the head of the queue becomes write batch group leader and responsible
@@ -771,7 +758,7 @@ struct DBOptions {
// If enable_pipelined_write is true, separate write thread queue is
// maintained for WAL write and memtable write. A write thread first enter WAL
// writer queue and then memtable writer queue. Pending thread on the WAL
// writer queue thus only have to wait for previous writers to finish their
// writer queue thus only have to wait for previous writers to finish thier
// WAL writing but not the memtable writing. Enabling the feature may improve
// write throughput and reduce latency of the prepare phase of two-phase
// commit.
@@ -942,6 +929,24 @@ enum ReadTier {
// Options that control read operations
struct ReadOptions {
// If true, all data read from underlying storage will be
// verified against corresponding checksums.
// Default: true
bool verify_checksums;
// Should the "data block"/"index block"/"filter block" read for this
// iteration be cached in memory?
// Callers may wish to set this field to false for bulk scans.
// Default: true
bool fill_cache;
// If this option is set and memtable implementation allows, Seek
// might only return keys with the same prefix as the seek-key
//
// ! NOT SUPPORTED ANYMORE: prefix_seek is on by default when prefix_extractor
// is configured
// bool prefix_seek;
// If "snapshot" is non-nullptr, read as of the supplied snapshot
// (which must belong to the DB that is being read and which must
// not have been released). If "snapshot" is nullptr, use an implicit
@@ -961,35 +966,12 @@ struct ReadOptions {
// Default: nullptr
const Slice* iterate_upper_bound;
// If non-zero, NewIterator will create a new table reader which
// performs reads of the given size. Using a large size (> 2MB) can
// improve the performance of forward iteration on spinning disks.
// Default: 0
size_t readahead_size;
// A threshold for the number of keys that can be skipped before failing an
// iterator seek as incomplete. The default value of 0 should be used to
// never fail a request as incomplete, even on skipping too many keys.
// Default: 0
uint64_t max_skippable_internal_keys;
// Specify if this read request should process data that ALREADY
// resides on a particular cache. If the required data is not
// found at the specified cache, then Status::Incomplete is returned.
// Default: kReadAllTier
ReadTier read_tier;
// If true, all data read from underlying storage will be
// verified against corresponding checksums.
// Default: true
bool verify_checksums;
// Should the "data block"/"index block"/"filter block" read for this
// iteration be cached in memory?
// Callers may wish to set this field to false for bulk scans.
// Default: true
bool fill_cache;
// Specify to create a tailing iterator -- a special iterator that has a
// view of the complete database (i.e. it can also be used to read newly
// added data) and is optimized for sequential reads. It will return records
@@ -1035,12 +1017,24 @@ struct ReadOptions {
// Default: false
bool background_purge_on_iterator_cleanup;
// If non-zero, NewIterator will create a new table reader which
// performs reads of the given size. Using a large size (> 2MB) can
// improve the performance of forward iteration on spinning disks.
// Default: 0
size_t readahead_size;
// If true, keys deleted using the DeleteRange() API will be visible to
// readers until they are naturally deleted during compaction. This improves
// read performance in DBs with many range deletions.
// Default: false
bool ignore_range_deletions;
// A threshold for the number of keys that can be skipped before failing an
// iterator seek as incomplete. The default value of 0 should be used to
// never fail a request as incomplete, even on skipping too many keys.
// Default: 0
uint64_t max_skippable_internal_keys;
ReadOptions();
ReadOptions(bool cksum, bool cache);
};
@@ -1079,21 +1073,11 @@ struct WriteOptions {
// immediately with Status::Incomplete().
bool no_slowdown;
// If true, this write request is of lower priority if compaction is
// behind. In this case, no_slowdown = true, the request will be cancelled
// immediately with Status::Incomplete() returned. Otherwise, it will be
// slowed down. The slowdown value is determined by RocksDB to guarantee
// it introduces minimum impacts to high priority writes.
//
// Default: false
bool low_pri;
WriteOptions()
: sync(false),
disableWAL(false),
ignore_missing_column_families(false),
no_slowdown(false),
low_pri(false) {}
no_slowdown(false) {}
};
// Options that control flush operations
+12 -3
View File
@@ -150,9 +150,18 @@ struct PerfContext {
uint64_t env_new_logger_nanos;
};
// Get Thread-local PerfContext object pointer
// if defined(NPERF_CONTEXT), then the pointer is not thread-local
PerfContext* get_perf_context();
#if defined(NPERF_CONTEXT) || defined(IOS_CROSS_COMPILE)
extern PerfContext perf_context;
#elif defined(_MSC_VER)
extern __declspec(thread) PerfContext perf_context;
#else
#if defined(OS_SOLARIS)
PerfContext *getPerfContext();
#define perf_context (*getPerfContext())
#else
extern __thread PerfContext perf_context;
#endif
#endif
}
+1
View File
@@ -12,6 +12,7 @@
namespace rocksdb {
// How much perf stats to collect. Affects perf_context and iostats_context.
enum PerfLevel : unsigned char {
kUninitialized = 0, // unknown setting
kDisable = 1, // disable perf stats
-2
View File
@@ -51,8 +51,6 @@ class RateLimiter {
// Total # of requests that go though rate limiter
virtual int64_t GetTotalRequests(
const Env::IOPriority pri = Env::IO_TOTAL) const = 0;
virtual int64_t GetBytesPerSecond() const = 0;
};
// Create a RateLimiter object, which can be shared among RocksDB instances to
+11 -34
View File
@@ -6,27 +6,18 @@
#ifndef ROCKSDB_LITE
#pragma once
#include <memory>
#include <string>
#include "rocksdb/env.h"
#include "rocksdb/options.h"
#include "rocksdb/table_properties.h"
#include "rocksdb/types.h"
#if defined(__GNUC__) || defined(__clang__)
#define ROCKSDB_DEPRECATED_FUNC __attribute__((__deprecated__))
#elif _WIN32
#define ROCKSDB_DEPRECATED_FUNC __declspec(deprecated)
#endif
namespace rocksdb {
class Comparator;
// ExternalSstFileInfo include information about sst files created
// using SstFileWriter.
// using SstFileWriter
struct ExternalSstFileInfo {
ExternalSstFileInfo() {}
ExternalSstFileInfo(const std::string& _file_path,
@@ -52,54 +43,39 @@ struct ExternalSstFileInfo {
};
// SstFileWriter is used to create sst files that can be added to database later
// All keys in files generated by SstFileWriter will have sequence number = 0.
// All keys in files generated by SstFileWriter will have sequence number = 0
class SstFileWriter {
public:
// User can pass `column_family` to specify that the the generated file will
// be ingested into this column_family, note that passing nullptr means that
// the column_family is unknown.
// If invalidate_page_cache is set to true, SstFileWriter will give the OS a
// hint that this file pages is not needed everytime we write 1MB to the file.
// To use the rate limiter an io_priority smaller than IO_TOTAL can be passed.
// hint that this file pages is not needed everytime we write 1MB to the file
SstFileWriter(const EnvOptions& env_options, const Options& options,
ColumnFamilyHandle* column_family = nullptr,
bool invalidate_page_cache = true,
Env::IOPriority io_priority = Env::IOPriority::IO_TOTAL)
bool invalidate_page_cache = true)
: SstFileWriter(env_options, options, options.comparator, column_family,
invalidate_page_cache, io_priority) {}
invalidate_page_cache) {}
// Deprecated API
SstFileWriter(const EnvOptions& env_options, const Options& options,
const Comparator* user_comparator,
ColumnFamilyHandle* column_family = nullptr,
bool invalidate_page_cache = true,
Env::IOPriority io_priority = Env::IOPriority::IO_TOTAL);
bool invalidate_page_cache = true);
~SstFileWriter();
// Prepare SstFileWriter to write into file located at "file_path".
Status Open(const std::string& file_path);
// Add a Put key with value to currently opened file (deprecated)
// Add key, value to currently opened file
// REQUIRES: key is after any previously added key according to comparator.
ROCKSDB_DEPRECATED_FUNC Status Add(const Slice& user_key, const Slice& value);
// Add a Put key with value to currently opened file
// REQUIRES: key is after any previously added key according to comparator.
Status Put(const Slice& user_key, const Slice& value);
// Add a Merge key with value to currently opened file
// REQUIRES: key is after any previously added key according to comparator.
Status Merge(const Slice& user_key, const Slice& value);
// Add a deletion key to currently opened file
// REQUIRES: key is after any previously added key according to comparator.
Status Delete(const Slice& user_key);
Status Add(const Slice& user_key, const Slice& value);
// Finalize writing to sst file and close file.
//
// An optional ExternalSstFileInfo pointer can be passed to the function
// which will be populated with information about the created sst file.
// which will be populated with information about the created sst file
Status Finish(ExternalSstFileInfo* file_info = nullptr);
// Return the current file size.
@@ -107,8 +83,9 @@ class SstFileWriter {
private:
void InvalidatePageCache(bool closing);
struct Rep;
std::unique_ptr<Rep> rep_;
Rep* rep_;
};
} // namespace rocksdb
-6
View File
@@ -21,7 +21,6 @@ namespace rocksdb {
* Keep adding ticker's here.
* 1. Any ticker should be added before TICKER_ENUM_MAX.
* 2. Add a readable string in TickersNameMap below for the newly added ticker.
* 3. Add a corresponding enum value to TickerType.java in the java API
*/
enum Tickers : uint32_t {
// total block cache misses
@@ -333,7 +332,6 @@ const std::vector<std::pair<Tickers, std::string>> TickersNameMap = {
* Add a new Histogram by assigning it the current value of HISTOGRAM_ENUM_MAX
* Add a string representation in HistogramsNameMap below
* And increment HISTOGRAM_ENUM_MAX
* Add a corresponding enum value to HistogramType.java in the java API
*/
enum Histograms : uint32_t {
DB_GET = 0,
@@ -372,9 +370,6 @@ enum Histograms : uint32_t {
BYTES_DECOMPRESSED,
COMPRESSION_TIMES_NANOS,
DECOMPRESSION_TIMES_NANOS,
// Number of merge operands passed to the merge operator in user read
// requests.
READ_NUM_MERGE_OPERANDS,
HISTOGRAM_ENUM_MAX, // TODO(ldemailly): enforce HistogramsNameMap match
};
@@ -410,7 +405,6 @@ const std::vector<std::pair<Histograms, std::string>> HistogramsNameMap = {
{BYTES_DECOMPRESSED, "rocksdb.bytes.decompressed"},
{COMPRESSION_TIMES_NANOS, "rocksdb.compression.times.nanos"},
{DECOMPRESSION_TIMES_NANOS, "rocksdb.decompression.times.nanos"},
{READ_NUM_MERGE_OPERANDS, "rocksdb.read.num.merge_operands"},
};
struct HistogramData {
+2 -1
View File
@@ -22,7 +22,8 @@
#if !defined(ROCKSDB_LITE) && \
!defined(NROCKSDB_THREAD_STATUS) && \
defined(ROCKSDB_SUPPORT_THREAD_LOCAL)
!defined(OS_MACOSX) && \
!defined(IOS_CROSS_COMPILE)
#define ROCKSDB_USING_THREAD_STATUS
#endif
-1
View File
@@ -29,7 +29,6 @@ class ThreadPool {
// Set the number of background threads that will be executing the
// scheduled jobs.
virtual void SetBackgroundThreads(int num) = 0;
virtual int GetBackgroundThreads() = 0;
// Get the number of jobs scheduled in the ThreadPool queue.
virtual unsigned int GetQueueLen() const = 0;
Loaded 100 of 224 files, more files were not shown because too many files have changed in this diff. Show more