@ -0,0 +1,35 @@ | |||
# Build matrix / environment variables are explained on: | |||
# https://www.appveyor.com/docs/appveyor-yml/ | |||
# This file can be validated on: https://ci.appveyor.com/tools/validate-yaml | |||
version: "{build}" | |||
environment: | |||
matrix: | |||
# AppVeyor currently has no custom job name feature. | |||
# http://help.appveyor.com/discussions/questions/1623-can-i-provide-a-friendly-name-for-jobs | |||
- JOB: Visual Studio 2017 | |||
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 | |||
CMAKE_GENERATOR: Visual Studio 15 2017 | |||
platform: | |||
- x86 | |||
- x64 | |||
configuration: | |||
- RelWithDebInfo | |||
- Debug | |||
build_script: | |||
- git submodule update --init --recursive | |||
- mkdir build | |||
- cd build | |||
- if "%platform%"=="x64" set CMAKE_GENERATOR=%CMAKE_GENERATOR% Win64 | |||
- cmake --version | |||
- cmake .. -G "%CMAKE_GENERATOR%" | |||
-DCMAKE_CONFIGURATION_TYPES="%CONFIGURATION%" | |||
- cmake --build . --config "%CONFIGURATION%" | |||
- cd .. | |||
test_script: | |||
- cd build && ctest --verbose --build-config "%CONFIGURATION%" && cd .. |
@ -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 |
@ -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/ |
@ -1,13 +1,79 @@ | |||
# Build matrix / environment variables are explained on: | |||
# http://about.travis-ci.org/docs/user/build-configuration/ | |||
# This file can be validated on: http://lint.travis-ci.org/ | |||
language: cpp | |||
dist: xenial | |||
osx_image: xcode10.2 | |||
compiler: | |||
- clang | |||
- gcc | |||
- clang | |||
os: | |||
- linux | |||
- osx | |||
sudo: false | |||
before_install: | |||
- echo $LANG | |||
- echo $LC_ALL | |||
env: | |||
- BUILD_TYPE=Debug | |||
- BUILD_TYPE=RelWithDebInfo | |||
addons: | |||
apt: | |||
sources: | |||
- llvm-toolchain-xenial-8 | |||
- ubuntu-toolchain-r-test | |||
packages: | |||
- clang-8 | |||
- cmake | |||
- gcc-8 | |||
- g++-8 | |||
- libgoogle-perftools-dev | |||
- libkyotocabinet-dev | |||
- libsnappy-dev | |||
- libsqlite3-dev | |||
- ninja-build | |||
homebrew: | |||
packages: | |||
- cmake | |||
- crc32c | |||
- gcc@8 | |||
- gperftools | |||
- kyotocabinet | |||
- llvm@8 | |||
- ninja | |||
- snappy | |||
- sqlite3 | |||
update: true | |||
install: | |||
# The following Homebrew packages aren't linked by default, and need to be | |||
# prepended to the path explicitly. | |||
- if [ "$TRAVIS_OS_NAME" == "osx" ]; then | |||
export PATH="$(brew --prefix llvm)/bin:$PATH"; | |||
fi | |||
# /usr/bin/gcc points to an older compiler on both Linux and macOS. | |||
- if [ "$CXX" = "g++" ]; then export CXX="g++-8" CC="gcc-8"; fi | |||
# /usr/bin/clang points to an older compiler on both Linux and macOS. | |||
# | |||
# Homebrew's llvm package doesn't ship a versioned clang++ binary, so the values | |||
# below don't work on macOS. Fortunately, the path change above makes the | |||
# default values (clang and clang++) resolve to the correct compiler on macOS. | |||
- if [ "$TRAVIS_OS_NAME" == "linux" ]; then | |||
if [ "$CXX" = "clang++" ]; then export CXX="clang++-8" CC="clang-8"; fi; | |||
fi | |||
- echo ${CC} | |||
- echo ${CXX} | |||
- ${CXX} --version | |||
- cmake --version | |||
before_script: | |||
- mkdir -p build && cd build | |||
- cmake .. -G Ninja -DCMAKE_BUILD_TYPE=$BUILD_TYPE | |||
- cmake --build . | |||
- cd .. | |||
script: | |||
- make -j 4 check | |||
- cd build && ctest --verbose && cd .. | |||
- "if [ -f build/db_bench ] ; then build/db_bench ; fi" | |||
- "if [ -f build/db_bench_sqlite3 ] ; then build/db_bench_sqlite3 ; fi" | |||
- "if [ -f build/db_bench_tree_db ] ; then build/db_bench_tree_db ; fi" |
@ -0,0 +1,454 @@ | |||
# 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.22.0 LANGUAGES C CXX) | |||
# 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) | |||
# This project requires C++11. | |||
set(CMAKE_CXX_STANDARD 11) | |||
set(CMAKE_CXX_STANDARD_REQUIRED ON) | |||
set(CMAKE_CXX_EXTENSIONS OFF) | |||
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(TestBigEndian) | |||
test_big_endian(LEVELDB_IS_BIG_ENDIAN) | |||
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) | |||
include(CheckCXXSourceCompiles) | |||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wstrict-prototypes") | |||
# Test whether -Wthread-safety is available. See | |||
# https://clang.llvm.org/docs/ThreadSafetyAnalysis.html | |||
# -Werror is necessary because unknown attributes only generate warnings. | |||
set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS}) | |||
list(APPEND CMAKE_REQUIRED_FLAGS -Werror -Wthread-safety) | |||
check_cxx_source_compiles(" | |||
struct __attribute__((lockable)) Lock { | |||
void Acquire() __attribute__((exclusive_lock_function())); | |||
void Release() __attribute__((unlock_function())); | |||
}; | |||
struct ThreadSafeType { | |||
Lock lock_; | |||
int data_ __attribute__((guarded_by(lock_))); | |||
}; | |||
int main() { return 0; } | |||
" HAVE_CLANG_THREAD_SAFETY) | |||
set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS}) | |||
# 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( | |||
"${PROJECT_SOURCE_DIR}/port/port_config.h.in" | |||
"${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h" | |||
) | |||
include_directories( | |||
"${PROJECT_BINARY_DIR}/include" | |||
"${PROJECT_SOURCE_DIR}" | |||
) | |||
if(BUILD_SHARED_LIBS) | |||
# Only export LEVELDB_EXPORT symbols from the shared library. | |||
add_compile_options(-fvisibility=hidden) | |||
endif(BUILD_SHARED_LIBS) | |||
add_library(leveldb "") | |||
target_sources(leveldb | |||
PRIVATE | |||
"${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h" | |||
"${PROJECT_SOURCE_DIR}/db/builder.cc" | |||
"${PROJECT_SOURCE_DIR}/db/builder.h" | |||
"${PROJECT_SOURCE_DIR}/db/c.cc" | |||
"${PROJECT_SOURCE_DIR}/db/db_impl.cc" | |||
"${PROJECT_SOURCE_DIR}/db/db_impl.h" | |||
"${PROJECT_SOURCE_DIR}/db/db_iter.cc" | |||
"${PROJECT_SOURCE_DIR}/db/db_iter.h" | |||
"${PROJECT_SOURCE_DIR}/db/dbformat.cc" | |||
"${PROJECT_SOURCE_DIR}/db/dbformat.h" | |||
"${PROJECT_SOURCE_DIR}/db/dumpfile.cc" | |||
"${PROJECT_SOURCE_DIR}/db/filename.cc" | |||
"${PROJECT_SOURCE_DIR}/db/filename.h" | |||
"${PROJECT_SOURCE_DIR}/db/log_format.h" | |||
"${PROJECT_SOURCE_DIR}/db/log_reader.cc" | |||
"${PROJECT_SOURCE_DIR}/db/log_reader.h" | |||
"${PROJECT_SOURCE_DIR}/db/log_writer.cc" | |||
"${PROJECT_SOURCE_DIR}/db/log_writer.h" | |||
"${PROJECT_SOURCE_DIR}/db/memtable.cc" | |||
"${PROJECT_SOURCE_DIR}/db/memtable.h" | |||
"${PROJECT_SOURCE_DIR}/db/repair.cc" | |||
"${PROJECT_SOURCE_DIR}/db/skiplist.h" | |||
"${PROJECT_SOURCE_DIR}/db/snapshot.h" | |||
"${PROJECT_SOURCE_DIR}/db/table_cache.cc" | |||
"${PROJECT_SOURCE_DIR}/db/table_cache.h" | |||
"${PROJECT_SOURCE_DIR}/db/version_edit.cc" | |||
"${PROJECT_SOURCE_DIR}/db/version_edit.h" | |||
"${PROJECT_SOURCE_DIR}/db/version_set.cc" | |||
"${PROJECT_SOURCE_DIR}/db/version_set.h" | |||
"${PROJECT_SOURCE_DIR}/db/write_batch_internal.h" | |||
"${PROJECT_SOURCE_DIR}/db/write_batch.cc" | |||
"${PROJECT_SOURCE_DIR}/port/port_stdcxx.h" | |||
"${PROJECT_SOURCE_DIR}/port/port.h" | |||
"${PROJECT_SOURCE_DIR}/port/thread_annotations.h" | |||
"${PROJECT_SOURCE_DIR}/table/block_builder.cc" | |||
"${PROJECT_SOURCE_DIR}/table/block_builder.h" | |||
"${PROJECT_SOURCE_DIR}/table/block.cc" | |||
"${PROJECT_SOURCE_DIR}/table/block.h" | |||
"${PROJECT_SOURCE_DIR}/table/filter_block.cc" | |||
"${PROJECT_SOURCE_DIR}/table/filter_block.h" | |||
"${PROJECT_SOURCE_DIR}/table/format.cc" | |||
"${PROJECT_SOURCE_DIR}/table/format.h" | |||
"${PROJECT_SOURCE_DIR}/table/iterator_wrapper.h" | |||
"${PROJECT_SOURCE_DIR}/table/iterator.cc" | |||
"${PROJECT_SOURCE_DIR}/table/merger.cc" | |||
"${PROJECT_SOURCE_DIR}/table/merger.h" | |||
"${PROJECT_SOURCE_DIR}/table/table_builder.cc" | |||
"${PROJECT_SOURCE_DIR}/table/table.cc" | |||
"${PROJECT_SOURCE_DIR}/table/two_level_iterator.cc" | |||
"${PROJECT_SOURCE_DIR}/table/two_level_iterator.h" | |||
"${PROJECT_SOURCE_DIR}/util/arena.cc" | |||
"${PROJECT_SOURCE_DIR}/util/arena.h" | |||
"${PROJECT_SOURCE_DIR}/util/bloom.cc" | |||
"${PROJECT_SOURCE_DIR}/util/cache.cc" | |||
"${PROJECT_SOURCE_DIR}/util/coding.cc" | |||
"${PROJECT_SOURCE_DIR}/util/coding.h" | |||
"${PROJECT_SOURCE_DIR}/util/comparator.cc" | |||
"${PROJECT_SOURCE_DIR}/util/crc32c.cc" | |||
"${PROJECT_SOURCE_DIR}/util/crc32c.h" | |||
"${PROJECT_SOURCE_DIR}/util/env.cc" | |||
"${PROJECT_SOURCE_DIR}/util/filter_policy.cc" | |||
"${PROJECT_SOURCE_DIR}/util/hash.cc" | |||
"${PROJECT_SOURCE_DIR}/util/hash.h" | |||
"${PROJECT_SOURCE_DIR}/util/logging.cc" | |||
"${PROJECT_SOURCE_DIR}/util/logging.h" | |||
"${PROJECT_SOURCE_DIR}/util/mutexlock.h" | |||
"${PROJECT_SOURCE_DIR}/util/no_destructor.h" | |||
"${PROJECT_SOURCE_DIR}/util/options.cc" | |||
"${PROJECT_SOURCE_DIR}/util/random.h" | |||
"${PROJECT_SOURCE_DIR}/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 | |||
"${PROJECT_SOURCE_DIR}/util/env_windows.cc" | |||
"${PROJECT_SOURCE_DIR}/util/windows_logger.h" | |||
) | |||
else (WIN32) | |||
target_sources(leveldb | |||
PRIVATE | |||
"${PROJECT_SOURCE_DIR}/util/env_posix.cc" | |||
"${PROJECT_SOURCE_DIR}/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 | |||
"${PROJECT_SOURCE_DIR}/helpers/memenv/memenv.cc" | |||
"${PROJECT_SOURCE_DIR}/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 | |||
"${PROJECT_SOURCE_DIR}/db/leveldbutil.cc" | |||
) | |||
target_link_libraries(leveldbutil leveldb) | |||
if(LEVELDB_BUILD_TESTS) | |||
enable_testing() | |||
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" | |||
"${PROJECT_SOURCE_DIR}/util/testharness.cc" | |||
"${PROJECT_SOURCE_DIR}/util/testharness.h" | |||
"${PROJECT_SOURCE_DIR}/util/testutil.cc" | |||
"${PROJECT_SOURCE_DIR}/util/testutil.h" | |||
"${test_file}" | |||
) | |||
target_link_libraries("${test_target_name}" leveldb) | |||
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("${PROJECT_SOURCE_DIR}/db/c_test.c") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/db/fault_injection_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/issues/issue178_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/issues/issue200_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/issues/issue320_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/util/env_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/util/status_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/util/no_destructor_test.cc") | |||
if(NOT BUILD_SHARED_LIBS) | |||
leveldb_test("${PROJECT_SOURCE_DIR}/db/autocompact_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/db/corruption_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/db/db_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/db/dbformat_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/db/filename_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/db/log_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/db/recovery_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/db/skiplist_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/db/version_edit_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/db/version_set_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/db/write_batch_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/helpers/memenv/memenv_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/table/filter_block_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/table/table_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/util/arena_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/util/bloom_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/util/cache_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/util/coding_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/util/crc32c_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/util/hash_test.cc") | |||
leveldb_test("${PROJECT_SOURCE_DIR}/util/logging_test.cc") | |||
# TODO(costan): This test also uses | |||
# "${PROJECT_SOURCE_DIR}/util/env_{posix|windows}_test_helper.h" | |||
if (WIN32) | |||
leveldb_test("${PROJECT_SOURCE_DIR}/util/env_windows_test.cc") | |||
else (WIN32) | |||
leveldb_test("${PROJECT_SOURCE_DIR}/util/env_posix_test.cc") | |||
endif (WIN32) | |||
endif(NOT BUILD_SHARED_LIBS) | |||
endif(LEVELDB_BUILD_TESTS) | |||
if(LEVELDB_BUILD_BENCHMARKS) | |||
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" | |||
"${PROJECT_SOURCE_DIR}/util/histogram.cc" | |||
"${PROJECT_SOURCE_DIR}/util/histogram.h" | |||
"${PROJECT_SOURCE_DIR}/util/testharness.cc" | |||
"${PROJECT_SOURCE_DIR}/util/testharness.h" | |||
"${PROJECT_SOURCE_DIR}/util/testutil.cc" | |||
"${PROJECT_SOURCE_DIR}/util/testutil.h" | |||
"${bench_file}" | |||
) | |||
target_link_libraries("${bench_target_name}" leveldb) | |||
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("${PROJECT_SOURCE_DIR}/benchmarks/db_bench.cc") | |||
endif(NOT BUILD_SHARED_LIBS) | |||
check_library_exists(sqlite3 sqlite3_open "" HAVE_SQLITE3) | |||
if(HAVE_SQLITE3) | |||
leveldb_benchmark("${PROJECT_SOURCE_DIR}/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("${PROJECT_SOURCE_DIR}/benchmarks/db_bench_tree_db.cc") | |||
target_link_libraries(db_bench_tree_db kyotocabinet) | |||
endif(HAVE_KYOTOCABINET) | |||
endif(LEVELDB_BUILD_BENCHMARKS) | |||
if(LEVELDB_INSTALL) | |||
include(GNUInstallDirs) | |||
install(TARGETS leveldb | |||
EXPORT leveldbTargets | |||
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} | |||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} | |||
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} | |||
) | |||
install( | |||
FILES | |||
"${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/c.h" | |||
"${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/cache.h" | |||
"${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/comparator.h" | |||
"${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/db.h" | |||
"${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/dumpfile.h" | |||
"${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/env.h" | |||
"${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/export.h" | |||
"${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/filter_policy.h" | |||
"${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/iterator.h" | |||
"${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/options.h" | |||
"${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/slice.h" | |||
"${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/status.h" | |||
"${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/table_builder.h" | |||
"${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/table.h" | |||
"${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/write_batch.h" | |||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/leveldb | |||
) | |||
include(CMakePackageConfigHelpers) | |||
write_basic_package_version_file( | |||
"${PROJECT_BINARY_DIR}/leveldbConfigVersion.cmake" | |||
COMPATIBILITY SameMajorVersion | |||
) | |||
install( | |||
EXPORT leveldbTargets | |||
NAMESPACE leveldb:: | |||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/leveldb" | |||
) | |||
install( | |||
FILES | |||
"${PROJECT_SOURCE_DIR}/cmake/leveldbConfig.cmake" | |||
"${PROJECT_BINARY_DIR}/leveldbConfigVersion.cmake" | |||
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/leveldb" | |||
) | |||
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 $@ |
@ -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 -DOS_MACOSX" | |||
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 -DOS_MACOSX" | |||
[ -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 @@ | |||
include("${CMAKE_CURRENT_LIST_DIR}/leveldbTargets.cmake") |
@ -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,128 @@ | |||
// 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 "leveldb/db.h" | |||
#include "leveldb/write_batch.h" | |||
#include "util/testharness.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 | |||
class Issue320 {}; | |||
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 = test::TmpDir() + "/leveldb_issue320_test"; | |||
ASSERT_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_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_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 | |||
int main(int argc, char** argv) { return leveldb::test::RunAllTests(); } |
@ -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 OS_MACOSX | |||
#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(OS_MACOSX) | |||
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,39 @@ | |||
// 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) | |||
// Define to 1 if your processor stores words with the most significant byte | |||
// first (like Motorola and SPARC, unlike Intel and VAX). | |||
#if !defined(LEVELDB_IS_BIG_ENDIAN) | |||
#cmakedefine01 LEVELDB_IS_BIG_ENDIAN | |||
#endif // !defined(LEVELDB_IS_BIG_ENDIAN) | |||
#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(OS_MACOSX) | |||
#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(OS_MACOSX) || 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(OS_MACOSX) || 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,129 +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) { | |||
// Process unaligned bytes | |||
for (unsigned int i = reinterpret_cast<uintptr_t>(p) % 8; i; --i) { | |||
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,153 @@ | |||
// 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 { | |||
static const bool kLittleEndian = !LEVELDB_IS_BIG_ENDIAN; | |||
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_ |