| @ -0,0 +1,18 @@ | |||
| # Run manually to reformat a file: | |||
| # clang-format -i --style=file <file> | |||
| # find . -iname '*.cc' -o -iname '*.h' -o -iname '*.h.in' | xargs clang-format -i --style=file | |||
| BasedOnStyle: Google | |||
| DerivePointerAlignment: false | |||
| # Public headers are in a different location in the internal Google repository. | |||
| # Order them so that when imported to the authoritative repository they will be | |||
| # in correct alphabetical order. | |||
| IncludeCategories: | |||
| - Regex: '^(<|"(benchmarks|db|helpers)/)' | |||
| Priority: 1 | |||
| - Regex: '^"(leveldb)/' | |||
| Priority: 2 | |||
| - Regex: '^(<|"(issues|port|table|third_party|util)/)' | |||
| Priority: 3 | |||
| - Regex: '.*' | |||
| Priority: 4 | |||
| @ -0,0 +1,101 @@ | |||
| # Copyright 2021 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. | |||
| name: ci | |||
| on: [push, pull_request] | |||
| permissions: | |||
| contents: read | |||
| jobs: | |||
| build-and-test: | |||
| name: >- | |||
| CI | |||
| ${{ matrix.os }} | |||
| ${{ matrix.compiler }} | |||
| ${{ matrix.optimized && 'release' || 'debug' }} | |||
| runs-on: ${{ matrix.os }} | |||
| strategy: | |||
| fail-fast: false | |||
| matrix: | |||
| compiler: [clang, gcc, msvc] | |||
| os: [ubuntu-latest, macos-latest, windows-latest] | |||
| optimized: [true, false] | |||
| exclude: | |||
| # MSVC only works on Windows. | |||
| - os: ubuntu-latest | |||
| compiler: msvc | |||
| - os: macos-latest | |||
| compiler: msvc | |||
| # Not testing with GCC on macOS. | |||
| - os: macos-latest | |||
| compiler: gcc | |||
| # Only testing with MSVC on Windows. | |||
| - os: windows-latest | |||
| compiler: clang | |||
| - os: windows-latest | |||
| compiler: gcc | |||
| include: | |||
| - compiler: clang | |||
| CC: clang | |||
| CXX: clang++ | |||
| - compiler: gcc | |||
| CC: gcc | |||
| CXX: g++ | |||
| - compiler: msvc | |||
| CC: | |||
| CXX: | |||
| env: | |||
| CMAKE_BUILD_DIR: ${{ github.workspace }}/build | |||
| CMAKE_BUILD_TYPE: ${{ matrix.optimized && 'RelWithDebInfo' || 'Debug' }} | |||
| CC: ${{ matrix.CC }} | |||
| CXX: ${{ matrix.CXX }} | |||
| BINARY_SUFFIX: ${{ startsWith(matrix.os, 'windows') && '.exe' || '' }} | |||
| BINARY_PATH: >- | |||
| ${{ format( | |||
| startsWith(matrix.os, 'windows') && '{0}\build\{1}\' || '{0}/build/', | |||
| github.workspace, | |||
| matrix.optimized && 'RelWithDebInfo' || 'Debug') }} | |||
| steps: | |||
| - uses: actions/checkout@v2 | |||
| with: | |||
| submodules: true | |||
| - name: Install dependencies on Linux | |||
| if: ${{ runner.os == 'Linux' }} | |||
| run: | | |||
| sudo apt-get update | |||
| sudo apt-get install libgoogle-perftools-dev libkyotocabinet-dev \ | |||
| libsnappy-dev libsqlite3-dev | |||
| - name: Generate build config | |||
| run: >- | |||
| cmake -S "${{ github.workspace }}" -B "${{ env.CMAKE_BUILD_DIR }}" | |||
| -DCMAKE_BUILD_TYPE=${{ env.CMAKE_BUILD_TYPE }} | |||
| -DCMAKE_INSTALL_PREFIX=${{ runner.temp }}/install_test/ | |||
| - name: Build | |||
| run: >- | |||
| cmake --build "${{ env.CMAKE_BUILD_DIR }}" | |||
| --config "${{ env.CMAKE_BUILD_TYPE }}" | |||
| - name: Run Tests | |||
| working-directory: ${{ github.workspace }}/build | |||
| run: ctest -C "${{ env.CMAKE_BUILD_TYPE }}" --verbose | |||
| - name: Run LevelDB Benchmarks | |||
| run: ${{ env.BINARY_PATH }}db_bench${{ env.BINARY_SUFFIX }} | |||
| - name: Run SQLite Benchmarks | |||
| if: ${{ runner.os != 'Windows' }} | |||
| run: ${{ env.BINARY_PATH }}db_bench_sqlite3${{ env.BINARY_SUFFIX }} | |||
| - name: Run Kyoto Cabinet Benchmarks | |||
| if: ${{ runner.os == 'Linux' && matrix.compiler == 'clang' }} | |||
| run: ${{ env.BINARY_PATH }}db_bench_tree_db${{ env.BINARY_SUFFIX }} | |||
| - name: Test CMake installation | |||
| run: cmake --build "${{ env.CMAKE_BUILD_DIR }}" --target install | |||
| @ -1,9 +1,8 @@ | |||
| build_config.mk | |||
| *.a | |||
| *.o | |||
| *.dylib* | |||
| *.so | |||
| *.so.* | |||
| *_test | |||
| db_bench | |||
| leveldbutil | |||
| # Editors. | |||
| *.sw* | |||
| .vscode | |||
| .DS_Store | |||
| # Build directory. | |||
| build/ | |||
| out/ | |||
| @ -0,0 +1,6 @@ | |||
| [submodule "third_party/googletest"] | |||
| path = third_party/googletest | |||
| url = https://github.com/google/googletest.git | |||
| [submodule "third_party/benchmark"] | |||
| path = third_party/benchmark | |||
| url = https://github.com/google/benchmark | |||
| @ -1,13 +0,0 @@ | |||
| language: cpp | |||
| compiler: | |||
| - clang | |||
| - gcc | |||
| os: | |||
| - linux | |||
| - osx | |||
| sudo: false | |||
| before_install: | |||
| - echo $LANG | |||
| - echo $LC_ALL | |||
| script: | |||
| - make -j 4 check | |||
| @ -0,0 +1,515 @@ | |||
| # Copyright 2017 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. | |||
| cmake_minimum_required(VERSION 3.9) | |||
| # Keep the version below in sync with the one in db.h | |||
| project(leveldb VERSION 1.23.0 LANGUAGES C CXX) | |||
| # C standard can be overridden when this is used as a sub-project. | |||
| if(NOT CMAKE_C_STANDARD) | |||
| # This project can use C11, but will gracefully decay down to C89. | |||
| set(CMAKE_C_STANDARD 11) | |||
| set(CMAKE_C_STANDARD_REQUIRED OFF) | |||
| set(CMAKE_C_EXTENSIONS OFF) | |||
| endif(NOT CMAKE_C_STANDARD) | |||
| # C++ standard can be overridden when this is used as a sub-project. | |||
| if(NOT CMAKE_CXX_STANDARD) | |||
| # This project requires C++11. | |||
| set(CMAKE_CXX_STANDARD 11) | |||
| set(CMAKE_CXX_STANDARD_REQUIRED ON) | |||
| set(CMAKE_CXX_EXTENSIONS OFF) | |||
| endif(NOT CMAKE_CXX_STANDARD) | |||
| if (WIN32) | |||
| set(LEVELDB_PLATFORM_NAME LEVELDB_PLATFORM_WINDOWS) | |||
| # TODO(cmumford): Make UNICODE configurable for Windows. | |||
| add_definitions(-D_UNICODE -DUNICODE) | |||
| else (WIN32) | |||
| set(LEVELDB_PLATFORM_NAME LEVELDB_PLATFORM_POSIX) | |||
| endif (WIN32) | |||
| option(LEVELDB_BUILD_TESTS "Build LevelDB's unit tests" ON) | |||
| option(LEVELDB_BUILD_BENCHMARKS "Build LevelDB's benchmarks" ON) | |||
| option(LEVELDB_INSTALL "Install LevelDB's header and library" ON) | |||
| include(CheckIncludeFile) | |||
| check_include_file("unistd.h" HAVE_UNISTD_H) | |||
| include(CheckLibraryExists) | |||
| check_library_exists(crc32c crc32c_value "" HAVE_CRC32C) | |||
| check_library_exists(snappy snappy_compress "" HAVE_SNAPPY) | |||
| check_library_exists(tcmalloc malloc "" HAVE_TCMALLOC) | |||
| include(CheckCXXSymbolExists) | |||
| # Using check_cxx_symbol_exists() instead of check_c_symbol_exists() because | |||
| # we're including the header from C++, and feature detection should use the same | |||
| # compiler language that the project will use later. Principles aside, some | |||
| # versions of do not expose fdatasync() in <unistd.h> in standard C mode | |||
| # (-std=c11), but do expose the function in standard C++ mode (-std=c++11). | |||
| check_cxx_symbol_exists(fdatasync "unistd.h" HAVE_FDATASYNC) | |||
| check_cxx_symbol_exists(F_FULLFSYNC "fcntl.h" HAVE_FULLFSYNC) | |||
| check_cxx_symbol_exists(O_CLOEXEC "fcntl.h" HAVE_O_CLOEXEC) | |||
| if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") | |||
| # Disable C++ exceptions. | |||
| string(REGEX REPLACE "/EH[a-z]+" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") | |||
| set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHs-c-") | |||
| add_definitions(-D_HAS_EXCEPTIONS=0) | |||
| # Disable RTTI. | |||
| string(REGEX REPLACE "/GR" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") | |||
| set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR-") | |||
| else(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") | |||
| # Enable strict prototype warnings for C code in clang and gcc. | |||
| if(NOT CMAKE_C_FLAGS MATCHES "-Wstrict-prototypes") | |||
| set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wstrict-prototypes") | |||
| endif(NOT CMAKE_C_FLAGS MATCHES "-Wstrict-prototypes") | |||
| # Disable C++ exceptions. | |||
| string(REGEX REPLACE "-fexceptions" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") | |||
| set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-exceptions") | |||
| # Disable RTTI. | |||
| string(REGEX REPLACE "-frtti" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") | |||
| set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti") | |||
| endif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") | |||
| # Test whether -Wthread-safety is available. See | |||
| # https://clang.llvm.org/docs/ThreadSafetyAnalysis.html | |||
| include(CheckCXXCompilerFlag) | |||
| check_cxx_compiler_flag(-Wthread-safety HAVE_CLANG_THREAD_SAFETY) | |||
| # Used by googletest. | |||
| check_cxx_compiler_flag(-Wno-missing-field-initializers | |||
| LEVELDB_HAVE_NO_MISSING_FIELD_INITIALIZERS) | |||
| include(CheckCXXSourceCompiles) | |||
| # Test whether C++17 __has_include is available. | |||
| check_cxx_source_compiles(" | |||
| #if defined(__has_include) && __has_include(<string>) | |||
| #include <string> | |||
| #endif | |||
| int main() { std::string str; return 0; } | |||
| " HAVE_CXX17_HAS_INCLUDE) | |||
| set(LEVELDB_PUBLIC_INCLUDE_DIR "include/leveldb") | |||
| set(LEVELDB_PORT_CONFIG_DIR "include/port") | |||
| configure_file( | |||
| "port/port_config.h.in" | |||
| "${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h" | |||
| ) | |||
| include_directories( | |||
| "${PROJECT_BINARY_DIR}/include" | |||
| "." | |||
| ) | |||
| if(BUILD_SHARED_LIBS) | |||
| # Only export LEVELDB_EXPORT symbols from the shared library. | |||
| add_compile_options(-fvisibility=hidden) | |||
| endif(BUILD_SHARED_LIBS) | |||
| # Must be included before CMAKE_INSTALL_INCLUDEDIR is used. | |||
| include(GNUInstallDirs) | |||
| add_library(leveldb "") | |||
| target_sources(leveldb | |||
| PRIVATE | |||
| "${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h" | |||
| "db/builder.cc" | |||
| "db/builder.h" | |||
| "db/c.cc" | |||
| "db/db_impl.cc" | |||
| "db/db_impl.h" | |||
| "db/db_iter.cc" | |||
| "db/db_iter.h" | |||
| "db/dbformat.cc" | |||
| "db/dbformat.h" | |||
| "db/dumpfile.cc" | |||
| "db/filename.cc" | |||
| "db/filename.h" | |||
| "db/log_format.h" | |||
| "db/log_reader.cc" | |||
| "db/log_reader.h" | |||
| "db/log_writer.cc" | |||
| "db/log_writer.h" | |||
| "db/memtable.cc" | |||
| "db/memtable.h" | |||
| "db/repair.cc" | |||
| "db/skiplist.h" | |||
| "db/snapshot.h" | |||
| "db/table_cache.cc" | |||
| "db/table_cache.h" | |||
| "db/version_edit.cc" | |||
| "db/version_edit.h" | |||
| "db/version_set.cc" | |||
| "db/version_set.h" | |||
| "db/write_batch_internal.h" | |||
| "db/write_batch.cc" | |||
| "port/port_stdcxx.h" | |||
| "port/port.h" | |||
| "port/thread_annotations.h" | |||
| "table/block_builder.cc" | |||
| "table/block_builder.h" | |||
| "table/block.cc" | |||
| "table/block.h" | |||
| "table/filter_block.cc" | |||
| "table/filter_block.h" | |||
| "table/format.cc" | |||
| "table/format.h" | |||
| "table/iterator_wrapper.h" | |||
| "table/iterator.cc" | |||
| "table/merger.cc" | |||
| "table/merger.h" | |||
| "table/table_builder.cc" | |||
| "table/table.cc" | |||
| "table/two_level_iterator.cc" | |||
| "table/two_level_iterator.h" | |||
| "util/arena.cc" | |||
| "util/arena.h" | |||
| "util/bloom.cc" | |||
| "util/cache.cc" | |||
| "util/coding.cc" | |||
| "util/coding.h" | |||
| "util/comparator.cc" | |||
| "util/crc32c.cc" | |||
| "util/crc32c.h" | |||
| "util/env.cc" | |||
| "util/filter_policy.cc" | |||
| "util/hash.cc" | |||
| "util/hash.h" | |||
| "util/logging.cc" | |||
| "util/logging.h" | |||
| "util/mutexlock.h" | |||
| "util/no_destructor.h" | |||
| "util/options.cc" | |||
| "util/random.h" | |||
| "util/status.cc" | |||
| # Only CMake 3.3+ supports PUBLIC sources in targets exported by "install". | |||
| $<$<VERSION_GREATER:CMAKE_VERSION,3.2>:PUBLIC> | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/c.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/cache.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/comparator.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/db.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/dumpfile.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/env.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/export.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/filter_policy.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/iterator.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/options.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/slice.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/status.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/table_builder.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/table.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/write_batch.h" | |||
| ) | |||
| if (WIN32) | |||
| target_sources(leveldb | |||
| PRIVATE | |||
| "util/env_windows.cc" | |||
| "util/windows_logger.h" | |||
| ) | |||
| else (WIN32) | |||
| target_sources(leveldb | |||
| PRIVATE | |||
| "util/env_posix.cc" | |||
| "util/posix_logger.h" | |||
| ) | |||
| endif (WIN32) | |||
| # MemEnv is not part of the interface and could be pulled to a separate library. | |||
| target_sources(leveldb | |||
| PRIVATE | |||
| "helpers/memenv/memenv.cc" | |||
| "helpers/memenv/memenv.h" | |||
| ) | |||
| target_include_directories(leveldb | |||
| PUBLIC | |||
| $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include> | |||
| $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> | |||
| ) | |||
| set_target_properties(leveldb | |||
| PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR}) | |||
| target_compile_definitions(leveldb | |||
| PRIVATE | |||
| # Used by include/export.h when building shared libraries. | |||
| LEVELDB_COMPILE_LIBRARY | |||
| # Used by port/port.h. | |||
| ${LEVELDB_PLATFORM_NAME}=1 | |||
| ) | |||
| if (NOT HAVE_CXX17_HAS_INCLUDE) | |||
| target_compile_definitions(leveldb | |||
| PRIVATE | |||
| LEVELDB_HAS_PORT_CONFIG_H=1 | |||
| ) | |||
| endif(NOT HAVE_CXX17_HAS_INCLUDE) | |||
| if(BUILD_SHARED_LIBS) | |||
| target_compile_definitions(leveldb | |||
| PUBLIC | |||
| # Used by include/export.h. | |||
| LEVELDB_SHARED_LIBRARY | |||
| ) | |||
| endif(BUILD_SHARED_LIBS) | |||
| if(HAVE_CLANG_THREAD_SAFETY) | |||
| target_compile_options(leveldb | |||
| PUBLIC | |||
| -Werror -Wthread-safety) | |||
| endif(HAVE_CLANG_THREAD_SAFETY) | |||
| if(HAVE_CRC32C) | |||
| target_link_libraries(leveldb crc32c) | |||
| endif(HAVE_CRC32C) | |||
| if(HAVE_SNAPPY) | |||
| target_link_libraries(leveldb snappy) | |||
| endif(HAVE_SNAPPY) | |||
| if(HAVE_TCMALLOC) | |||
| target_link_libraries(leveldb tcmalloc) | |||
| endif(HAVE_TCMALLOC) | |||
| # Needed by port_stdcxx.h | |||
| find_package(Threads REQUIRED) | |||
| target_link_libraries(leveldb Threads::Threads) | |||
| add_executable(leveldbutil | |||
| "db/leveldbutil.cc" | |||
| ) | |||
| target_link_libraries(leveldbutil leveldb) | |||
| if(LEVELDB_BUILD_TESTS) | |||
| enable_testing() | |||
| # Prevent overriding the parent project's compiler/linker settings on Windows. | |||
| set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) | |||
| set(install_gtest OFF) | |||
| set(install_gmock OFF) | |||
| set(build_gmock ON) | |||
| # This project is tested using GoogleTest. | |||
| add_subdirectory("third_party/googletest") | |||
| # GoogleTest triggers a missing field initializers warning. | |||
| if(LEVELDB_HAVE_NO_MISSING_FIELD_INITIALIZERS) | |||
| set_property(TARGET gtest | |||
| APPEND PROPERTY COMPILE_OPTIONS -Wno-missing-field-initializers) | |||
| set_property(TARGET gmock | |||
| APPEND PROPERTY COMPILE_OPTIONS -Wno-missing-field-initializers) | |||
| endif(LEVELDB_HAVE_NO_MISSING_FIELD_INITIALIZERS) | |||
| add_executable(leveldb_tests "") | |||
| target_sources(leveldb_tests | |||
| PRIVATE | |||
| # "db/fault_injection_test.cc" | |||
| # "issues/issue178_test.cc" | |||
| # "issues/issue200_test.cc" | |||
| # "issues/issue320_test.cc" | |||
| "${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h" | |||
| # "util/env_test.cc" | |||
| "util/status_test.cc" | |||
| "util/no_destructor_test.cc" | |||
| "util/testutil.cc" | |||
| "util/testutil.h" | |||
| ) | |||
| if(NOT BUILD_SHARED_LIBS) | |||
| target_sources(leveldb_tests | |||
| PRIVATE | |||
| "db/autocompact_test.cc" | |||
| "db/corruption_test.cc" | |||
| "db/db_test.cc" | |||
| "db/dbformat_test.cc" | |||
| "db/filename_test.cc" | |||
| "db/log_test.cc" | |||
| "db/recovery_test.cc" | |||
| "db/skiplist_test.cc" | |||
| "db/version_edit_test.cc" | |||
| "db/version_set_test.cc" | |||
| "db/write_batch_test.cc" | |||
| "helpers/memenv/memenv_test.cc" | |||
| "table/filter_block_test.cc" | |||
| "table/table_test.cc" | |||
| "util/arena_test.cc" | |||
| "util/bloom_test.cc" | |||
| "util/cache_test.cc" | |||
| "util/coding_test.cc" | |||
| "util/crc32c_test.cc" | |||
| "util/hash_test.cc" | |||
| "util/logging_test.cc" | |||
| ) | |||
| endif(NOT BUILD_SHARED_LIBS) | |||
| target_link_libraries(leveldb_tests leveldb gmock gtest gtest_main) | |||
| target_compile_definitions(leveldb_tests | |||
| PRIVATE | |||
| ${LEVELDB_PLATFORM_NAME}=1 | |||
| ) | |||
| if (NOT HAVE_CXX17_HAS_INCLUDE) | |||
| target_compile_definitions(leveldb_tests | |||
| PRIVATE | |||
| LEVELDB_HAS_PORT_CONFIG_H=1 | |||
| ) | |||
| endif(NOT HAVE_CXX17_HAS_INCLUDE) | |||
| add_test(NAME "leveldb_tests" COMMAND "leveldb_tests") | |||
| function(leveldb_test test_file) | |||
| get_filename_component(test_target_name "${test_file}" NAME_WE) | |||
| add_executable("${test_target_name}" "") | |||
| target_sources("${test_target_name}" | |||
| PRIVATE | |||
| "${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h" | |||
| "util/testutil.cc" | |||
| "util/testutil.h" | |||
| "${test_file}" | |||
| ) | |||
| target_link_libraries("${test_target_name}" leveldb gmock gtest) | |||
| target_compile_definitions("${test_target_name}" | |||
| PRIVATE | |||
| ${LEVELDB_PLATFORM_NAME}=1 | |||
| ) | |||
| if (NOT HAVE_CXX17_HAS_INCLUDE) | |||
| target_compile_definitions("${test_target_name}" | |||
| PRIVATE | |||
| LEVELDB_HAS_PORT_CONFIG_H=1 | |||
| ) | |||
| endif(NOT HAVE_CXX17_HAS_INCLUDE) | |||
| add_test(NAME "${test_target_name}" COMMAND "${test_target_name}") | |||
| endfunction(leveldb_test) | |||
| leveldb_test("db/c_test.c") | |||
| if(NOT BUILD_SHARED_LIBS) | |||
| # TODO(costan): This test also uses | |||
| # "util/env_{posix|windows}_test_helper.h" | |||
| if (WIN32) | |||
| leveldb_test("util/env_windows_test.cc") | |||
| else (WIN32) | |||
| leveldb_test("util/env_posix_test.cc") | |||
| endif (WIN32) | |||
| endif(NOT BUILD_SHARED_LIBS) | |||
| endif(LEVELDB_BUILD_TESTS) | |||
| if(LEVELDB_BUILD_BENCHMARKS) | |||
| # This project uses Google benchmark for benchmarking. | |||
| set(BENCHMARK_ENABLE_TESTING OFF CACHE BOOL "" FORCE) | |||
| set(BENCHMARK_ENABLE_EXCEPTIONS OFF CACHE BOOL "" FORCE) | |||
| add_subdirectory("third_party/benchmark") | |||
| function(leveldb_benchmark bench_file) | |||
| get_filename_component(bench_target_name "${bench_file}" NAME_WE) | |||
| add_executable("${bench_target_name}" "") | |||
| target_sources("${bench_target_name}" | |||
| PRIVATE | |||
| "${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h" | |||
| "util/histogram.cc" | |||
| "util/histogram.h" | |||
| "util/testutil.cc" | |||
| "util/testutil.h" | |||
| "${bench_file}" | |||
| ) | |||
| target_link_libraries("${bench_target_name}" leveldb gmock gtest benchmark) | |||
| target_compile_definitions("${bench_target_name}" | |||
| PRIVATE | |||
| ${LEVELDB_PLATFORM_NAME}=1 | |||
| ) | |||
| if (NOT HAVE_CXX17_HAS_INCLUDE) | |||
| target_compile_definitions("${bench_target_name}" | |||
| PRIVATE | |||
| LEVELDB_HAS_PORT_CONFIG_H=1 | |||
| ) | |||
| endif(NOT HAVE_CXX17_HAS_INCLUDE) | |||
| endfunction(leveldb_benchmark) | |||
| if(NOT BUILD_SHARED_LIBS) | |||
| leveldb_benchmark("benchmarks/db_bench.cc") | |||
| endif(NOT BUILD_SHARED_LIBS) | |||
| check_library_exists(sqlite3 sqlite3_open "" HAVE_SQLITE3) | |||
| if(HAVE_SQLITE3) | |||
| leveldb_benchmark("benchmarks/db_bench_sqlite3.cc") | |||
| target_link_libraries(db_bench_sqlite3 sqlite3) | |||
| endif(HAVE_SQLITE3) | |||
| # check_library_exists is insufficient here because the library names have | |||
| # different manglings when compiled with clang or gcc, at least when installed | |||
| # with Homebrew on Mac. | |||
| set(OLD_CMAKE_REQURED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES}) | |||
| list(APPEND CMAKE_REQUIRED_LIBRARIES kyotocabinet) | |||
| check_cxx_source_compiles(" | |||
| #include <kcpolydb.h> | |||
| int main() { | |||
| kyotocabinet::TreeDB* db = new kyotocabinet::TreeDB(); | |||
| delete db; | |||
| return 0; | |||
| } | |||
| " HAVE_KYOTOCABINET) | |||
| set(CMAKE_REQUIRED_LIBRARIES ${OLD_CMAKE_REQURED_LIBRARIES}) | |||
| if(HAVE_KYOTOCABINET) | |||
| leveldb_benchmark("benchmarks/db_bench_tree_db.cc") | |||
| target_link_libraries(db_bench_tree_db kyotocabinet) | |||
| endif(HAVE_KYOTOCABINET) | |||
| endif(LEVELDB_BUILD_BENCHMARKS) | |||
| if(LEVELDB_INSTALL) | |||
| install(TARGETS leveldb | |||
| EXPORT leveldbTargets | |||
| RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} | |||
| LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} | |||
| ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} | |||
| ) | |||
| install( | |||
| FILES | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/c.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/cache.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/comparator.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/db.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/dumpfile.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/env.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/export.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/filter_policy.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/iterator.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/options.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/slice.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/status.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/table_builder.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/table.h" | |||
| "${LEVELDB_PUBLIC_INCLUDE_DIR}/write_batch.h" | |||
| DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/leveldb" | |||
| ) | |||
| include(CMakePackageConfigHelpers) | |||
| configure_package_config_file( | |||
| "cmake/${PROJECT_NAME}Config.cmake.in" | |||
| "${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}Config.cmake" | |||
| INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" | |||
| ) | |||
| write_basic_package_version_file( | |||
| "${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}ConfigVersion.cmake" | |||
| COMPATIBILITY SameMajorVersion | |||
| ) | |||
| install( | |||
| EXPORT leveldbTargets | |||
| NAMESPACE leveldb:: | |||
| DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" | |||
| ) | |||
| install( | |||
| FILES | |||
| "${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}Config.cmake" | |||
| "${PROJECT_BINARY_DIR}/cmake/${PROJECT_NAME}ConfigVersion.cmake" | |||
| DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" | |||
| ) | |||
| endif(LEVELDB_INSTALL) | |||
| @ -1,424 +0,0 @@ | |||
| # 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. | |||
| #----------------------------------------------- | |||
| # Uncomment exactly one of the lines labelled (A), (B), and (C) below | |||
| # to switch between compilation modes. | |||
| # (A) Production use (optimized mode) | |||
| OPT ?= -O2 -DNDEBUG | |||
| # (B) Debug mode, w/ full line-level debugging symbols | |||
| # OPT ?= -g2 | |||
| # (C) Profiling mode: opt, but w/debugging symbols | |||
| # OPT ?= -O2 -g2 -DNDEBUG | |||
| #----------------------------------------------- | |||
| # detect what platform we're building on | |||
| $(shell CC="$(CC)" CXX="$(CXX)" TARGET_OS="$(TARGET_OS)" \ | |||
| ./build_detect_platform build_config.mk ./) | |||
| # this file is generated by the previous line to set build flags and sources | |||
| include build_config.mk | |||
| TESTS = \ | |||
| db/autocompact_test \ | |||
| db/c_test \ | |||
| db/corruption_test \ | |||
| db/db_test \ | |||
| db/dbformat_test \ | |||
| db/fault_injection_test \ | |||
| db/filename_test \ | |||
| db/log_test \ | |||
| db/recovery_test \ | |||
| db/skiplist_test \ | |||
| db/version_edit_test \ | |||
| db/version_set_test \ | |||
| db/write_batch_test \ | |||
| helpers/memenv/memenv_test \ | |||
| issues/issue178_test \ | |||
| issues/issue200_test \ | |||
| table/filter_block_test \ | |||
| table/table_test \ | |||
| util/arena_test \ | |||
| util/bloom_test \ | |||
| util/cache_test \ | |||
| util/coding_test \ | |||
| util/crc32c_test \ | |||
| util/env_posix_test \ | |||
| util/env_test \ | |||
| util/hash_test | |||
| UTILS = \ | |||
| db/db_bench \ | |||
| db/leveldbutil | |||
| # Put the object files in a subdirectory, but the application at the top of the object dir. | |||
| PROGNAMES := $(notdir $(TESTS) $(UTILS)) | |||
| # On Linux may need libkyotocabinet-dev for dependency. | |||
| BENCHMARKS = \ | |||
| doc/bench/db_bench_sqlite3 \ | |||
| doc/bench/db_bench_tree_db | |||
| CFLAGS += -I. -I./include $(PLATFORM_CCFLAGS) $(OPT) | |||
| CXXFLAGS += -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT) | |||
| LDFLAGS += $(PLATFORM_LDFLAGS) | |||
| LIBS += $(PLATFORM_LIBS) | |||
| SIMULATOR_OUTDIR=out-ios-x86 | |||
| DEVICE_OUTDIR=out-ios-arm | |||
| ifeq ($(PLATFORM), IOS) | |||
| # Note: iOS should probably be using libtool, not ar. | |||
| AR=xcrun ar | |||
| SIMULATORSDK=$(shell xcrun -sdk iphonesimulator --show-sdk-path) | |||
| DEVICESDK=$(shell xcrun -sdk iphoneos --show-sdk-path) | |||
| DEVICE_CFLAGS = -isysroot "$(DEVICESDK)" -arch armv6 -arch armv7 -arch armv7s -arch arm64 | |||
| SIMULATOR_CFLAGS = -isysroot "$(SIMULATORSDK)" -arch i686 -arch x86_64 | |||
| STATIC_OUTDIR=out-ios-universal | |||
| else | |||
| STATIC_OUTDIR=out-static | |||
| SHARED_OUTDIR=out-shared | |||
| STATIC_PROGRAMS := $(addprefix $(STATIC_OUTDIR)/, $(PROGNAMES)) | |||
| SHARED_PROGRAMS := $(addprefix $(SHARED_OUTDIR)/, db_bench) | |||
| endif | |||
| STATIC_LIBOBJECTS := $(addprefix $(STATIC_OUTDIR)/, $(SOURCES:.cc=.o)) | |||
| STATIC_MEMENVOBJECTS := $(addprefix $(STATIC_OUTDIR)/, $(MEMENV_SOURCES:.cc=.o)) | |||
| DEVICE_LIBOBJECTS := $(addprefix $(DEVICE_OUTDIR)/, $(SOURCES:.cc=.o)) | |||
| DEVICE_MEMENVOBJECTS := $(addprefix $(DEVICE_OUTDIR)/, $(MEMENV_SOURCES:.cc=.o)) | |||
| SIMULATOR_LIBOBJECTS := $(addprefix $(SIMULATOR_OUTDIR)/, $(SOURCES:.cc=.o)) | |||
| SIMULATOR_MEMENVOBJECTS := $(addprefix $(SIMULATOR_OUTDIR)/, $(MEMENV_SOURCES:.cc=.o)) | |||
| SHARED_LIBOBJECTS := $(addprefix $(SHARED_OUTDIR)/, $(SOURCES:.cc=.o)) | |||
| SHARED_MEMENVOBJECTS := $(addprefix $(SHARED_OUTDIR)/, $(MEMENV_SOURCES:.cc=.o)) | |||
| TESTUTIL := $(STATIC_OUTDIR)/util/testutil.o | |||
| TESTHARNESS := $(STATIC_OUTDIR)/util/testharness.o $(TESTUTIL) | |||
| STATIC_TESTOBJS := $(addprefix $(STATIC_OUTDIR)/, $(addsuffix .o, $(TESTS))) | |||
| STATIC_UTILOBJS := $(addprefix $(STATIC_OUTDIR)/, $(addsuffix .o, $(UTILS))) | |||
| STATIC_ALLOBJS := $(STATIC_LIBOBJECTS) $(STATIC_MEMENVOBJECTS) $(STATIC_TESTOBJS) $(STATIC_UTILOBJS) $(TESTHARNESS) | |||
| DEVICE_ALLOBJS := $(DEVICE_LIBOBJECTS) $(DEVICE_MEMENVOBJECTS) | |||
| SIMULATOR_ALLOBJS := $(SIMULATOR_LIBOBJECTS) $(SIMULATOR_MEMENVOBJECTS) | |||
| default: all | |||
| # Should we build shared libraries? | |||
| ifneq ($(PLATFORM_SHARED_EXT),) | |||
| # Many leveldb test apps use non-exported API's. Only build a subset for testing. | |||
| SHARED_ALLOBJS := $(SHARED_LIBOBJECTS) $(SHARED_MEMENVOBJECTS) $(TESTHARNESS) | |||
| ifneq ($(PLATFORM_SHARED_VERSIONED),true) | |||
| SHARED_LIB1 = libleveldb.$(PLATFORM_SHARED_EXT) | |||
| SHARED_LIB2 = $(SHARED_LIB1) | |||
| SHARED_LIB3 = $(SHARED_LIB1) | |||
| SHARED_LIBS = $(SHARED_LIB1) | |||
| SHARED_MEMENVLIB = $(SHARED_OUTDIR)/libmemenv.a | |||
| else | |||
| # Update db.h if you change these. | |||
| SHARED_VERSION_MAJOR = 1 | |||
| SHARED_VERSION_MINOR = 20 | |||
| SHARED_LIB1 = libleveldb.$(PLATFORM_SHARED_EXT) | |||
| SHARED_LIB2 = $(SHARED_LIB1).$(SHARED_VERSION_MAJOR) | |||
| SHARED_LIB3 = $(SHARED_LIB1).$(SHARED_VERSION_MAJOR).$(SHARED_VERSION_MINOR) | |||
| SHARED_LIBS = $(SHARED_OUTDIR)/$(SHARED_LIB1) $(SHARED_OUTDIR)/$(SHARED_LIB2) $(SHARED_OUTDIR)/$(SHARED_LIB3) | |||
| $(SHARED_OUTDIR)/$(SHARED_LIB1): $(SHARED_OUTDIR)/$(SHARED_LIB3) | |||
| ln -fs $(SHARED_LIB3) $(SHARED_OUTDIR)/$(SHARED_LIB1) | |||
| $(SHARED_OUTDIR)/$(SHARED_LIB2): $(SHARED_OUTDIR)/$(SHARED_LIB3) | |||
| ln -fs $(SHARED_LIB3) $(SHARED_OUTDIR)/$(SHARED_LIB2) | |||
| SHARED_MEMENVLIB = $(SHARED_OUTDIR)/libmemenv.a | |||
| endif | |||
| $(SHARED_OUTDIR)/$(SHARED_LIB3): $(SHARED_LIBOBJECTS) | |||
| $(CXX) $(LDFLAGS) $(PLATFORM_SHARED_LDFLAGS)$(SHARED_LIB2) $(SHARED_LIBOBJECTS) -o $(SHARED_OUTDIR)/$(SHARED_LIB3) $(LIBS) | |||
| endif # PLATFORM_SHARED_EXT | |||
| all: $(SHARED_LIBS) $(SHARED_PROGRAMS) $(STATIC_OUTDIR)/libleveldb.a $(STATIC_OUTDIR)/libmemenv.a $(STATIC_PROGRAMS) | |||
| check: $(STATIC_PROGRAMS) | |||
| for t in $(notdir $(TESTS)); do echo "***** Running $$t"; $(STATIC_OUTDIR)/$$t || exit 1; done | |||
| clean: | |||
| -rm -rf out-static out-shared out-ios-x86 out-ios-arm out-ios-universal | |||
| -rm -f build_config.mk | |||
| -rm -rf ios-x86 ios-arm | |||
| $(STATIC_OUTDIR): | |||
| mkdir $@ | |||
| $(STATIC_OUTDIR)/db: | $(STATIC_OUTDIR) | |||
| mkdir $@ | |||
| $(STATIC_OUTDIR)/helpers/memenv: | $(STATIC_OUTDIR) | |||
| mkdir -p $@ | |||
| $(STATIC_OUTDIR)/port: | $(STATIC_OUTDIR) | |||
| mkdir $@ | |||
| $(STATIC_OUTDIR)/table: | $(STATIC_OUTDIR) | |||
| mkdir $@ | |||
| $(STATIC_OUTDIR)/util: | $(STATIC_OUTDIR) | |||
| mkdir $@ | |||
| .PHONY: STATIC_OBJDIRS | |||
| STATIC_OBJDIRS: \ | |||
| $(STATIC_OUTDIR)/db \ | |||
| $(STATIC_OUTDIR)/port \ | |||
| $(STATIC_OUTDIR)/table \ | |||
| $(STATIC_OUTDIR)/util \ | |||
| $(STATIC_OUTDIR)/helpers/memenv | |||
| $(SHARED_OUTDIR): | |||
| mkdir $@ | |||
| $(SHARED_OUTDIR)/db: | $(SHARED_OUTDIR) | |||
| mkdir $@ | |||
| $(SHARED_OUTDIR)/helpers/memenv: | $(SHARED_OUTDIR) | |||
| mkdir -p $@ | |||
| $(SHARED_OUTDIR)/port: | $(SHARED_OUTDIR) | |||
| mkdir $@ | |||
| $(SHARED_OUTDIR)/table: | $(SHARED_OUTDIR) | |||
| mkdir $@ | |||
| $(SHARED_OUTDIR)/util: | $(SHARED_OUTDIR) | |||
| mkdir $@ | |||
| .PHONY: SHARED_OBJDIRS | |||
| SHARED_OBJDIRS: \ | |||
| $(SHARED_OUTDIR)/db \ | |||
| $(SHARED_OUTDIR)/port \ | |||
| $(SHARED_OUTDIR)/table \ | |||
| $(SHARED_OUTDIR)/util \ | |||
| $(SHARED_OUTDIR)/helpers/memenv | |||
| $(DEVICE_OUTDIR): | |||
| mkdir $@ | |||
| $(DEVICE_OUTDIR)/db: | $(DEVICE_OUTDIR) | |||
| mkdir $@ | |||
| $(DEVICE_OUTDIR)/helpers/memenv: | $(DEVICE_OUTDIR) | |||
| mkdir -p $@ | |||
| $(DEVICE_OUTDIR)/port: | $(DEVICE_OUTDIR) | |||
| mkdir $@ | |||
| $(DEVICE_OUTDIR)/table: | $(DEVICE_OUTDIR) | |||
| mkdir $@ | |||
| $(DEVICE_OUTDIR)/util: | $(DEVICE_OUTDIR) | |||
| mkdir $@ | |||
| .PHONY: DEVICE_OBJDIRS | |||
| DEVICE_OBJDIRS: \ | |||
| $(DEVICE_OUTDIR)/db \ | |||
| $(DEVICE_OUTDIR)/port \ | |||
| $(DEVICE_OUTDIR)/table \ | |||
| $(DEVICE_OUTDIR)/util \ | |||
| $(DEVICE_OUTDIR)/helpers/memenv | |||
| $(SIMULATOR_OUTDIR): | |||
| mkdir $@ | |||
| $(SIMULATOR_OUTDIR)/db: | $(SIMULATOR_OUTDIR) | |||
| mkdir $@ | |||
| $(SIMULATOR_OUTDIR)/helpers/memenv: | $(SIMULATOR_OUTDIR) | |||
| mkdir -p $@ | |||
| $(SIMULATOR_OUTDIR)/port: | $(SIMULATOR_OUTDIR) | |||
| mkdir $@ | |||
| $(SIMULATOR_OUTDIR)/table: | $(SIMULATOR_OUTDIR) | |||
| mkdir $@ | |||
| $(SIMULATOR_OUTDIR)/util: | $(SIMULATOR_OUTDIR) | |||
| mkdir $@ | |||
| .PHONY: SIMULATOR_OBJDIRS | |||
| SIMULATOR_OBJDIRS: \ | |||
| $(SIMULATOR_OUTDIR)/db \ | |||
| $(SIMULATOR_OUTDIR)/port \ | |||
| $(SIMULATOR_OUTDIR)/table \ | |||
| $(SIMULATOR_OUTDIR)/util \ | |||
| $(SIMULATOR_OUTDIR)/helpers/memenv | |||
| $(STATIC_ALLOBJS): | STATIC_OBJDIRS | |||
| $(DEVICE_ALLOBJS): | DEVICE_OBJDIRS | |||
| $(SIMULATOR_ALLOBJS): | SIMULATOR_OBJDIRS | |||
| $(SHARED_ALLOBJS): | SHARED_OBJDIRS | |||
| ifeq ($(PLATFORM), IOS) | |||
| $(DEVICE_OUTDIR)/libleveldb.a: $(DEVICE_LIBOBJECTS) | |||
| rm -f $@ | |||
| $(AR) -rs $@ $(DEVICE_LIBOBJECTS) | |||
| $(SIMULATOR_OUTDIR)/libleveldb.a: $(SIMULATOR_LIBOBJECTS) | |||
| rm -f $@ | |||
| $(AR) -rs $@ $(SIMULATOR_LIBOBJECTS) | |||
| $(DEVICE_OUTDIR)/libmemenv.a: $(DEVICE_MEMENVOBJECTS) | |||
| rm -f $@ | |||
| $(AR) -rs $@ $(DEVICE_MEMENVOBJECTS) | |||
| $(SIMULATOR_OUTDIR)/libmemenv.a: $(SIMULATOR_MEMENVOBJECTS) | |||
| rm -f $@ | |||
| $(AR) -rs $@ $(SIMULATOR_MEMENVOBJECTS) | |||
| # For iOS, create universal object libraries to be used on both the simulator and | |||
| # a device. | |||
| $(STATIC_OUTDIR)/libleveldb.a: $(STATIC_OUTDIR) $(DEVICE_OUTDIR)/libleveldb.a $(SIMULATOR_OUTDIR)/libleveldb.a | |||
| lipo -create $(DEVICE_OUTDIR)/libleveldb.a $(SIMULATOR_OUTDIR)/libleveldb.a -output $@ | |||
| $(STATIC_OUTDIR)/libmemenv.a: $(STATIC_OUTDIR) $(DEVICE_OUTDIR)/libmemenv.a $(SIMULATOR_OUTDIR)/libmemenv.a | |||
| lipo -create $(DEVICE_OUTDIR)/libmemenv.a $(SIMULATOR_OUTDIR)/libmemenv.a -output $@ | |||
| else | |||
| $(STATIC_OUTDIR)/libleveldb.a:$(STATIC_LIBOBJECTS) | |||
| rm -f $@ | |||
| $(AR) -rs $@ $(STATIC_LIBOBJECTS) | |||
| $(STATIC_OUTDIR)/libmemenv.a:$(STATIC_MEMENVOBJECTS) | |||
| rm -f $@ | |||
| $(AR) -rs $@ $(STATIC_MEMENVOBJECTS) | |||
| endif | |||
| $(SHARED_MEMENVLIB):$(SHARED_MEMENVOBJECTS) | |||
| rm -f $@ | |||
| $(AR) -rs $@ $(SHARED_MEMENVOBJECTS) | |||
| $(STATIC_OUTDIR)/db_bench:db/db_bench.cc $(STATIC_LIBOBJECTS) $(TESTUTIL) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) db/db_bench.cc $(STATIC_LIBOBJECTS) $(TESTUTIL) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/db_bench_sqlite3:doc/bench/db_bench_sqlite3.cc $(STATIC_LIBOBJECTS) $(TESTUTIL) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) doc/bench/db_bench_sqlite3.cc $(STATIC_LIBOBJECTS) $(TESTUTIL) -o $@ -lsqlite3 $(LIBS) | |||
| $(STATIC_OUTDIR)/db_bench_tree_db:doc/bench/db_bench_tree_db.cc $(STATIC_LIBOBJECTS) $(TESTUTIL) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) doc/bench/db_bench_tree_db.cc $(STATIC_LIBOBJECTS) $(TESTUTIL) -o $@ -lkyotocabinet $(LIBS) | |||
| $(STATIC_OUTDIR)/leveldbutil:db/leveldbutil.cc $(STATIC_LIBOBJECTS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) db/leveldbutil.cc $(STATIC_LIBOBJECTS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/arena_test:util/arena_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) util/arena_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/autocompact_test:db/autocompact_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) db/autocompact_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/bloom_test:util/bloom_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) util/bloom_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/c_test:$(STATIC_OUTDIR)/db/c_test.o $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(STATIC_OUTDIR)/db/c_test.o $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/cache_test:util/cache_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) util/cache_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/coding_test:util/coding_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) util/coding_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/corruption_test:db/corruption_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) db/corruption_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/crc32c_test:util/crc32c_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) util/crc32c_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/db_test:db/db_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) db/db_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/dbformat_test:db/dbformat_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) db/dbformat_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/env_posix_test:util/env_posix_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) util/env_posix_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/env_test:util/env_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) util/env_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/fault_injection_test:db/fault_injection_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) db/fault_injection_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/filename_test:db/filename_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) db/filename_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/filter_block_test:table/filter_block_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) table/filter_block_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/hash_test:util/hash_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) util/hash_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/issue178_test:issues/issue178_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) issues/issue178_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/issue200_test:issues/issue200_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) issues/issue200_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/log_test:db/log_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) db/log_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/recovery_test:db/recovery_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) db/recovery_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/table_test:table/table_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) table/table_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/skiplist_test:db/skiplist_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) db/skiplist_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/version_edit_test:db/version_edit_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) db/version_edit_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/version_set_test:db/version_set_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) db/version_set_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/write_batch_test:db/write_batch_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) | |||
| $(CXX) $(LDFLAGS) $(CXXFLAGS) db/write_batch_test.cc $(STATIC_LIBOBJECTS) $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(STATIC_OUTDIR)/memenv_test:$(STATIC_OUTDIR)/helpers/memenv/memenv_test.o $(STATIC_OUTDIR)/libmemenv.a $(STATIC_OUTDIR)/libleveldb.a $(TESTHARNESS) | |||
| $(XCRUN) $(CXX) $(LDFLAGS) $(STATIC_OUTDIR)/helpers/memenv/memenv_test.o $(STATIC_OUTDIR)/libmemenv.a $(STATIC_OUTDIR)/libleveldb.a $(TESTHARNESS) -o $@ $(LIBS) | |||
| $(SHARED_OUTDIR)/db_bench:$(SHARED_OUTDIR)/db/db_bench.o $(SHARED_LIBS) $(TESTUTIL) | |||
| $(XCRUN) $(CXX) $(LDFLAGS) $(CXXFLAGS) $(PLATFORM_SHARED_CFLAGS) $(SHARED_OUTDIR)/db/db_bench.o $(TESTUTIL) $(SHARED_OUTDIR)/$(SHARED_LIB3) -o $@ $(LIBS) | |||
| .PHONY: run-shared | |||
| run-shared: $(SHARED_OUTDIR)/db_bench | |||
| LD_LIBRARY_PATH=$(SHARED_OUTDIR) $(SHARED_OUTDIR)/db_bench | |||
| $(SIMULATOR_OUTDIR)/%.o: %.cc | |||
| xcrun -sdk iphonesimulator $(CXX) $(CXXFLAGS) $(SIMULATOR_CFLAGS) -c $< -o $@ | |||
| $(DEVICE_OUTDIR)/%.o: %.cc | |||
| xcrun -sdk iphoneos $(CXX) $(CXXFLAGS) $(DEVICE_CFLAGS) -c $< -o $@ | |||
| $(SIMULATOR_OUTDIR)/%.o: %.c | |||
| xcrun -sdk iphonesimulator $(CC) $(CFLAGS) $(SIMULATOR_CFLAGS) -c $< -o $@ | |||
| $(DEVICE_OUTDIR)/%.o: %.c | |||
| xcrun -sdk iphoneos $(CC) $(CFLAGS) $(DEVICE_CFLAGS) -c $< -o $@ | |||
| $(STATIC_OUTDIR)/%.o: %.cc | |||
| $(CXX) $(CXXFLAGS) -c $< -o $@ | |||
| $(STATIC_OUTDIR)/%.o: %.c | |||
| $(CC) $(CFLAGS) -c $< -o $@ | |||
| $(SHARED_OUTDIR)/%.o: %.cc | |||
| $(CXX) $(CXXFLAGS) $(PLATFORM_SHARED_CFLAGS) -c $< -o $@ | |||
| $(SHARED_OUTDIR)/%.o: %.c | |||
| $(CC) $(CFLAGS) $(PLATFORM_SHARED_CFLAGS) -c $< -o $@ | |||
| $(STATIC_OUTDIR)/port/port_posix_sse.o: port/port_posix_sse.cc | |||
| $(CXX) $(CXXFLAGS) $(PLATFORM_SSEFLAGS) -c $< -o $@ | |||
| $(SHARED_OUTDIR)/port/port_posix_sse.o: port/port_posix_sse.cc | |||
| $(CXX) $(CXXFLAGS) $(PLATFORM_SHARED_CFLAGS) $(PLATFORM_SSEFLAGS) -c $< -o $@ | |||
| @ -0,0 +1,92 @@ | |||
| // Copyright (c) 2019 The LevelDB Authors. All rights reserved. | |||
| // Use of this source code is governed by a BSD-style license that can be | |||
| // found in the LICENSE file. See the AUTHORS file for names of contributors. | |||
| #include <cinttypes> | |||
| #include <cstdio> | |||
| #include <string> | |||
| #include "gtest/gtest.h" | |||
| #include "benchmark/benchmark.h" | |||
| #include "db/version_set.h" | |||
| #include "leveldb/comparator.h" | |||
| #include "leveldb/db.h" | |||
| #include "leveldb/env.h" | |||
| #include "leveldb/options.h" | |||
| #include "port/port.h" | |||
| #include "util/mutexlock.h" | |||
| #include "util/testutil.h" | |||
| namespace leveldb { | |||
| namespace { | |||
| std::string MakeKey(unsigned int num) { | |||
| char buf[30]; | |||
| std::snprintf(buf, sizeof(buf), "%016u", num); | |||
| return std::string(buf); | |||
| } | |||
| void BM_LogAndApply(benchmark::State& state) { | |||
| const int num_base_files = state.range(0); | |||
| std::string dbname = testing::TempDir() + "leveldb_test_benchmark"; | |||
| DestroyDB(dbname, Options()); | |||
| DB* db = nullptr; | |||
| Options opts; | |||
| opts.create_if_missing = true; | |||
| Status s = DB::Open(opts, dbname, &db); | |||
| ASSERT_LEVELDB_OK(s); | |||
| ASSERT_TRUE(db != nullptr); | |||
| delete db; | |||
| db = nullptr; | |||
| Env* env = Env::Default(); | |||
| port::Mutex mu; | |||
| MutexLock l(&mu); | |||
| InternalKeyComparator cmp(BytewiseComparator()); | |||
| Options options; | |||
| VersionSet vset(dbname, &options, nullptr, &cmp); | |||
| bool save_manifest; | |||
| ASSERT_LEVELDB_OK(vset.Recover(&save_manifest)); | |||
| VersionEdit vbase; | |||
| uint64_t fnum = 1; | |||
| for (int i = 0; i < num_base_files; i++) { | |||
| InternalKey start(MakeKey(2 * fnum), 1, kTypeValue); | |||
| InternalKey limit(MakeKey(2 * fnum + 1), 1, kTypeDeletion); | |||
| vbase.AddFile(2, fnum++, 1 /* file size */, start, limit); | |||
| } | |||
| ASSERT_LEVELDB_OK(vset.LogAndApply(&vbase, &mu)); | |||
| uint64_t start_micros = env->NowMicros(); | |||
| for (auto st : state) { | |||
| VersionEdit vedit; | |||
| vedit.RemoveFile(2, fnum); | |||
| InternalKey start(MakeKey(2 * fnum), 1, kTypeValue); | |||
| InternalKey limit(MakeKey(2 * fnum + 1), 1, kTypeDeletion); | |||
| vedit.AddFile(2, fnum++, 1 /* file size */, start, limit); | |||
| vset.LogAndApply(&vedit, &mu); | |||
| } | |||
| uint64_t stop_micros = env->NowMicros(); | |||
| unsigned int us = stop_micros - start_micros; | |||
| char buf[16]; | |||
| std::snprintf(buf, sizeof(buf), "%d", num_base_files); | |||
| std::fprintf(stderr, | |||
| "BM_LogAndApply/%-6s %8" PRIu64 | |||
| " iters : %9u us (%7.0f us / iter)\n", | |||
| buf, state.iterations(), us, ((float)us) / state.iterations()); | |||
| } | |||
| BENCHMARK(BM_LogAndApply)->Arg(1)->Arg(100)->Arg(10000)->Arg(100000); | |||
| } // namespace | |||
| } // namespace leveldb | |||
| BENCHMARK_MAIN(); | |||
| @ -1,256 +0,0 @@ | |||
| #!/bin/sh | |||
| # | |||
| # Detects OS we're compiling on and outputs a file specified by the first | |||
| # argument, which in turn gets read while processing Makefile. | |||
| # | |||
| # The output will set the following variables: | |||
| # CC C Compiler path | |||
| # CXX C++ Compiler path | |||
| # PLATFORM_LDFLAGS Linker flags | |||
| # PLATFORM_LIBS Libraries flags | |||
| # PLATFORM_SHARED_EXT Extension for shared libraries | |||
| # PLATFORM_SHARED_LDFLAGS Flags for building shared library | |||
| # This flag is embedded just before the name | |||
| # of the shared library without intervening spaces | |||
| # PLATFORM_SHARED_CFLAGS Flags for compiling objects for shared library | |||
| # PLATFORM_CCFLAGS C compiler flags | |||
| # PLATFORM_CXXFLAGS C++ compiler flags. Will contain: | |||
| # PLATFORM_SHARED_VERSIONED Set to 'true' if platform supports versioned | |||
| # shared libraries, empty otherwise. | |||
| # | |||
| # The PLATFORM_CCFLAGS and PLATFORM_CXXFLAGS might include the following: | |||
| # | |||
| # -DLEVELDB_ATOMIC_PRESENT if <atomic> is present | |||
| # -DLEVELDB_PLATFORM_POSIX for Posix-based platforms | |||
| # -DSNAPPY if the Snappy library is present | |||
| # | |||
| OUTPUT=$1 | |||
| PREFIX=$2 | |||
| if test -z "$OUTPUT" || test -z "$PREFIX"; then | |||
| echo "usage: $0 <output-filename> <directory_prefix>" >&2 | |||
| exit 1 | |||
| fi | |||
| # Delete existing output, if it exists | |||
| rm -f $OUTPUT | |||
| touch $OUTPUT | |||
| if test -z "$CC"; then | |||
| CC=cc | |||
| fi | |||
| if test -z "$CXX"; then | |||
| CXX=g++ | |||
| fi | |||
| if test -z "$TMPDIR"; then | |||
| TMPDIR=/tmp | |||
| fi | |||
| # Detect OS | |||
| if test -z "$TARGET_OS"; then | |||
| TARGET_OS=`uname -s` | |||
| fi | |||
| COMMON_FLAGS= | |||
| CROSS_COMPILE= | |||
| PLATFORM_CCFLAGS= | |||
| PLATFORM_CXXFLAGS= | |||
| PLATFORM_LDFLAGS= | |||
| PLATFORM_LIBS= | |||
| PLATFORM_SHARED_EXT="so" | |||
| PLATFORM_SHARED_LDFLAGS="-shared -Wl,-soname -Wl," | |||
| PLATFORM_SHARED_CFLAGS="-fPIC" | |||
| PLATFORM_SHARED_VERSIONED=true | |||
| PLATFORM_SSEFLAGS= | |||
| MEMCMP_FLAG= | |||
| if [ "$CXX" = "g++" ]; then | |||
| # Use libc's memcmp instead of GCC's memcmp. This results in ~40% | |||
| # performance improvement on readrandom under gcc 4.4.3 on Linux/x86. | |||
| MEMCMP_FLAG="-fno-builtin-memcmp" | |||
| fi | |||
| case "$TARGET_OS" in | |||
| CYGWIN_*) | |||
| PLATFORM=OS_LINUX | |||
| COMMON_FLAGS="$MEMCMP_FLAG -lpthread -DOS_LINUX -DCYGWIN" | |||
| PLATFORM_LDFLAGS="-lpthread" | |||
| PORT_FILE=port/port_posix.cc | |||
| PORT_SSE_FILE=port/port_posix_sse.cc | |||
| ;; | |||
| Darwin) | |||
| PLATFORM=OS_MACOSX | |||
| COMMON_FLAGS="$MEMCMP_FLAG" | |||
| PLATFORM_SHARED_EXT=dylib | |||
| [ -z "$INSTALL_PATH" ] && INSTALL_PATH=`pwd` | |||
| PLATFORM_SHARED_LDFLAGS="-dynamiclib -install_name $INSTALL_PATH/" | |||
| PORT_FILE=port/port_posix.cc | |||
| PORT_SSE_FILE=port/port_posix_sse.cc | |||
| ;; | |||
| Linux) | |||
| PLATFORM=OS_LINUX | |||
| COMMON_FLAGS="$MEMCMP_FLAG -pthread -DOS_LINUX" | |||
| PLATFORM_LDFLAGS="-pthread" | |||
| PORT_FILE=port/port_posix.cc | |||
| PORT_SSE_FILE=port/port_posix_sse.cc | |||
| ;; | |||
| SunOS) | |||
| PLATFORM=OS_SOLARIS | |||
| COMMON_FLAGS="$MEMCMP_FLAG -D_REENTRANT -DOS_SOLARIS" | |||
| PLATFORM_LIBS="-lpthread -lrt" | |||
| PORT_FILE=port/port_posix.cc | |||
| PORT_SSE_FILE=port/port_posix_sse.cc | |||
| ;; | |||
| FreeBSD) | |||
| PLATFORM=OS_FREEBSD | |||
| COMMON_FLAGS="$MEMCMP_FLAG -D_REENTRANT -DOS_FREEBSD" | |||
| PLATFORM_LIBS="-lpthread" | |||
| PORT_FILE=port/port_posix.cc | |||
| PORT_SSE_FILE=port/port_posix_sse.cc | |||
| ;; | |||
| NetBSD) | |||
| PLATFORM=OS_NETBSD | |||
| COMMON_FLAGS="$MEMCMP_FLAG -D_REENTRANT -DOS_NETBSD" | |||
| PLATFORM_LIBS="-lpthread -lgcc_s" | |||
| PORT_FILE=port/port_posix.cc | |||
| PORT_SSE_FILE=port/port_posix_sse.cc | |||
| ;; | |||
| OpenBSD) | |||
| PLATFORM=OS_OPENBSD | |||
| COMMON_FLAGS="$MEMCMP_FLAG -D_REENTRANT -DOS_OPENBSD" | |||
| PLATFORM_LDFLAGS="-pthread" | |||
| PORT_FILE=port/port_posix.cc | |||
| PORT_SSE_FILE=port/port_posix_sse.cc | |||
| ;; | |||
| DragonFly) | |||
| PLATFORM=OS_DRAGONFLYBSD | |||
| COMMON_FLAGS="$MEMCMP_FLAG -D_REENTRANT -DOS_DRAGONFLYBSD" | |||
| PLATFORM_LIBS="-lpthread" | |||
| PORT_FILE=port/port_posix.cc | |||
| PORT_SSE_FILE=port/port_posix_sse.cc | |||
| ;; | |||
| OS_ANDROID_CROSSCOMPILE) | |||
| PLATFORM=OS_ANDROID | |||
| COMMON_FLAGS="$MEMCMP_FLAG -D_REENTRANT -DOS_ANDROID -DLEVELDB_PLATFORM_POSIX" | |||
| PLATFORM_LDFLAGS="" # All pthread features are in the Android C library | |||
| PORT_FILE=port/port_posix.cc | |||
| PORT_SSE_FILE=port/port_posix_sse.cc | |||
| CROSS_COMPILE=true | |||
| ;; | |||
| HP-UX) | |||
| PLATFORM=OS_HPUX | |||
| COMMON_FLAGS="$MEMCMP_FLAG -D_REENTRANT -DOS_HPUX" | |||
| PLATFORM_LDFLAGS="-pthread" | |||
| PORT_FILE=port/port_posix.cc | |||
| PORT_SSE_FILE=port/port_posix_sse.cc | |||
| # man ld: +h internal_name | |||
| PLATFORM_SHARED_LDFLAGS="-shared -Wl,+h -Wl," | |||
| ;; | |||
| IOS) | |||
| PLATFORM=IOS | |||
| COMMON_FLAGS="$MEMCMP_FLAG" | |||
| [ -z "$INSTALL_PATH" ] && INSTALL_PATH=`pwd` | |||
| PORT_FILE=port/port_posix.cc | |||
| PORT_SSE_FILE=port/port_posix_sse.cc | |||
| PLATFORM_SHARED_EXT= | |||
| PLATFORM_SHARED_LDFLAGS= | |||
| PLATFORM_SHARED_CFLAGS= | |||
| PLATFORM_SHARED_VERSIONED= | |||
| ;; | |||
| *) | |||
| echo "Unknown platform!" >&2 | |||
| exit 1 | |||
| esac | |||
| # We want to make a list of all cc files within util, db, table, and helpers | |||
| # except for the test and benchmark files. By default, find will output a list | |||
| # of all files matching either rule, so we need to append -print to make the | |||
| # prune take effect. | |||
| DIRS="$PREFIX/db $PREFIX/util $PREFIX/table" | |||
| set -f # temporarily disable globbing so that our patterns aren't expanded | |||
| PRUNE_TEST="-name *test*.cc -prune" | |||
| PRUNE_BENCH="-name *_bench.cc -prune" | |||
| PRUNE_TOOL="-name leveldbutil.cc -prune" | |||
| PORTABLE_FILES=`find $DIRS $PRUNE_TEST -o $PRUNE_BENCH -o $PRUNE_TOOL -o -name '*.cc' -print | sort | sed "s,^$PREFIX/,," | tr "\n" " "` | |||
| set +f # re-enable globbing | |||
| # The sources consist of the portable files, plus the platform-specific port | |||
| # file. | |||
| echo "SOURCES=$PORTABLE_FILES $PORT_FILE $PORT_SSE_FILE" >> $OUTPUT | |||
| echo "MEMENV_SOURCES=helpers/memenv/memenv.cc" >> $OUTPUT | |||
| if [ "$CROSS_COMPILE" = "true" ]; then | |||
| # Cross-compiling; do not try any compilation tests. | |||
| true | |||
| else | |||
| CXXOUTPUT="${TMPDIR}/leveldb_build_detect_platform-cxx.$$" | |||
| # If -std=c++0x works, use <atomic> as fallback for when memory barriers | |||
| # are not available. | |||
| $CXX $CXXFLAGS -std=c++0x -x c++ - -o $CXXOUTPUT 2>/dev/null <<EOF | |||
| #include <atomic> | |||
| int main() {} | |||
| EOF | |||
| if [ "$?" = 0 ]; then | |||
| COMMON_FLAGS="$COMMON_FLAGS -DLEVELDB_PLATFORM_POSIX -DLEVELDB_ATOMIC_PRESENT" | |||
| PLATFORM_CXXFLAGS="-std=c++0x" | |||
| else | |||
| COMMON_FLAGS="$COMMON_FLAGS -DLEVELDB_PLATFORM_POSIX" | |||
| fi | |||
| # Test whether Snappy library is installed | |||
| # http://code.google.com/p/snappy/ | |||
| $CXX $CXXFLAGS -x c++ - -o $CXXOUTPUT 2>/dev/null <<EOF | |||
| #include <snappy.h> | |||
| int main() {} | |||
| EOF | |||
| if [ "$?" = 0 ]; then | |||
| COMMON_FLAGS="$COMMON_FLAGS -DSNAPPY" | |||
| PLATFORM_LIBS="$PLATFORM_LIBS -lsnappy" | |||
| fi | |||
| # Test whether tcmalloc is available | |||
| $CXX $CXXFLAGS -x c++ - -o $CXXOUTPUT -ltcmalloc 2>/dev/null <<EOF | |||
| int main() {} | |||
| EOF | |||
| if [ "$?" = 0 ]; then | |||
| PLATFORM_LIBS="$PLATFORM_LIBS -ltcmalloc" | |||
| fi | |||
| rm -f $CXXOUTPUT 2>/dev/null | |||
| # Test if gcc SSE 4.2 is supported | |||
| $CXX $CXXFLAGS -x c++ - -o $CXXOUTPUT -msse4.2 2>/dev/null <<EOF | |||
| int main() {} | |||
| EOF | |||
| if [ "$?" = 0 ]; then | |||
| PLATFORM_SSEFLAGS="-msse4.2" | |||
| fi | |||
| rm -f $CXXOUTPUT 2>/dev/null | |||
| fi | |||
| # Use the SSE 4.2 CRC32C intrinsics iff runtime checks indicate compiler supports them. | |||
| if [ -n "$PLATFORM_SSEFLAGS" ]; then | |||
| PLATFORM_SSEFLAGS="$PLATFORM_SSEFLAGS -DLEVELDB_PLATFORM_POSIX_SSE" | |||
| fi | |||
| PLATFORM_CCFLAGS="$PLATFORM_CCFLAGS $COMMON_FLAGS" | |||
| PLATFORM_CXXFLAGS="$PLATFORM_CXXFLAGS $COMMON_FLAGS" | |||
| echo "CC=$CC" >> $OUTPUT | |||
| echo "CXX=$CXX" >> $OUTPUT | |||
| echo "PLATFORM=$PLATFORM" >> $OUTPUT | |||
| echo "PLATFORM_LDFLAGS=$PLATFORM_LDFLAGS" >> $OUTPUT | |||
| echo "PLATFORM_LIBS=$PLATFORM_LIBS" >> $OUTPUT | |||
| echo "PLATFORM_CCFLAGS=$PLATFORM_CCFLAGS" >> $OUTPUT | |||
| echo "PLATFORM_CXXFLAGS=$PLATFORM_CXXFLAGS" >> $OUTPUT | |||
| echo "PLATFORM_SSEFLAGS=$PLATFORM_SSEFLAGS" >> $OUTPUT | |||
| echo "PLATFORM_SHARED_CFLAGS=$PLATFORM_SHARED_CFLAGS" >> $OUTPUT | |||
| echo "PLATFORM_SHARED_EXT=$PLATFORM_SHARED_EXT" >> $OUTPUT | |||
| echo "PLATFORM_SHARED_LDFLAGS=$PLATFORM_SHARED_LDFLAGS" >> $OUTPUT | |||
| echo "PLATFORM_SHARED_VERSIONED=$PLATFORM_SHARED_VERSIONED" >> $OUTPUT | |||
| @ -0,0 +1,9 @@ | |||
| # Copyright 2019 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. | |||
| @PACKAGE_INIT@ | |||
| include("${CMAKE_CURRENT_LIST_DIR}/leveldbTargets.cmake") | |||
| check_required_components(leveldb) | |||
| @ -0,0 +1,33 @@ | |||
| // Copyright (c) 2017 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. | |||
| #ifndef STORAGE_LEVELDB_INCLUDE_EXPORT_H_ | |||
| #define STORAGE_LEVELDB_INCLUDE_EXPORT_H_ | |||
| #if !defined(LEVELDB_EXPORT) | |||
| #if defined(LEVELDB_SHARED_LIBRARY) | |||
| #if defined(_WIN32) | |||
| #if defined(LEVELDB_COMPILE_LIBRARY) | |||
| #define LEVELDB_EXPORT __declspec(dllexport) | |||
| #else | |||
| #define LEVELDB_EXPORT __declspec(dllimport) | |||
| #endif // defined(LEVELDB_COMPILE_LIBRARY) | |||
| #else // defined(_WIN32) | |||
| #if defined(LEVELDB_COMPILE_LIBRARY) | |||
| #define LEVELDB_EXPORT __attribute__((visibility("default"))) | |||
| #else | |||
| #define LEVELDB_EXPORT | |||
| #endif | |||
| #endif // defined(_WIN32) | |||
| #else // defined(LEVELDB_SHARED_LIBRARY) | |||
| #define LEVELDB_EXPORT | |||
| #endif | |||
| #endif // !defined(LEVELDB_EXPORT) | |||
| #endif // STORAGE_LEVELDB_INCLUDE_EXPORT_H_ | |||
| @ -0,0 +1,126 @@ | |||
| // Copyright (c) 2019 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 <cstdint> | |||
| #include <cstdlib> | |||
| #include <iostream> | |||
| #include <memory> | |||
| #include <string> | |||
| #include <vector> | |||
| #include "gtest/gtest.h" | |||
| #include "leveldb/db.h" | |||
| #include "leveldb/write_batch.h" | |||
| #include "util/testutil.h" | |||
| namespace leveldb { | |||
| namespace { | |||
| // Creates a random number in the range of [0, max). | |||
| int GenerateRandomNumber(int max) { return std::rand() % max; } | |||
| std::string CreateRandomString(int32_t index) { | |||
| static const size_t len = 1024; | |||
| char bytes[len]; | |||
| size_t i = 0; | |||
| while (i < 8) { | |||
| bytes[i] = 'a' + ((index >> (4 * i)) & 0xf); | |||
| ++i; | |||
| } | |||
| while (i < sizeof(bytes)) { | |||
| bytes[i] = 'a' + GenerateRandomNumber(26); | |||
| ++i; | |||
| } | |||
| return std::string(bytes, sizeof(bytes)); | |||
| } | |||
| } // namespace | |||
| TEST(Issue320, Test) { | |||
| std::srand(0); | |||
| bool delete_before_put = false; | |||
| bool keep_snapshots = true; | |||
| std::vector<std::unique_ptr<std::pair<std::string, std::string>>> test_map( | |||
| 10000); | |||
| std::vector<Snapshot const*> snapshots(100, nullptr); | |||
| DB* db; | |||
| Options options; | |||
| options.create_if_missing = true; | |||
| std::string dbpath = testing::TempDir() + "leveldb_issue320_test"; | |||
| ASSERT_LEVELDB_OK(DB::Open(options, dbpath, &db)); | |||
| uint32_t target_size = 10000; | |||
| uint32_t num_items = 0; | |||
| uint32_t count = 0; | |||
| std::string key; | |||
| std::string value, old_value; | |||
| WriteOptions writeOptions; | |||
| ReadOptions readOptions; | |||
| while (count < 200000) { | |||
| if ((++count % 1000) == 0) { | |||
| std::cout << "count: " << count << std::endl; | |||
| } | |||
| int index = GenerateRandomNumber(test_map.size()); | |||
| WriteBatch batch; | |||
| if (test_map[index] == nullptr) { | |||
| num_items++; | |||
| test_map[index].reset(new std::pair<std::string, std::string>( | |||
| CreateRandomString(index), CreateRandomString(index))); | |||
| batch.Put(test_map[index]->first, test_map[index]->second); | |||
| } else { | |||
| ASSERT_LEVELDB_OK( | |||
| db->Get(readOptions, test_map[index]->first, &old_value)); | |||
| if (old_value != test_map[index]->second) { | |||
| std::cout << "ERROR incorrect value returned by Get" << std::endl; | |||
| std::cout << " count=" << count << std::endl; | |||
| std::cout << " old value=" << old_value << std::endl; | |||
| std::cout << " test_map[index]->second=" << test_map[index]->second | |||
| << std::endl; | |||
| std::cout << " test_map[index]->first=" << test_map[index]->first | |||
| << std::endl; | |||
| std::cout << " index=" << index << std::endl; | |||
| ASSERT_EQ(old_value, test_map[index]->second); | |||
| } | |||
| if (num_items >= target_size && GenerateRandomNumber(100) > 30) { | |||
| batch.Delete(test_map[index]->first); | |||
| test_map[index] = nullptr; | |||
| --num_items; | |||
| } else { | |||
| test_map[index]->second = CreateRandomString(index); | |||
| if (delete_before_put) batch.Delete(test_map[index]->first); | |||
| batch.Put(test_map[index]->first, test_map[index]->second); | |||
| } | |||
| } | |||
| ASSERT_LEVELDB_OK(db->Write(writeOptions, &batch)); | |||
| if (keep_snapshots && GenerateRandomNumber(10) == 0) { | |||
| int i = GenerateRandomNumber(snapshots.size()); | |||
| if (snapshots[i] != nullptr) { | |||
| db->ReleaseSnapshot(snapshots[i]); | |||
| } | |||
| snapshots[i] = db->GetSnapshot(); | |||
| } | |||
| } | |||
| for (Snapshot const* snapshot : snapshots) { | |||
| if (snapshot) { | |||
| db->ReleaseSnapshot(snapshot); | |||
| } | |||
| } | |||
| delete db; | |||
| DestroyDB(dbpath, options); | |||
| } | |||
| } // namespace leveldb | |||
| @ -1,242 +0,0 @@ | |||
| // 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. | |||
| // AtomicPointer provides storage for a lock-free pointer. | |||
| // Platform-dependent implementation of AtomicPointer: | |||
| // - If the platform provides a cheap barrier, we use it with raw pointers | |||
| // - If <atomic> is present (on newer versions of gcc, it is), we use | |||
| // a <atomic>-based AtomicPointer. However we prefer the memory | |||
| // barrier based version, because at least on a gcc 4.4 32-bit build | |||
| // on linux, we have encountered a buggy <atomic> implementation. | |||
| // Also, some <atomic> implementations are much slower than a memory-barrier | |||
| // based implementation (~16ns for <atomic> based acquire-load vs. ~1ns for | |||
| // a barrier based acquire-load). | |||
| // This code is based on atomicops-internals-* in Google's perftools: | |||
| // http://code.google.com/p/google-perftools/source/browse/#svn%2Ftrunk%2Fsrc%2Fbase | |||
| #ifndef PORT_ATOMIC_POINTER_H_ | |||
| #define PORT_ATOMIC_POINTER_H_ | |||
| #include <stdint.h> | |||
| #ifdef LEVELDB_ATOMIC_PRESENT | |||
| #include <atomic> | |||
| #endif | |||
| #ifdef OS_WIN | |||
| #include <windows.h> | |||
| #endif | |||
| #ifdef __APPLE__ | |||
| #include <libkern/OSAtomic.h> | |||
| #endif | |||
| #if defined(_M_X64) || defined(__x86_64__) | |||
| #define ARCH_CPU_X86_FAMILY 1 | |||
| #elif defined(_M_IX86) || defined(__i386__) || defined(__i386) | |||
| #define ARCH_CPU_X86_FAMILY 1 | |||
| #elif defined(__ARMEL__) | |||
| #define ARCH_CPU_ARM_FAMILY 1 | |||
| #elif defined(__aarch64__) | |||
| #define ARCH_CPU_ARM64_FAMILY 1 | |||
| #elif defined(__ppc__) || defined(__powerpc__) || defined(__powerpc64__) | |||
| #define ARCH_CPU_PPC_FAMILY 1 | |||
| #elif defined(__mips__) | |||
| #define ARCH_CPU_MIPS_FAMILY 1 | |||
| #endif | |||
| namespace leveldb { | |||
| namespace port { | |||
| // Define MemoryBarrier() if available | |||
| // Windows on x86 | |||
| #if defined(OS_WIN) && defined(COMPILER_MSVC) && defined(ARCH_CPU_X86_FAMILY) | |||
| // windows.h already provides a MemoryBarrier(void) macro | |||
| // http://msdn.microsoft.com/en-us/library/ms684208(v=vs.85).aspx | |||
| #define LEVELDB_HAVE_MEMORY_BARRIER | |||
| // Mac OS | |||
| #elif defined(__APPLE__) | |||
| inline void MemoryBarrier() { | |||
| OSMemoryBarrier(); | |||
| } | |||
| #define LEVELDB_HAVE_MEMORY_BARRIER | |||
| // Gcc on x86 | |||
| #elif defined(ARCH_CPU_X86_FAMILY) && defined(__GNUC__) | |||
| inline void MemoryBarrier() { | |||
| // See http://gcc.gnu.org/ml/gcc/2003-04/msg01180.html for a discussion on | |||
| // this idiom. Also see http://en.wikipedia.org/wiki/Memory_ordering. | |||
| __asm__ __volatile__("" : : : "memory"); | |||
| } | |||
| #define LEVELDB_HAVE_MEMORY_BARRIER | |||
| // Sun Studio | |||
| #elif defined(ARCH_CPU_X86_FAMILY) && defined(__SUNPRO_CC) | |||
| inline void MemoryBarrier() { | |||
| // See http://gcc.gnu.org/ml/gcc/2003-04/msg01180.html for a discussion on | |||
| // this idiom. Also see http://en.wikipedia.org/wiki/Memory_ordering. | |||
| asm volatile("" : : : "memory"); | |||
| } | |||
| #define LEVELDB_HAVE_MEMORY_BARRIER | |||
| // ARM Linux | |||
| #elif defined(ARCH_CPU_ARM_FAMILY) && defined(__linux__) | |||
| typedef void (*LinuxKernelMemoryBarrierFunc)(void); | |||
| // The Linux ARM kernel provides a highly optimized device-specific memory | |||
| // barrier function at a fixed memory address that is mapped in every | |||
| // user-level process. | |||
| // | |||
| // This beats using CPU-specific instructions which are, on single-core | |||
| // devices, un-necessary and very costly (e.g. ARMv7-A "dmb" takes more | |||
| // than 180ns on a Cortex-A8 like the one on a Nexus One). Benchmarking | |||
| // shows that the extra function call cost is completely negligible on | |||
| // multi-core devices. | |||
| // | |||
| inline void MemoryBarrier() { | |||
| (*(LinuxKernelMemoryBarrierFunc)0xffff0fa0)(); | |||
| } | |||
| #define LEVELDB_HAVE_MEMORY_BARRIER | |||
| // ARM64 | |||
| #elif defined(ARCH_CPU_ARM64_FAMILY) | |||
| inline void MemoryBarrier() { | |||
| asm volatile("dmb sy" : : : "memory"); | |||
| } | |||
| #define LEVELDB_HAVE_MEMORY_BARRIER | |||
| // PPC | |||
| #elif defined(ARCH_CPU_PPC_FAMILY) && defined(__GNUC__) | |||
| inline void MemoryBarrier() { | |||
| // TODO for some powerpc expert: is there a cheaper suitable variant? | |||
| // Perhaps by having separate barriers for acquire and release ops. | |||
| asm volatile("sync" : : : "memory"); | |||
| } | |||
| #define LEVELDB_HAVE_MEMORY_BARRIER | |||
| // MIPS | |||
| #elif defined(ARCH_CPU_MIPS_FAMILY) && defined(__GNUC__) | |||
| inline void MemoryBarrier() { | |||
| __asm__ __volatile__("sync" : : : "memory"); | |||
| } | |||
| #define LEVELDB_HAVE_MEMORY_BARRIER | |||
| #endif | |||
| // AtomicPointer built using platform-specific MemoryBarrier() | |||
| #if defined(LEVELDB_HAVE_MEMORY_BARRIER) | |||
| class AtomicPointer { | |||
| private: | |||
| void* rep_; | |||
| public: | |||
| AtomicPointer() { } | |||
| explicit AtomicPointer(void* p) : rep_(p) {} | |||
| inline void* NoBarrier_Load() const { return rep_; } | |||
| inline void NoBarrier_Store(void* v) { rep_ = v; } | |||
| inline void* Acquire_Load() const { | |||
| void* result = rep_; | |||
| MemoryBarrier(); | |||
| return result; | |||
| } | |||
| inline void Release_Store(void* v) { | |||
| MemoryBarrier(); | |||
| rep_ = v; | |||
| } | |||
| }; | |||
| // AtomicPointer based on <cstdatomic> | |||
| #elif defined(LEVELDB_ATOMIC_PRESENT) | |||
| class AtomicPointer { | |||
| private: | |||
| std::atomic<void*> rep_; | |||
| public: | |||
| AtomicPointer() { } | |||
| explicit AtomicPointer(void* v) : rep_(v) { } | |||
| inline void* Acquire_Load() const { | |||
| return rep_.load(std::memory_order_acquire); | |||
| } | |||
| inline void Release_Store(void* v) { | |||
| rep_.store(v, std::memory_order_release); | |||
| } | |||
| inline void* NoBarrier_Load() const { | |||
| return rep_.load(std::memory_order_relaxed); | |||
| } | |||
| inline void NoBarrier_Store(void* v) { | |||
| rep_.store(v, std::memory_order_relaxed); | |||
| } | |||
| }; | |||
| // Atomic pointer based on sparc memory barriers | |||
| #elif defined(__sparcv9) && defined(__GNUC__) | |||
| class AtomicPointer { | |||
| private: | |||
| void* rep_; | |||
| public: | |||
| AtomicPointer() { } | |||
| explicit AtomicPointer(void* v) : rep_(v) { } | |||
| inline void* Acquire_Load() const { | |||
| void* val; | |||
| __asm__ __volatile__ ( | |||
| "ldx [%[rep_]], %[val] \n\t" | |||
| "membar #LoadLoad|#LoadStore \n\t" | |||
| : [val] "=r" (val) | |||
| : [rep_] "r" (&rep_) | |||
| : "memory"); | |||
| return val; | |||
| } | |||
| inline void Release_Store(void* v) { | |||
| __asm__ __volatile__ ( | |||
| "membar #LoadStore|#StoreStore \n\t" | |||
| "stx %[v], [%[rep_]] \n\t" | |||
| : | |||
| : [rep_] "r" (&rep_), [v] "r" (v) | |||
| : "memory"); | |||
| } | |||
| inline void* NoBarrier_Load() const { return rep_; } | |||
| inline void NoBarrier_Store(void* v) { rep_ = v; } | |||
| }; | |||
| // Atomic pointer based on ia64 acq/rel | |||
| #elif defined(__ia64) && defined(__GNUC__) | |||
| class AtomicPointer { | |||
| private: | |||
| void* rep_; | |||
| public: | |||
| AtomicPointer() { } | |||
| explicit AtomicPointer(void* v) : rep_(v) { } | |||
| inline void* Acquire_Load() const { | |||
| void* val ; | |||
| __asm__ __volatile__ ( | |||
| "ld8.acq %[val] = [%[rep_]] \n\t" | |||
| : [val] "=r" (val) | |||
| : [rep_] "r" (&rep_) | |||
| : "memory" | |||
| ); | |||
| return val; | |||
| } | |||
| inline void Release_Store(void* v) { | |||
| __asm__ __volatile__ ( | |||
| "st8.rel [%[rep_]] = %[v] \n\t" | |||
| : | |||
| : [rep_] "r" (&rep_), [v] "r" (v) | |||
| : "memory" | |||
| ); | |||
| } | |||
| inline void* NoBarrier_Load() const { return rep_; } | |||
| inline void NoBarrier_Store(void* v) { rep_ = v; } | |||
| }; | |||
| // We have neither MemoryBarrier(), nor <atomic> | |||
| #else | |||
| #error Please implement AtomicPointer for this platform. | |||
| #endif | |||
| #undef LEVELDB_HAVE_MEMORY_BARRIER | |||
| #undef ARCH_CPU_X86_FAMILY | |||
| #undef ARCH_CPU_ARM_FAMILY | |||
| #undef ARCH_CPU_ARM64_FAMILY | |||
| #undef ARCH_CPU_PPC_FAMILY | |||
| } // namespace port | |||
| } // namespace leveldb | |||
| #endif // PORT_ATOMIC_POINTER_H_ | |||
| @ -0,0 +1,33 @@ | |||
| // Copyright 2017 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. | |||
| #ifndef STORAGE_LEVELDB_PORT_PORT_CONFIG_H_ | |||
| #define STORAGE_LEVELDB_PORT_PORT_CONFIG_H_ | |||
| // Define to 1 if you have a definition for fdatasync() in <unistd.h>. | |||
| #if !defined(HAVE_FDATASYNC) | |||
| #cmakedefine01 HAVE_FDATASYNC | |||
| #endif // !defined(HAVE_FDATASYNC) | |||
| // Define to 1 if you have a definition for F_FULLFSYNC in <fcntl.h>. | |||
| #if !defined(HAVE_FULLFSYNC) | |||
| #cmakedefine01 HAVE_FULLFSYNC | |||
| #endif // !defined(HAVE_FULLFSYNC) | |||
| // Define to 1 if you have a definition for O_CLOEXEC in <fcntl.h>. | |||
| #if !defined(HAVE_O_CLOEXEC) | |||
| #cmakedefine01 HAVE_O_CLOEXEC | |||
| #endif // !defined(HAVE_O_CLOEXEC) | |||
| // Define to 1 if you have Google CRC32C. | |||
| #if !defined(HAVE_CRC32C) | |||
| #cmakedefine01 HAVE_CRC32C | |||
| #endif // !defined(HAVE_CRC32C) | |||
| // Define to 1 if you have Google Snappy. | |||
| #if !defined(HAVE_SNAPPY) | |||
| #cmakedefine01 HAVE_SNAPPY | |||
| #endif // !defined(HAVE_SNAPPY) | |||
| #endif // STORAGE_LEVELDB_PORT_PORT_CONFIG_H_ | |||
| @ -1,53 +0,0 @@ | |||
| // 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 "port/port_posix.h" | |||
| #include <cstdlib> | |||
| #include <stdio.h> | |||
| #include <string.h> | |||
| namespace leveldb { | |||
| namespace port { | |||
| static void PthreadCall(const char* label, int result) { | |||
| if (result != 0) { | |||
| fprintf(stderr, "pthread %s: %s\n", label, strerror(result)); | |||
| abort(); | |||
| } | |||
| } | |||
| Mutex::Mutex() { PthreadCall("init mutex", pthread_mutex_init(&mu_, NULL)); } | |||
| Mutex::~Mutex() { PthreadCall("destroy mutex", pthread_mutex_destroy(&mu_)); } | |||
| void Mutex::Lock() { PthreadCall("lock", pthread_mutex_lock(&mu_)); } | |||
| void Mutex::Unlock() { PthreadCall("unlock", pthread_mutex_unlock(&mu_)); } | |||
| CondVar::CondVar(Mutex* mu) | |||
| : mu_(mu) { | |||
| PthreadCall("init cv", pthread_cond_init(&cv_, NULL)); | |||
| } | |||
| CondVar::~CondVar() { PthreadCall("destroy cv", pthread_cond_destroy(&cv_)); } | |||
| void CondVar::Wait() { | |||
| PthreadCall("wait", pthread_cond_wait(&cv_, &mu_->mu_)); | |||
| } | |||
| void CondVar::Signal() { | |||
| PthreadCall("signal", pthread_cond_signal(&cv_)); | |||
| } | |||
| void CondVar::SignalAll() { | |||
| PthreadCall("broadcast", pthread_cond_broadcast(&cv_)); | |||
| } | |||
| void InitOnce(OnceType* once, void (*initializer)()) { | |||
| PthreadCall("once", pthread_once(once, initializer)); | |||
| } | |||
| } // namespace port | |||
| } // namespace leveldb | |||
| @ -1,156 +0,0 @@ | |||
| // 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. | |||
| // | |||
| // See port_example.h for documentation for the following types/functions. | |||
| #ifndef STORAGE_LEVELDB_PORT_PORT_POSIX_H_ | |||
| #define STORAGE_LEVELDB_PORT_PORT_POSIX_H_ | |||
| #undef PLATFORM_IS_LITTLE_ENDIAN | |||
| #if defined(__APPLE__) | |||
| #include <machine/endian.h> | |||
| #if defined(__DARWIN_LITTLE_ENDIAN) && defined(__DARWIN_BYTE_ORDER) | |||
| #define PLATFORM_IS_LITTLE_ENDIAN \ | |||
| (__DARWIN_BYTE_ORDER == __DARWIN_LITTLE_ENDIAN) | |||
| #endif | |||
| #elif defined(OS_SOLARIS) | |||
| #include <sys/isa_defs.h> | |||
| #ifdef _LITTLE_ENDIAN | |||
| #define PLATFORM_IS_LITTLE_ENDIAN true | |||
| #else | |||
| #define PLATFORM_IS_LITTLE_ENDIAN false | |||
| #endif | |||
| #elif defined(OS_FREEBSD) || defined(OS_OPENBSD) ||\ | |||
| defined(OS_NETBSD) || defined(OS_DRAGONFLYBSD) | |||
| #include <sys/types.h> | |||
| #include <sys/endian.h> | |||
| #define PLATFORM_IS_LITTLE_ENDIAN (_BYTE_ORDER == _LITTLE_ENDIAN) | |||
| #elif defined(OS_HPUX) | |||
| #define PLATFORM_IS_LITTLE_ENDIAN false | |||
| #elif defined(OS_ANDROID) | |||
| // Due to a bug in the NDK x86 <sys/endian.h> definition, | |||
| // _BYTE_ORDER must be used instead of __BYTE_ORDER on Android. | |||
| // See http://code.google.com/p/android/issues/detail?id=39824 | |||
| #include <endian.h> | |||
| #define PLATFORM_IS_LITTLE_ENDIAN (_BYTE_ORDER == _LITTLE_ENDIAN) | |||
| #else | |||
| #include <endian.h> | |||
| #endif | |||
| #include <pthread.h> | |||
| #ifdef SNAPPY | |||
| #include <snappy.h> | |||
| #endif | |||
| #include <stdint.h> | |||
| #include <string> | |||
| #include "port/atomic_pointer.h" | |||
| #ifndef PLATFORM_IS_LITTLE_ENDIAN | |||
| #define PLATFORM_IS_LITTLE_ENDIAN (__BYTE_ORDER == __LITTLE_ENDIAN) | |||
| #endif | |||
| #if defined(__APPLE__) || defined(OS_SOLARIS) || defined(OS_FREEBSD) ||\ | |||
| defined(OS_NETBSD) || defined(OS_OPENBSD) || defined(OS_DRAGONFLYBSD) ||\ | |||
| defined(OS_ANDROID) || defined(OS_HPUX) || defined(CYGWIN) | |||
| // Use fread/fwrite/fflush on platforms without _unlocked variants | |||
| #define fread_unlocked fread | |||
| #define fwrite_unlocked fwrite | |||
| #define fflush_unlocked fflush | |||
| #endif | |||
| #if defined(__APPLE__) || defined(OS_FREEBSD) ||\ | |||
| defined(OS_OPENBSD) || defined(OS_DRAGONFLYBSD) | |||
| // Use fsync() on platforms without fdatasync() | |||
| #define fdatasync fsync | |||
| #endif | |||
| #if defined(OS_ANDROID) && __ANDROID_API__ < 9 | |||
| // fdatasync() was only introduced in API level 9 on Android. Use fsync() | |||
| // when targetting older platforms. | |||
| #define fdatasync fsync | |||
| #endif | |||
| namespace leveldb { | |||
| namespace port { | |||
| static const bool kLittleEndian = PLATFORM_IS_LITTLE_ENDIAN; | |||
| #undef PLATFORM_IS_LITTLE_ENDIAN | |||
| class CondVar; | |||
| class Mutex { | |||
| public: | |||
| Mutex(); | |||
| ~Mutex(); | |||
| void Lock(); | |||
| void Unlock(); | |||
| void AssertHeld() { } | |||
| private: | |||
| friend class CondVar; | |||
| pthread_mutex_t mu_; | |||
| // No copying | |||
| Mutex(const Mutex&); | |||
| void operator=(const Mutex&); | |||
| }; | |||
| class CondVar { | |||
| public: | |||
| explicit CondVar(Mutex* mu); | |||
| ~CondVar(); | |||
| void Wait(); | |||
| void Signal(); | |||
| void SignalAll(); | |||
| private: | |||
| pthread_cond_t cv_; | |||
| Mutex* mu_; | |||
| }; | |||
| typedef pthread_once_t OnceType; | |||
| #define LEVELDB_ONCE_INIT PTHREAD_ONCE_INIT | |||
| extern void InitOnce(OnceType* once, void (*initializer)()); | |||
| inline bool Snappy_Compress(const char* input, size_t length, | |||
| ::std::string* output) { | |||
| #ifdef SNAPPY | |||
| output->resize(snappy::MaxCompressedLength(length)); | |||
| size_t outlen; | |||
| snappy::RawCompress(input, length, &(*output)[0], &outlen); | |||
| output->resize(outlen); | |||
| return true; | |||
| #endif | |||
| return false; | |||
| } | |||
| inline bool Snappy_GetUncompressedLength(const char* input, size_t length, | |||
| size_t* result) { | |||
| #ifdef SNAPPY | |||
| return snappy::GetUncompressedLength(input, length, result); | |||
| #else | |||
| return false; | |||
| #endif | |||
| } | |||
| inline bool Snappy_Uncompress(const char* input, size_t length, | |||
| char* output) { | |||
| #ifdef SNAPPY | |||
| return snappy::RawUncompress(input, length, output); | |||
| #else | |||
| return false; | |||
| #endif | |||
| } | |||
| inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) { | |||
| return false; | |||
| } | |||
| uint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size); | |||
| } // namespace port | |||
| } // namespace leveldb | |||
| #endif // STORAGE_LEVELDB_PORT_PORT_POSIX_H_ | |||
| @ -1,133 +0,0 @@ | |||
| // Copyright 2016 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. | |||
| // | |||
| // A portable implementation of crc32c, optimized to handle | |||
| // four bytes at a time. | |||
| // | |||
| // In a separate source file to allow this accelerated CRC32C function to be | |||
| // compiled with the appropriate compiler flags to enable x86 SSE 4.2 | |||
| // instructions. | |||
| #include <stdint.h> | |||
| #include <string.h> | |||
| #include "port/port.h" | |||
| #if defined(LEVELDB_PLATFORM_POSIX_SSE) | |||
| #if defined(_MSC_VER) | |||
| #include <intrin.h> | |||
| #elif defined(__GNUC__) && defined(__SSE4_2__) | |||
| #include <nmmintrin.h> | |||
| #include <cpuid.h> | |||
| #endif | |||
| #endif // defined(LEVELDB_PLATFORM_POSIX_SSE) | |||
| namespace leveldb { | |||
| namespace port { | |||
| #if defined(LEVELDB_PLATFORM_POSIX_SSE) | |||
| // Used to fetch a naturally-aligned 32-bit word in little endian byte-order | |||
| static inline uint32_t LE_LOAD32(const uint8_t *p) { | |||
| // SSE is x86 only, so ensured that |p| is always little-endian. | |||
| uint32_t word; | |||
| memcpy(&word, p, sizeof(word)); | |||
| return word; | |||
| } | |||
| #if defined(_M_X64) || defined(__x86_64__) // LE_LOAD64 is only used on x64. | |||
| // Used to fetch a naturally-aligned 64-bit word in little endian byte-order | |||
| static inline uint64_t LE_LOAD64(const uint8_t *p) { | |||
| uint64_t dword; | |||
| memcpy(&dword, p, sizeof(dword)); | |||
| return dword; | |||
| } | |||
| #endif // defined(_M_X64) || defined(__x86_64__) | |||
| static inline bool HaveSSE42() { | |||
| #if defined(_MSC_VER) | |||
| int cpu_info[4]; | |||
| __cpuid(cpu_info, 1); | |||
| return (cpu_info[2] & (1 << 20)) != 0; | |||
| #elif defined(__GNUC__) | |||
| unsigned int eax, ebx, ecx, edx; | |||
| __get_cpuid(1, &eax, &ebx, &ecx, &edx); | |||
| return (ecx & (1 << 20)) != 0; | |||
| #else | |||
| return false; | |||
| #endif | |||
| } | |||
| #endif // defined(LEVELDB_PLATFORM_POSIX_SSE) | |||
| // For further improvements see Intel publication at: | |||
| // http://download.intel.com/design/intarch/papers/323405.pdf | |||
| uint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size) { | |||
| #if !defined(LEVELDB_PLATFORM_POSIX_SSE) | |||
| return 0; | |||
| #else | |||
| static bool have = HaveSSE42(); | |||
| if (!have) { | |||
| return 0; | |||
| } | |||
| const uint8_t *p = reinterpret_cast<const uint8_t *>(buf); | |||
| const uint8_t *e = p + size; | |||
| uint32_t l = crc ^ 0xffffffffu; | |||
| #define STEP1 do { \ | |||
| l = _mm_crc32_u8(l, *p++); \ | |||
| } while (0) | |||
| #define STEP4 do { \ | |||
| l = _mm_crc32_u32(l, LE_LOAD32(p)); \ | |||
| p += 4; \ | |||
| } while (0) | |||
| #define STEP8 do { \ | |||
| l = _mm_crc32_u64(l, LE_LOAD64(p)); \ | |||
| p += 8; \ | |||
| } while (0) | |||
| if (size > 16) { | |||
| // Point x at first 8-byte aligned byte in string. This must be inside the | |||
| // string, due to the size check above. | |||
| const uintptr_t pval = reinterpret_cast<uintptr_t>(p); | |||
| const uint8_t* x = reinterpret_cast<const uint8_t*>(((pval + 7) >> 3) << 3); | |||
| // Process bytes until p is 8-byte aligned. | |||
| while (p != x) { | |||
| STEP1; | |||
| } | |||
| // _mm_crc32_u64 is only available on x64. | |||
| #if defined(_M_X64) || defined(__x86_64__) | |||
| // Process 8 bytes at a time | |||
| while ((e-p) >= 8) { | |||
| STEP8; | |||
| } | |||
| // Process 4 bytes at a time | |||
| if ((e-p) >= 4) { | |||
| STEP4; | |||
| } | |||
| #else // !(defined(_M_X64) || defined(__x86_64__)) | |||
| // Process 4 bytes at a time | |||
| while ((e-p) >= 4) { | |||
| STEP4; | |||
| } | |||
| #endif // defined(_M_X64) || defined(__x86_64__) | |||
| } | |||
| // Process the last few bytes | |||
| while (p != e) { | |||
| STEP1; | |||
| } | |||
| #undef STEP8 | |||
| #undef STEP4 | |||
| #undef STEP1 | |||
| return l ^ 0xffffffffu; | |||
| #endif // defined(LEVELDB_PLATFORM_POSIX_SSE) | |||
| } | |||
| } // namespace port | |||
| } // namespace leveldb | |||
| @ -0,0 +1,151 @@ | |||
| // Copyright (c) 2018 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. | |||
| #ifndef STORAGE_LEVELDB_PORT_PORT_STDCXX_H_ | |||
| #define STORAGE_LEVELDB_PORT_PORT_STDCXX_H_ | |||
| // port/port_config.h availability is automatically detected via __has_include | |||
| // in newer compilers. If LEVELDB_HAS_PORT_CONFIG_H is defined, it overrides the | |||
| // configuration detection. | |||
| #if defined(LEVELDB_HAS_PORT_CONFIG_H) | |||
| #if LEVELDB_HAS_PORT_CONFIG_H | |||
| #include "port/port_config.h" | |||
| #endif // LEVELDB_HAS_PORT_CONFIG_H | |||
| #elif defined(__has_include) | |||
| #if __has_include("port/port_config.h") | |||
| #include "port/port_config.h" | |||
| #endif // __has_include("port/port_config.h") | |||
| #endif // defined(LEVELDB_HAS_PORT_CONFIG_H) | |||
| #if HAVE_CRC32C | |||
| #include <crc32c/crc32c.h> | |||
| #endif // HAVE_CRC32C | |||
| #if HAVE_SNAPPY | |||
| #include <snappy.h> | |||
| #endif // HAVE_SNAPPY | |||
| #include <cassert> | |||
| #include <condition_variable> // NOLINT | |||
| #include <cstddef> | |||
| #include <cstdint> | |||
| #include <mutex> // NOLINT | |||
| #include <string> | |||
| #include "port/thread_annotations.h" | |||
| namespace leveldb { | |||
| namespace port { | |||
| class CondVar; | |||
| // Thinly wraps std::mutex. | |||
| class LOCKABLE Mutex { | |||
| public: | |||
| Mutex() = default; | |||
| ~Mutex() = default; | |||
| Mutex(const Mutex&) = delete; | |||
| Mutex& operator=(const Mutex&) = delete; | |||
| void Lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.lock(); } | |||
| void Unlock() UNLOCK_FUNCTION() { mu_.unlock(); } | |||
| void AssertHeld() ASSERT_EXCLUSIVE_LOCK() {} | |||
| private: | |||
| friend class CondVar; | |||
| std::mutex mu_; | |||
| }; | |||
| // Thinly wraps std::condition_variable. | |||
| class CondVar { | |||
| public: | |||
| explicit CondVar(Mutex* mu) : mu_(mu) { assert(mu != nullptr); } | |||
| ~CondVar() = default; | |||
| CondVar(const CondVar&) = delete; | |||
| CondVar& operator=(const CondVar&) = delete; | |||
| void Wait() { | |||
| std::unique_lock<std::mutex> lock(mu_->mu_, std::adopt_lock); | |||
| cv_.wait(lock); | |||
| lock.release(); | |||
| } | |||
| void Signal() { cv_.notify_one(); } | |||
| void SignalAll() { cv_.notify_all(); } | |||
| private: | |||
| std::condition_variable cv_; | |||
| Mutex* const mu_; | |||
| }; | |||
| inline bool Snappy_Compress(const char* input, size_t length, | |||
| std::string* output) { | |||
| #if HAVE_SNAPPY | |||
| output->resize(snappy::MaxCompressedLength(length)); | |||
| size_t outlen; | |||
| snappy::RawCompress(input, length, &(*output)[0], &outlen); | |||
| output->resize(outlen); | |||
| return true; | |||
| #else | |||
| // Silence compiler warnings about unused arguments. | |||
| (void)input; | |||
| (void)length; | |||
| (void)output; | |||
| #endif // HAVE_SNAPPY | |||
| return false; | |||
| } | |||
| inline bool Snappy_GetUncompressedLength(const char* input, size_t length, | |||
| size_t* result) { | |||
| #if HAVE_SNAPPY | |||
| return snappy::GetUncompressedLength(input, length, result); | |||
| #else | |||
| // Silence compiler warnings about unused arguments. | |||
| (void)input; | |||
| (void)length; | |||
| (void)result; | |||
| return false; | |||
| #endif // HAVE_SNAPPY | |||
| } | |||
| inline bool Snappy_Uncompress(const char* input, size_t length, char* output) { | |||
| #if HAVE_SNAPPY | |||
| return snappy::RawUncompress(input, length, output); | |||
| #else | |||
| // Silence compiler warnings about unused arguments. | |||
| (void)input; | |||
| (void)length; | |||
| (void)output; | |||
| return false; | |||
| #endif // HAVE_SNAPPY | |||
| } | |||
| inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) { | |||
| // Silence compiler warnings about unused arguments. | |||
| (void)func; | |||
| (void)arg; | |||
| return false; | |||
| } | |||
| inline uint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size) { | |||
| #if HAVE_CRC32C | |||
| return ::crc32c::Extend(crc, reinterpret_cast<const uint8_t*>(buf), size); | |||
| #else | |||
| // Silence compiler warnings about unused arguments. | |||
| (void)crc; | |||
| (void)buf; | |||
| (void)size; | |||
| return 0; | |||
| #endif // HAVE_CRC32C | |||
| } | |||
| } // namespace port | |||
| } // namespace leveldb | |||
| #endif // STORAGE_LEVELDB_PORT_PORT_STDCXX_H_ | |||
| @ -1,24 +0,0 @@ | |||
| // 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. | |||
| // MSVC didn't ship with this file until the 2010 version. | |||
| #ifndef STORAGE_LEVELDB_PORT_WIN_STDINT_H_ | |||
| #define STORAGE_LEVELDB_PORT_WIN_STDINT_H_ | |||
| #if !defined(_MSC_VER) | |||
| #error This file should only be included when compiling with MSVC. | |||
| #endif | |||
| // Define C99 equivalent types. | |||
| typedef signed char int8_t; | |||
| typedef signed short int16_t; | |||
| typedef signed int int32_t; | |||
| typedef signed long long int64_t; | |||
| typedef unsigned char uint8_t; | |||
| typedef unsigned short uint16_t; | |||
| typedef unsigned int uint32_t; | |||
| typedef unsigned long long uint64_t; | |||
| #endif // STORAGE_LEVELDB_PORT_WIN_STDINT_H_ | |||