作者: 谢瑞阳 10225101483 徐翔宇 10225101535
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

454 lines
16 KiB

leveldb: Fix PosixWritableFile::Sync() on Apple systems. Apple doesn't follow POSIX specifications for fsync(). Instead, fsync() guarantees to flush the buffer cache to the device, which means the data will survive kernel panics, but may not survive power outages. Applications that need stronger guarantees (like databases) need to use fcntl(F_FULLFSYNC). This CL switches PosixWritableFile::Sync() to get the stronger guarantees on Apple systems. The improved implementation follows the same principles as SQLite [1] and node.js [2]. Research for the fcntl() to fsync() fallback strategy: Apple's released source code at https://opensource.apple.com/ shows at least three different error codes being returned when a filesystem does not support F_FULLFSYNC. fcntl() is implemented in xnu-4903.221.2 in bsd/kern/kern_descrip.c, where it delegates to fcntl_nocancel(). The documentation for fcntl_nocancel() mentions error codes for some operations, but does not include F_FULLFSYNC. The F_FULLSYNC branch in fcntl_nocancel() calls VNOP_IOCTL(_, F_FULLSYNC, NULL, 0, _), whose return value sets the error code. VNOP_IOCTL() is implemented in bsd/vfs/kpi_vfs.c and calls the ioctl function in the vnode's operation vector. The per-filesystem function names follow the pattern _vnop_ioctl() for all the instances in opensource code: {hfs,msdosfs,nfs,ntfs,smbfs,webdav,zfs}_vnop_ioctl(). hfs-407.30.1, msdosfs-229.200.3, and nfs in xnu-4903.221.2 handle F_FULLFSYNC. ntfs-94.200.1 and smb-759.40.1 do not handle F_FULLFSYNC, and the default branch returns ENOSUP. webdav-380.200.1 also does not handle F_FULLFSYNC, but the default branch returns EINVAL. zfs-59 also does not handle F_FULLSYNC, and its default branch returns ENOTTY. From a different angle, Apple's ntfs-94.200.1 includes utility code that uses fcntl(F_FULLFSYNC) and falls back to fsync() just like we do, supporting the hypothesis that there is no good way to detect lack of F_FULLFSYNC support. Also, Apple's fcntl() man page [3] does not mention a way to detect lack of F_FULLFSYNC support. [1] https://www.sqlite.org/src/doc/trunk/src/os_unix.c [2] https://github.com/libuv/libuv/blob/master/src/unix/fs.c [3] https://developer.apple.com/library/archive/documentatiVon/System/Conceptual/ManPages_iPhoneOS/man2/fcntl.2.html Tested: https://travis-ci.org/pwnall/leveldb/builds/477318498 TAP global presubmit ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=228593729
6 years ago
Fix snapshot compaction bug Closes google/leveldb#320 During compaction it was possible that records from a block b1=(l1,u1) would be pushed down from level i to level i+1. If there is a block b2=(l2,u2) at level i with k1 = user_key(u1) = user_key(l2) then a subsequent search for k1 will yield the record l2 which has a smaller sequence number than u1 because the sort order for records sorts increasing by user key but decreaing by sequence number. This change add a call to a new function AddBoundaryInputs to SetupOtherInputs. AddBoundaryInputs searches for a block b2 matching the criteria above and adds it to the set of files to be compacted. Whenever AddBoundaryInputs is called it is important that the compaction fileset in level i+1 (known as c->inputs_[1] in the code) be recomputed. Each call to AddBoundaryInputs is followed by a call to GetOverlappingInputs. SetupOtherInputs is called on both manual and automated compaction passes. It is called for both level zero and for levels greater than 0. The original change posted in https://github.com/google/leveldb/pull/339 has been modified to also include changed made by Chris Mumford<cmumford@google.com> in https://github.com/cmumford/leveldb/commit/4b72cb14f8da2aab12451c24b8e205aff686e9dc 1. Releasing snapshots during test cleanup to avoid memory leak warnings. 2. Refactored test to use testutil.h to be in line with other issue tests and to create the test database in the correct temporary location. 3. Added copyright banner. Otherwise, just minor formatting and limiting character width to 80 characters. Additionally the change was rebased on top of current master and changes previously made to the Makefile were ported to the CMakeLists.txt. Testing Done: A test program (issue320_test) was constructed that performs mutations while snapshots are active. issue320_test fails without this bug fix after 64k writes. It passes with this bug fix. It was run with 200M writes and passed. Unit tests were written for the new function that was added to the code. Make test was run and seen to pass. Signed-off-by: Richard Cole <richcole@amazon.com>
9 years ago
Add move constructor to Status. This will result in smaller code generation when Status instances are passed around. Benchmarks don't indicate a significant change either way. CPU: 48 * Intel(R) Xeon(R) CPU E5-2690 v3 @ 2.60GHz CPUCache: 30720 KB Keys: 16 bytes each Values: 100 bytes each (50 bytes after compression) Entries: 1000000 RawSize: 110.6 MB (estimated) FileSize: 62.9 MB (estimated) Baseline: fillseq : 3.589 micros/op; 30.8 MB/s fillsync : 4165.299 micros/op; 0.0 MB/s (1000 ops) fillrandom : 5.864 micros/op; 18.9 MB/s overwrite : 7.830 micros/op; 14.1 MB/s readrandom : 5.534 micros/op; (1000000 of 1000000 found) readrandom : 4.292 micros/op; (1000000 of 1000000 found) readseq : 0.312 micros/op; 354.1 MB/s readreverse : 0.501 micros/op; 220.8 MB/s compact : 886211.000 micros/op; readrandom : 3.518 micros/op; (1000000 of 1000000 found) readseq : 0.251 micros/op; 441.2 MB/s readreverse : 0.456 micros/op; 242.4 MB/s fill100K : 1329.723 micros/op; 71.7 MB/s (1000 ops) crc32c : 1.976 micros/op; 1976.7 MB/s (4K per op) snappycomp : 4.705 micros/op; 830.2 MB/s (output: 55.1%) snappyuncomp : 0.958 micros/op; 4079.1 MB/s acquireload : 0.727 micros/op; (each op is 1000 loads) New: fillseq : 3.129 micros/op; 35.4 MB/s fillsync : 2748.099 micros/op; 0.0 MB/s (1000 ops) fillrandom : 5.394 micros/op; 20.5 MB/s overwrite : 7.253 micros/op; 15.3 MB/s readrandom : 5.655 micros/op; (1000000 of 1000000 found) readrandom : 4.425 micros/op; (1000000 of 1000000 found) readseq : 0.298 micros/op; 371.3 MB/s readreverse : 0.508 micros/op; 217.9 MB/s compact : 885842.000 micros/op; readrandom : 3.545 micros/op; (1000000 of 1000000 found) readseq : 0.252 micros/op; 438.2 MB/s readreverse : 0.425 micros/op; 260.2 MB/s fill100K : 1418.347 micros/op; 67.2 MB/s (1000 ops) crc32c : 1.987 micros/op; 1966.0 MB/s (4K per op) snappycomp : 4.767 micros/op; 819.4 MB/s (output: 55.1%) snappyuncomp : 0.916 micros/op; 4264.9 MB/s acquireload : 0.665 micros/op; (each op is 1000 loads) ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=194002392
6 years ago
  1. # Copyright 2017 The LevelDB Authors. All rights reserved.
  2. # Use of this source code is governed by a BSD-style license that can be
  3. # found in the LICENSE file. See the AUTHORS file for names of contributors.
  4. cmake_minimum_required(VERSION 3.9)
  5. # Keep the version below in sync with the one in db.h
  6. project(leveldb VERSION 1.22.0 LANGUAGES C CXX)
  7. # This project can use C11, but will gracefully decay down to C89.
  8. set(CMAKE_C_STANDARD 11)
  9. set(CMAKE_C_STANDARD_REQUIRED OFF)
  10. set(CMAKE_C_EXTENSIONS OFF)
  11. # This project requires C++11.
  12. set(CMAKE_CXX_STANDARD 11)
  13. set(CMAKE_CXX_STANDARD_REQUIRED ON)
  14. set(CMAKE_CXX_EXTENSIONS OFF)
  15. if (WIN32)
  16. set(LEVELDB_PLATFORM_NAME LEVELDB_PLATFORM_WINDOWS)
  17. # TODO(cmumford): Make UNICODE configurable for Windows.
  18. add_definitions(-D_UNICODE -DUNICODE)
  19. else (WIN32)
  20. set(LEVELDB_PLATFORM_NAME LEVELDB_PLATFORM_POSIX)
  21. endif (WIN32)
  22. option(LEVELDB_BUILD_TESTS "Build LevelDB's unit tests" ON)
  23. option(LEVELDB_BUILD_BENCHMARKS "Build LevelDB's benchmarks" ON)
  24. option(LEVELDB_INSTALL "Install LevelDB's header and library" ON)
  25. include(TestBigEndian)
  26. test_big_endian(LEVELDB_IS_BIG_ENDIAN)
  27. include(CheckIncludeFile)
  28. check_include_file("unistd.h" HAVE_UNISTD_H)
  29. include(CheckLibraryExists)
  30. check_library_exists(crc32c crc32c_value "" HAVE_CRC32C)
  31. check_library_exists(snappy snappy_compress "" HAVE_SNAPPY)
  32. check_library_exists(tcmalloc malloc "" HAVE_TCMALLOC)
  33. include(CheckCXXSymbolExists)
  34. # Using check_cxx_symbol_exists() instead of check_c_symbol_exists() because
  35. # we're including the header from C++, and feature detection should use the same
  36. # compiler language that the project will use later. Principles aside, some
  37. # versions of do not expose fdatasync() in <unistd.h> in standard C mode
  38. # (-std=c11), but do expose the function in standard C++ mode (-std=c++11).
  39. check_cxx_symbol_exists(fdatasync "unistd.h" HAVE_FDATASYNC)
  40. check_cxx_symbol_exists(F_FULLFSYNC "fcntl.h" HAVE_FULLFSYNC)
  41. check_cxx_symbol_exists(O_CLOEXEC "fcntl.h" HAVE_O_CLOEXEC)
  42. include(CheckCXXSourceCompiles)
  43. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wstrict-prototypes")
  44. # Test whether -Wthread-safety is available. See
  45. # https://clang.llvm.org/docs/ThreadSafetyAnalysis.html
  46. # -Werror is necessary because unknown attributes only generate warnings.
  47. set(OLD_CMAKE_REQUIRED_FLAGS ${CMAKE_REQUIRED_FLAGS})
  48. list(APPEND CMAKE_REQUIRED_FLAGS -Werror -Wthread-safety)
  49. check_cxx_source_compiles("
  50. struct __attribute__((lockable)) Lock {
  51. void Acquire() __attribute__((exclusive_lock_function()));
  52. void Release() __attribute__((unlock_function()));
  53. };
  54. struct ThreadSafeType {
  55. Lock lock_;
  56. int data_ __attribute__((guarded_by(lock_)));
  57. };
  58. int main() { return 0; }
  59. " HAVE_CLANG_THREAD_SAFETY)
  60. set(CMAKE_REQUIRED_FLAGS ${OLD_CMAKE_REQUIRED_FLAGS})
  61. # Test whether C++17 __has_include is available.
  62. check_cxx_source_compiles("
  63. #if defined(__has_include) && __has_include(<string>)
  64. #include <string>
  65. #endif
  66. int main() { std::string str; return 0; }
  67. " HAVE_CXX17_HAS_INCLUDE)
  68. set(LEVELDB_PUBLIC_INCLUDE_DIR "include/leveldb")
  69. set(LEVELDB_PORT_CONFIG_DIR "include/port")
  70. configure_file(
  71. "${PROJECT_SOURCE_DIR}/port/port_config.h.in"
  72. "${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h"
  73. )
  74. include_directories(
  75. "${PROJECT_BINARY_DIR}/include"
  76. "${PROJECT_SOURCE_DIR}"
  77. )
  78. if(BUILD_SHARED_LIBS)
  79. # Only export LEVELDB_EXPORT symbols from the shared library.
  80. add_compile_options(-fvisibility=hidden)
  81. endif(BUILD_SHARED_LIBS)
  82. add_library(leveldb "")
  83. target_sources(leveldb
  84. PRIVATE
  85. "${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h"
  86. "${PROJECT_SOURCE_DIR}/db/builder.cc"
  87. "${PROJECT_SOURCE_DIR}/db/builder.h"
  88. "${PROJECT_SOURCE_DIR}/db/c.cc"
  89. "${PROJECT_SOURCE_DIR}/db/db_impl.cc"
  90. "${PROJECT_SOURCE_DIR}/db/db_impl.h"
  91. "${PROJECT_SOURCE_DIR}/db/db_iter.cc"
  92. "${PROJECT_SOURCE_DIR}/db/db_iter.h"
  93. "${PROJECT_SOURCE_DIR}/db/dbformat.cc"
  94. "${PROJECT_SOURCE_DIR}/db/dbformat.h"
  95. "${PROJECT_SOURCE_DIR}/db/dumpfile.cc"
  96. "${PROJECT_SOURCE_DIR}/db/filename.cc"
  97. "${PROJECT_SOURCE_DIR}/db/filename.h"
  98. "${PROJECT_SOURCE_DIR}/db/log_format.h"
  99. "${PROJECT_SOURCE_DIR}/db/log_reader.cc"
  100. "${PROJECT_SOURCE_DIR}/db/log_reader.h"
  101. "${PROJECT_SOURCE_DIR}/db/log_writer.cc"
  102. "${PROJECT_SOURCE_DIR}/db/log_writer.h"
  103. "${PROJECT_SOURCE_DIR}/db/memtable.cc"
  104. "${PROJECT_SOURCE_DIR}/db/memtable.h"
  105. "${PROJECT_SOURCE_DIR}/db/repair.cc"
  106. "${PROJECT_SOURCE_DIR}/db/skiplist.h"
  107. "${PROJECT_SOURCE_DIR}/db/snapshot.h"
  108. "${PROJECT_SOURCE_DIR}/db/table_cache.cc"
  109. "${PROJECT_SOURCE_DIR}/db/table_cache.h"
  110. "${PROJECT_SOURCE_DIR}/db/version_edit.cc"
  111. "${PROJECT_SOURCE_DIR}/db/version_edit.h"
  112. "${PROJECT_SOURCE_DIR}/db/version_set.cc"
  113. "${PROJECT_SOURCE_DIR}/db/version_set.h"
  114. "${PROJECT_SOURCE_DIR}/db/write_batch_internal.h"
  115. "${PROJECT_SOURCE_DIR}/db/write_batch.cc"
  116. "${PROJECT_SOURCE_DIR}/port/port_stdcxx.h"
  117. "${PROJECT_SOURCE_DIR}/port/port.h"
  118. "${PROJECT_SOURCE_DIR}/port/thread_annotations.h"
  119. "${PROJECT_SOURCE_DIR}/table/block_builder.cc"
  120. "${PROJECT_SOURCE_DIR}/table/block_builder.h"
  121. "${PROJECT_SOURCE_DIR}/table/block.cc"
  122. "${PROJECT_SOURCE_DIR}/table/block.h"
  123. "${PROJECT_SOURCE_DIR}/table/filter_block.cc"
  124. "${PROJECT_SOURCE_DIR}/table/filter_block.h"
  125. "${PROJECT_SOURCE_DIR}/table/format.cc"
  126. "${PROJECT_SOURCE_DIR}/table/format.h"
  127. "${PROJECT_SOURCE_DIR}/table/iterator_wrapper.h"
  128. "${PROJECT_SOURCE_DIR}/table/iterator.cc"
  129. "${PROJECT_SOURCE_DIR}/table/merger.cc"
  130. "${PROJECT_SOURCE_DIR}/table/merger.h"
  131. "${PROJECT_SOURCE_DIR}/table/table_builder.cc"
  132. "${PROJECT_SOURCE_DIR}/table/table.cc"
  133. "${PROJECT_SOURCE_DIR}/table/two_level_iterator.cc"
  134. "${PROJECT_SOURCE_DIR}/table/two_level_iterator.h"
  135. "${PROJECT_SOURCE_DIR}/util/arena.cc"
  136. "${PROJECT_SOURCE_DIR}/util/arena.h"
  137. "${PROJECT_SOURCE_DIR}/util/bloom.cc"
  138. "${PROJECT_SOURCE_DIR}/util/cache.cc"
  139. "${PROJECT_SOURCE_DIR}/util/coding.cc"
  140. "${PROJECT_SOURCE_DIR}/util/coding.h"
  141. "${PROJECT_SOURCE_DIR}/util/comparator.cc"
  142. "${PROJECT_SOURCE_DIR}/util/crc32c.cc"
  143. "${PROJECT_SOURCE_DIR}/util/crc32c.h"
  144. "${PROJECT_SOURCE_DIR}/util/env.cc"
  145. "${PROJECT_SOURCE_DIR}/util/filter_policy.cc"
  146. "${PROJECT_SOURCE_DIR}/util/hash.cc"
  147. "${PROJECT_SOURCE_DIR}/util/hash.h"
  148. "${PROJECT_SOURCE_DIR}/util/logging.cc"
  149. "${PROJECT_SOURCE_DIR}/util/logging.h"
  150. "${PROJECT_SOURCE_DIR}/util/mutexlock.h"
  151. "${PROJECT_SOURCE_DIR}/util/no_destructor.h"
  152. "${PROJECT_SOURCE_DIR}/util/options.cc"
  153. "${PROJECT_SOURCE_DIR}/util/random.h"
  154. "${PROJECT_SOURCE_DIR}/util/status.cc"
  155. # Only CMake 3.3+ supports PUBLIC sources in targets exported by "install".
  156. $<$<VERSION_GREATER:CMAKE_VERSION,3.2>:PUBLIC>
  157. "${LEVELDB_PUBLIC_INCLUDE_DIR}/c.h"
  158. "${LEVELDB_PUBLIC_INCLUDE_DIR}/cache.h"
  159. "${LEVELDB_PUBLIC_INCLUDE_DIR}/comparator.h"
  160. "${LEVELDB_PUBLIC_INCLUDE_DIR}/db.h"
  161. "${LEVELDB_PUBLIC_INCLUDE_DIR}/dumpfile.h"
  162. "${LEVELDB_PUBLIC_INCLUDE_DIR}/env.h"
  163. "${LEVELDB_PUBLIC_INCLUDE_DIR}/export.h"
  164. "${LEVELDB_PUBLIC_INCLUDE_DIR}/filter_policy.h"
  165. "${LEVELDB_PUBLIC_INCLUDE_DIR}/iterator.h"
  166. "${LEVELDB_PUBLIC_INCLUDE_DIR}/options.h"
  167. "${LEVELDB_PUBLIC_INCLUDE_DIR}/slice.h"
  168. "${LEVELDB_PUBLIC_INCLUDE_DIR}/status.h"
  169. "${LEVELDB_PUBLIC_INCLUDE_DIR}/table_builder.h"
  170. "${LEVELDB_PUBLIC_INCLUDE_DIR}/table.h"
  171. "${LEVELDB_PUBLIC_INCLUDE_DIR}/write_batch.h"
  172. )
  173. if (WIN32)
  174. target_sources(leveldb
  175. PRIVATE
  176. "${PROJECT_SOURCE_DIR}/util/env_windows.cc"
  177. "${PROJECT_SOURCE_DIR}/util/windows_logger.h"
  178. )
  179. else (WIN32)
  180. target_sources(leveldb
  181. PRIVATE
  182. "${PROJECT_SOURCE_DIR}/util/env_posix.cc"
  183. "${PROJECT_SOURCE_DIR}/util/posix_logger.h"
  184. )
  185. endif (WIN32)
  186. # MemEnv is not part of the interface and could be pulled to a separate library.
  187. target_sources(leveldb
  188. PRIVATE
  189. "${PROJECT_SOURCE_DIR}/helpers/memenv/memenv.cc"
  190. "${PROJECT_SOURCE_DIR}/helpers/memenv/memenv.h"
  191. )
  192. target_include_directories(leveldb
  193. PUBLIC
  194. $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
  195. $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
  196. )
  197. set_target_properties(leveldb
  198. PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION ${PROJECT_VERSION_MAJOR})
  199. target_compile_definitions(leveldb
  200. PRIVATE
  201. # Used by include/export.h when building shared libraries.
  202. LEVELDB_COMPILE_LIBRARY
  203. # Used by port/port.h.
  204. ${LEVELDB_PLATFORM_NAME}=1
  205. )
  206. if (NOT HAVE_CXX17_HAS_INCLUDE)
  207. target_compile_definitions(leveldb
  208. PRIVATE
  209. LEVELDB_HAS_PORT_CONFIG_H=1
  210. )
  211. endif(NOT HAVE_CXX17_HAS_INCLUDE)
  212. if(BUILD_SHARED_LIBS)
  213. target_compile_definitions(leveldb
  214. PUBLIC
  215. # Used by include/export.h.
  216. LEVELDB_SHARED_LIBRARY
  217. )
  218. endif(BUILD_SHARED_LIBS)
  219. if(HAVE_CLANG_THREAD_SAFETY)
  220. target_compile_options(leveldb
  221. PUBLIC
  222. -Werror -Wthread-safety)
  223. endif(HAVE_CLANG_THREAD_SAFETY)
  224. if(HAVE_CRC32C)
  225. target_link_libraries(leveldb crc32c)
  226. endif(HAVE_CRC32C)
  227. if(HAVE_SNAPPY)
  228. target_link_libraries(leveldb snappy)
  229. endif(HAVE_SNAPPY)
  230. if(HAVE_TCMALLOC)
  231. target_link_libraries(leveldb tcmalloc)
  232. endif(HAVE_TCMALLOC)
  233. # Needed by port_stdcxx.h
  234. find_package(Threads REQUIRED)
  235. target_link_libraries(leveldb Threads::Threads)
  236. add_executable(leveldbutil
  237. "${PROJECT_SOURCE_DIR}/db/leveldbutil.cc"
  238. )
  239. target_link_libraries(leveldbutil leveldb)
  240. if(LEVELDB_BUILD_TESTS)
  241. enable_testing()
  242. function(leveldb_test test_file)
  243. get_filename_component(test_target_name "${test_file}" NAME_WE)
  244. add_executable("${test_target_name}" "")
  245. target_sources("${test_target_name}"
  246. PRIVATE
  247. "${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h"
  248. "${PROJECT_SOURCE_DIR}/util/testharness.cc"
  249. "${PROJECT_SOURCE_DIR}/util/testharness.h"
  250. "${PROJECT_SOURCE_DIR}/util/testutil.cc"
  251. "${PROJECT_SOURCE_DIR}/util/testutil.h"
  252. "${test_file}"
  253. )
  254. target_link_libraries("${test_target_name}" leveldb)
  255. target_compile_definitions("${test_target_name}"
  256. PRIVATE
  257. ${LEVELDB_PLATFORM_NAME}=1
  258. )
  259. if (NOT HAVE_CXX17_HAS_INCLUDE)
  260. target_compile_definitions("${test_target_name}"
  261. PRIVATE
  262. LEVELDB_HAS_PORT_CONFIG_H=1
  263. )
  264. endif(NOT HAVE_CXX17_HAS_INCLUDE)
  265. add_test(NAME "${test_target_name}" COMMAND "${test_target_name}")
  266. endfunction(leveldb_test)
  267. leveldb_test("${PROJECT_SOURCE_DIR}/db/c_test.c")
  268. leveldb_test("${PROJECT_SOURCE_DIR}/db/fault_injection_test.cc")
  269. leveldb_test("${PROJECT_SOURCE_DIR}/issues/issue178_test.cc")
  270. leveldb_test("${PROJECT_SOURCE_DIR}/issues/issue200_test.cc")
  271. leveldb_test("${PROJECT_SOURCE_DIR}/issues/issue320_test.cc")
  272. leveldb_test("${PROJECT_SOURCE_DIR}/util/env_test.cc")
  273. leveldb_test("${PROJECT_SOURCE_DIR}/util/status_test.cc")
  274. leveldb_test("${PROJECT_SOURCE_DIR}/util/no_destructor_test.cc")
  275. if(NOT BUILD_SHARED_LIBS)
  276. leveldb_test("${PROJECT_SOURCE_DIR}/db/autocompact_test.cc")
  277. leveldb_test("${PROJECT_SOURCE_DIR}/db/corruption_test.cc")
  278. leveldb_test("${PROJECT_SOURCE_DIR}/db/db_test.cc")
  279. leveldb_test("${PROJECT_SOURCE_DIR}/db/dbformat_test.cc")
  280. leveldb_test("${PROJECT_SOURCE_DIR}/db/filename_test.cc")
  281. leveldb_test("${PROJECT_SOURCE_DIR}/db/log_test.cc")
  282. leveldb_test("${PROJECT_SOURCE_DIR}/db/recovery_test.cc")
  283. leveldb_test("${PROJECT_SOURCE_DIR}/db/skiplist_test.cc")
  284. leveldb_test("${PROJECT_SOURCE_DIR}/db/version_edit_test.cc")
  285. leveldb_test("${PROJECT_SOURCE_DIR}/db/version_set_test.cc")
  286. leveldb_test("${PROJECT_SOURCE_DIR}/db/write_batch_test.cc")
  287. leveldb_test("${PROJECT_SOURCE_DIR}/helpers/memenv/memenv_test.cc")
  288. leveldb_test("${PROJECT_SOURCE_DIR}/table/filter_block_test.cc")
  289. leveldb_test("${PROJECT_SOURCE_DIR}/table/table_test.cc")
  290. leveldb_test("${PROJECT_SOURCE_DIR}/util/arena_test.cc")
  291. leveldb_test("${PROJECT_SOURCE_DIR}/util/bloom_test.cc")
  292. leveldb_test("${PROJECT_SOURCE_DIR}/util/cache_test.cc")
  293. leveldb_test("${PROJECT_SOURCE_DIR}/util/coding_test.cc")
  294. leveldb_test("${PROJECT_SOURCE_DIR}/util/crc32c_test.cc")
  295. leveldb_test("${PROJECT_SOURCE_DIR}/util/hash_test.cc")
  296. leveldb_test("${PROJECT_SOURCE_DIR}/util/logging_test.cc")
  297. # TODO(costan): This test also uses
  298. # "${PROJECT_SOURCE_DIR}/util/env_{posix|windows}_test_helper.h"
  299. if (WIN32)
  300. leveldb_test("${PROJECT_SOURCE_DIR}/util/env_windows_test.cc")
  301. else (WIN32)
  302. leveldb_test("${PROJECT_SOURCE_DIR}/util/env_posix_test.cc")
  303. endif (WIN32)
  304. endif(NOT BUILD_SHARED_LIBS)
  305. endif(LEVELDB_BUILD_TESTS)
  306. if(LEVELDB_BUILD_BENCHMARKS)
  307. function(leveldb_benchmark bench_file)
  308. get_filename_component(bench_target_name "${bench_file}" NAME_WE)
  309. add_executable("${bench_target_name}" "")
  310. target_sources("${bench_target_name}"
  311. PRIVATE
  312. "${PROJECT_BINARY_DIR}/${LEVELDB_PORT_CONFIG_DIR}/port_config.h"
  313. "${PROJECT_SOURCE_DIR}/util/histogram.cc"
  314. "${PROJECT_SOURCE_DIR}/util/histogram.h"
  315. "${PROJECT_SOURCE_DIR}/util/testharness.cc"
  316. "${PROJECT_SOURCE_DIR}/util/testharness.h"
  317. "${PROJECT_SOURCE_DIR}/util/testutil.cc"
  318. "${PROJECT_SOURCE_DIR}/util/testutil.h"
  319. "${bench_file}"
  320. )
  321. target_link_libraries("${bench_target_name}" leveldb)
  322. target_compile_definitions("${bench_target_name}"
  323. PRIVATE
  324. ${LEVELDB_PLATFORM_NAME}=1
  325. )
  326. if (NOT HAVE_CXX17_HAS_INCLUDE)
  327. target_compile_definitions("${bench_target_name}"
  328. PRIVATE
  329. LEVELDB_HAS_PORT_CONFIG_H=1
  330. )
  331. endif(NOT HAVE_CXX17_HAS_INCLUDE)
  332. endfunction(leveldb_benchmark)
  333. if(NOT BUILD_SHARED_LIBS)
  334. leveldb_benchmark("${PROJECT_SOURCE_DIR}/benchmarks/db_bench.cc")
  335. endif(NOT BUILD_SHARED_LIBS)
  336. check_library_exists(sqlite3 sqlite3_open "" HAVE_SQLITE3)
  337. if(HAVE_SQLITE3)
  338. leveldb_benchmark("${PROJECT_SOURCE_DIR}/benchmarks/db_bench_sqlite3.cc")
  339. target_link_libraries(db_bench_sqlite3 sqlite3)
  340. endif(HAVE_SQLITE3)
  341. # check_library_exists is insufficient here because the library names have
  342. # different manglings when compiled with clang or gcc, at least when installed
  343. # with Homebrew on Mac.
  344. set(OLD_CMAKE_REQURED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES})
  345. list(APPEND CMAKE_REQUIRED_LIBRARIES kyotocabinet)
  346. check_cxx_source_compiles("
  347. #include <kcpolydb.h>
  348. int main() {
  349. kyotocabinet::TreeDB* db = new kyotocabinet::TreeDB();
  350. delete db;
  351. return 0;
  352. }
  353. " HAVE_KYOTOCABINET)
  354. set(CMAKE_REQUIRED_LIBRARIES ${OLD_CMAKE_REQURED_LIBRARIES})
  355. if(HAVE_KYOTOCABINET)
  356. leveldb_benchmark("${PROJECT_SOURCE_DIR}/benchmarks/db_bench_tree_db.cc")
  357. target_link_libraries(db_bench_tree_db kyotocabinet)
  358. endif(HAVE_KYOTOCABINET)
  359. endif(LEVELDB_BUILD_BENCHMARKS)
  360. if(LEVELDB_INSTALL)
  361. include(GNUInstallDirs)
  362. install(TARGETS leveldb
  363. EXPORT leveldbTargets
  364. RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
  365. LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
  366. ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
  367. )
  368. install(
  369. FILES
  370. "${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/c.h"
  371. "${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/cache.h"
  372. "${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/comparator.h"
  373. "${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/db.h"
  374. "${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/dumpfile.h"
  375. "${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/env.h"
  376. "${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/export.h"
  377. "${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/filter_policy.h"
  378. "${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/iterator.h"
  379. "${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/options.h"
  380. "${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/slice.h"
  381. "${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/status.h"
  382. "${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/table_builder.h"
  383. "${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/table.h"
  384. "${PROJECT_SOURCE_DIR}/${LEVELDB_PUBLIC_INCLUDE_DIR}/write_batch.h"
  385. DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/leveldb
  386. )
  387. include(CMakePackageConfigHelpers)
  388. write_basic_package_version_file(
  389. "${PROJECT_BINARY_DIR}/leveldbConfigVersion.cmake"
  390. COMPATIBILITY SameMajorVersion
  391. )
  392. install(
  393. EXPORT leveldbTargets
  394. NAMESPACE leveldb::
  395. DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/leveldb"
  396. )
  397. install(
  398. FILES
  399. "${PROJECT_SOURCE_DIR}/cmake/leveldbConfig.cmake"
  400. "${PROJECT_BINARY_DIR}/leveldbConfigVersion.cmake"
  401. DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/leveldb"
  402. )
  403. endif(LEVELDB_INSTALL)