From 7d2acd6395ec84beca34718a75371bc11f0c9f60 Mon Sep 17 00:00:00 2001 From: Alex Gorrod Date: Tue, 13 Sep 2016 10:27:16 +1000 Subject: Import wiredtiger: 911c940adab547d36ac305fc627a79e637fa3c40 from branch mongodb-3.2 ref: dddca65..911c940ada for: 3.2.10 SERVER-24971 Excessive memory held by sessions when application threads do evictions SERVER-25843 Coverity analysis defect 99856: Redundant test SERVER-25845 Coverity analysis defect 99859: Explicit null dereferenced SERVER-25846 Coverity analysis defect 99861: Dereference after null check WT-1162 Add latency to Jenkins wtperf tests and plots WT-2026 Maximum pages size at eviction too large WT-2221 Document which statistics are available via a "fast" configuration vs. an "all" configuration WT-2233 Investigate changing when the eviction server switches to aggressive mode. WT-2239 Make sure LSM cursors read up to date dsk_gen, it was racing with compact WT-2323 Allocate a transaction id at the beginning of join cursor iteration WT-2353 Failure to create async threads as part of a wiredtiger_open call will cause a hang WT-2380 Make scripts fail if code doesn't match style WT-2486 Update make check so that it runs faster WT-2555 make format run on Windows WT-2578 remove write barriers from the TAILQ_INSERT_XXX macros WT-2631 nullptr is passed for parameters marked with attribute non-null WT-2638 ftruncate may not be supported WT-2645 wt dump: push the complexity of collecting metadata into a dump cursor WT-2648 cache-line alignment for new ports WT-2665 Limit allocator fragmentation in WiredTiger WT-2678 The metadata should not imply that an empty value is true WT-2688 configure --enable-python doesn't check for availability of swig WT-2693 Check open_cursor error paths for consistent handling WT-2695 Integrate s390x accelerated crc32c support WT-2708 split child-update race with reconciliation/eviction WT-2711 Change statistics log configuration options WT-2719 add fuzz testing for WiredTiger options and reconfiguration. WT-2728 Don't re-read log file headers during log_flush WT-2729 Focus eviction walks in largest trees WT-2730 cursor next/prev can return the wrong key/value pair when crossing a page boundary WT-2731 Raw compression can create pages that are larger than expected WT-2732 Coverity analysis defect 99665: Redundant test WT-2734 Improve documentation of eviction behavior WT-2737 Scrub dirty pages rather than evicting them WT-2738 Remove the ability to change the default checkpoint name WT-2739 pluggable file systems documentation cleanups WT-2743 Thread count statistics always report 0 WT-2744 partial line even with line buffering set WT-2746 track checkpoint I/O separately from eviction I/O WT-2751 column-store statistics incorrectly calculates the number of entries WT-2752 Fixes to zipfian wtperf workload config WT-2755 flexelint configuration treats size_t as 4B type WT-2756 Upgrade the autoconf archive package to check for swig 3.0 WT-2757 Column tables behave differently when column names are provided WT-2759 Releasing the hot-backup lock doesn't require the schema lock. WT-2760 Fix a bug in backup related to directory sync. Change the filesystem API to make durable the default WT-2762 wtstats tool fails if checkpoint runs WT-2763 Unit test test_intpack failing on OSX WT-2764 Optimize checkpoints to reduce throughput disruption WT-2765 wt dump: indices need to be shown in the dump output WT-2766 Don't count eviction of lookaside file pages for the purpose of checking stuck cache WT-2767 test suite needs way to run an individual scenario WT-2769 Update documentation to reflect correct limits of memory_page_max WT-2770 Add statistics tracking schema operations WT-2772 Investigate log performance testing weirdness WT-2773 search_near in indexes does not find exact matches WT-2774 minor cleanups/improvements WT-2778 Python test suite: make scenario initialization consistent WT-2779 Raw compression created unexpectedly large pages on disk WT-2781 Enhance bulk cursor option with an option to return immediately on contention WT-2782 Missing a fs_directory_list_free in ex_file_system.c WT-2783 wtperf multi-btree.wtperf dumps core on Mac WT-2785 Scrub dirty pages rather than evicting them: single-page reconciliation WT-2787 Include src/include/wiredtiger_ext.h is problematic WT-2788 Java: freed memory overwrite during handle close can cause JNI crash WT-2791 Enhance OS X Evergreen unit test WT-2793 wtperf config improvements WT-2795 Update documentation around read-only configuration WT-2796 Memory leak in reconciliation uncovered by stress testing WT-2798 Crash vulnerability with nojournal after create during checkpoint WT-2800 Illegal file format in test/format on PPC WT-2801 Crash vulnerability from eviction of metadata during checkpoint WT-2802 Transaction commit causes heap-use-after free WT-2803 Add verbose functionality to WT Evergreen tests WT-2804 Don't read values in a tree without a snapshot WT-2805 Infinite recursion if error streams fail WT-2806 wtperf allocation size off-by-one WT-2807 Switch Jenkins performance tests to tcmalloc WT-2811 Reconciliation asserts that transaction time has gone backwards WT-2812 Error when reconfiguring cache targets WT-2813 small cache usage stuck even with large cache WT-2814 Enhance wtperf to support single-op truncate mode WT-2816 Improve WiredTiger eviction performance WT-2817 Investigate performance regression in develop, add workload to wtperf/runners WT-2818 The page visibility check when queuing pages for eviction is overly restrictive WT-2820 add gcc warn_unused_result attribute WT-2822 panic mutex and other functions that cannot fail WT-2823 support file handles without a truncate method WT-2824 wtperf displays connection and table create configurations twice WT-2826 clang38 false positive on uninitialized variable. WT-2827 checkpoint log_size configuration improvements WT-2828 Make long wtperf tests reflect mongoDB usage WT-2829 Switch automated testing to use enable-strict configure option WT-2832 Python test uses hard-coded temporary directory WT-2834 Join cursor: discrepancy with bloom filters WT-2835 WT_CONNECTION.leak-memory can skip memory map and cache cleanup WT-2838 Don't free session handles on close if leak memory is configured WT-2839 lint: Ignoring return value of function WT-2840 clang analysis: garbage values WT-2841 Jenkins Valgrind runner is reporting errors in test wt2719_reconfig WT-2842 split wtperf's configuration into per-database and per-run parts WT-2843 Fix a bug in recovery if there is no filesystem truncate support WT-2846 Several bugs related to reconfiguring eviction server at runtime WT-2847 Merge fair locks into read/write locks. WT-2850 clang 4.1 attribute warnings when building WT-2853 Multi threaded reader writer example shows temporary slowdown or lockup WT-2857 POSIX ftruncate calls should be #ifdef'd HAVE_FTRUNCATE WT-2862 Fix lint error in test case for forced eviction with multiple cursors WT-2863 Support UTF-8 paths on Windows WT-2865 eviction thread error failure WT-2866 Eviction server algorithm tuning WT-2867 Review and fix barrier usage in __lsm_tree_close WT-2868 Add sample_interval to checkpoint-stress wtperf config WT-2869 Performance regression on secondaries WT-2870 Rename wtperf checkpoint schema jobs WT-2871 __wt_verbose has the wrong GCC format attributes WT-2872 Recent stuck cache test/stress failures. WT-2873 Refactor CRC32 code WT-2875 Test test_wt2853_perf can run too long under valgrind WT-2876 Extend wtperf to support a log like table WT-2878 Verbose changes affected performance WT-2881 Add -Wpedantic to clang compiler warning flags WT-2883 wiredtiger_open with verbose=handleops recursive loop WT-2885 __wt_checkpoint_signal lint WT-2886 Decide how in-memory configuration and eviction_dirty_target interact WT-2888 Switch functions to return void where possible WT-2892 hot backup can race with block truncate WT-2896 Coverity #1362535: resource leak WT-2897 Checkpoints can become corrupted on failure WT-2901 Add option to disable checkpoint dirty stepdown phase WT-2903 Reduce the impact of checkpoint scrubbing on applications --- src/third_party/wiredtiger/SConscript | 17 +- src/third_party/wiredtiger/SConstruct | 39 +- .../wiredtiger/bench/wtperf/Makefile.am | 12 +- src/third_party/wiredtiger/bench/wtperf/config.c | 71 +- .../bench/wtperf/runners/1bn-lsm-50r50u.wtperf | 20 - .../bench/wtperf/runners/1bn-lsm-80r20u.wtperf | 18 - .../bench/wtperf/runners/1bn-lsm-populate.wtperf | 19 - .../bench/wtperf/runners/1bn-lsm-rdonly.wtperf | 18 - .../bench/wtperf/runners/2bn-lsm-50r50u.wtperf | 20 - .../bench/wtperf/runners/2bn-lsm-80r20u.wtperf | 18 - .../bench/wtperf/runners/2bn-lsm-populate.wtperf | 19 - .../bench/wtperf/runners/2bn-lsm-rdonly.wtperf | 18 - .../bench/wtperf/runners/500m-btree-50r50u.wtperf | 17 +- .../bench/wtperf/runners/500m-btree-80r20u.wtperf | 17 +- .../wtperf/runners/500m-btree-populate.wtperf | 24 +- .../bench/wtperf/runners/500m-btree-rdonly.wtperf | 17 +- .../bench/wtperf/runners/500m-lsm-50r50u.wtperf | 20 - .../bench/wtperf/runners/500m-lsm-80r20u.wtperf | 18 - .../bench/wtperf/runners/500m-lsm-populate.wtperf | 19 - .../bench/wtperf/runners/500m-lsm-rdonly.wtperf | 18 - .../bench/wtperf/runners/50m-lsm-50r50u.wtperf | 19 - .../bench/wtperf/runners/50m-lsm-80r20u.wtperf | 17 - .../bench/wtperf/runners/50m-lsm-populate.wtperf | 18 - .../bench/wtperf/runners/50m-lsm-rdonly.wtperf | 17 - .../wtperf/runners/checkpoint-schema-race.wtperf | 20 + .../runners/checkpoint-stress-schema-ops.wtperf | 19 + .../bench/wtperf/runners/checkpoint-stress.wtperf | 23 + .../runners/checkpoint_stress_schema_ops.wtperf | 19 - .../wtperf/runners/evict-btree-stress-multi.wtperf | 12 + .../bench/wtperf/runners/fruit-lsm.wtperf | 22 - .../bench/wtperf/runners/fruit-short.wtperf | 20 - .../bench/wtperf/runners/log-append-large.wtperf | 10 - .../bench/wtperf/runners/log-append-zero.wtperf | 8 - .../bench/wtperf/runners/log-append.wtperf | 8 - .../bench/wtperf/runners/log-nockpt.wtperf | 12 - .../bench/wtperf/runners/log-noprealloc.wtperf | 11 - .../wiredtiger/bench/wtperf/runners/log.wtperf | 27 +- .../wtperf/runners/mongodb-secondary-apply.wtperf | 21 + .../runners/multi-btree-zipfian-populate.wtperf | 19 + .../runners/multi-btree-zipfian-workload.wtperf | 18 + .../bench/wtperf/runners/overflow-10k-short.wtperf | 19 - .../bench/wtperf/runners/overflow-10k.wtperf | 16 +- .../wtperf/runners/overflow-130k-short.wtperf | 19 - .../bench/wtperf/runners/overflow-130k.wtperf | 18 +- .../wiredtiger/bench/wtperf/runners/wtperf_run.sh | 13 +- src/third_party/wiredtiger/bench/wtperf/wtperf.c | 295 +-- src/third_party/wiredtiger/bench/wtperf/wtperf.h | 94 +- .../wiredtiger/bench/wtperf/wtperf_opt.i | 5 + .../wiredtiger/bench/wtperf/wtperf_throttle.c | 13 +- .../wiredtiger/bench/wtperf/wtperf_truncate.c | 35 +- .../wiredtiger/build_posix/Make.subdirs | 8 +- .../wiredtiger/build_posix/aclocal/ax_pkg_swig.m4 | 10 +- .../wiredtiger/build_posix/aclocal/options.m4 | 13 + .../wiredtiger/build_posix/aclocal/strict.m4 | 1 + .../wiredtiger/build_posix/configure.ac.in | 21 +- .../wiredtiger/build_win/wiredtiger_config.h | 9 +- src/third_party/wiredtiger/dist/api_config.py | 6 +- src/third_party/wiredtiger/dist/api_data.py | 111 +- src/third_party/wiredtiger/dist/filelist | 8 +- src/third_party/wiredtiger/dist/flags.py | 6 +- src/third_party/wiredtiger/dist/s_all | 16 + src/third_party/wiredtiger/dist/s_funcs.list | 1 + src/third_party/wiredtiger/dist/s_longlines | 1 + src/third_party/wiredtiger/dist/s_prototypes | 10 +- src/third_party/wiredtiger/dist/s_string.ok | 46 +- src/third_party/wiredtiger/dist/s_style | 7 +- src/third_party/wiredtiger/dist/s_void | 134 ++ src/third_party/wiredtiger/dist/s_win | 2 +- src/third_party/wiredtiger/dist/stat.py | 11 +- src/third_party/wiredtiger/dist/stat_data.py | 74 +- src/third_party/wiredtiger/examples/c/ex_all.c | 14 +- src/third_party/wiredtiger/examples/c/ex_encrypt.c | 6 +- .../wiredtiger/examples/c/ex_file_system.c | 4 +- .../ext/collators/revint/revint_collator.c | 12 +- .../ext/compressors/zlib/zlib_compress.c | 2 +- .../wiredtiger/ext/encryptors/rotn/rotn_encrypt.c | 13 +- .../wiredtiger/ext/test/kvs_bdb/kvs_bdb.c | 7 + src/third_party/wiredtiger/lang/java/Makefile.am | 1 + src/third_party/wiredtiger/lang/java/wiredtiger.i | 1 - src/third_party/wiredtiger/src/async/async_api.c | 22 +- src/third_party/wiredtiger/src/async/async_op.c | 7 +- .../wiredtiger/src/async/async_worker.c | 11 +- src/third_party/wiredtiger/src/block/block_addr.c | 42 +- src/third_party/wiredtiger/src/block/block_ckpt.c | 116 +- .../wiredtiger/src/block/block_compact.c | 65 +- src/third_party/wiredtiger/src/block/block_ext.c | 77 +- src/third_party/wiredtiger/src/block/block_map.c | 2 +- src/third_party/wiredtiger/src/block/block_mgr.c | 52 +- src/third_party/wiredtiger/src/block/block_open.c | 31 +- src/third_party/wiredtiger/src/block/block_read.c | 42 +- .../wiredtiger/src/block/block_session.c | 2 +- src/third_party/wiredtiger/src/block/block_slvg.c | 26 +- src/third_party/wiredtiger/src/block/block_vrfy.c | 13 +- src/third_party/wiredtiger/src/block/block_write.c | 203 +- src/third_party/wiredtiger/src/bloom/bloom.c | 16 +- src/third_party/wiredtiger/src/btree/bt_compact.c | 4 +- src/third_party/wiredtiger/src/btree/bt_curnext.c | 2 +- src/third_party/wiredtiger/src/btree/bt_curprev.c | 2 +- src/third_party/wiredtiger/src/btree/bt_cursor.c | 2 +- src/third_party/wiredtiger/src/btree/bt_debug.c | 478 ++--- src/third_party/wiredtiger/src/btree/bt_discard.c | 19 +- src/third_party/wiredtiger/src/btree/bt_handle.c | 25 +- src/third_party/wiredtiger/src/btree/bt_io.c | 21 +- src/third_party/wiredtiger/src/btree/bt_ovfl.c | 15 +- src/third_party/wiredtiger/src/btree/bt_page.c | 7 +- src/third_party/wiredtiger/src/btree/bt_read.c | 50 +- .../wiredtiger/src/btree/bt_rebalance.c | 20 +- src/third_party/wiredtiger/src/btree/bt_slvg.c | 91 +- src/third_party/wiredtiger/src/btree/bt_split.c | 197 +- src/third_party/wiredtiger/src/btree/bt_stat.c | 5 +- src/third_party/wiredtiger/src/btree/bt_sync.c | 62 +- src/third_party/wiredtiger/src/btree/bt_vrfy.c | 10 +- src/third_party/wiredtiger/src/btree/bt_walk.c | 20 +- src/third_party/wiredtiger/src/btree/row_key.c | 6 +- src/third_party/wiredtiger/src/btree/row_modify.c | 15 +- src/third_party/wiredtiger/src/btree/row_srch.c | 2 +- src/third_party/wiredtiger/src/cache/cache_las.c | 6 +- .../wiredtiger/src/checksum/arm64/crc32-arm64.c | 101 + src/third_party/wiredtiger/src/checksum/checksum.c | 1329 ------------- .../wiredtiger/src/checksum/power8/crc32_wrapper.c | 36 +- .../wiredtiger/src/checksum/software/checksum.c | 1165 +++++++++++ .../wiredtiger/src/checksum/x86/crc32-x86.c | 160 ++ .../wiredtiger/src/checksum/zseries/LICENSE.TXT | 482 +++++ .../wiredtiger/src/checksum/zseries/README.md | 61 + .../wiredtiger/src/checksum/zseries/crc32-s390x.c | 96 + .../wiredtiger/src/checksum/zseries/crc32-s390x.h | 12 + .../wiredtiger/src/checksum/zseries/crc32le-vx.S | 280 +++ .../src/checksum/zseries/slicing-consts.h | 2096 ++++++++++++++++++++ .../wiredtiger/src/checksum/zseries/vx-insn.h | 480 +++++ src/third_party/wiredtiger/src/config/config.c | 24 +- src/third_party/wiredtiger/src/config/config_api.c | 11 +- .../wiredtiger/src/config/config_check.c | 10 +- .../wiredtiger/src/config/config_collapse.c | 4 +- src/third_party/wiredtiger/src/config/config_def.c | 356 ++-- src/third_party/wiredtiger/src/conn/conn_api.c | 14 +- src/third_party/wiredtiger/src/conn/conn_cache.c | 104 +- .../wiredtiger/src/conn/conn_cache_pool.c | 103 +- src/third_party/wiredtiger/src/conn/conn_ckpt.c | 61 +- src/third_party/wiredtiger/src/conn/conn_dhandle.c | 32 +- src/third_party/wiredtiger/src/conn/conn_handle.c | 2 +- src/third_party/wiredtiger/src/conn/conn_log.c | 133 +- src/third_party/wiredtiger/src/conn/conn_open.c | 33 +- src/third_party/wiredtiger/src/conn/conn_stat.c | 9 +- src/third_party/wiredtiger/src/conn/conn_sweep.c | 35 +- src/third_party/wiredtiger/src/cursor/cur_backup.c | 54 +- src/third_party/wiredtiger/src/cursor/cur_config.c | 4 +- src/third_party/wiredtiger/src/cursor/cur_ds.c | 5 +- src/third_party/wiredtiger/src/cursor/cur_dump.c | 4 +- src/third_party/wiredtiger/src/cursor/cur_file.c | 38 +- src/third_party/wiredtiger/src/cursor/cur_index.c | 56 +- src/third_party/wiredtiger/src/cursor/cur_join.c | 23 +- src/third_party/wiredtiger/src/cursor/cur_json.c | 11 +- src/third_party/wiredtiger/src/cursor/cur_log.c | 28 +- .../wiredtiger/src/cursor/cur_metadata.c | 163 +- src/third_party/wiredtiger/src/cursor/cur_stat.c | 28 +- src/third_party/wiredtiger/src/cursor/cur_std.c | 7 +- src/third_party/wiredtiger/src/cursor/cur_table.c | 19 +- .../wiredtiger/src/docs/custom-file-systems.dox | 43 +- src/third_party/wiredtiger/src/docs/license.dox | 15 +- src/third_party/wiredtiger/src/docs/readonly.dox | 3 +- src/third_party/wiredtiger/src/docs/spell.ok | 5 + src/third_party/wiredtiger/src/docs/tune-cache.dox | 50 +- src/third_party/wiredtiger/src/docs/upgrading.dox | 41 +- src/third_party/wiredtiger/src/docs/wtperf.dox | 6 + src/third_party/wiredtiger/src/evict/evict_lru.c | 1421 +++++++------ src/third_party/wiredtiger/src/evict/evict_page.c | 221 ++- src/third_party/wiredtiger/src/include/api.h | 6 +- src/third_party/wiredtiger/src/include/block.h | 15 +- src/third_party/wiredtiger/src/include/btmem.h | 54 +- src/third_party/wiredtiger/src/include/btree.h | 16 +- src/third_party/wiredtiger/src/include/btree.i | 257 ++- src/third_party/wiredtiger/src/include/buf.i | 3 +- src/third_party/wiredtiger/src/include/cache.h | 117 +- src/third_party/wiredtiger/src/include/cache.i | 186 +- .../wiredtiger/src/include/connection.h | 19 +- src/third_party/wiredtiger/src/include/cursor.h | 10 +- src/third_party/wiredtiger/src/include/cursor.i | 2 +- src/third_party/wiredtiger/src/include/error.h | 4 +- src/third_party/wiredtiger/src/include/extern.h | 1181 +++++------ .../wiredtiger/src/include/extern_posix.h | 42 +- .../wiredtiger/src/include/extern_win.h | 42 +- src/third_party/wiredtiger/src/include/flags.h | 22 +- src/third_party/wiredtiger/src/include/hardware.h | 11 +- src/third_party/wiredtiger/src/include/intpack.i | 8 +- src/third_party/wiredtiger/src/include/log.h | 4 +- src/third_party/wiredtiger/src/include/misc.h | 5 + src/third_party/wiredtiger/src/include/misc.i | 23 +- src/third_party/wiredtiger/src/include/mutex.h | 20 +- src/third_party/wiredtiger/src/include/mutex.i | 126 +- .../wiredtiger/src/include/os_fhandle.i | 92 +- src/third_party/wiredtiger/src/include/os_fs.i | 16 +- .../wiredtiger/src/include/os_fstream.i | 15 +- src/third_party/wiredtiger/src/include/packing.i | 6 +- src/third_party/wiredtiger/src/include/queue.h | 174 +- src/third_party/wiredtiger/src/include/serial.i | 4 +- src/third_party/wiredtiger/src/include/stat.h | 41 +- .../wiredtiger/src/include/thread_group.h | 61 + src/third_party/wiredtiger/src/include/txn.i | 25 +- .../wiredtiger/src/include/wiredtiger.in | 753 ++++--- .../wiredtiger/src/include/wt_internal.h | 11 +- src/third_party/wiredtiger/src/log/log.c | 287 +-- src/third_party/wiredtiger/src/log/log_slot.c | 2 +- src/third_party/wiredtiger/src/lsm/lsm_cursor.c | 29 +- src/third_party/wiredtiger/src/lsm/lsm_manager.c | 26 +- src/third_party/wiredtiger/src/lsm/lsm_merge.c | 47 +- src/third_party/wiredtiger/src/lsm/lsm_meta.c | 51 +- src/third_party/wiredtiger/src/lsm/lsm_stat.c | 4 +- src/third_party/wiredtiger/src/lsm/lsm_tree.c | 135 +- src/third_party/wiredtiger/src/lsm/lsm_work_unit.c | 72 +- src/third_party/wiredtiger/src/lsm/lsm_worker.c | 11 +- src/third_party/wiredtiger/src/meta/meta_ckpt.c | 11 +- src/third_party/wiredtiger/src/meta/meta_table.c | 19 +- src/third_party/wiredtiger/src/meta/meta_track.c | 3 +- .../wiredtiger/src/os_common/os_fhandle.c | 26 +- .../wiredtiger/src/os_common/os_fs_inmemory.c | 36 - .../wiredtiger/src/os_common/os_fstream_stdio.c | 4 +- .../wiredtiger/src/os_posix/os_fallocate.c | 85 +- src/third_party/wiredtiger/src/os_posix/os_fs.c | 8 +- src/third_party/wiredtiger/src/os_posix/os_map.c | 4 +- .../wiredtiger/src/os_posix/os_mtx_cond.c | 49 +- src/third_party/wiredtiger/src/os_win/os_dir.c | 32 +- src/third_party/wiredtiger/src/os_win/os_dlopen.c | 4 +- src/third_party/wiredtiger/src/os_win/os_fs.c | 126 +- src/third_party/wiredtiger/src/os_win/os_map.c | 8 +- .../wiredtiger/src/os_win/os_mtx_cond.c | 49 +- src/third_party/wiredtiger/src/os_win/os_utf8.c | 84 + .../wiredtiger/src/reconcile/rec_track.c | 42 +- .../wiredtiger/src/reconcile/rec_write.c | 370 ++-- .../wiredtiger/src/schema/schema_create.c | 6 +- .../wiredtiger/src/schema/schema_open.c | 10 +- .../wiredtiger/src/schema/schema_plan.c | 16 +- .../wiredtiger/src/schema/schema_stat.c | 2 +- .../wiredtiger/src/session/session_api.c | 180 +- .../wiredtiger/src/session/session_compact.c | 14 +- .../wiredtiger/src/session/session_dhandle.c | 28 +- src/third_party/wiredtiger/src/support/cond_auto.c | 17 +- src/third_party/wiredtiger/src/support/err.c | 23 +- src/third_party/wiredtiger/src/support/global.c | 12 +- src/third_party/wiredtiger/src/support/hazard.c | 19 + src/third_party/wiredtiger/src/support/huffman.c | 4 +- src/third_party/wiredtiger/src/support/mtx_rw.c | 85 +- src/third_party/wiredtiger/src/support/stat.c | 136 +- .../wiredtiger/src/support/thread_group.c | 336 ++++ src/third_party/wiredtiger/src/txn/txn.c | 32 +- src/third_party/wiredtiger/src/txn/txn_ckpt.c | 499 ++++- src/third_party/wiredtiger/src/txn/txn_log.c | 7 +- src/third_party/wiredtiger/src/txn/txn_nsnap.c | 11 +- src/third_party/wiredtiger/src/txn/txn_recover.c | 16 +- src/third_party/wiredtiger/src/utilities/util.h | 3 +- .../wiredtiger/src/utilities/util_dump.c | 210 +- .../wiredtiger/src/utilities/util_list.c | 54 +- .../wiredtiger/src/utilities/util_misc.c | 15 +- src/third_party/wiredtiger/test/bloom/test_bloom.c | 3 +- .../wiredtiger/test/checkpoint/test_checkpoint.c | 9 +- src/third_party/wiredtiger/test/csuite/Makefile.am | 15 + .../test/csuite/wt1965_col_efficiency/main.c | 3 +- .../test/csuite/wt2246_col_append/main.c | 4 +- .../test/csuite/wt2323_join_visibility/main.c | 402 ++++ .../test/csuite/wt2447_join_main_table/main.c | 3 +- .../wiredtiger/test/csuite/wt2695_checksum/main.c | 143 ++ .../wiredtiger/test/csuite/wt2719_reconfig/main.c | 283 +++ .../test/csuite/wt2834_join_bloom_fix/main.c | 199 ++ .../wiredtiger/test/csuite/wt2853_perf/main.c | 330 +++ .../test/cursor_order/cursor_order_ops.c | 3 +- src/third_party/wiredtiger/test/format/bdb.c | 1 + src/third_party/wiredtiger/test/format/config.h | 8 +- src/third_party/wiredtiger/test/format/format.h | 17 +- src/third_party/wiredtiger/test/format/ops.c | 6 +- src/third_party/wiredtiger/test/format/rebalance.c | 10 +- src/third_party/wiredtiger/test/format/salvage.c | 2 +- src/third_party/wiredtiger/test/format/smoke.sh | 2 +- src/third_party/wiredtiger/test/format/t.c | 12 +- src/third_party/wiredtiger/test/format/util.c | 16 +- src/third_party/wiredtiger/test/format/wts.c | 16 +- .../com/wiredtiger/test/ConcurrentCloseTest.java | 179 ++ .../wiredtiger/test/manydbs/Makefile.am | 3 +- src/third_party/wiredtiger/test/manydbs/manydbs.c | 5 +- src/third_party/wiredtiger/test/manydbs/smoke.sh | 18 - src/third_party/wiredtiger/test/mciproject.yml | 49 +- .../wiredtiger/test/recovery/Makefile.am | 3 +- .../wiredtiger/test/recovery/random-abort.c | 18 +- src/third_party/wiredtiger/test/recovery/smoke.sh | 8 + .../wiredtiger/test/recovery/truncated-log.c | 115 +- src/third_party/wiredtiger/test/salvage/salvage.c | 4 +- src/third_party/wiredtiger/test/suite/helper.py | 43 + src/third_party/wiredtiger/test/suite/run.py | 41 +- .../wiredtiger/test/suite/test_async01.py | 4 +- .../wiredtiger/test/suite/test_async02.py | 4 +- .../wiredtiger/test/suite/test_backup02.py | 4 +- .../wiredtiger/test/suite/test_backup03.py | 36 +- .../wiredtiger/test/suite/test_backup04.py | 4 +- .../wiredtiger/test/suite/test_backup05.py | 1 - .../wiredtiger/test/suite/test_base02.py | 4 +- .../wiredtiger/test/suite/test_base05.py | 4 +- .../wiredtiger/test/suite/test_bug003.py | 4 +- .../wiredtiger/test/suite/test_bug006.py | 4 +- .../wiredtiger/test/suite/test_bug008.py | 4 +- .../wiredtiger/test/suite/test_bug009.py | 1 - .../wiredtiger/test/suite/test_bug011.py | 2 +- .../wiredtiger/test/suite/test_bug016.py | 109 + .../wiredtiger/test/suite/test_bulk01.py | 4 +- .../wiredtiger/test/suite/test_bulk02.py | 7 +- .../wiredtiger/test/suite/test_checkpoint01.py | 14 +- .../wiredtiger/test/suite/test_checkpoint02.py | 4 +- .../wiredtiger/test/suite/test_colgap.py | 6 +- .../wiredtiger/test/suite/test_collator.py | 1 - .../wiredtiger/test/suite/test_compact01.py | 4 +- .../wiredtiger/test/suite/test_compact02.py | 7 +- .../wiredtiger/test/suite/test_compress01.py | 4 +- .../wiredtiger/test/suite/test_config03.py | 7 +- .../wiredtiger/test/suite/test_config04.py | 2 +- .../wiredtiger/test/suite/test_cursor01.py | 4 +- .../wiredtiger/test/suite/test_cursor02.py | 4 +- .../wiredtiger/test/suite/test_cursor03.py | 4 +- .../wiredtiger/test/suite/test_cursor04.py | 4 +- .../wiredtiger/test/suite/test_cursor06.py | 4 +- .../wiredtiger/test/suite/test_cursor07.py | 4 +- .../wiredtiger/test/suite/test_cursor08.py | 12 +- .../wiredtiger/test/suite/test_cursor09.py | 4 +- .../wiredtiger/test/suite/test_cursor_compare.py | 4 +- .../wiredtiger/test/suite/test_cursor_pin.py | 4 +- .../wiredtiger/test/suite/test_cursor_random.py | 8 +- .../wiredtiger/test/suite/test_cursor_random02.py | 4 +- src/third_party/wiredtiger/test/suite/test_drop.py | 4 +- src/third_party/wiredtiger/test/suite/test_dump.py | 11 +- src/third_party/wiredtiger/test/suite/test_dupc.py | 4 +- .../wiredtiger/test/suite/test_durability01.py | 1 - .../wiredtiger/test/suite/test_empty.py | 4 +- .../wiredtiger/test/suite/test_encrypt01.py | 5 +- .../wiredtiger/test/suite/test_encrypt02.py | 4 +- .../wiredtiger/test/suite/test_encrypt03.py | 4 +- .../wiredtiger/test/suite/test_encrypt04.py | 5 +- .../wiredtiger/test/suite/test_encrypt05.py | 5 +- .../wiredtiger/test/suite/test_encrypt06.py | 4 +- .../wiredtiger/test/suite/test_encrypt07.py | 1 - src/third_party/wiredtiger/test/suite/test_excl.py | 4 +- .../wiredtiger/test/suite/test_huffman01.py | 4 +- .../wiredtiger/test/suite/test_huffman02.py | 4 +- .../wiredtiger/test/suite/test_index02.py | 68 + .../wiredtiger/test/suite/test_inmem01.py | 88 +- .../wiredtiger/test/suite/test_intpack.py | 35 +- .../wiredtiger/test/suite/test_join01.py | 10 +- .../wiredtiger/test/suite/test_join02.py | 4 +- .../wiredtiger/test/suite/test_join03.py | 1 - .../wiredtiger/test/suite/test_join04.py | 1 - .../wiredtiger/test/suite/test_join05.py | 1 - .../wiredtiger/test/suite/test_join06.py | 23 +- .../wiredtiger/test/suite/test_join07.py | 4 +- .../wiredtiger/test/suite/test_join08.py | 1 - .../wiredtiger/test/suite/test_jsondump01.py | 50 +- .../wiredtiger/test/suite/test_lsm01.py | 8 +- .../test/suite/test_metadata_cursor01.py | 4 +- .../wiredtiger/test/suite/test_nsnap01.py | 1 - .../wiredtiger/test/suite/test_nsnap02.py | 1 - .../wiredtiger/test/suite/test_nsnap03.py | 1 - .../wiredtiger/test/suite/test_nsnap04.py | 1 - .../wiredtiger/test/suite/test_overwrite.py | 4 +- .../wiredtiger/test/suite/test_perf001.py | 4 +- .../wiredtiger/test/suite/test_readonly01.py | 5 +- .../wiredtiger/test/suite/test_rebalance.py | 4 +- .../wiredtiger/test/suite/test_reconfig01.py | 2 - .../wiredtiger/test/suite/test_reconfig03.py | 66 + .../wiredtiger/test/suite/test_rename.py | 4 +- .../wiredtiger/test/suite/test_schema02.py | 4 +- .../wiredtiger/test/suite/test_schema03.py | 15 +- .../wiredtiger/test/suite/test_schema04.py | 4 +- .../wiredtiger/test/suite/test_schema05.py | 4 +- .../wiredtiger/test/suite/test_schema06.py | 5 +- .../wiredtiger/test/suite/test_split.py | 1 - .../wiredtiger/test/suite/test_stat01.py | 4 +- .../wiredtiger/test/suite/test_stat02.py | 35 +- .../wiredtiger/test/suite/test_stat03.py | 4 +- .../wiredtiger/test/suite/test_stat04.py | 10 +- .../wiredtiger/test/suite/test_stat05.py | 13 +- .../wiredtiger/test/suite/test_sweep01.py | 4 +- .../wiredtiger/test/suite/test_sweep03.py | 4 +- .../wiredtiger/test/suite/test_truncate01.py | 13 +- .../wiredtiger/test/suite/test_truncate02.py | 5 +- .../wiredtiger/test/suite/test_txn01.py | 4 +- .../wiredtiger/test/suite/test_txn02.py | 12 +- .../wiredtiger/test/suite/test_txn03.py | 4 +- .../wiredtiger/test/suite/test_txn04.py | 4 +- .../wiredtiger/test/suite/test_txn05.py | 5 +- .../wiredtiger/test/suite/test_txn06.py | 1 - .../wiredtiger/test/suite/test_txn07.py | 17 +- .../wiredtiger/test/suite/test_txn08.py | 1 - .../wiredtiger/test/suite/test_txn09.py | 9 +- .../wiredtiger/test/suite/test_txn10.py | 1 - .../wiredtiger/test/suite/test_txn12.py | 1 - .../wiredtiger/test/suite/test_txn13.py | 4 +- .../wiredtiger/test/suite/test_txn14.py | 4 +- .../wiredtiger/test/suite/test_txn15.py | 4 +- .../wiredtiger/test/suite/test_upgrade.py | 4 +- .../wiredtiger/test/suite/test_util02.py | 4 +- .../wiredtiger/test/suite/test_util03.py | 4 +- .../wiredtiger/test/suite/test_util13.py | 4 +- .../wiredtiger/test/suite/wtscenario.py | 36 +- src/third_party/wiredtiger/test/suite/wttest.py | 6 +- src/third_party/wiredtiger/test/thread/rw.c | 8 +- src/third_party/wiredtiger/test/thread/smoke.sh | 6 +- src/third_party/wiredtiger/test/utility/misc.c | 42 + .../wiredtiger/test/utility/parse_opts.c | 2 +- .../wiredtiger/test/utility/test_util.h | 5 + .../wiredtiger/test/windows/windows_shim.c | 11 + .../wiredtiger/test/windows/windows_shim.h | 2 + .../wiredtiger/tools/wtstats/stat_data.py | 53 +- .../wiredtiger/tools/wtstats/wtstats.py | 2 + 407 files changed, 15249 insertions(+), 7720 deletions(-) delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/1bn-lsm-50r50u.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/1bn-lsm-80r20u.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/1bn-lsm-populate.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/1bn-lsm-rdonly.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/2bn-lsm-50r50u.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/2bn-lsm-80r20u.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/2bn-lsm-populate.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/2bn-lsm-rdonly.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/500m-lsm-50r50u.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/500m-lsm-80r20u.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/500m-lsm-populate.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/500m-lsm-rdonly.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/50m-lsm-50r50u.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/50m-lsm-80r20u.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/50m-lsm-populate.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/50m-lsm-rdonly.wtperf create mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/checkpoint-schema-race.wtperf create mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/checkpoint-stress-schema-ops.wtperf create mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/checkpoint-stress.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/checkpoint_stress_schema_ops.wtperf create mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/evict-btree-stress-multi.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/fruit-lsm.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/fruit-short.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/log-append-large.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/log-append-zero.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/log-append.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/log-nockpt.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/log-noprealloc.wtperf create mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/mongodb-secondary-apply.wtperf create mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/multi-btree-zipfian-populate.wtperf create mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/multi-btree-zipfian-workload.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/overflow-10k-short.wtperf delete mode 100644 src/third_party/wiredtiger/bench/wtperf/runners/overflow-130k-short.wtperf create mode 100644 src/third_party/wiredtiger/dist/s_void create mode 100644 src/third_party/wiredtiger/src/checksum/arm64/crc32-arm64.c delete mode 100644 src/third_party/wiredtiger/src/checksum/checksum.c create mode 100644 src/third_party/wiredtiger/src/checksum/software/checksum.c create mode 100644 src/third_party/wiredtiger/src/checksum/x86/crc32-x86.c create mode 100644 src/third_party/wiredtiger/src/checksum/zseries/LICENSE.TXT create mode 100644 src/third_party/wiredtiger/src/checksum/zseries/README.md create mode 100644 src/third_party/wiredtiger/src/checksum/zseries/crc32-s390x.c create mode 100644 src/third_party/wiredtiger/src/checksum/zseries/crc32-s390x.h create mode 100644 src/third_party/wiredtiger/src/checksum/zseries/crc32le-vx.S create mode 100644 src/third_party/wiredtiger/src/checksum/zseries/slicing-consts.h create mode 100644 src/third_party/wiredtiger/src/checksum/zseries/vx-insn.h create mode 100644 src/third_party/wiredtiger/src/include/thread_group.h create mode 100644 src/third_party/wiredtiger/src/os_win/os_utf8.c create mode 100644 src/third_party/wiredtiger/src/support/thread_group.c create mode 100644 src/third_party/wiredtiger/test/csuite/wt2323_join_visibility/main.c create mode 100644 src/third_party/wiredtiger/test/csuite/wt2695_checksum/main.c create mode 100644 src/third_party/wiredtiger/test/csuite/wt2719_reconfig/main.c create mode 100644 src/third_party/wiredtiger/test/csuite/wt2834_join_bloom_fix/main.c create mode 100644 src/third_party/wiredtiger/test/csuite/wt2853_perf/main.c create mode 100644 src/third_party/wiredtiger/test/java/com/wiredtiger/test/ConcurrentCloseTest.java delete mode 100755 src/third_party/wiredtiger/test/manydbs/smoke.sh create mode 100755 src/third_party/wiredtiger/test/recovery/smoke.sh create mode 100644 src/third_party/wiredtiger/test/suite/test_bug016.py create mode 100644 src/third_party/wiredtiger/test/suite/test_index02.py create mode 100644 src/third_party/wiredtiger/test/suite/test_reconfig03.py diff --git a/src/third_party/wiredtiger/SConscript b/src/third_party/wiredtiger/SConscript index f740040245b..62307e9f409 100644 --- a/src/third_party/wiredtiger/SConscript +++ b/src/third_party/wiredtiger/SConscript @@ -130,9 +130,13 @@ env.Alias('generated-sources', "wiredtiger.h") # included. # condition_map = { - 'POSIX_HOST' : not env.TargetOSIs('windows'), - 'POWERPC_HOST' : env['TARGET_ARCH'] == 'ppc64le', + 'POSIX_HOST' : not env.TargetOSIs('windows'), 'WINDOWS_HOST' : env.TargetOSIs('windows'), + + 'ARM64_HOST' : env['TARGET_ARCH'] == 'aarch64', + 'POWERPC_HOST' : env['TARGET_ARCH'] == 'ppc64le', + 'X86_HOST' : env['TARGET_ARCH'] == 'x86_64', + 'ZSERIES_HOST' : env['TARGET_ARCH'] == 's390x', } def filtered_filelist(f): @@ -155,6 +159,15 @@ if useSnappy: env.Append(CPPDEFINES=['HAVE_BUILTIN_EXTENSION_SNAPPY']) wtsources.append("ext/compressors/snappy/snappy_compress.c") +# Use hardware by default on all platforms if available. +# If not available at runtime, we fall back to software in some cases. +# +# On zSeries we may disable because SLES 11 kernel doe not support the instructions. +if not (env['TARGET_ARCH'] == 's390x' and get_option("use-s390x-crc32") == "off"): + # Disable ARM hardware CRC for now - the extensions aren't always available + if env['TARGET_ARCH'] != 'aarch64': + env.Append(CPPDEFINES=["HAVE_CRC32_HARDWARE"]) + wtlib = env.Library( target="wiredtiger", source=wtsources, diff --git a/src/third_party/wiredtiger/SConstruct b/src/third_party/wiredtiger/SConstruct index a5dd8761d6c..0ccdf59babc 100644 --- a/src/third_party/wiredtiger/SConstruct +++ b/src/third_party/wiredtiger/SConstruct @@ -245,9 +245,12 @@ wtheader = env.Substfile( # included. # condition_map = { + 'ARM64_HOST' : False, 'POSIX_HOST' : env['PLATFORM'] == 'posix', 'POWERPC_HOST' : False, 'WINDOWS_HOST' : env['PLATFORM'] == 'win32', + 'X86_HOST' : True, + 'ZSERIES_HOST' : False, } def filtered_filelist(f): @@ -441,28 +444,22 @@ t = env.Program("t_fops", "test/fops/t.c"], LIBS=[wtlib, shim, testutil] + wtlibs) env.Append(CPPPATH=["test/utility"]) -env.Alias("check", env.SmokeTest(t)) Default(t) -if useBdb: - benv = env.Clone() - - benv.Append(CPPDEFINES=['BERKELEY_DB_PATH=\\"' + useBdb.replace("\\", "\\\\") + '\\"']) - - t = benv.Program("t_format", - ["test/format/backup.c", - "test/format/bdb.c", - "test/format/bulk.c", - "test/format/compact.c", - "test/format/config.c", - "test/format/ops.c", - "test/format/salvage.c", - "test/format/t.c", - "test/format/util.c", - "test/format/wts.c"], - LIBS=[wtlib, shim, "libdb61"] + wtlibs) - env.Alias("test", env.SmokeTest(t)) - Default(t) +t = env.Program("t_format", + ["test/format/backup.c", + "test/format/bulk.c", + "test/format/compact.c", + "test/format/config.c", + "test/format/lrt.c", + "test/format/ops.c", + "test/format/rebalance.c", + "test/format/salvage.c", + "test/format/t.c", + "test/format/util.c", + "test/format/wts.c"], + LIBS=[wtlib, shim, testutil] + wtlibs) +Default(t) #env.Program("t_thread", #["test/thread/file.c", @@ -484,7 +481,7 @@ t = env.Program("wtperf", [ "bench/wtperf/wtperf_throttle.c", "bench/wtperf/wtperf_truncate.c", ], - LIBS=[wtlib, shim] + wtlibs) + LIBS=[wtlib, shim, testutil] + wtlibs) Default(t) #Build the Examples diff --git a/src/third_party/wiredtiger/bench/wtperf/Makefile.am b/src/third_party/wiredtiger/bench/wtperf/Makefile.am index cc1f84b5406..57792e3887f 100644 --- a/src/third_party/wiredtiger/bench/wtperf/Makefile.am +++ b/src/third_party/wiredtiger/bench/wtperf/Makefile.am @@ -1,13 +1,17 @@ -AM_CPPFLAGS = -I$(top_builddir) -I$(top_srcdir)/src/include - -LDADD = $(top_builddir)/libwiredtiger.la -lm +AM_CPPFLAGS = -I$(top_builddir) +AM_CPPFLAGS +=-I$(top_srcdir)/src/include +AM_CPPFLAGS +=-I$(top_srcdir)/test/utility noinst_PROGRAMS = wtperf -wtperf_LDFLAGS = -static wtperf_SOURCES =\ config.c idle_table_cycle.c misc.c track.c wtperf.c \ wtperf.h wtperf_opt.i wtperf_throttle.c wtperf_truncate.c +wtperf_LDADD = $(top_builddir)/test/utility/libtest_util.la +wtperf_LDADD +=$(top_builddir)/libwiredtiger.la +wtperf_LDADD +=-lm +wtperf_LDFLAGS = -static + TESTS = smoke.sh AM_TESTS_ENVIRONMENT = rm -rf WT_TEST ; mkdir WT_TEST ; # automake 1.11 compatibility diff --git a/src/third_party/wiredtiger/bench/wtperf/config.c b/src/third_party/wiredtiger/bench/wtperf/config.c index 0dc38287155..48127afc10e 100644 --- a/src/third_party/wiredtiger/bench/wtperf/config.c +++ b/src/third_party/wiredtiger/bench/wtperf/config.c @@ -94,31 +94,42 @@ config_unescape(char *orig) } /* - * config_assign -- - * Assign the src config to the dest, any storage allocated in dest is - * freed as a result. + * config_copy -- + * CONFIG structure initialization, based on a source configuration. */ -int -config_assign(CONFIG *dest, const CONFIG *src) +void +config_copy(CONFIG *dest, const CONFIG *src) { CONFIG_QUEUE_ENTRY *conf_line, *tmp_line; size_t i; char *newstr, **pstr; - config_free(dest); memcpy(dest, src, sizeof(CONFIG)); + if (src->home != NULL) + dest->home = dstrdup(src->home); + if (src->monitor_dir != NULL) + dest->monitor_dir = dstrdup(src->monitor_dir); + if (src->partial_config != NULL) + dest->partial_config = dstrdup(src->partial_config); + if (src->reopen_config != NULL) + dest->reopen_config = dstrdup(src->reopen_config); + if (src->base_uri != NULL) + dest->base_uri = dstrdup(src->base_uri); + if (src->uris != NULL) { dest->uris = dcalloc(src->table_count, sizeof(char *)); for (i = 0; i < src->table_count; i++) dest->uris[i] = dstrdup(src->uris[i]); } + + if (src->async_config != NULL) + dest->async_config = dstrdup(src->async_config); + dest->ckptthreads = NULL; dest->popthreads = NULL; dest->workers = NULL; - if (src->base_uri != NULL) - dest->base_uri = dstrdup(src->base_uri); if (src->workload != NULL) { dest->workload = dcalloc(WORKLOAD_MAX, sizeof(WORKLOAD)); memcpy(dest->workload, @@ -145,7 +156,6 @@ config_assign(CONFIG *dest, const CONFIG *src) tmp_line->string = dstrdup(conf_line->string); TAILQ_INSERT_TAIL(&dest->config_head, tmp_line, c); } - return (0); } /* @@ -159,6 +169,31 @@ config_free(CONFIG *cfg) size_t i; char **pstr; + free(cfg->home); + free(cfg->monitor_dir); + free(cfg->partial_config); + free(cfg->reopen_config); + + /* Free the various URIs */ + free(cfg->base_uri); + free(cfg->log_table_uri); + + if (cfg->uris != NULL) { + for (i = 0; i < cfg->table_count; i++) + free(cfg->uris[i]); + free(cfg->uris); + } + + free(cfg->async_config); + + free(cfg->ckptthreads); + free(cfg->popthreads); + + free(cfg->workers); + free(cfg->workload); + + cleanup_truncate_config(cfg); + while (!TAILQ_EMPTY(&cfg->config_head)) { config_line = TAILQ_FIRST(&cfg->config_head); TAILQ_REMOVE(&cfg->config_head, config_line, c); @@ -174,20 +209,6 @@ config_free(CONFIG *cfg) free(*pstr); *pstr = NULL; } - if (cfg->uris != NULL) { - for (i = 0; i < cfg->table_count; i++) - free(cfg->uris[i]); - free(cfg->uris); - } - - cleanup_truncate_config(cfg); - free(cfg->base_uri); - free(cfg->ckptthreads); - free(cfg->partial_config); - free(cfg->popthreads); - free(cfg->reopen_config); - free(cfg->workers); - free(cfg->workload); } /* @@ -390,9 +411,9 @@ config_threads(CONFIG *cfg, const char *config, size_t len) return (0); err: if (group != NULL) - (void)group->close(group); + testutil_check(group->close(group)); if (scan != NULL) - (void)scan->close(scan); + testutil_check(scan->close(scan)); fprintf(stderr, "invalid thread configuration or scan error: %.*s\n", diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/1bn-lsm-50r50u.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/1bn-lsm-50r50u.wtperf deleted file mode 100644 index 2f09a63a0fd..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/1bn-lsm-50r50u.wtperf +++ /dev/null @@ -1,20 +0,0 @@ -# wtperf options file: simulate riak and its test3 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. -# This test assumes that its correlating populate already completed and exists. -# -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=60)" -conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,lsm_manager=(worker_thread_max=8)" -compression="snappy" -create=false -sess_config="isolation=snapshot" -table_config="internal_page_max=128K,lsm=(bloom_config=(leaf_page_max=8MB),bloom_bit_count=28,bloom_hash_count=19,bloom_oldest=true,chunk_max=5GB,chunk_size=100MB),type=lsm,leaf_page_max=16K,os_cache_dirty_max=16MB" -key_sz=40 -value_sz=1000 -max_latency=2000 -pareto=20 -report_interval=10 -run_time=14400 -sample_interval=10 -#threads=((count=20,reads=1,updates=1)) -threads=((count=10,reads=1),(count=10,updates=1)) diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/1bn-lsm-80r20u.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/1bn-lsm-80r20u.wtperf deleted file mode 100644 index 8139cdc16ea..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/1bn-lsm-80r20u.wtperf +++ /dev/null @@ -1,18 +0,0 @@ -# wtperf options file: simulate riak and its test2 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. -# This test assumes that its correlating populate already completed and exists. -# -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=60)" -conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,lsm_manager=(worker_thread_max=6)" -compression="snappy" -create=false -sess_config="isolation=snapshot" -table_config="internal_page_max=128K,lsm=(bloom_config=(leaf_page_max=8MB),bloom_bit_count=28,bloom_hash_count=19,bloom_oldest=true,chunk_max=5GB,chunk_size=100MB),type=lsm,leaf_page_max=16K,os_cache_dirty_max=16MB" -key_sz=40 -value_sz=1000 -max_latency=2000 -report_interval=10 -run_time=14400 -sample_interval=10 -threads=((count=20,reads=4,updates=1)) diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/1bn-lsm-populate.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/1bn-lsm-populate.wtperf deleted file mode 100644 index f25960f565a..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/1bn-lsm-populate.wtperf +++ /dev/null @@ -1,19 +0,0 @@ -# wtperf options file: simulate riak and its test1 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. -# This task is the populate phase for its family of tests. -# -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=60)" -conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,lsm_manager=(worker_thread_max=6)" -compact=true -compression="snappy" -sess_config="isolation=snapshot" -table_config="internal_page_max=128K,lsm=(bloom_config=(leaf_page_max=8MB),bloom_bit_count=28,bloom_hash_count=19,bloom_oldest=true,chunk_max=5GB,chunk_size=100MB),type=lsm,leaf_page_max=16K,os_cache_dirty_max=16MB" -icount=1000000000 -key_sz=40 -value_sz=1000 -max_latency=2000 -populate_threads=20 -report_interval=10 -random_value=true -sample_interval=10 diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/1bn-lsm-rdonly.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/1bn-lsm-rdonly.wtperf deleted file mode 100644 index 01cb4427a70..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/1bn-lsm-rdonly.wtperf +++ /dev/null @@ -1,18 +0,0 @@ -# wtperf options file: simulate riak and its test4 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. -# This test assumes that its correlating populate already completed and exists. -# -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=60)" -conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,lsm_manager=(worker_thread_max=6)" -compression="snappy" -create=false -sess_config="isolation=snapshot" -table_config="internal_page_max=128K,lsm=(bloom_config=(leaf_page_max=8MB),bloom_bit_count=28,bloom_hash_count=19,bloom_oldest=true,chunk_max=5GB,chunk_size=100MB),type=lsm,leaf_page_max=16K,os_cache_dirty_max=16MB" -key_sz=40 -value_sz=1000 -max_latency=2000 -report_interval=10 -run_time=14400 -sample_interval=10 -threads=((count=20,reads=1)) diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/2bn-lsm-50r50u.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/2bn-lsm-50r50u.wtperf deleted file mode 100644 index 13552d4c78e..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/2bn-lsm-50r50u.wtperf +++ /dev/null @@ -1,20 +0,0 @@ -# wtperf options file: simulate riak and its test3 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. -# This test assumes that its correlating populate already completed and exists. -# -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=60)" -conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,lsm_manager=(worker_thread_max=8)" -compression="snappy" -create=false -sess_config="isolation=snapshot" -table_config="internal_page_max=128K,lsm=(bloom_config=(leaf_page_max=8MB),bloom_bit_count=28,bloom_hash_count=19,bloom_oldest=true,chunk_max=20GB,chunk_size=100MB),type=lsm,leaf_page_max=16K,os_cache_dirty_max=16MB" -key_sz=40 -value_sz=1000 -max_latency=2000 -pareto=20 -report_interval=10 -run_time=14400 -sample_interval=10 -#threads=((count=20,reads=1,updates=1)) -threads=((count=10,reads=1),(count=10,updates=1)) diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/2bn-lsm-80r20u.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/2bn-lsm-80r20u.wtperf deleted file mode 100644 index 9d66019db24..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/2bn-lsm-80r20u.wtperf +++ /dev/null @@ -1,18 +0,0 @@ -# wtperf options file: simulate riak and its test2 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. -# This test assumes that its correlating populate already completed and exists. -# -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=60)" -conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,lsm_manager=(worker_thread_max=6)" -compression="snappy" -create=false -sess_config="isolation=snapshot" -table_config="internal_page_max=128K,lsm=(bloom_config=(leaf_page_max=8MB),bloom_bit_count=28,bloom_hash_count=19,bloom_oldest=true,chunk_max=20GB,chunk_size=100MB),type=lsm,leaf_page_max=16K,os_cache_dirty_max=16MB" -key_sz=40 -value_sz=1000 -max_latency=2000 -report_interval=10 -run_time=14400 -sample_interval=10 -threads=((count=20,reads=4,updates=1)) diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/2bn-lsm-populate.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/2bn-lsm-populate.wtperf deleted file mode 100644 index ad2ecaaa790..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/2bn-lsm-populate.wtperf +++ /dev/null @@ -1,19 +0,0 @@ -# wtperf options file: simulate riak and its test1 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. -# This task is the populate phase for its family of tests. -# -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=60)" -conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,lsm_manager=(worker_thread_max=6)" -compact=true -compression="snappy" -sess_config="isolation=snapshot" -table_config="internal_page_max=128K,lsm=(bloom_config=(leaf_page_max=8MB),bloom_bit_count=28,bloom_hash_count=19,bloom_oldest=true,chunk_max=20GB,chunk_size=100MB),type=lsm,leaf_page_max=16K,os_cache_dirty_max=16MB" -icount=2000000000 -key_sz=40 -value_sz=1000 -max_latency=2000 -populate_threads=20 -report_interval=10 -random_value=true -sample_interval=10 diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/2bn-lsm-rdonly.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/2bn-lsm-rdonly.wtperf deleted file mode 100644 index 64e64ab1f7e..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/2bn-lsm-rdonly.wtperf +++ /dev/null @@ -1,18 +0,0 @@ -# wtperf options file: simulate riak and its test4 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. -# This test assumes that its correlating populate already completed and exists. -# -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=60)" -conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,lsm_manager=(worker_thread_max=6)" -compression="snappy" -create=false -sess_config="isolation=snapshot" -table_config="internal_page_max=128K,lsm=(bloom_config=(leaf_page_max=8MB),bloom_bit_count=28,bloom_hash_count=19,bloom_oldest=true,chunk_max=20GB,chunk_size=100MB),type=lsm,leaf_page_max=16K,os_cache_dirty_max=16MB" -key_sz=40 -value_sz=1000 -max_latency=2000 -report_interval=10 -run_time=14400 -sample_interval=10 -threads=((count=20,reads=1)) diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/500m-btree-50r50u.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/500m-btree-50r50u.wtperf index 4ca956d2afe..06745bf7cca 100644 --- a/src/third_party/wiredtiger/bench/wtperf/runners/500m-btree-50r50u.wtperf +++ b/src/third_party/wiredtiger/bench/wtperf/runners/500m-btree-50r50u.wtperf @@ -1,19 +1,22 @@ -# wtperf options file: simulate riak and its test3 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. +# wtperf options file: simulate MongoDB. +# The configuration for the connection and table are from mongoDB. +# We use multiple tables to simulate collections and indexes. # This test assumes that its correlating populate already completed and exists. # -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=60)" -conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,log=(enabled),statistics=(fast),statistics_log=(wait=30)" -checkpoint_interval=60 +# Set cache to half of memory of AWS perf instance. Enable logging and +# checkpoints. Collect wiredtiger stats for ftdc. +conn_config="cache_size=16G,checkpoint=(wait=60,log_size=2GB),session_max=20000,log=(enabled),statistics=(fast),statistics_log=(wait=30,json),eviction=(threads_max=4)" create=false compression="snappy" sess_config="isolation=snapshot" +table_count=2 key_sz=40 -value_sz=1000 +value_sz=120 max_latency=2000 pareto=20 report_interval=10 run_time=7200 sample_interval=10 +sample_rate=1 threads=((count=10,reads=1),(count=10,updates=1)) +warmup=120 diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/500m-btree-80r20u.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/500m-btree-80r20u.wtperf index 50488f72ead..77edbfb4941 100644 --- a/src/third_party/wiredtiger/bench/wtperf/runners/500m-btree-80r20u.wtperf +++ b/src/third_party/wiredtiger/bench/wtperf/runners/500m-btree-80r20u.wtperf @@ -1,18 +1,21 @@ -# wtperf options file: simulate riak and its test2 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. +# wtperf options file: simulate MongoDB. +# The configuration for the connection and table are from mongoDB. +# We use multiple tables to simulate collections and indexes. # This test assumes that its correlating populate already completed and exists. # -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=60)" -conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,log=(enabled),statistics=(fast),statistics_log=(wait=30)" -checkpoint_interval=60 +# Set cache to half of memory of AWS perf instance. Enable logging and +# checkpoints. Collect wiredtiger stats for ftdc. +conn_config="cache_size=16G,checkpoint=(wait=60,log_size=2GB),session_max=20000,log=(enabled),statistics=(fast),statistics_log=(wait=30,json),eviction=(threads_max=4)" create=false compression="snappy" sess_config="isolation=snapshot +table_count=2 key_sz=40 -value_sz=1000 +value_sz=120 max_latency=2000 report_interval=10 run_time=7200 sample_interval=10 +sample_rate=1 threads=((count=20,reads=4,updates=1)) +warmup=120 diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/500m-btree-populate.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/500m-btree-populate.wtperf index 9f34b8a8b1f..f9aed094aa1 100644 --- a/src/third_party/wiredtiger/bench/wtperf/runners/500m-btree-populate.wtperf +++ b/src/third_party/wiredtiger/bench/wtperf/runners/500m-btree-populate.wtperf @@ -1,20 +1,26 @@ -# wtperf options file: simulate riak and its test1 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. -# This task is the populate phase for its family of tests. +# wtperf options file: simulate MongoDB. +# The configuration for the connection and table are from mongoDB. +# We use multiple tables to simulate collections and indexes. +# This test assumes that its correlating populate already completed and exists. # -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=60)" -conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,log=(enabled),statistics=(fast),statistics_log=(wait=30)" -checkpoint_interval=60 +# Set cache to half of memory. This value is computed from the AWS instance +# where Jenkins perf runs which has 32G. Enable logging and checkpoints. +# Collect wiredtiger stats for ftdc. +# +# This generates about 80 Gb of uncompressed data. But it should compress +# well and be small on disk. +conn_config="cache_size=16G,checkpoint=(wait=60,log_size=2GB),session_max=20000,log=(enabled),statistics=(fast),statistics_log=(wait=30,json),eviction=(threads_max=4)" compact=true compression="snappy" sess_config="isolation=snapshot" -table_config="internal_page_max=128K,type=file,leaf_page_max=16K" +table_config="internal_page_max=16K,type=file,leaf_page_max=16K,memory_page_max=10M,split_pct=90" +table_count=2 icount=500000000 key_sz=40 -value_sz=1000 +value_sz=120 max_latency=2000 populate_threads=20 report_interval=10 random_value=true sample_interval=10 +sample_rate=1 diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/500m-btree-rdonly.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/500m-btree-rdonly.wtperf index 965306262a3..2c9540ff589 100644 --- a/src/third_party/wiredtiger/bench/wtperf/runners/500m-btree-rdonly.wtperf +++ b/src/third_party/wiredtiger/bench/wtperf/runners/500m-btree-rdonly.wtperf @@ -1,18 +1,21 @@ -# wtperf options file: simulate riak and its test4 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. +# wtperf options file: simulate MongoDB. +# The configuration for the connection and table are from mongoDB. +# We use multiple tables to simulate collections and indexes. # This test assumes that its correlating populate already completed and exists. # -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=60)" -conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,log=(enabled),statistics=(fast),statistics_log=(wait=30)" -checkpoint_interval=60 +# Set cache to half of memory of AWS perf instance. Enable logging and +# checkpoints. Collect wiredtiger stats for ftdc. +conn_config="cache_size=16G,checkpoint=(wait=60,log_size=2GB),session_max=20000,log=(enabled),statistics=(fast),statistics_log=(wait=30,json),eviction=(threads_max=4)" create=false compression="snappy" sess_config="isolation=snapshot" +table_count=2 key_sz=40 -value_sz=1000 +value_sz=120 max_latency=2000 report_interval=10 run_time=7200 sample_interval=10 +sample_rate=1 threads=((count=20,reads=1)) +warmup=120 diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/500m-lsm-50r50u.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/500m-lsm-50r50u.wtperf deleted file mode 100644 index bd79e508895..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/500m-lsm-50r50u.wtperf +++ /dev/null @@ -1,20 +0,0 @@ -# wtperf options file: simulate riak and its test3 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. -# This test assumes that its correlating populate already completed and exists. -# -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=60)" -conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,lsm_manager=(worker_thread_max=8)" -create=false -compression="snappy" -sess_config="isolation=snapshot" -table_config="internal_page_max=128K,lsm=(bloom_config=(leaf_page_max=8MB),bloom_bit_count=28,bloom_hash_count=19,bloom_oldest=true,chunk_max=5GB,chunk_size=100MB),type=lsm,leaf_page_max=16K,os_cache_dirty_max=16MB" -key_sz=40 -value_sz=1000 -max_latency=2000 -pareto=20 -report_interval=10 -run_time=14400 -sample_interval=10 -#threads=((count=20,reads=1,updates=1)) -threads=((count=10,reads=1),(count=10,updates=1)) diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/500m-lsm-80r20u.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/500m-lsm-80r20u.wtperf deleted file mode 100644 index e5ae5e66401..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/500m-lsm-80r20u.wtperf +++ /dev/null @@ -1,18 +0,0 @@ -# wtperf options file: simulate riak and its test2 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. -# This test assumes that its correlating populate already completed and exists. -# -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=60)" -conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,lsm_manager=(worker_thread_max=6)" -create=false -compression="snappy" -sess_config="isolation=snapshot -table_config="internal_page_max=128K,lsm=(bloom_config=(leaf_page_max=8MB),bloom_bit_count=28,bloom_hash_count=19,bloom_oldest=true,chunk_max=5GB,chunk_size=100MB),type=lsm,leaf_page_max=16K,os_cache_dirty_max=16MB" -key_sz=40 -value_sz=1000 -max_latency=2000 -report_interval=10 -run_time=14400 -sample_interval=10 -threads=((count=20,reads=4,updates=1)) diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/500m-lsm-populate.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/500m-lsm-populate.wtperf deleted file mode 100644 index 1451fe3d673..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/500m-lsm-populate.wtperf +++ /dev/null @@ -1,19 +0,0 @@ -# wtperf options file: simulate riak and its test1 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. -# This task is the populate phase for its family of tests. -# -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=60)" -conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,lsm_manager=(worker_thread_max=6)" -compact=true -compression="snappy" -sess_config="isolation=snapshot" -table_config="internal_page_max=128K,lsm=(bloom_config=(leaf_page_max=8MB),bloom_bit_count=28,bloom_hash_count=19,bloom_oldest=true,chunk_max=5GB,chunk_size=100MB),type=lsm,leaf_page_max=16K,os_cache_dirty_max=16MB" -icount=500000000 -key_sz=40 -value_sz=1000 -max_latency=2000 -populate_threads=20 -report_interval=10 -random_value=true -sample_interval=10 diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/500m-lsm-rdonly.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/500m-lsm-rdonly.wtperf deleted file mode 100644 index af30affafb0..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/500m-lsm-rdonly.wtperf +++ /dev/null @@ -1,18 +0,0 @@ -# wtperf options file: simulate riak and its test4 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. -# This test assumes that its correlating populate already completed and exists. -# -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=60)" -conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,lsm_manager=(worker_thread_max=6)" -create=false -compression="snappy" -sess_config="isolation=snapshot" -table_config="internal_page_max=128K,lsm=(bloom_config=(leaf_page_max=8MB),bloom_bit_count=28,bloom_hash_count=19,bloom_oldest=true,chunk_max=5GB,chunk_size=100MB),type=lsm,leaf_page_max=16K,os_cache_dirty_max=16MB" -key_sz=40 -value_sz=1000 -max_latency=2000 -report_interval=10 -run_time=14400 -sample_interval=10 -threads=((count=20,reads=1)) diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/50m-lsm-50r50u.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/50m-lsm-50r50u.wtperf deleted file mode 100644 index 07add74eb6d..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/50m-lsm-50r50u.wtperf +++ /dev/null @@ -1,19 +0,0 @@ -# wtperf options file: simulate riak and its test3 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. -# This test assumes that its correlating populate already completed and exists. -# -#conn_config="cache_size=10G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=30)" -conn_config="cache_size=10G,checkpoint_sync=false,mmap=false,session_max=1024,lsm_manager=(worker_thread_max=6)" -create=false -sess_config="isolation=snapshot" -table_config="internal_page_max=128K,lsm=(bloom_config=(leaf_page_max=8MB),bloom_bit_count=28,bloom_hash_count=19,bloom_oldest=true,chunk_size=100MB),type=lsm,leaf_page_max=16K,os_cache_dirty_max=16MB" -key_sz=40 -value_sz=1000 -max_latency=2000 -pareto=20 -report_interval=10 -run_time=1440 -sample_interval=10 -#threads=((count=10,reads=1,updates=1)) -threads=((count=5,reads=1),(count=5,updates=1)) diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/50m-lsm-80r20u.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/50m-lsm-80r20u.wtperf deleted file mode 100644 index 96c51ef5fa7..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/50m-lsm-80r20u.wtperf +++ /dev/null @@ -1,17 +0,0 @@ -# wtperf options file: simulate riak and its test2 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. -# This test assumes that its correlating populate already completed and exists. -# -#conn_config="cache_size=10G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=30)" -conn_config="cache_size=10G,checkpoint_sync=false,mmap=false,session_max=1024,lsm_manager=(worker_thread_max=6)" -create=false -sess_config="isolation=snapshot" -table_config="internal_page_max=128K,lsm=(bloom_config=(leaf_page_max=8MB),bloom_bit_count=28,bloom_hash_count=19,bloom_oldest=true,chunk_size=100MB),type=lsm,leaf_page_max=16K,os_cache_dirty_max=16MB" -key_sz=40 -value_sz=1000 -max_latency=2000 -report_interval=10 -run_time=1440 -sample_interval=10 -threads=((count=10,reads=4,updates=1)) diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/50m-lsm-populate.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/50m-lsm-populate.wtperf deleted file mode 100644 index 6893abec007..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/50m-lsm-populate.wtperf +++ /dev/null @@ -1,18 +0,0 @@ -# wtperf options file: simulate riak and its test1 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. -# This task is the populate phase for its family of tests. -# -#conn_config="cache_size=10G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=30),lsm_manager=(worker_thread_max=6)" -conn_config="cache_size=10G,checkpoint_sync=false,mmap=false,session_max=1024,lsm_manager=(worker_thread_max=6)" -compact=true -sess_config="isolation=snapshot" -table_config="internal_page_max=128K,lsm=(bloom_config=(leaf_page_max=8MB),bloom_bit_count=28,bloom_hash_count=19,bloom_oldest=true,chunk_size=100MB),type=lsm,leaf_page_max=16K,os_cache_dirty_max=16MB" -icount=50000000 -key_sz=40 -value_sz=1000 -max_latency=2000 -populate_threads=10 -report_interval=10 -random_value=true -sample_interval=10 diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/50m-lsm-rdonly.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/50m-lsm-rdonly.wtperf deleted file mode 100644 index 53b38f20c51..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/50m-lsm-rdonly.wtperf +++ /dev/null @@ -1,17 +0,0 @@ -# wtperf options file: simulate riak and its test4 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. -# This test assumes that its correlating populate already completed and exists. -# -#conn_config="cache_size=10G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=30)" -conn_config="cache_size=10G,checkpoint_sync=false,mmap=false,session_max=1024,lsm_manager=(worker_thread_max=6)" -create=false -sess_config="isolation=snapshot" -table_config="internal_page_max=128K,lsm=(bloom_config=(leaf_page_max=8MB),bloom_bit_count=28,bloom_hash_count=19,bloom_oldest=true,chunk_size=100MB),type=lsm,leaf_page_max=16K,os_cache_dirty_max=16MB" -key_sz=40 -value_sz=1000 -max_latency=2000 -report_interval=10 -run_time=1440 -sample_interval=10 -threads=((count=10,reads=1)) diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/checkpoint-schema-race.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/checkpoint-schema-race.wtperf new file mode 100644 index 00000000000..ade8e88ee9b --- /dev/null +++ b/src/third_party/wiredtiger/bench/wtperf/runners/checkpoint-schema-race.wtperf @@ -0,0 +1,20 @@ +# Check create and drop behavior concurrent with checkpoints (WT-2798). +# Setup a multiple tables and a cache size large enough that checkpoints can +# take a long time. +conn_config="cache_size=8GB,log=(enabled=false),checkpoint=(wait=30)" +table_config="leaf_page_max=4k,internal_page_max=16k,type=file" +icount=10000000 +table_count=100 +table_count_idle=100 +# Turn on create/drop of idle tables, but don't worry if individual operations +# take a long time. +idle_table_cycle=120 +populate_threads=5 +checkpoint_threads=0 +report_interval=5 +# 100 million +random_range=10000000 +run_time=300 +# Setup a workload that dirties a lot of the cache +threads=((count=2,reads=1),(count=2,inserts=1),(count=2,updates=1)) +value_sz=500 diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/checkpoint-stress-schema-ops.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/checkpoint-stress-schema-ops.wtperf new file mode 100644 index 00000000000..b69ead7f8b1 --- /dev/null +++ b/src/third_party/wiredtiger/bench/wtperf/runners/checkpoint-stress-schema-ops.wtperf @@ -0,0 +1,19 @@ +# A stress configuration, to create long running checkpoints and see how +# they interfere with schema level operations (table create, drop). +# Setup a cache size large enough that checkpoints can take a long time. +conn_config="cache_size=8GB,log=(enabled=false),checkpoint=(wait=30)" +table_config="leaf_page_max=4k,internal_page_max=16k,type=file" +icount=10000000 +table_count_idle=100 +# Turn on create/drop of idle tables, and error if a single operation takes +# more than 5 seconds. +idle_table_cycle=5 +populate_threads=5 +checkpoint_threads=0 +report_interval=5 +# 100 million +random_range=100000000 +run_time=1000 +# Setup a workload that dirties a lot of the cache +threads=((count=2,reads=1),(count=2,inserts=1),(count=2,updates=1)) +value_sz=500 diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/checkpoint-stress.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/checkpoint-stress.wtperf new file mode 100644 index 00000000000..d992f69eb67 --- /dev/null +++ b/src/third_party/wiredtiger/bench/wtperf/runners/checkpoint-stress.wtperf @@ -0,0 +1,23 @@ +# A stress configuration to create long running checkpoints while doing a lot +# of updates. +conn_config="cache_size=10GB,log=(enabled=false)" +table_config="leaf_page_max=32k,internal_page_max=16k,allocation_size=4k,split_pct=90,type=file" +# Enough data to fill the cache. 100 million 1k records results in two ~6GB +# tables +icount=100000000 +create=true +compression="snappy" +populate_threads=1 +checkpoint_interval=60 +checkpoint_threads=1 +report_interval=10 +# Run for a longer duration to ensure checkpoints are completing. +run_time=600 +# MongoDB always has multiple tables, and checkpoints behave differently when +# there is more than a single table. +table_count=2 +threads=((count=6,updates=1)) +value_sz=1000 +sample_interval=10 +sample_rate=1 +warmup=120 diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/checkpoint_stress_schema_ops.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/checkpoint_stress_schema_ops.wtperf deleted file mode 100644 index b69ead7f8b1..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/checkpoint_stress_schema_ops.wtperf +++ /dev/null @@ -1,19 +0,0 @@ -# A stress configuration, to create long running checkpoints and see how -# they interfere with schema level operations (table create, drop). -# Setup a cache size large enough that checkpoints can take a long time. -conn_config="cache_size=8GB,log=(enabled=false),checkpoint=(wait=30)" -table_config="leaf_page_max=4k,internal_page_max=16k,type=file" -icount=10000000 -table_count_idle=100 -# Turn on create/drop of idle tables, and error if a single operation takes -# more than 5 seconds. -idle_table_cycle=5 -populate_threads=5 -checkpoint_threads=0 -report_interval=5 -# 100 million -random_range=100000000 -run_time=1000 -# Setup a workload that dirties a lot of the cache -threads=((count=2,reads=1),(count=2,inserts=1),(count=2,updates=1)) -value_sz=500 diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/evict-btree-stress-multi.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/evict-btree-stress-multi.wtperf new file mode 100644 index 00000000000..9699b9ae3bb --- /dev/null +++ b/src/third_party/wiredtiger/bench/wtperf/runners/evict-btree-stress-multi.wtperf @@ -0,0 +1,12 @@ +conn_config="cache_size=1G,eviction=(threads_max=4),session_max=2000" +table_config="type=file" +table_count=100 +icount=100000000 +report_interval=5 +run_time=600 +populate_threads=1 +threads=((count=100,updates=1,reads=4,ops_per_txn=30)) +# Warn if a latency over a quarter second is seen +max_latency=250 +sample_interval=5 +sample_rate=1 diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/fruit-lsm.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/fruit-lsm.wtperf deleted file mode 100644 index e5817554201..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/fruit-lsm.wtperf +++ /dev/null @@ -1,22 +0,0 @@ -# wtperf options file: simulate riak and its test1 and test2 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. -# -conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=600),log=(enabled=true),transaction_sync=(enabled=true,method=none),checkpoint=(wait=180),lsm_manager=(worker_thread_max=12)" -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=600)" -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024" -compact=true -sess_config="isolation=snapshot" -table_config="internal_page_max=128K,lsm=(bloom_config=(leaf_page_max=8MB),bloom_bit_count=28,bloom_hash_count=19,bloom_oldest=true,chunk_size=100MB),type=lsm,leaf_page_max=16K,leaf_item_max=4K,os_cache_dirty_max=16MB" -icount=25000000 -key_sz=40 -value_sz=800 -#max_latency=2000 -pareto=20 -populate_threads=20 -report_interval=10 -random_value=true -run_time=18000 -sample_interval=10 -table_count=8 -threads=((count=20,read=6,update=1)) diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/fruit-short.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/fruit-short.wtperf deleted file mode 100644 index 10cb423a92d..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/fruit-short.wtperf +++ /dev/null @@ -1,20 +0,0 @@ -# wtperf options file: simulate riak and its test1 and test2 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. -# -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=600)" -conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,lsm_manager=(worker_thread_max=6)" -compact=true -sess_config="isolation=snapshot" -table_config="internal_page_max=128K,lsm=(bloom_config=(leaf_page_max=8MB),bloom_bit_count=28,bloom_hash_count=19,bloom_oldest=true,chunk_size=100MB),type=lsm,leaf_page_max=16K" -icount=25000000 -key_sz=40 -value_sz=800 -max_latency=2000 -pareto=20 -populate_threads=20 -report_interval=10 -random_value=true -run_time=1800 -sample_interval=10 -threads=((count=20,read=6,update=1)) diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/log-append-large.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/log-append-large.wtperf deleted file mode 100644 index c1364c17c28..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/log-append-large.wtperf +++ /dev/null @@ -1,10 +0,0 @@ -# wtperf options file: Test a log file with a multi-threaded -# append workload. We want to create a very large number of log file -# switches with fewer records per log file than we have active threads. -conn_config="cache_size=1G,log=(enabled=true,file_max=20MB),checkpoint=(log_size=1G)" -table_config="type=file" -icount=1000 -report_interval=5 -run_time=0 -value_sz=5000000 -populate_threads=8 diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/log-append-zero.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/log-append-zero.wtperf deleted file mode 100644 index 973d2cddd0d..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/log-append-zero.wtperf +++ /dev/null @@ -1,8 +0,0 @@ -# wtperf options file: Test a log file with a multi-threaded -# append workload. -conn_config="cache_size=1G,log=(enabled=true,file_max=20MB,zero_fill=true),checkpoint=(log_size=1G)" -table_config="type=file" -icount=50000000 -report_interval=5 -run_time=0 -populate_threads=8 diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/log-append.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/log-append.wtperf deleted file mode 100644 index 9d0a78e3c61..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/log-append.wtperf +++ /dev/null @@ -1,8 +0,0 @@ -# wtperf options file: Test a log file with a multi-threaded -# append workload. -conn_config="cache_size=1G,log=(enabled=true,file_max=20MB),checkpoint=(log_size=1G)" -table_config="type=file" -icount=50000000 -report_interval=5 -run_time=0 -populate_threads=8 diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/log-nockpt.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/log-nockpt.wtperf deleted file mode 100644 index a078cead740..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/log-nockpt.wtperf +++ /dev/null @@ -1,12 +0,0 @@ -# wtperf options file: Test performance with a log file enabled. -# Set the log file reasonably small to catch log-swtich bottle -# necks. -conn_config="cache_size=1G,log=(enabled=true,file_max=20MB)" -table_config="type=file" -icount=50000 -report_interval=5 -run_time=40 -populate_threads=1 -random_range=50000000 -threads=((count=8,inserts=1)) - diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/log-noprealloc.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/log-noprealloc.wtperf deleted file mode 100644 index 66032f599aa..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/log-noprealloc.wtperf +++ /dev/null @@ -1,11 +0,0 @@ -# wtperf options file: Test performance with a log file enabled. -# Set the log file reasonably small to catch log-swtich bottle -# necks. -conn_config="cache_size=1G,log=(enabled=true,file_max=200K,prealloc=false),checkpoint=(log_size=500MB)" -table_config="type=file" -icount=50000 -report_interval=5 -run_time=120 -populate_threads=1 -random_range=50000000 -threads=((count=8,inserts=1)) diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/log.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/log.wtperf index 32a9cc3b0a6..6cf50dfb5a5 100644 --- a/src/third_party/wiredtiger/bench/wtperf/runners/log.wtperf +++ b/src/third_party/wiredtiger/bench/wtperf/runners/log.wtperf @@ -1,10 +1,27 @@ +# # wtperf options file: Test performance with a log file enabled. # Set the log file small to catch log-swtich bottlenecks. -conn_config="cache_size=1G,log=(enabled=true,file_max=200K),checkpoint=(log_size=500MB)" +# +# Perform updates instead of inserts to stress logging not eviction, +# page splits or reconciliation. Have it fit in cache. +# +# We expect this test can and will be run in other forms from the command +# line to change log file size, pre-allocation, zero filling, logging off +# and checkpoint off. +# +# Jenkins runs for perf testing: +# - Config as-is +# - Config + "-C "log=(enabled,file_max=1M)": small log files and switching +# - Config + "-C "log=(enabled,zero_fill=true,file_max=1M)": zero-filling +# - Config + "-C "checkpoint=(wait=0)": no checkpoints +# - Config + "-C "log=(enabled,prealloc=false,file_max=1M)": no pre-allocation +# +conn_config="cache_size=5G,log=(enabled=true),checkpoint=(log_size=500M),eviction=(threads_max=4)" table_config="type=file" -icount=50000 +icount=1000000 report_interval=5 -run_time=120 +run_time=180 populate_threads=1 -random_range=50000000 -threads=((count=8,inserts=1)) +threads=((count=8,updates=1)) +# Warm up the cache for a minute. +warmup=60 diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/mongodb-secondary-apply.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/mongodb-secondary-apply.wtperf new file mode 100644 index 00000000000..f9e41184f95 --- /dev/null +++ b/src/third_party/wiredtiger/bench/wtperf/runners/mongodb-secondary-apply.wtperf @@ -0,0 +1,21 @@ +# Simulate the MongoDB oplog apply threads on a secondary. +conn_config="cache_size=10GB,session_max=1000,eviction=(threads_min=4,threads_max=4),log=(enabled=false),transaction_sync=(enabled=false),checkpoint_sync=true,checkpoint=(wait=60),statistics=(fast),statistics_log=(json,wait=1)" +table_config="allocation_size=4k,memory_page_max=5MB,prefix_compression=false,split_pct=75,leaf_page_max=32k,internal_page_max=16k,type=file" +# Spread the workload out over several tables. +table_count=4 +# We like compression. +compression=snappy +icount=1000 +populate_threads=1 +reopen_connection=true +log_like_table=true +report_interval=5 +run_time=360 +# Configure multiple threads doing a limited number of operations each. Enclose +# a few operations in an explicit transaction to simulate MongoDB apply on a +# secondary. +threads=((count=16,throttle=1000,inserts=1,ops_per_txn=3)) +# Configure a moderately large value size +value_sz=1800 +sample_interval=5 +sample_rate=1 diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/multi-btree-zipfian-populate.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/multi-btree-zipfian-populate.wtperf new file mode 100644 index 00000000000..ddd9c055eac --- /dev/null +++ b/src/third_party/wiredtiger/bench/wtperf/runners/multi-btree-zipfian-populate.wtperf @@ -0,0 +1,19 @@ +# Create a set of tables with uneven distribution of data +conn_config="cache_size=1G,eviction=(threads_max=4),file_manager=(close_idle_time=100000),checkpoint=(wait=60,log_size=2GB),statistics=(fast),statistics_log=(wait=5,json),session_max=1000" +table_config="type=file" +table_count=100 +icount=0 +random_range=1000000000 +pareto=10 +range_partition=true +report_interval=5 + +run_ops=10000000 +populate_threads=0 +icount=0 +threads=((count=20,inserts=1)) + +# Warn if a latency over 1 second is seen +max_latency=1000 +sample_interval=5 +sample_rate=1 diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/multi-btree-zipfian-workload.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/multi-btree-zipfian-workload.wtperf new file mode 100644 index 00000000000..380350c88c8 --- /dev/null +++ b/src/third_party/wiredtiger/bench/wtperf/runners/multi-btree-zipfian-workload.wtperf @@ -0,0 +1,18 @@ +# Read from a set of tables with uneven distribution of data +conn_config="cache_size=1G,eviction=(threads_max=4),file_manager=(close_idle_time=100000),checkpoint=(wait=60,log_size=2GB),statistics=(fast),statistics_log=(wait=5,json),session_max=1000" +table_config="type=file" +table_count=100 +icount=0 +random_range=1000000000 +pareto=10 +range_partition=true +report_interval=5 +create=false + +run_time=600 +threads=((count=20,reads=1)) + +# Warn if a latency over 1 second is seen +max_latency=1000 +sample_interval=5 +sample_rate=1 diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/overflow-10k-short.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/overflow-10k-short.wtperf deleted file mode 100644 index 47228079db8..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/overflow-10k-short.wtperf +++ /dev/null @@ -1,19 +0,0 @@ -# wtperf options file: simulate riak and a short form of its voxer config. -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. -# -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=600)" -conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,lsm_manager=(worker_thread_max=6)" -compact=true -compression="snappy" -sess_config="isolation=snapshot" -table_config="internal_page_max=128K,lsm=(bloom_config=(leaf_page_max=8MB),bloom_bit_count=28,bloom_hash_count=19,bloom_oldest=true,chunk_size=100MB),type=lsm,leaf_page_max=16K,os_cache_dirty_max=16MB" -icount=15000 -key_sz=40 -value_sz=10000 -max_latency=2000 -populate_threads=1 -report_interval=5 -random_value=true -run_time=300 -threads=((count=10,read=1),(count=10,update=1)) diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/overflow-10k.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/overflow-10k.wtperf index 9b4ed2acaee..5d7eeea9cf2 100644 --- a/src/third_party/wiredtiger/bench/wtperf/runners/overflow-10k.wtperf +++ b/src/third_party/wiredtiger/bench/wtperf/runners/overflow-10k.wtperf @@ -1,9 +1,7 @@ -# wtperf options file: simulate riak and its test1 and test2 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. # -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=600)" -conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,lsm_manager=(worker_thread_max=6)" +# Run with overflow items and LSM. +# +conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,lsm_manager=(worker_thread_max=6),statistics=(fast),statistics_log=(wait=10)" compact=true compression="snappy" sess_config="isolation=snapshot" @@ -13,8 +11,8 @@ key_sz=40 value_sz=10000 max_latency=2000 populate_threads=1 -report_interval=10 +report_interval=5 random_value=true -run_time=18000 -sample_interval=10 -threads=((count=20,read=1,update=1)) +run_time=300 +threads=((count=10,read=1),(count=10,update=1)) +warmup=30 diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/overflow-130k-short.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/overflow-130k-short.wtperf deleted file mode 100644 index 83f67062bf8..00000000000 --- a/src/third_party/wiredtiger/bench/wtperf/runners/overflow-130k-short.wtperf +++ /dev/null @@ -1,19 +0,0 @@ -# wtperf options file: simulate riak and a short form of its voxer config. -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. -# -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=600)" -conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,lsm_manager=(worker_thread_max=6)" -compact=true -compression="snappy" -sess_config="isolation=snapshot" -table_config="internal_page_max=128K,lsm=(bloom_config=(leaf_page_max=8MB),bloom_bit_count=28,bloom_hash_count=19,bloom_oldest=true,chunk_size=100MB),type=lsm,leaf_page_max=16K,os_cache_dirty_max=16MB" -icount=15000 -key_sz=40 -value_sz=130000 -max_latency=2000 -populate_threads=1 -report_interval=5 -random_value=true -run_time=300 -threads=((count=10,read=1),(count=10,update=1)) diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/overflow-130k.wtperf b/src/third_party/wiredtiger/bench/wtperf/runners/overflow-130k.wtperf index a3439f0c575..2be01afd08a 100644 --- a/src/third_party/wiredtiger/bench/wtperf/runners/overflow-130k.wtperf +++ b/src/third_party/wiredtiger/bench/wtperf/runners/overflow-130k.wtperf @@ -1,20 +1,18 @@ -# wtperf options file: simulate riak and its test1 and test2 configuration -# The configuration for the connection and table are from riak and the -# specification of the data (count, size, threads) is from basho_bench. # -#conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,statistics=(fast,clear),statistics_log=(wait=600)" -conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,session_max=1024,lsm_manager=(worker_thread_max=6)" +# Run with very large overflow items and btree. +# +conn_config="cache_size=21G,checkpoint_sync=false,mmap=false,statistics=(fast),statistics_log=(wait=10)" compact=true compression="snappy" sess_config="isolation=snapshot" -table_config="internal_page_max=128K,lsm=(bloom_config=(leaf_page_max=8MB),bloom_bit_count=28,bloom_hash_count=19,bloom_oldest=true,chunk_size=100MB),type=lsm,leaf_page_max=16K,os_cache_dirty_max=16MB" +table_config="internal_page_max=128K,type=file,leaf_page_max=16K,os_cache_dirty_max=16MB,leaf_value_max=32K" icount=15000 key_sz=40 value_sz=130000 max_latency=2000 populate_threads=1 -report_interval=10 +report_interval=5 random_value=true -run_time=18000 -sample_interval=10 -threads=((count=20,read=1,update=1)) +run_time=300 +threads=((count=10,read=1),(count=10,update=1)) +warmup=30 diff --git a/src/third_party/wiredtiger/bench/wtperf/runners/wtperf_run.sh b/src/third_party/wiredtiger/bench/wtperf/runners/wtperf_run.sh index 7a1ad44f39c..9968edc468a 100755 --- a/src/third_party/wiredtiger/bench/wtperf/runners/wtperf_run.sh +++ b/src/third_party/wiredtiger/bench/wtperf/runners/wtperf_run.sh @@ -22,11 +22,16 @@ runmax=$2 # have 3 or 4 args. wtarg="" wtarg2="" +create=1 if test "$#" -gt "2"; then wtarg=$3 if test "$#" -eq "4"; then wtarg2=$4 fi + if test "$wtarg" == "NOCREATE"; then + create=0 + wtarg=$wtarg2 + fi fi home=./WT_TEST @@ -86,9 +91,11 @@ getmin=0 getmax=1 run=1 while test "$run" -le "$runmax"; do - rm -rf $home - mkdir $home - LD_PRELOAD=/usr/lib64/libjemalloc.so.1 LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib ./wtperf -O $wttest $wtarg $wtarg2 + if test "$create" -eq "1"; then + rm -rf $home + mkdir $home + fi + LD_PRELOAD=/usr/local/lib/libtcmalloc.so LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib ./wtperf -O $wttest $wtarg $wtarg2 if test "$?" -ne "0"; then exit 1 fi diff --git a/src/third_party/wiredtiger/bench/wtperf/wtperf.c b/src/third_party/wiredtiger/bench/wtperf/wtperf.c index 9d35f6fa640..bf6b156bb69 100644 --- a/src/third_party/wiredtiger/bench/wtperf/wtperf.c +++ b/src/third_party/wiredtiger/bench/wtperf/wtperf.c @@ -29,14 +29,16 @@ #include "wtperf.h" /* Default values. */ +#define DEFAULT_HOME "WT_TEST" +#define DEFAULT_MONITOR_DIR "WT_TEST" static const CONFIG default_cfg = { - "WT_TEST", /* home */ - "WT_TEST", /* monitor dir */ + NULL, /* home */ + NULL, /* monitor dir */ NULL, /* partial logging */ NULL, /* reopen config */ NULL, /* base_uri */ + NULL, /* log_table_uri */ NULL, /* uris */ - NULL, /* helium_mount */ NULL, /* conn */ NULL, /* logf */ NULL, /* async */ @@ -54,6 +56,7 @@ static const CONFIG default_cfg = { 0, /* truncate operations */ 0, /* update operations */ 0, /* insert key */ + 0, /* log like table key */ 0, /* checkpoint in progress */ 0, /* thread error */ 0, /* notify threads to stop */ @@ -73,14 +76,14 @@ static const char * const debug_cconfig = ""; static const char * const debug_tconfig = ""; static void *checkpoint_worker(void *); -static int create_tables(CONFIG *); -static int drop_all_tables(CONFIG *); +static int drop_all_tables(CONFIG *); static int execute_populate(CONFIG *); static int execute_workload(CONFIG *); static int find_table_count(CONFIG *); static void *monitor(void *); static void *populate_thread(void *); static void randomize_value(CONFIG_THREAD *, char *); +static void recreate_dir(const char *); static int start_all_runs(CONFIG *); static int start_run(CONFIG *); static int start_threads(CONFIG *, @@ -93,10 +96,6 @@ static void *worker(void *); static uint64_t wtperf_rand(CONFIG_THREAD *); static uint64_t wtperf_value_range(CONFIG *); -#define HELIUM_NAME "dev1" -#define HELIUM_PATH \ - "../../ext/test/helium/.libs/libwiredtiger_helium.so" -#define HELIUM_CONFIG ",type=helium" #define INDEX_COL_NAMES ",columns=(key,val)" /* Retrieve an ID for the next insert operation. */ @@ -154,6 +153,23 @@ randomize_value(CONFIG_THREAD *thread, char *value_buf) vb[i] = ((rand_val >> 16) % 255) + 1; } +/* + * Partition data by key ranges. + */ +static uint32_t +map_key_to_table(CONFIG *cfg, uint64_t k) +{ + if (cfg->range_partition) { + /* Take care to return a result in [0..table_count-1]. */ + if (k > cfg->icount + cfg->random_range) + return (0); + return ((uint32_t)((k - 1) / + ((cfg->icount + cfg->random_range + cfg->table_count - 1) / + cfg->table_count))); + } else + return ((uint32_t)(k % cfg->table_count)); +} + /* * Figure out and extend the size of the value string, used for growing * updates. We know that the value to be updated is in the threads value @@ -393,7 +409,7 @@ worker_async(void *arg) * Then retry to get an async op. */ while ((ret = conn->async_new_op( - conn, cfg->uris[next_val % cfg->table_count], + conn, cfg->uris[map_key_to_table(cfg, next_val)], NULL, &cb, &asyncop)) == EBUSY) (void)usleep(10000); if (ret != 0) @@ -466,7 +482,7 @@ do_range_reads(CONFIG *cfg, WT_CURSOR *cursor) range_key_buf = &buf[0]; /* Save where the first key is for comparisons. */ - cursor->get_key(cursor, &range_key_buf); + testutil_check(cursor->get_key(cursor, &range_key_buf)); extract_key(range_key_buf, &next_val); for (range = 0; range < cfg->read_range; ++range) { @@ -477,7 +493,7 @@ do_range_reads(CONFIG *cfg, WT_CURSOR *cursor) break; /* Retrieve and decode the key */ - cursor->get_key(cursor, &range_key_buf); + testutil_check(cursor->get_key(cursor, &range_key_buf)); extract_key(range_key_buf, &next_val); if (next_val < prev_val) { lprintf(cfg, EINVAL, 0, @@ -498,11 +514,11 @@ worker(void *arg) CONFIG_THREAD *thread; TRACK *trk; WT_CONNECTION *conn; - WT_CURSOR **cursors, *cursor, *tmp_cursor; + WT_CURSOR **cursors, *cursor, *log_table_cursor, *tmp_cursor; WT_SESSION *session; size_t i; int64_t ops, ops_per_txn; - uint64_t next_val, usecs; + uint64_t log_id, next_val, usecs; uint8_t *op, *op_end; int measure_latency, ret, truncated; char *value_buf, *key_buf, *value; @@ -512,6 +528,7 @@ worker(void *arg) cfg = thread->cfg; conn = cfg->conn; cursors = NULL; + log_table_cursor = NULL; /* -Wconditional-initialized */ ops = 0; ops_per_txn = thread->workload->ops_per_txn; session = NULL; @@ -546,10 +563,19 @@ worker(void *arg) goto err; } } + if (cfg->log_like_table) { + if ((ret = session->open_cursor(session, + cfg->log_table_uri, NULL, NULL, &log_table_cursor)) != 0) { + lprintf(cfg, ret, 0, + "worker: WT_SESSION.open_cursor: %s", + cfg->log_table_uri); + goto err; + } + } + /* Setup the timer for throttling. */ - if (thread->workload->throttle != 0 && - (ret = setup_throttle(thread)) != 0) - goto err; + if (thread->workload->throttle != 0) + setup_throttle(thread); /* Setup for truncate */ if (thread->workload->truncate != 0) @@ -562,7 +588,7 @@ worker(void *arg) op = thread->workload->ops; op_end = op + sizeof(thread->workload->ops); - if (ops_per_txn != 0 && + if ((ops_per_txn != 0 || cfg->log_like_table) && (ret = session->begin_transaction(session, NULL)) != 0) { lprintf(cfg, ret, 0, "First transaction begin failed"); goto err; @@ -611,7 +637,7 @@ worker(void *arg) /* * Spread the data out around the multiple databases. */ - cursor = cursors[next_val % cfg->table_count]; + cursor = cursors[map_key_to_table(cfg, next_val)]; /* * Skip the first time we do an operation, when trk->ops @@ -755,6 +781,20 @@ op_err: if (ret == WT_ROLLBACK && ops_per_txn != 0) { goto err; /* can't happen */ } + /* Update the log-like table. */ + if (cfg->log_like_table && + (*op != WORKER_READ && *op != WORKER_TRUNCATE)) { + log_id = __wt_atomic_add64(&cfg->log_like_table_key, 1); + log_table_cursor->set_key(log_table_cursor, log_id); + log_table_cursor->set_value( + log_table_cursor, value_buf); + if ((ret = + log_table_cursor->insert(log_table_cursor)) != 0) { + lprintf(cfg, ret, 0, "Cursor insert failed"); + goto err; + } + } + /* Release the cursor, if we have multiple tables. */ if (cfg->table_count > 1 && ret == 0 && *op != WORKER_INSERT && *op != WORKER_INSERT_RMW) { @@ -780,8 +820,12 @@ op_err: if (ret == WT_ROLLBACK && ops_per_txn != 0) { ++trk->ops; } - /* Commit our work if configured for explicit transactions */ - if (ops_per_txn != 0 && ops++ % ops_per_txn == 0) { + /* + * Commit the transaction if grouping operations together + * or tracking changes in our log table. + */ + if ((cfg->log_like_table && ops_per_txn == 0) || + (ops_per_txn != 0 && ops++ % ops_per_txn == 0)) { if ((ret = session->commit_transaction( session, NULL)) != 0) { lprintf(cfg, ret, 0, @@ -806,6 +850,7 @@ op_err: if (ret == WT_ROLLBACK && ops_per_txn != 0) { */ if (--thread->throttle_cfg.ops_count == 0) worker_throttle(thread); + } if ((ret = session->close(session, NULL)) != 0) { @@ -1010,7 +1055,7 @@ populate_thread(void *arg) /* * Figure out which table this op belongs to. */ - cursor = cursors[op % cfg->table_count]; + cursor = cursors[map_key_to_table(cfg, op)]; generate_key(cfg, key_buf, op); measure_latency = cfg->sample_interval != 0 && @@ -1148,7 +1193,7 @@ populate_async(void *arg) * Allocate an async op for whichever table. */ while ((ret = conn->async_new_op( - conn, cfg->uris[op % cfg->table_count], + conn, cfg->uris[map_key_to_table(cfg, op)], NULL, &cb, &asyncop)) == EBUSY) (void)usleep(10000); if (ret != 0) @@ -1527,8 +1572,7 @@ execute_populate(CONFIG *cfg) print_ops_sec = 0; } else { print_secs = (double)msecs / (double)MSEC_PER_SEC; - print_ops_sec = - (uint64_t)((cfg->icount / msecs) / MSEC_PER_SEC); + print_ops_sec = (uint64_t)(cfg->icount / print_secs); } lprintf(cfg, 0, 1, "Load time: %.2f\n" "load ops/sec: %" PRIu64, @@ -1858,7 +1902,7 @@ create_uris(CONFIG *cfg) base_uri_len = strlen(cfg->base_uri); cfg->uris = dcalloc(cfg->table_count, sizeof(char *)); for (i = 0; i < cfg->table_count; i++) { - uri = cfg->uris[i] = dcalloc(base_uri_len + 5, 1); + uri = cfg->uris[i] = dcalloc(base_uri_len + 6, 1); /* * If there is only one table, just use base name. */ @@ -1867,6 +1911,10 @@ create_uris(CONFIG *cfg) else sprintf(uri, "%s%05d", cfg->base_uri, i); } + + /* Create the log-like-table URI. */ + cfg->log_table_uri = dcalloc(base_uri_len + 11, 1); + sprintf(cfg->log_table_uri, "%s_log_table", cfg->base_uri); } static int @@ -1877,9 +1925,6 @@ create_tables(CONFIG *cfg) int ret; char buf[512]; - if (cfg->create == 0) - return (0); - if ((ret = cfg->conn->open_session( cfg->conn, NULL, cfg->sess_config, &session)) != 0) { lprintf(cfg, ret, 0, @@ -1896,6 +1941,11 @@ create_tables(CONFIG *cfg) return (ret); } } + if (cfg->log_like_table && (ret = session->create(session, + cfg->log_table_uri, "key_format=Q,value_format=S")) != 0) { + lprintf(cfg, ret, 0, "Error creating log table %s", buf); + return (ret); + } for (i = 0; i < cfg->table_count; i++) { if (cfg->log_partial && i > 0) { @@ -1936,13 +1986,12 @@ start_all_runs(CONFIG *cfg) { CONFIG *next_cfg, **configs; pthread_t *threads; - size_t cmd_len, home_len, i; + size_t home_len, i; int ret, t_ret; - char *cmd_buf, *new_home; + char *new_home; ret = 0; configs = NULL; - cmd_buf = NULL; if (cfg->database_count == 1) return (start_run(cfg)); @@ -1954,30 +2003,27 @@ start_all_runs(CONFIG *cfg) threads = dcalloc(cfg->database_count, sizeof(pthread_t)); home_len = strlen(cfg->home); - cmd_len = (home_len * 2) + 30; /* Add some slop. */ - cmd_buf = dcalloc(cmd_len, 1); for (i = 0; i < cfg->database_count; i++) { next_cfg = dcalloc(1, sizeof(CONFIG)); configs[i] = next_cfg; - if ((ret = config_assign(next_cfg, cfg)) != 0) - goto err; + config_copy(next_cfg, cfg); /* Setup a unique home directory for each database. */ new_home = dmalloc(home_len + 5); snprintf(new_home, home_len + 5, "%s/D%02d", cfg->home, (int)i); + free(next_cfg->home); next_cfg->home = new_home; /* If the monitor dir is default, update it too. */ - if (strcmp(cfg->monitor_dir, cfg->home) == 0) - next_cfg->monitor_dir = new_home; - - /* Create clean home directories. */ - snprintf(cmd_buf, cmd_len, "rm -rf %s && mkdir %s", - next_cfg->home, next_cfg->home); - if ((ret = system(cmd_buf)) != 0) { - fprintf(stderr, "%s: failed\n", cmd_buf); - goto err; + if (strcmp(cfg->monitor_dir, cfg->home) == 0) { + free(next_cfg->monitor_dir); + next_cfg->monitor_dir = dstrdup(new_home); } + + /* If creating the sub-database, recreate its home */ + if (cfg->create != 0) + recreate_dir(next_cfg->home); + if ((ret = pthread_create( &threads[i], NULL, thread_run_wtperf, next_cfg)) != 0) { lprintf(cfg, ret, 0, "Error creating thread"); @@ -1986,22 +2032,19 @@ start_all_runs(CONFIG *cfg) } /* Wait for threads to finish. */ - for (i = 0; i < cfg->database_count; i++) { + for (i = 0; i < cfg->database_count; i++) if ((t_ret = pthread_join(threads[i], NULL)) != 0) { lprintf(cfg, ret, 0, "Error joining thread"); if (ret == 0) ret = t_ret; } - } err: for (i = 0; i < cfg->database_count && configs[i] != NULL; i++) { - free((char *)configs[i]->home); config_free(configs[i]); free(configs[i]); } free(configs); free(threads); - free(cmd_buf); return (ret); } @@ -2024,8 +2067,8 @@ start_run(CONFIG *cfg) { pthread_t monitor_thread; uint64_t total_ops; + uint32_t run_time; int monitor_created, ret, t_ret; - char helium_buf[256]; monitor_created = ret = 0; /* [-Wconditional-uninitialized] */ @@ -2040,21 +2083,10 @@ start_run(CONFIG *cfg) goto err; } - /* Configure optional Helium volume. */ - if (cfg->helium_mount != NULL) { - snprintf(helium_buf, sizeof(helium_buf), - "entry=wiredtiger_extension_init,config=[" - "%s=[helium_devices=\"he://./%s\"," - "helium_o_volume_truncate=1]]", - HELIUM_NAME, cfg->helium_mount); - if ((ret = cfg->conn->load_extension( - cfg->conn, HELIUM_PATH, helium_buf)) != 0) - lprintf(cfg, - ret, 0, "Error loading Helium: %s", helium_buf); - } - create_uris(cfg); - if ((ret = create_tables(cfg)) != 0) + + /* If creating, create the tables. */ + if (cfg->create != 0 && (ret = create_tables(cfg)) != 0) goto err; /* Start the monitor thread. */ @@ -2083,7 +2115,8 @@ start_run(CONFIG *cfg) goto err; /* Didn't create, set insert count. */ - if (cfg->create == 0 && find_table_count(cfg) != 0) + if (cfg->create == 0 && cfg->random_range == 0 && + find_table_count(cfg) != 0) goto err; /* Start the checkpoint thread. */ if (cfg->checkpoint_threads != 0) { @@ -2108,26 +2141,27 @@ start_run(CONFIG *cfg) cfg->ckpt_ops = sum_ckpt_ops(cfg); total_ops = cfg->read_ops + cfg->insert_ops + cfg->update_ops; + run_time = cfg->run_time == 0 ? 1 : cfg->run_time; lprintf(cfg, 0, 1, "Executed %" PRIu64 " read operations (%" PRIu64 "%%) %" PRIu64 " ops/sec", cfg->read_ops, (cfg->read_ops * 100) / total_ops, - cfg->read_ops / cfg->run_time); + cfg->read_ops / run_time); lprintf(cfg, 0, 1, "Executed %" PRIu64 " insert operations (%" PRIu64 "%%) %" PRIu64 " ops/sec", cfg->insert_ops, (cfg->insert_ops * 100) / total_ops, - cfg->insert_ops / cfg->run_time); + cfg->insert_ops / run_time); lprintf(cfg, 0, 1, "Executed %" PRIu64 " truncate operations (%" PRIu64 "%%) %" PRIu64 " ops/sec", cfg->truncate_ops, (cfg->truncate_ops * 100) / total_ops, - cfg->truncate_ops / cfg->run_time); + cfg->truncate_ops / run_time); lprintf(cfg, 0, 1, "Executed %" PRIu64 " update operations (%" PRIu64 "%%) %" PRIu64 " ops/sec", cfg->update_ops, (cfg->update_ops * 100) / total_ops, - cfg->update_ops / cfg->run_time); + cfg->update_ops / run_time); lprintf(cfg, 0, 1, "Executed %" PRIu64 " checkpoint operations", cfg->ckpt_ops); @@ -2182,28 +2216,30 @@ err: if (ret == 0) extern int __wt_optind, __wt_optreset; extern char *__wt_optarg; +void (*custom_die)(void) = NULL; int main(int argc, char *argv[]) { CONFIG *cfg, _cfg; size_t req_len, sreq_len; - int ch, monitor_set, ret; - const char *opts = "C:H:h:m:O:o:T:"; + bool monitor_set; + int ch, ret; + const char *opts = "C:h:m:O:o:T:"; const char *config_opts; char *cc_buf, *sess_cfg, *tc_buf, *user_cconfig, *user_tconfig; - monitor_set = ret = 0; + monitor_set = false; + ret = 0; config_opts = NULL; cc_buf = sess_cfg = tc_buf = user_cconfig = user_tconfig = NULL; /* Setup the default configuration values. */ cfg = &_cfg; memset(cfg, 0, sizeof(*cfg)); - if (config_assign(cfg, &default_cfg)) - goto err; - - TAILQ_INIT(&cfg->config_head); + config_copy(cfg, &default_cfg); + cfg->home = dstrdup(DEFAULT_HOME); + cfg->monitor_dir = dstrdup(DEFAULT_MONITOR_DIR); /* Do a basic validation of options, and home is needed before open. */ while ((ch = __wt_getopt("wtperf", argc, argv, opts)) != EOF) @@ -2219,8 +2255,14 @@ main(int argc, char *argv[]) strcat(user_cconfig, __wt_optarg); } break; - case 'H': - cfg->helium_mount = __wt_optarg; + case 'h': + free(cfg->home); + cfg->home = dstrdup(__wt_optarg); + break; + case 'm': + free(cfg->monitor_dir); + cfg->monitor_dir = dstrdup(__wt_optarg); + monitor_set = true; break; case 'O': config_opts = __wt_optarg; @@ -2236,15 +2278,7 @@ main(int argc, char *argv[]) strcat(user_tconfig, __wt_optarg); } break; - case 'h': - cfg->home = __wt_optarg; - break; - case 'm': - cfg->monitor_dir = __wt_optarg; - monitor_set = 1; - break; case '?': - fprintf(stderr, "Invalid option\n"); usage(); goto einval; } @@ -2253,8 +2287,10 @@ main(int argc, char *argv[]) * If the user did not specify a monitor directory then set the * monitor directory to the home dir. */ - if (!monitor_set) - cfg->monitor_dir = cfg->home; + if (!monitor_set) { + free(cfg->monitor_dir); + cfg->monitor_dir = dstrdup(cfg->home); + } /* Parse configuration settings from configuration file. */ if (config_opts != NULL && config_opt_file(cfg, config_opts) != 0) @@ -2300,7 +2336,7 @@ main(int argc, char *argv[]) * to 4096 if needed. */ req_len = strlen(",async=(enabled=true,threads=)") + 4; - cfg->async_config = dcalloc(req_len, 1); + cfg->async_config = dmalloc(req_len); snprintf(cfg->async_config, req_len, ",async=(enabled=true,threads=%" PRIu32 ")", cfg->async_threads); @@ -2321,13 +2357,9 @@ main(int argc, char *argv[]) } /* Build the URI from the table name. */ - req_len = strlen("table:") + - strlen(HELIUM_NAME) + strlen(cfg->table_name) + 2; - cfg->base_uri = dcalloc(req_len, 1); - snprintf(cfg->base_uri, req_len, "table:%s%s%s", - cfg->helium_mount == NULL ? "" : HELIUM_NAME, - cfg->helium_mount == NULL ? "" : "/", - cfg->table_name); + req_len = strlen("table:") + strlen(cfg->table_name) + 2; + cfg->base_uri = dmalloc(req_len); + snprintf(cfg->base_uri, req_len, "table:%s", cfg->table_name); /* Make stdout line buffered, so verbose output appears quickly. */ __wt_stream_set_line_buffer(stdout); @@ -2336,7 +2368,7 @@ main(int argc, char *argv[]) if (cfg->verbose > 1 || user_cconfig != NULL || cfg->session_count_idle > 0 || cfg->compress_ext != NULL || cfg->async_config != NULL) { - req_len = strlen(cfg->conn_config) + strlen(debug_cconfig) + 3; + req_len = strlen(debug_cconfig) + 3; if (user_cconfig != NULL) req_len += strlen(user_cconfig); if (cfg->async_config != NULL) @@ -2346,58 +2378,60 @@ main(int argc, char *argv[]) if (cfg->session_count_idle > 0) { sreq_len = strlen(",session_max=") + 6; req_len += sreq_len; - sess_cfg = dcalloc(sreq_len, 1); + sess_cfg = dmalloc(sreq_len); snprintf(sess_cfg, sreq_len, ",session_max=%" PRIu32, cfg->session_count_idle + cfg->workers_cnt + cfg->populate_threads + 10); } - cc_buf = dcalloc(req_len, 1); + cc_buf = dmalloc(req_len); /* * This is getting hard to parse. */ - snprintf(cc_buf, req_len, "%s%s%s%s%s%s%s%s", - cfg->conn_config, + snprintf(cc_buf, req_len, "%s%s%s%s%s%s%s", cfg->async_config ? cfg->async_config : "", cfg->compress_ext ? cfg->compress_ext : "", - cfg->verbose > 1 ? ",": "", - cfg->verbose > 1 ? debug_cconfig : "", + cfg->verbose > 1 && strlen(debug_cconfig) ? ",": "", + cfg->verbose > 1 && + strlen(debug_cconfig) ? debug_cconfig : "", sess_cfg ? sess_cfg : "", user_cconfig ? ",": "", user_cconfig ? user_cconfig : ""); - if ((ret = config_opt_str(cfg, "conn_config", cc_buf)) != 0) - goto err; + if (strlen(cc_buf)) + if ((ret = config_opt_str( + cfg, "conn_config", cc_buf)) != 0) + goto err; } - if (cfg->verbose > 1 || cfg->index || cfg->helium_mount != NULL || + if (cfg->verbose > 1 || cfg->index || user_tconfig != NULL || cfg->compress_table != NULL) { - req_len = strlen(cfg->table_config) + strlen(HELIUM_CONFIG) + - strlen(debug_tconfig) + 3; + req_len = strlen(debug_tconfig) + 3; if (user_tconfig != NULL) req_len += strlen(user_tconfig); if (cfg->compress_table != NULL) req_len += strlen(cfg->compress_table); if (cfg->index) req_len += strlen(INDEX_COL_NAMES); - tc_buf = dcalloc(req_len, 1); + tc_buf = dmalloc(req_len); /* * This is getting hard to parse. */ - snprintf(tc_buf, req_len, "%s%s%s%s%s%s%s%s", - cfg->table_config, + snprintf(tc_buf, req_len, "%s%s%s%s%s%s", cfg->index ? INDEX_COL_NAMES : "", cfg->compress_table ? cfg->compress_table : "", - cfg->verbose > 1 ? ",": "", - cfg->verbose > 1 ? debug_tconfig : "", + cfg->verbose > 1 && strlen(debug_tconfig) ? ",": "", + cfg->verbose > 1 && + strlen(debug_tconfig) ? debug_tconfig : "", user_tconfig ? ",": "", - user_tconfig ? user_tconfig : "", - cfg->helium_mount == NULL ? "" : HELIUM_CONFIG); - if ((ret = config_opt_str(cfg, "table_config", tc_buf)) != 0) - goto err; + user_tconfig ? user_tconfig : ""); + if (strlen(tc_buf)) + if ((ret = config_opt_str( + cfg, "table_config", tc_buf)) != 0) + goto err; } if (cfg->log_partial && cfg->table_count > 1) { req_len = strlen(cfg->table_config) + strlen(LOG_PARTIAL_CONFIG) + 1; - cfg->partial_config = dcalloc(req_len, 1); + cfg->partial_config = dmalloc(req_len); snprintf(cfg->partial_config, req_len, "%s%s", cfg->table_config, LOG_PARTIAL_CONFIG); } @@ -2410,7 +2444,7 @@ main(int argc, char *argv[]) strlen(READONLY_CONFIG) + 1; else req_len = strlen(cfg->conn_config) + 1; - cfg->reopen_config = dcalloc(req_len, 1); + cfg->reopen_config = dmalloc(req_len); if (cfg->readonly) snprintf(cfg->reopen_config, req_len, "%s%s", cfg->conn_config, READONLY_CONFIG); @@ -2422,6 +2456,10 @@ main(int argc, char *argv[]) if ((ret = config_sanity(cfg)) != 0) goto err; + /* If creating, remove and re-create the home directory. */ + if (cfg->create != 0) + recreate_dir(cfg->home); + /* Write a copy of the config. */ config_to_file(cfg); @@ -2536,6 +2574,19 @@ stop_threads(CONFIG *cfg, u_int num, CONFIG_THREAD *threads) return (0); } +static void +recreate_dir(const char *name) +{ + char *buf; + size_t len; + + len = strlen(name) * 2 + 100; + buf = dmalloc(len); + (void)snprintf(buf, len, "rm -rf %s && mkdir %s", name, name); + testutil_checkfmt(system(buf), "system: %s", buf); + free(buf); +} + static int drop_all_tables(CONFIG *cfg) { @@ -2552,7 +2603,7 @@ drop_all_tables(CONFIG *cfg) "Error opening a session on %s", cfg->home); return (ret); } - (void)__wt_epoch(NULL, &start); + testutil_check(__wt_epoch(NULL, &start)); for (i = 0; i < cfg->table_count; i++) { if ((ret = session->drop( session, cfg->uris[i], NULL)) != 0) { @@ -2561,7 +2612,7 @@ drop_all_tables(CONFIG *cfg) goto err; } } - (void)__wt_epoch(NULL, &stop); + testutil_check(__wt_epoch(NULL, &stop)); msecs = WT_TIMEDIFF_MS(stop, start); lprintf(cfg, 0, 1, "Executed %" PRIu32 " drop operations average time %" PRIu64 "ms", @@ -2615,7 +2666,7 @@ wtperf_rand(CONFIG_THREAD *thread) * first item in the table being "hot". */ if (rval > wtperf_value_range(cfg)) - rval = wtperf_value_range(cfg); + rval = 0; } /* * Wrap the key to within the expected range and avoid zero: we never diff --git a/src/third_party/wiredtiger/bench/wtperf/wtperf.h b/src/third_party/wiredtiger/bench/wtperf/wtperf.h index d874fa4eefe..1bb94db2634 100644 --- a/src/third_party/wiredtiger/bench/wtperf/wtperf.h +++ b/src/third_party/wiredtiger/bench/wtperf/wtperf.h @@ -29,14 +29,11 @@ #ifndef HAVE_WTPERF_H #define HAVE_WTPERF_H -#include +#include "test_util.h" + #include #include -#ifdef _WIN32 -#include "windows_shim.h" -#endif - #include "config_opt.h" typedef struct __config CONFIG; @@ -46,7 +43,7 @@ typedef struct __truncate_queue_entry TRUNCATE_QUEUE_ENTRY; #define EXT_PFX ",extensions=(" #define EXT_SFX ")" #define EXTPATH "../../ext/compressors/" /* Extensions path */ -#define BLKCMP_PFX ",block_compressor=" +#define BLKCMP_PFX "block_compressor=" #define LZ4_BLK BLKCMP_PFX "lz4" #define LZ4_EXT \ @@ -83,7 +80,6 @@ typedef struct { typedef struct { uint64_t stone_gap; uint64_t needed_stones; - uint64_t final_stone_gap; uint64_t expected_total; uint64_t total_inserts; uint64_t last_total_inserts; @@ -120,13 +116,13 @@ typedef struct { * an initialization in wtperf.c in the default_cfg. */ struct __config { /* Configuration structure */ - const char *home; /* WiredTiger home */ - const char *monitor_dir; /* Monitor output dir */ + char *home; /* WiredTiger home */ + char *monitor_dir; /* Monitor output dir */ char *partial_config; /* Config string for partial logging */ char *reopen_config; /* Config string for conn reopen */ char *base_uri; /* Object URI */ + char *log_table_uri; /* URI for log table */ char **uris; /* URIs if multiple tables */ - const char *helium_mount; /* Optional Helium mount point */ WT_CONNECTION *conn; /* Database connection */ @@ -156,6 +152,7 @@ struct __config { /* Configuration structure */ uint64_t update_ops; /* update operations */ uint64_t insert_key; /* insert key */ + uint64_t log_like_table_key; /* used to allocate IDs for log table */ volatile int ckpt; /* checkpoint in progress */ volatile int error; /* thread error */ @@ -264,9 +261,9 @@ struct __config_thread { /* Per-thread structure */ }; void cleanup_truncate_config(CONFIG *); -int config_assign(CONFIG *, const CONFIG *); int config_compress(CONFIG *); void config_free(CONFIG *); +void config_copy(CONFIG *, const CONFIG *); int config_opt_file(CONFIG *, const char *); int config_opt_line(CONFIG *, const char *); int config_opt_str(CONFIG *, const char *, const char *); @@ -281,7 +278,7 @@ void latency_print(CONFIG *); int run_truncate( CONFIG *, CONFIG_THREAD *, WT_CURSOR *, WT_SESSION *, int *); int setup_log_file(CONFIG *); -int setup_throttle(CONFIG_THREAD*); +void setup_throttle(CONFIG_THREAD*); int setup_truncate(CONFIG *, CONFIG_THREAD *, WT_SESSION *); int start_idle_table_cycle(CONFIG *, pthread_t *); int stop_idle_table_cycle(CONFIG *, pthread_t); @@ -292,7 +289,7 @@ uint64_t sum_read_ops(CONFIG *); uint64_t sum_truncate_ops(CONFIG *); uint64_t sum_update_ops(CONFIG *); void usage(void); -int worker_throttle(CONFIG_THREAD*); +void worker_throttle(CONFIG_THREAD*); void lprintf(const CONFIG *, int err, uint32_t, const char *, ...) #if defined(__GNUC__) @@ -328,75 +325,4 @@ die(int e, const char *str) fprintf(stderr, "Call to %s failed: %s", str, wiredtiger_strerror(e)); exit(EXIT_FAILURE); } - -/* - * dmalloc -- - * Call malloc, dying on failure. - */ -static inline void * -dmalloc(size_t len) -{ - void *p; - - if ((p = malloc(len)) == NULL) - die(errno, "malloc"); - return (p); -} - -/* - * dcalloc -- - * Call calloc, dying on failure. - */ -static inline void * -dcalloc(size_t num, size_t size) -{ - void *p; - - if ((p = calloc(num, size)) == NULL) - die(errno, "calloc"); - return (p); -} - -/* - * drealloc -- - * Call realloc, dying on failure. - */ -static inline void * -drealloc(void *p, size_t len) -{ - void *repl; - - if ((repl = realloc(p, len)) == NULL) - die(errno, "realloc"); - return (repl); -} - -/* - * dstrdup -- - * Call strdup, dying on failure. - */ -static inline char * -dstrdup(const char *str) -{ - char *p; - - if ((p = strdup(str)) == NULL) - die(errno, "strdup"); - return (p); -} - -/* - * dstrndup -- - * Call emulating strndup, dying on failure. Don't use actual strndup here - * as it is not supported within MSVC. - */ -static inline char * -dstrndup(const char *str, const size_t len) -{ - char *p; - - p = dcalloc(len + 1, sizeof(char)); - memcpy(p, str, len); - return (p); -} #endif diff --git a/src/third_party/wiredtiger/bench/wtperf/wtperf_opt.i b/src/third_party/wiredtiger/bench/wtperf/wtperf_opt.i index 2afd20f777f..17517ffe477 100644 --- a/src/third_party/wiredtiger/bench/wtperf/wtperf_opt.i +++ b/src/third_party/wiredtiger/bench/wtperf/wtperf_opt.i @@ -120,6 +120,8 @@ DEF_OPT_AS_BOOL(insert_rmw, 0, "execute a read prior to each insert in workload phase") DEF_OPT_AS_UINT32(key_sz, 20, "key size") DEF_OPT_AS_BOOL(log_partial, 0, "perform partial logging on first table only.") +DEF_OPT_AS_BOOL(log_like_table, 0, + "Append all modification operations to another shared table.") DEF_OPT_AS_UINT32(min_throughput, 0, "notify if any throughput measured is less than this amount. " "Aborts or prints warning based on min_throughput_fatal setting. " @@ -144,6 +146,7 @@ DEF_OPT_AS_UINT32(random_range, 0, "if non zero choose a value from within this range as the key for " "insert operations") DEF_OPT_AS_BOOL(random_value, 0, "generate random content for the value") +DEF_OPT_AS_BOOL(range_partition, 0, "partition data by range (vs hash)") DEF_OPT_AS_UINT32(read_range, 0, "scan a range of keys after each search") DEF_OPT_AS_BOOL(readonly, 0, "reopen the connection between populate and workload phases in readonly " @@ -193,6 +196,8 @@ DEF_OPT_AS_CONFIG_STRING(transaction_config, "", "transaction configuration string, relevant when populate_opts_per_txn " "is nonzero") DEF_OPT_AS_STRING(table_name, "test", "table name") +DEF_OPT_AS_BOOL(truncate_single_ops, 0, + "Implement truncate via cursor remove instead of session API") DEF_OPT_AS_UINT32(value_sz_max, 1000, "maximum value size when delta updates are present. Default disabled") DEF_OPT_AS_UINT32(value_sz_min, 1, diff --git a/src/third_party/wiredtiger/bench/wtperf/wtperf_throttle.c b/src/third_party/wiredtiger/bench/wtperf/wtperf_throttle.c index a98fd9b18d7..e49bca00d07 100644 --- a/src/third_party/wiredtiger/bench/wtperf/wtperf_throttle.c +++ b/src/third_party/wiredtiger/bench/wtperf/wtperf_throttle.c @@ -31,7 +31,7 @@ /* * Put the initial config together for running a throttled workload. */ -int +void setup_throttle(CONFIG_THREAD *thread) { THROTTLE_CONFIG *throttle_cfg; @@ -70,15 +70,14 @@ setup_throttle(CONFIG_THREAD *thread) throttle_cfg->ops_count = throttle_cfg->ops_per_increment; /* Set the first timestamp of when we incremented */ - WT_RET(__wt_epoch(NULL, &throttle_cfg->last_increment)); - return (0); + testutil_check(__wt_epoch(NULL, &throttle_cfg->last_increment)); } /* * Run the throttle function. We will sleep if needed and then reload the * counter to perform more operations. */ -int +void worker_throttle(CONFIG_THREAD *thread) { THROTTLE_CONFIG *throttle_cfg; @@ -87,7 +86,7 @@ worker_throttle(CONFIG_THREAD *thread) throttle_cfg = &thread->throttle_cfg; - WT_RET(__wt_epoch(NULL, &now)); + testutil_check(__wt_epoch(NULL, &now)); /* * If we did enough operations in the current interval, sleep for @@ -102,7 +101,7 @@ worker_throttle(CONFIG_THREAD *thread) /* * After sleeping, set the interval to the current time. */ - WT_RET(__wt_epoch(NULL, &throttle_cfg->last_increment)); + testutil_check(__wt_epoch(NULL, &throttle_cfg->last_increment)); } else { throttle_cfg->ops_count = (usecs_delta * throttle_cfg->ops_per_increment) / @@ -115,6 +114,4 @@ worker_throttle(CONFIG_THREAD *thread) */ throttle_cfg->ops_count = WT_MIN(throttle_cfg->ops_count, thread->workload->throttle); - - return (0); } diff --git a/src/third_party/wiredtiger/bench/wtperf/wtperf_truncate.c b/src/third_party/wiredtiger/bench/wtperf/wtperf_truncate.c index 11b09c60d5d..e6ebc83c681 100644 --- a/src/third_party/wiredtiger/bench/wtperf/wtperf_truncate.c +++ b/src/third_party/wiredtiger/bench/wtperf/wtperf_truncate.c @@ -128,6 +128,7 @@ run_truncate(CONFIG *cfg, CONFIG_THREAD *thread, TRUNCATE_CONFIG *trunc_cfg; TRUNCATE_QUEUE_ENTRY *truncate_item; + char *next_key; int ret, t_ret; uint64_t used_stone_gap; @@ -184,15 +185,33 @@ run_truncate(CONFIG *cfg, CONFIG_THREAD *thread, truncate_item = TAILQ_FIRST(&cfg->stone_head); trunc_cfg->num_stones--; TAILQ_REMOVE(&cfg->stone_head, truncate_item, q); - cursor->set_key(cursor,truncate_item->key); - if ((ret = cursor->search(cursor)) != 0) { - lprintf(cfg, ret, 0, "Truncate search: failed"); - goto err; - } - if ((ret = session->truncate(session, NULL, NULL, cursor, NULL)) != 0) { - lprintf(cfg, ret, 0, "Truncate: failed"); - goto err; + /* + * Truncate the content via a single truncate call or a cursor walk + * depending on the configuration. + */ + if (cfg->truncate_single_ops) { + while ((ret = cursor->next(cursor)) == 0) { + testutil_check(cursor->get_key(cursor, &next_key)); + if (strcmp(next_key, truncate_item->key) == 0) + break; + if ((ret = cursor->remove(cursor)) != 0) { + lprintf(cfg, ret, 0, "Truncate remove: failed"); + goto err; + } + } + } else { + cursor->set_key(cursor,truncate_item->key); + if ((ret = cursor->search(cursor)) != 0) { + lprintf(cfg, ret, 0, "Truncate search: failed"); + goto err; + } + + if ((ret = session->truncate( + session, NULL, NULL, cursor, NULL)) != 0) { + lprintf(cfg, ret, 0, "Truncate: failed"); + goto err; + } } *truncatedp = 1; diff --git a/src/third_party/wiredtiger/build_posix/Make.subdirs b/src/third_party/wiredtiger/build_posix/Make.subdirs index 64749378ed1..0b5175e4196 100644 --- a/src/third_party/wiredtiger/build_posix/Make.subdirs +++ b/src/third_party/wiredtiger/build_posix/Make.subdirs @@ -18,14 +18,15 @@ ext/extractors/csv ext/test/kvs_bdb HAVE_BERKELEY_DB . api/leveldb LEVELDB -bench/wtperf examples/c lang/java JAVA examples/java JAVA lang/python PYTHON -# Make the tests +# Test/Benchmark support library. test/utility + +# Test programs. test/bloom test/checkpoint test/csuite @@ -39,3 +40,6 @@ test/readonly test/recovery test/salvage test/thread + +# Benchmark programs. +bench/wtperf diff --git a/src/third_party/wiredtiger/build_posix/aclocal/ax_pkg_swig.m4 b/src/third_party/wiredtiger/build_posix/aclocal/ax_pkg_swig.m4 index 9ebdeb531b9..89941bc3fa9 100644 --- a/src/third_party/wiredtiger/build_posix/aclocal/ax_pkg_swig.m4 +++ b/src/third_party/wiredtiger/build_posix/aclocal/ax_pkg_swig.m4 @@ -32,9 +32,9 @@ # LICENSE # # Copyright (c) 2008 Sebastian Huber -# Copyright (c) 2008 Alan W. Irwin +# Copyright (c) 2008 Alan W. Irwin # Copyright (c) 2008 Rafael Laboissiere -# Copyright (c) 2008 Andrew Collier +# Copyright (c) 2008 Andrew Collier # Copyright (c) 2011 Murray Cumming # # This program is free software; you can redistribute it and/or modify it @@ -63,11 +63,11 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 8 +#serial 11 AC_DEFUN([AX_PKG_SWIG],[ - # Some systems have SWIG 2.0 named "swig2.0" - AC_PATH_PROGS([SWIG],[swig2.0 swig]) + # Ubuntu has swig 2.0 as /usr/bin/swig2.0 + AC_PATH_PROGS([SWIG],[swig swig3.0 swig2.0]) if test -z "$SWIG" ; then m4_ifval([$3],[$3],[:]) elif test -n "$1" ; then diff --git a/src/third_party/wiredtiger/build_posix/aclocal/options.m4 b/src/third_party/wiredtiger/build_posix/aclocal/options.m4 index 5f9b8748df2..1f6a1690279 100644 --- a/src/third_party/wiredtiger/build_posix/aclocal/options.m4 +++ b/src/third_party/wiredtiger/build_posix/aclocal/options.m4 @@ -47,6 +47,19 @@ AM_CONDITIONAL([HAVE_BUILTIN_EXTENSION_ZLIB], [test "$wt_cv_with_builtin_extension_zlib" = "yes"]) AC_MSG_RESULT($with_builtins) +AH_TEMPLATE( + HAVE_CRC32_HARDWARE, [Define to 1 to configure CRC32 hardware support.]) +AC_MSG_CHECKING(if --enable-crc32-hardware option specified) +AC_ARG_ENABLE(crc32-hardware, + AC_HELP_STRING([--enable-crc32-hardware], + [Enable CRC32 hardware support.]), r=$enableval, r=yes) +case "$r" in +no) wt_cv_enable_crc32_hardware=no;; +*) AC_DEFINE(HAVE_CRC32_HARDWARE) + wt_cv_enable_crc32_hardware=yes;; +esac +AC_MSG_RESULT($wt_cv_enable_crc32_hardware) + AH_TEMPLATE(HAVE_DIAGNOSTIC, [Define to 1 for diagnostic tests.]) AC_MSG_CHECKING(if --enable-diagnostic option specified) AC_ARG_ENABLE(diagnostic, diff --git a/src/third_party/wiredtiger/build_posix/aclocal/strict.m4 b/src/third_party/wiredtiger/build_posix/aclocal/strict.m4 index b59f09fe584..0dbd5dbee16 100644 --- a/src/third_party/wiredtiger/build_posix/aclocal/strict.m4 +++ b/src/third_party/wiredtiger/build_posix/aclocal/strict.m4 @@ -64,6 +64,7 @@ AC_DEFUN([AM_CLANG_WARNINGS], [ # removed in the not-too-distant future. # Apple clang version 4.1 # (tags/Apple/clang-421.11.66) (based on LLVM 3.1svn) + w="$w -Wno-attributes" w="$w -Wno-pedantic" w="$w -Wno-unused-command-line-argument" diff --git a/src/third_party/wiredtiger/build_posix/configure.ac.in b/src/third_party/wiredtiger/build_posix/configure.ac.in index bbc6cf89d91..cbd9e4e4123 100644 --- a/src/third_party/wiredtiger/build_posix/configure.ac.in +++ b/src/third_party/wiredtiger/build_posix/configure.ac.in @@ -58,6 +58,17 @@ AS_CASE([$host_cpu], [powerpc*], [wt_cv_powerpc="yes"], [wt_cv_powerpc="no"]) AM_CONDITIONAL([POWERPC_HOST], [test "$wt_cv_powerpc" = "yes"]) +AS_CASE([$host_cpu], + [amd*|i[[3456]]86*|pentium|x86*], [wt_cv_x86="yes"], [wt_cv_x86="no"]) +AM_CONDITIONAL([X86_HOST], [test "$wt_cv_x86" = "yes"]) +AS_CASE([$host_cpu], + [s390x*], [wt_cv_zseries="yes"], + [wt_cv_zseries="no"]) +AM_CONDITIONAL([ZSERIES_HOST], [test "$wt_cv_zseries" = "yes"]) +AS_CASE([$host_cpu], + [aarch64*], [wt_cv_arm64="yes"], + [wt_cv_arm64="no"]) +AM_CONDITIONAL([ARM64_HOST], [test "$wt_cv_arm64" = "yes"]) # This is a workaround as part of WT-2459. Currently, clang (v3.7) does not # support compiling the ASM code we have to perform the CRC checks on PowerPC. @@ -85,8 +96,10 @@ fi # Java and Python APIs if test "$wt_cv_enable_java" = "yes" -o "$wt_cv_enable_python" = "yes"; then + # Only a warning, we need to build release packages without SWIG. AX_PKG_SWIG(2.0.4, [], - [AC_MSG_WARN([SWIG is required to rebuild Java or Python APIs.])]) + [AC_MSG_WARN([SWIG is required to rebuild Java or Python APIs.]) && + SWIG="SWIG_NOT_FOUND_DURING_CONFIGURE"]) fi if test "$wt_cv_enable_java" = "yes"; then @@ -119,9 +132,8 @@ AC_CHECK_LIB(dl, dlopen) AC_CHECK_LIB(rt, sched_yield) AC_CHECK_FUNCS([\ - clock_gettime fallocate fcntl fread_unlocked ftruncate gettimeofday\ - posix_fadvise posix_fallocate posix_madvise\ - strtouq sync_file_range]) + clock_gettime fallocate ftruncate gettimeofday posix_fadvise\ + posix_fallocate posix_madvise strtouq sync_file_range]) # OS X wrongly reports that it has fdatasync AS_CASE([$host_os], [darwin*], [], [AC_CHECK_FUNCS([fdatasync])]) @@ -225,6 +237,7 @@ AM_COND_IF([LEVELDB], AC_CONFIG_FILES([ Makefile wiredtiger.h:src/include/wiredtiger.in + wiredtiger_ext.h:src/include/wiredtiger_ext.h wiredtiger.pc:build_posix/wiredtiger.pc.in ]) AC_OUTPUT diff --git a/src/third_party/wiredtiger/build_win/wiredtiger_config.h b/src/third_party/wiredtiger/build_win/wiredtiger_config.h index 33dbc9b724d..83ddc6eb194 100644 --- a/src/third_party/wiredtiger/build_win/wiredtiger_config.h +++ b/src/third_party/wiredtiger/build_win/wiredtiger_config.h @@ -22,6 +22,9 @@ /* Define to 1 if you have the `clock_gettime' function. */ /* #undef HAVE_CLOCK_GETTIME */ +/* Define to 1 to enable CRC32 hardware support. */ +/* #undef HAVE_CRC32_HARDWARE */ + /* Define to 1 for diagnostic tests. */ /* #undef HAVE_DIAGNOSTIC */ @@ -31,15 +34,9 @@ /* Define to 1 if you have the `fallocate' function. */ /* #undef HAVE_FALLOCATE */ -/* Define to 1 if you have the `fcntl' function. */ -/* #undef HAVE_FCNTL 1 */ - /* Define to 1 if you have the `fdatasync' function. */ /* #undef HAVE_FDATASYNC */ -/* Define to 1 if you have the `fread_unlocked' function. */ -/* #undef HAVE_FREAD_UNLOCKED */ - /* Define to 1 if you have the `ftruncate' function. */ /* #undef HAVE_FTRUNCATE */ diff --git a/src/third_party/wiredtiger/dist/api_config.py b/src/third_party/wiredtiger/dist/api_config.py index b451e939ef3..5ccd8247b76 100644 --- a/src/third_party/wiredtiger/dist/api_config.py +++ b/src/third_party/wiredtiger/dist/api_config.py @@ -195,13 +195,15 @@ def checkstr(c): def get_default(c): t = gettype(c) if c.default == 'false': - return '0' + return 'false' + elif c.default == 'true': + return 'true' elif t == 'string' and c.default == 'none': return '' elif t == 'category': return '(%s)' % (','.join('%s=%s' % (subc.name, get_default(subc)) for subc in sorted(c.subconfig))) - elif (c.default or t == 'int') and c.default != 'true': + elif c.default or t == 'int': return str(c.default).replace('"', '\\"') else: return '' diff --git a/src/third_party/wiredtiger/dist/api_data.py b/src/third_party/wiredtiger/dist/api_data.py index 0d995a3e2e2..44fc935d5d3 100644 --- a/src/third_party/wiredtiger/dist/api_data.py +++ b/src/third_party/wiredtiger/dist/api_data.py @@ -170,7 +170,7 @@ file_config = format_meta + [ It is stored in clear text, and thus is available when the wiredtiger database is reopened. On the first use of a (name, keyid) combination, the WT_ENCRYPTOR::customize - function is called with the keyid as an argument.'''), + function is called with the keyid as an argument'''), ]), Config('format', 'btree', r''' the file format''', @@ -238,17 +238,17 @@ file_config = format_meta + [ min=0, undoc=True), Config('log', '', r''' the transaction log configuration for this object. Only valid if - log is enabled in ::wiredtiger_open.''', + log is enabled in ::wiredtiger_open''', type='category', subconfig=[ Config('enabled', 'true', r''' - if false, this object has checkpoint-level durability.''', + if false, this object has checkpoint-level durability''', type='boolean'), ]), Config('memory_page_max', '5MB', r''' the maximum size a page can grow to in memory before being reconciled to disk. The specified size will be adjusted to a lower - bound of 50 * leaf_page_max, and an upper bound of - cache_size / 2. This limit is soft - it is possible + bound of leaf_page_max, and an upper bound of + cache_size / 10. This limit is soft - it is possible for pages to be temporarily larger than this value. This setting is ignored for LSM trees, see \c chunk_size''', min='512B', max='10TB'), @@ -352,7 +352,7 @@ connection_runtime_config = [ Config('threads', '2', r''' the number of worker threads to service asynchronous requests. Each worker thread uses a session from the configured - session_max.''', + session_max''', min='1', max='20'), # !!! Must match WT_ASYNC_MAX_WORKERS ]), Config('cache_size', '100MB', r''' @@ -373,11 +373,10 @@ connection_runtime_config = [ periodically checkpoint the database. Enabling the checkpoint server uses a session from the configured session_max''', type='category', subconfig=[ - Config('name', '"WiredTigerCheckpoint"', r''' - the checkpoint name'''), Config('log_size', '0', r''' wait for this amount of log record bytes to be written to - the log between each checkpoint. A database can configure + the log between each checkpoint. If non-zero, this value will + use a minimum of the log file size. A database can configure both log_size and wait to set an upper bound for checkpoints; setting this value above 0 configures periodic checkpoints''', min='0', max='2GB'), @@ -388,24 +387,46 @@ connection_runtime_config = [ ]), Config('error_prefix', '', r''' prefix string for error messages'''), - Config('eviction_dirty_target', '80', r''' - continue evicting until the cache has less dirty memory than the - value, as a percentage of the total cache size. Dirty pages will - only be evicted if the cache is full enough to trigger eviction''', - min=5, max=99), - Config('eviction_dirty_trigger', '95', r''' - trigger eviction when the cache is using this much memory for dirty - content, as a percentage of the total cache size. This setting only - alters behavior if it is lower than eviction_trigger''', - min=5, max=99), + Config('eviction', '', r''' + eviction configuration options''', + type='category', subconfig=[ + Config('threads_max', '1', r''' + maximum number of threads WiredTiger will start to help evict + pages from cache. The number of threads started will vary + depending on the current eviction load. Each eviction worker + thread uses a session from the configured session_max''', + min=1, max=20), + Config('threads_min', '1', r''' + minimum number of threads WiredTiger will start to help evict + pages from cache. The number of threads currently running will + vary depending on the current eviction load''', + min=1, max=20), + ]), + Config('eviction_checkpoint_target', '15', r''' + perform eviction at the beginning of checkpoints to bring the dirty + content in cache to this level, expressed as a percentage of the total + cache size. Ignored if set to zero or \c in_memory is \c true''', + min=0, max=99), + Config('eviction_dirty_target', '5', r''' + perform eviction in worker threads when the cache contains at least + this much dirty content, expressed as a percentage of the total cache + size. Ignored if \c in_memory is \c true''', + min=1, max=99), + Config('eviction_dirty_trigger', '20', r''' + trigger application threads to perform eviction when the cache contains + at least this much dirty content, expressed as a percentage of the + total cache size. This setting only alters behavior if it is lower than + eviction_trigger. Ignored if \c in_memory is \c true''', + min=1, max=99), Config('eviction_target', '80', r''' - continue evicting until the cache has less total memory than the - value, as a percentage of the total cache size. Must be less than - \c eviction_trigger''', + perform eviction in worker threads when the cache contains at least + this much content, expressed as a percentage of the total cache size. + Must be less than \c eviction_trigger''', min=10, max=99), Config('eviction_trigger', '95', r''' - trigger eviction when the cache is using this much memory, as a - percentage of the total cache size''', min=10, max=99), + trigger application threads to perform eviction when the cache contains + at least this much content, expressed as a percentage of the + total cache size''', min=10, max=99), Config('file_manager', '', r''' control how file handles are managed''', type='category', subconfig=[ @@ -423,7 +444,7 @@ connection_runtime_config = [ Config('lsm_manager', '', r''' configure database wide options for LSM tree management. The LSM manager is started automatically the first time an LSM tree is opened. - The LSM manager uses a session from the configured session_max.''', + The LSM manager uses a session from the configured session_max''', type='category', subconfig=[ Config('worker_thread_max', '4', r''' Configure a set of threads to manage merging LSM trees in @@ -438,21 +459,6 @@ connection_runtime_config = [ Config('lsm_merge', 'true', r''' merge LSM chunks where possible (deprecated)''', type='boolean', undoc=True), - Config('eviction', '', r''' - eviction configuration options.''', - type='category', subconfig=[ - Config('threads_max', '1', r''' - maximum number of threads WiredTiger will start to help evict - pages from cache. The number of threads started will vary - depending on the current eviction load. Each eviction worker - thread uses a session from the configured session_max''', - min=1, max=20), - Config('threads_min', '1', r''' - minimum number of threads WiredTiger will start to help evict - pages from cache. The number of threads currently running will - vary depending on the current eviction load''', - min=1, max=20), - ]), Config('shared_cache', '', r''' shared cache configuration options. A database should configure either a cache_size or a shared_cache not both. Enabling a @@ -518,6 +524,7 @@ connection_runtime_config = [ 'shared_cache', 'split', 'temporary', + 'thread_group', 'transaction', 'verify', 'version', @@ -530,7 +537,7 @@ log_configuration_common = [ automatically archive unneeded log files''', type='boolean'), Config('prealloc', 'true', r''' - pre-allocate log files.''', + pre-allocate log files''', type='boolean'), Config('zero_fill', 'false', r''' manually write zeroes into log files''', @@ -651,7 +658,7 @@ wiredtiger_open_common =\ direct I/O, and including \c "checkpoint" will cause WiredTiger data files opened at a checkpoint (i.e: read only) to use direct I/O. \c direct_io should be combined with \c write_through to get the - equivalent of \c O_DIRECT on Windows.''', + equivalent of \c O_DIRECT on Windows''', type='list', choices=['checkpoint', 'data', 'log']), Config('encryption', '', r''' configure an encryptor for system wide metadata and logs. @@ -670,13 +677,13 @@ wiredtiger_open_common =\ It is stored in clear text, and thus is available when the wiredtiger database is reopened. On the first use of a (name, keyid) combination, the WT_ENCRYPTOR::customize - function is called with the keyid as an argument.'''), + function is called with the keyid as an argument'''), Config('secretkey', '', r''' A string that is passed to the WT_ENCRYPTOR::customize function. It is never stored in clear text, so must be given to any subsequent ::wiredtiger_open calls to reopen the database. It must also be provided to any "wt" commands used with - this database.'''), + this database'''), ]), Config('extensions', '', r''' list of shared library extensions to load (using dlopen). @@ -737,7 +744,7 @@ wiredtiger_open_common =\ files to write through cache, including \c "log" will cause WiredTiger log files to write through cache. \c write_through should be combined with \c direct_io to get the equivalent of POSIX \c O_DIRECT on - Windows.''', + Windows''', type='list', choices=['data', 'log']), ] @@ -822,8 +829,9 @@ methods = { 'WT_SESSION.drop' : Method([ Config('checkpoint_wait', 'true', r''' - wait for the checkpoint lock, if \c checkpoint_wait=false, fail if - this lock is not available immediately''', + wait for the checkpoint lock, if \c checkpoint_wait=false, perform + the drop operation without taking a lock, returning EBUSY if the + operation conflicts with a running checkpoint''', type='boolean', undoc=True), Config('force', 'false', r''' return success if the object does not exist''', @@ -904,6 +912,11 @@ methods = { "WiredTigerCheckpoint" opens the most recent internal checkpoint taken for the object). The cursor does not support data modification'''), + Config('checkpoint_wait', 'true', r''' + wait for the checkpoint lock, if \c checkpoint_wait=false, open the + cursor without taking a lock, returning EBUSY if the operation + conflicts with a running checkpoint''', + type='boolean', undoc=True), Config('dump', '', r''' configure the cursor for dump format inputs and outputs: "hex" selects a simple hexadecimal format, "json" selects a JSON format @@ -978,7 +991,7 @@ methods = { Config('timeout_ms', '1200000', r''' maximum amount of time to wait for background sync to complete in milliseconds. A value of zero disables the timeout and returns - immediately.''', + immediately''', type='int'), ]), @@ -1081,7 +1094,7 @@ methods = { Config('names', '', r''' drop specific named snapshots''', type='list'), Config('to', '', r''' - drop all snapshots up to and including the specified name.'''), + drop all snapshots up to and including the specified name'''), ]), Config('name', '', r'''specify a name for the snapshot'''), ]), diff --git a/src/third_party/wiredtiger/dist/filelist b/src/third_party/wiredtiger/dist/filelist index 59624508cf0..19fa1122a27 100644 --- a/src/third_party/wiredtiger/dist/filelist +++ b/src/third_party/wiredtiger/dist/filelist @@ -47,9 +47,13 @@ src/btree/row_key.c src/btree/row_modify.c src/btree/row_srch.c src/cache/cache_las.c -src/checksum/checksum.c +src/checksum/arm64/crc32-arm64.c ARM64_HOST src/checksum/power8/crc32.S POWERPC_HOST src/checksum/power8/crc32_wrapper.c POWERPC_HOST +src/checksum/software/checksum.c +src/checksum/x86/crc32-x86.c X86_HOST +src/checksum/zseries/crc32-s390x.c ZSERIES_HOST +src/checksum/zseries/crc32le-vx.S ZSERIES_HOST src/config/config.c src/config/config_api.c src/config/config_check.c @@ -145,6 +149,7 @@ src/os_win/os_sleep.c WINDOWS_HOST src/os_win/os_snprintf.c WINDOWS_HOST src/os_win/os_thread.c WINDOWS_HOST src/os_win/os_time.c WINDOWS_HOST +src/os_win/os_utf8.c WINDOWS_HOST src/os_win/os_vsnprintf.c WINDOWS_HOST src/os_win/os_winerr.c WINDOWS_HOST src/os_win/os_yield.c WINDOWS_HOST @@ -182,6 +187,7 @@ src/support/pow.c src/support/rand.c src/support/scratch.c src/support/stat.c +src/support/thread_group.c src/txn/txn.c src/txn/txn_ckpt.c src/txn/txn_ext.c diff --git a/src/third_party/wiredtiger/dist/flags.py b/src/third_party/wiredtiger/dist/flags.py index b5f36fb707a..93b6e0cbbf4 100644 --- a/src/third_party/wiredtiger/dist/flags.py +++ b/src/third_party/wiredtiger/dist/flags.py @@ -37,10 +37,13 @@ flags = { 'READ_WONT_NEED', ], 'rec_write' : [ + 'CHECKPOINTING', + 'EVICTING', 'EVICT_IN_MEMORY', + 'EVICT_INMEM_SPLIT', 'EVICT_LOOKASIDE', + 'EVICT_SCRUB', 'EVICT_UPDATE_RESTORE', - 'EVICTING', 'VISIBILITY_ERR', ], 'txn_log_checkpoint' : [ @@ -77,6 +80,7 @@ flags = { 'VERB_SHARED_CACHE', 'VERB_SPLIT', 'VERB_TEMPORARY', + 'VERB_THREAD_GROUP', 'VERB_TRANSACTION', 'VERB_VERIFY', 'VERB_VERSION', diff --git a/src/third_party/wiredtiger/dist/s_all b/src/third_party/wiredtiger/dist/s_all index 46a68864906..33b8f6a76ba 100755 --- a/src/third_party/wiredtiger/dist/s_all +++ b/src/third_party/wiredtiger/dist/s_all @@ -15,6 +15,8 @@ echo 'dist/s_all run started...' force= reconf=0 +errmode=0 +errfound=0 while : do case "$1" in -A) # Reconfigure the library build. @@ -23,6 +25,9 @@ while : -f) # Force versions to be updated force="-f" shift;; + -E) # Return an error code on failure + errmode=1 + shift;; *) break;; esac @@ -48,6 +53,14 @@ errchk() echo "#######################" rm -f $2 + + # Some tests shouldn't return an error, we exclude them here. + case "$1" in + *s_export*) + break;; + *) + errfound=1;; + esac } run() @@ -108,3 +121,6 @@ for f in `find . -name ${t_pfx}\*`; do done echo 'dist/s_all run finished' +if test $errmode -ne 0; then + exit $errfound; +fi diff --git a/src/third_party/wiredtiger/dist/s_funcs.list b/src/third_party/wiredtiger/dist/s_funcs.list index c0d9f2e688f..01835390997 100644 --- a/src/third_party/wiredtiger/dist/s_funcs.list +++ b/src/third_party/wiredtiger/dist/s_funcs.list @@ -1,6 +1,7 @@ # List of functions that aren't found by s_funcs, but that's OK. FUNC_END FUNC_START +WT_CRC32_ENTRY WT_CURDUMP_PASS __bit_ffs __bit_nclr diff --git a/src/third_party/wiredtiger/dist/s_longlines b/src/third_party/wiredtiger/dist/s_longlines index 91dada361f4..43e350022dd 100755 --- a/src/third_party/wiredtiger/dist/s_longlines +++ b/src/third_party/wiredtiger/dist/s_longlines @@ -9,6 +9,7 @@ l=`(cd .. && find dist -name '*.py' && find src -name '*.in') | sed -e '/checksum\/power8/d' \ + -e '/checksum\/zseries/d' \ -e '/dist\/stat_data\.py/d' \ -e '/include\/extern\.h/d' \ -e '/include\/extern_posix\.h/d' \ diff --git a/src/third_party/wiredtiger/dist/s_prototypes b/src/third_party/wiredtiger/dist/s_prototypes index 73f7be371ea..5633c3b5140 100755 --- a/src/third_party/wiredtiger/dist/s_prototypes +++ b/src/third_party/wiredtiger/dist/s_prototypes @@ -28,7 +28,7 @@ proto() -e 's/\* /\*/g' \ -e 's/ */ /g' \ -e 's/^/extern /' \ - -e 's/WT_GCC_FUNC_/WT_GCC_FUNC_DECL_/g' \ + -e 's/WT_GCC_FUNC_ATTRIBUTE/WT_GCC_FUNC_DECL_ATTRIBUTE/g' \ -e '# If a line ends in #endif, appending a semicolon will result' \ -e '# in an illegal expression, force an appended newline using' \ -e '# the H command because substitute may not allow newline in' \ @@ -39,11 +39,14 @@ proto() -e H \ -e x \ -e '}' \ + -e '# Add the gcc warn_unused_result attribute to any external' \ + -e '# functions that return an int.' \ + -e '/^extern int /s/$/ WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result))/' \ -e 's/$/;/' \ -e p < $1 } -# proto -- +# externs -- # generate the list of prototypes given a file list externs() { @@ -73,6 +76,9 @@ externs f=../src/include/extern.h l=`sed \ -e '/^[a-z]/!d' \ + -e '/\/checksum\/arm64/d' \ + -e '/\/checksum\/power8/d' \ + -e '/\/checksum\/zseries/d' \ -e '/os_posix/d' \ -e '/os_win/d' \ -e 's/[ ].*$//' filelist` diff --git a/src/third_party/wiredtiger/dist/s_string.ok b/src/third_party/wiredtiger/dist/s_string.ok index 0694c90e5d3..1887cbd936f 100644 --- a/src/third_party/wiredtiger/dist/s_string.ok +++ b/src/third_party/wiredtiger/dist/s_string.ok @@ -5,6 +5,7 @@ AAAAAAAAAAAAA AAAAAAAAAAAAAAAA AAAAAAAAAAAAAAAAAA ABCDEFGHIJKLMNOPQRSTUVWXYZ +ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz ADDR ADDRs AJ @@ -12,6 +13,7 @@ API APIs ARG ARGS +ASM ASYNC Addr Ailamaki @@ -37,6 +39,7 @@ BZ Barack Bitfield Bitwise +Brueckner Bsearch Btree Buf @@ -59,6 +62,7 @@ CSV CURSORs CURSTD CallsCustDate +Castagnoli Checkpointing Checksum Checksums @@ -67,9 +71,9 @@ CloseHandle Comparator Config Coverity -CreateFileA CreateFileMapping -CreateFileMappingA +CreateFileMappingW +CreateFileW Crummey CustomersPhone DECL @@ -85,7 +89,7 @@ DbCursor DbEnv Decrement Decrypt -DeleteFileA +DeleteFileW EACCES EAGAIN EB @@ -135,17 +139,18 @@ GIDs Gcc Geoff GetEnvironmentVariableA -GetFileAttributesA GetFileAttributesEx +GetFileAttributesW GetFileSizeEx GetLastError -GetModuleHandleEx +GetModuleHandleExW GetProcAddress Google HFS HHHH HHHHLL HHHLL +Hendrik HyperLevelDB IEC IEEE @@ -156,9 +161,11 @@ INCR INIT INITIALIZER INMEM +INSN INTL ISA ITEMs +InitializeCriticalSectionAndSpinCount Inline Intra Ippokratis @@ -205,7 +212,10 @@ MEMALIGN MERCHANTABILITY METADATA MONGODB +MRXB +MRXBOPC MSVC +MULTI MULTIBLOCK MUTEX Manos @@ -218,8 +228,9 @@ Mewhort Mitzenmacher MongoDB MoveFile -MoveFileA +MoveFileW Multi +MultiByteToWideChar Multithreaded Mutex MySecret @@ -232,6 +243,7 @@ NOTFOUND NOTREACHED NOVALUE NUL +NUM NetBSD NoAddr Noll @@ -242,6 +254,7 @@ OUTBUFF OVFL ObWgfvgw Obama +Opcode Outfmt PARAM POSIX @@ -275,6 +288,7 @@ RMW RNG RPC RUNDIR +RXB Radu ReadFile Readonly @@ -314,6 +328,7 @@ StoreLoad StoreStore TAILQ TCMalloc +TESTUTIL TODO TORTIOUS TSO @@ -344,6 +359,8 @@ Uryyb VARCHAR VLDB VMSG +VR +VX Vc Vfprintf Vigenere @@ -361,6 +378,7 @@ Wconditional WeakHashLen Werror Wformat +WideCharToMultiByte WinNT WiredTiger WiredTiger's @@ -406,12 +424,14 @@ autocommit autoconf automake bInheritHandle +bal basecfg basho bcr bdb beginthreadex bigram +binutils bitcnt bitfield bitfields @@ -453,6 +473,7 @@ call's calloc cas catfmt +cb ccr cd centric @@ -499,6 +520,7 @@ conn connectionp const constantp +consts cookiep copydoc copyin @@ -530,6 +552,7 @@ curtable cust customp cv +cx cxa dT data's @@ -623,11 +646,13 @@ extlist fadvise fallocate fblocks +fc fclose fcntl fd fdatasync fdopen +fextend ffc fflush ffs @@ -705,7 +730,10 @@ iSh ibackup icount idx +ifdef ifdef's +iiSii +iiii iiu ikey im @@ -896,6 +924,7 @@ onint online onpage oo +opcode opendir openfile optimizations @@ -903,6 +932,7 @@ optype ori os osfhandle +other's ovfl ownp pR @@ -937,6 +967,7 @@ prepend prepended prepending presize +presync primary's printf printlog @@ -959,6 +990,7 @@ qrrSS qsort quartile qup +rN rS rb rbrace @@ -1144,6 +1176,7 @@ usr utf util uu +vN vW va valgrind @@ -1163,6 +1196,7 @@ vsnprintf vtype vunpack vw +vxr waitpid walk's warmup diff --git a/src/third_party/wiredtiger/dist/s_style b/src/third_party/wiredtiger/dist/s_style index a222c004cc3..47f18ef1f18 100755 --- a/src/third_party/wiredtiger/dist/s_style +++ b/src/third_party/wiredtiger/dist/s_style @@ -20,7 +20,8 @@ if [ $# -ne 1 ]; then -name '*.[chisy]' -o -name '*.in' -o -name '*.dox' | sed -e '/Makefile.in/d' \ -e '/build_win\/wiredtiger_config.h/d' \ - -e '/checksum\/power8/d' | + -e '/checksum\/power8/d' \ + -e '/checksum\/zseries/d' | xargs $xp -n 1 -I{} sh ./dist/s_style {} else # General style correction and cleanup for a single file @@ -33,7 +34,7 @@ else exit 1; fi - egrep -w 'a a|an an|and and|are are|be be|by by|for for|from from|if if|in in|is is|it it|of of|the the|this this|to to|was was|were were|when when|with with|a an|an a|a the|the a' $f > $t + egrep -w 'a a|an an|and and|are are|be be|by by|for for|from from|if if|in in[^-]|is is|it it|of of|the the|this this|to to|was was|were were|when when|with with|a an|an a|a the|the a' $f > $t test -s $t && { echo "paired typo" echo "============================" @@ -173,7 +174,7 @@ else -e 's/\([ ,]\)u_int64_t\([ ,]\)/\1uint64_t\2/g' \ -e 's/\([ ,]\)u_quad\([ ,]\)/\1uint64_t\2/g' \ -e 's/\([|&=+-]\) *\([^*]\)/\1 \2/' \ - -e 's/(void) \([a-zA-Z_]\)/(void)\1/' \ + -e 's/[ ](void) \([a-zA-Z_]\)/(void)\1/' \ -e '/for /!s/;;$/;/' \ -e 's/(EOPNOTSUPP)/(ENOTSUP)/' \ -e 's/(unsigned)/(u_int)/' \ diff --git a/src/third_party/wiredtiger/dist/s_void b/src/third_party/wiredtiger/dist/s_void new file mode 100644 index 00000000000..ab2f23a5fdd --- /dev/null +++ b/src/third_party/wiredtiger/dist/s_void @@ -0,0 +1,134 @@ +#! /bin/sh + +t=__wt.$$ +trap 'rm -f $t; exit 0' 0 1 2 3 13 15 + +cd .. + +# Turn a C file into a line per function that returns an int. +file_parse() +{ + sed -n \ + -e '/^int$/b loop' \ + -e '/^static int$/b loop' \ + -e 'd' \ + -e ': loop' \ + -e 'H' \ + -e 'n' \ + -e '/^}$/!b loop' \ + -e 'H' \ + -e 'x' \ + -e 's/\n/ /g' \ + -e 'p' \ + -e 's/.*//' \ + -e 'x' \ + -e 'd' $1 +} + +# Strip out a list of functions that will be flagged, but are OK. +func_ok() +{ + sed \ + -e '/int __bm_stat$/d' \ + -e '/int __checkpoint_presync$/d' \ + -e '/int __compact_uri_analyze$/d' \ + -e '/int __curlog_reset$/d' \ + -e '/int __handle_close_default$/d' \ + -e '/int __handle_progress_default$/d' \ + -e '/int __im_file_close$/d' \ + -e '/int __im_file_lock$/d' \ + -e '/int __im_file_size$/d' \ + -e '/int __im_file_sync$/d' \ + -e '/int __im_fs_directory_list_free$/d' \ + -e '/int __im_fs_exist$/d' \ + -e '/int __posix_file_close$/d' \ + -e '/int __posix_terminate$/d' \ + -e '/int __rec_destroy_session$/d' \ + -e '/int __win_terminate$/d' \ + -e '/int __wt_block_compact_end$/d' \ + -e '/int __wt_block_compact_start$/d' \ + -e '/int __wt_block_manager_size$/d' \ + -e '/int __wt_block_write_size$/d' \ + -e '/int __wt_curjoin_joined$/d' \ + -e '/int __wt_cursor_close$/d' \ + -e '/int __wt_cursor_noop$/d' \ + -e '/int __wt_epoch$/d' \ + -e '/int __wt_errno$/d' \ + -e '/int __wt_get_vm_pagesize$/d' \ + -e '/int __wt_lsm_manager_pop_entry$/d' \ + -e '/int __wt_once$/d' \ + -e '/int __wt_posix_directory_list_free$/d' \ + -e '/int __wt_stat_connection_desc$/d' \ + -e '/int __wt_stat_dsrc_desc$/d' \ + -e '/int __wt_stat_join_desc$/d' \ + -e '/int __wt_win_directory_list_free$/d' \ + -e '/int bdb_compare_reverse$/d' \ + -e '/int csv_terminate$/d' \ + -e '/int demo_file_close$/d' \ + -e '/int demo_file_lock$/d' \ + -e '/int demo_file_size$/d' \ + -e '/int demo_file_sync$/d' \ + -e '/int demo_fs_directory_list_free$/d' \ + -e '/int demo_fs_exist$/d' \ + -e '/int handle_message$/d' \ + -e '/int handle_progress$/d' \ + -e '/int helium_cursor_reset$/d' \ + -e '/int helium_session_verify$/d' \ + -e '/int log_print_err$/d' \ + -e '/int lz4_error$/d' \ + -e '/int lz4_pre_size$/d' \ + -e '/int lz4_terminate$/d' \ + -e '/int main$/d' \ + -e '/int nop_decompress$/d' \ + -e '/int nop_decrypt$/d' \ + -e '/int nop_pre_size$/d' \ + -e '/int nop_sizing$/d' \ + -e '/int nop_terminate$/d' \ + -e '/int nop_terminate$/d' \ + -e '/int os_errno$/d' \ + -e '/int revint_terminate$/d' \ + -e '/int rotn_error$/d' \ + -e '/int rotn_sizing$/d' \ + -e '/int rotn_terminate$/d' \ + -e '/int uri2name$/d' \ + -e '/int usage$/d' \ + -e '/int util_err$/d' \ + -e '/int wiredtiger_extension_init$/d' \ + -e '/int wiredtiger_extension_terminate$/d' \ + -e '/int wiredtiger_pack_close$/d' \ + -e '/int wt_snappy_pre_size$/d' \ + -e '/int wt_snappy_terminate$/d' \ + -e '/int zlib_error$/d' \ + -e '/int zlib_terminate$/d' +} + +# Complain about functions which return an "int" but which don't return except +# at the end of the function. This script is a kluge and isn't run by default. +for f in `find bench ext src test -name '*.[ci]'`; do + if expr "$f" : '.*/windows_shim.c' > /dev/null; then + continue + fi + + # Turn each function into a single line, then discard the function's + # final "return" call, then discard any function that still has some + # form of return assignment or call. + file_parse $f | + sed -e 's/return ([^)]*); }$//' \ + -e '/[A-Z]*_API_CALL[A-Z_]*(/d' \ + -e '/WT_CURSOR_NEEDKEY(/d' \ + -e '/WT_CURSOR_NEEDVALUE(/d' \ + -e '/WT_ERR[A-Z_]*(/d' \ + -e '/WT_ILLEGAL_VALUE[A-Z_]*(/d' \ + -e '/WT_PANIC[A-Z_]*(/d' \ + -e '/WT_RET[A-Z_]*(/d' \ + -e '/WT_TRET(/d' \ + -e '/[^a-z_]ret = /d' \ + -e '/[^a-z_]return (/d' \ + -e 's/^\([^(]*\).*/\1/' \ + -e 's/^ *//' | + func_ok > $t + test -s $t && { + echo "========== $f" + cat $t + } +done diff --git a/src/third_party/wiredtiger/dist/s_win b/src/third_party/wiredtiger/dist/s_win index 49deb348bc3..5b45cacf0f4 100755 --- a/src/third_party/wiredtiger/dist/s_win +++ b/src/third_party/wiredtiger/dist/s_win @@ -19,7 +19,7 @@ win_config() test -s $t && { echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" - echo "Windows #defines missing from $f" + echo "$f: configuration #defines do not match POSIX" echo "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" cat $t exit 1 diff --git a/src/third_party/wiredtiger/dist/stat.py b/src/third_party/wiredtiger/dist/stat.py index 7961bf7053f..c3c85bbe9b4 100644 --- a/src/third_party/wiredtiger/dist/stat.py +++ b/src/third_party/wiredtiger/dist/stat.py @@ -41,7 +41,16 @@ compare_srcfile(tmp_file, '../src/include/stat.h') def print_defines_one(capname, base, stats): for v, l in enumerate(stats, base): - f.write('/*! %s */\n' % '\n * '.join(textwrap.wrap(l.desc, 70))) + desc = l.desc + if 'all_only' in l.flags: + desc += ', only reported if statistics=all is set' + if len(textwrap.wrap(desc, 70)) > 1: + f.write('/*!\n') + f.write(' * %s\n' % '\n * '.join(textwrap.wrap(desc, 70))) + f.write(' */\n') + else: + f.write('/*! %s */\n' % desc) + #f.write('/*! %s */\n' % '\n * '.join(textwrap.wrap(desc, 70))) f.write('#define\tWT_STAT_' + capname + '_' + l.name.upper() + "\t" * max(1, 6 - int((len('WT_STAT_' + capname + '_' + l.name)) / 8)) + str(v) + '\n') diff --git a/src/third_party/wiredtiger/dist/stat_data.py b/src/third_party/wiredtiger/dist/stat_data.py index 694ffc86ee4..a050849ad76 100644 --- a/src/third_party/wiredtiger/dist/stat_data.py +++ b/src/third_party/wiredtiger/dist/stat_data.py @@ -9,6 +9,7 @@ # # Data-source statistics are normally aggregated across the set of underlying # objects. Additional optional configuration flags are available: +# all_only Only gets reported when statistics=all set # max_aggregate Take the maximum value when aggregating statistics # no_clear Value not cleared when statistics cleared # no_scale Don't scale value per second in the logging tool script @@ -81,10 +82,10 @@ class SessionStat(Stat): prefix = 'session' def __init__(self, name, desc, flags=''): Stat.__init__(self, name, SessionStat.prefix, desc, flags) -class ThreadState(Stat): +class ThreadStat(Stat): prefix = 'thread-state' def __init__(self, name, desc, flags=''): - Stat.__init__(self, name, ThreadState.prefix, desc, flags) + Stat.__init__(self, name, ThreadStat.prefix, desc, flags) class TxnStat(Stat): prefix = 'transaction' def __init__(self, name, desc, flags=''): @@ -105,7 +106,7 @@ groups['evict'] = [ BlockStat.prefix, CacheStat.prefix, ConnStat.prefix, - ThreadState.prefix + ThreadStat.prefix ] groups['lsm'] = [LSMStat.prefix, TxnStat.prefix] groups['memory'] = [CacheStat.prefix, ConnStat.prefix, RecStat.prefix] @@ -113,7 +114,7 @@ groups['system'] = [ ConnStat.prefix, DhandleStat.prefix, SessionStat.prefix, - ThreadState.prefix + ThreadStat.prefix ] ########################################## @@ -159,6 +160,7 @@ connection_stats = [ BlockStat('block_byte_map_read', 'mapped bytes read', 'size'), BlockStat('block_byte_read', 'bytes read', 'size'), BlockStat('block_byte_write', 'bytes written', 'size'), + BlockStat('block_byte_write_checkpoint', 'bytes written for checkpoint', 'size'), BlockStat('block_map_read', 'mapped blocks read'), BlockStat('block_preload', 'blocks pre-loaded'), BlockStat('block_read', 'blocks read'), @@ -168,11 +170,12 @@ connection_stats = [ # Cache and eviction statistics ########################################## CacheStat('cache_bytes_dirty', 'tracked dirty bytes in the cache', 'no_clear,no_scale,size'), + CacheStat('cache_bytes_image', 'bytes belonging to page images in the cache', 'no_clear,no_scale,size'), CacheStat('cache_bytes_internal', 'tracked bytes belonging to internal pages in the cache', 'no_clear,no_scale,size'), CacheStat('cache_bytes_inuse', 'bytes currently in the cache', 'no_clear,no_scale,size'), CacheStat('cache_bytes_leaf', 'tracked bytes belonging to leaf pages in the cache', 'no_clear,no_scale,size'), CacheStat('cache_bytes_max', 'maximum bytes configured', 'no_clear,no_scale,size'), - CacheStat('cache_bytes_overflow', 'tracked bytes belonging to overflow pages in the cache', 'no_clear,no_scale,size'), + CacheStat('cache_bytes_other', 'bytes not belonging to page images in the cache', 'no_clear,no_scale,size'), CacheStat('cache_bytes_read', 'bytes read into cache', 'size'), CacheStat('cache_bytes_write', 'bytes written from cache', 'size'), CacheStat('cache_eviction_aggressive_set', 'eviction currently operating in aggressive mode', 'no_clear,no_scale'), @@ -193,17 +196,17 @@ connection_stats = [ CacheStat('cache_eviction_internal', 'internal pages evicted'), CacheStat('cache_eviction_maximum_page_size', 'maximum page size at eviction', 'no_clear,no_scale,size'), CacheStat('cache_eviction_pages_queued', 'pages queued for eviction'), - CacheStat('cache_eviction_pages_queued_oldest', 'pages queued for urgent eviction'), + CacheStat('cache_eviction_pages_queued_oldest', 'pages queued for urgent eviction during walk'), + CacheStat('cache_eviction_pages_queued_urgent', 'pages queued for urgent eviction'), CacheStat('cache_eviction_pages_seen', 'pages seen by eviction walk'), CacheStat('cache_eviction_queue_empty', 'eviction server candidate queue empty when topping up'), CacheStat('cache_eviction_queue_not_empty', 'eviction server candidate queue not empty when topping up'), CacheStat('cache_eviction_server_evicting', 'eviction server evicting pages'), - CacheStat('cache_eviction_server_not_evicting', 'eviction server populating queue, but not evicting pages'), CacheStat('cache_eviction_server_slept', 'eviction server slept, because we did not make progress with eviction'), - CacheStat('cache_eviction_server_toobig', 'eviction server skipped very large page'), CacheStat('cache_eviction_slow', 'eviction server unable to reach eviction goal'), CacheStat('cache_eviction_split_internal', 'internal pages split during eviction'), CacheStat('cache_eviction_split_leaf', 'leaf pages split during eviction'), + CacheStat('cache_eviction_state', 'eviction state', 'no_clear,no_scale'), CacheStat('cache_eviction_walk', 'pages walked for eviction'), CacheStat('cache_eviction_walks_active', 'files with active eviction walks', 'no_clear,no_scale,size'), CacheStat('cache_eviction_walks_started', 'files with new eviction walks started'), @@ -215,12 +218,14 @@ connection_stats = [ CacheStat('cache_inmem_splittable', 'in-memory page passed criteria to be split'), CacheStat('cache_lookaside_insert', 'lookaside table insert calls'), CacheStat('cache_lookaside_remove', 'lookaside table remove calls'), + CacheStat('cache_overflow_value', 'overflow values cached in memory', 'no_scale'), CacheStat('cache_overhead', 'percentage overhead', 'no_clear,no_scale'), CacheStat('cache_pages_dirty', 'tracked dirty pages in the cache', 'no_clear,no_scale'), CacheStat('cache_pages_inuse', 'pages currently held in the cache', 'no_clear,no_scale'), CacheStat('cache_pages_requested', 'pages requested from the cache'), CacheStat('cache_read', 'pages read into cache'), CacheStat('cache_read_lookaside', 'pages read into cache requiring lookaside entries'), + CacheStat('cache_read_overflow', 'overflow pages read into cache'), CacheStat('cache_write', 'pages written from cache'), CacheStat('cache_write_lookaside', 'page written requiring lookaside records'), CacheStat('cache_write_restore', 'pages written requiring in-memory restoration'), @@ -271,8 +276,8 @@ connection_stats = [ LogStat('log_slot_unbuffered', 'consolidated slot unbuffered writes'), LogStat('log_sync', 'log sync operations'), LogStat('log_sync_dir', 'log sync_dir operations'), - LogStat('log_sync_dir_duration', 'log sync_dir time duration (usecs)'), - LogStat('log_sync_duration', 'log sync time duration (usecs)'), + LogStat('log_sync_dir_duration', 'log sync_dir time duration (usecs)', 'no_clear,no_scale'), + LogStat('log_sync_duration', 'log sync time duration (usecs)', 'no_clear,no_scale'), LogStat('log_write_lsn', 'log server thread advances write LSN'), LogStat('log_write_lsn_skip', 'log server thread write LSN walk skipped'), LogStat('log_writes', 'log write operations'), @@ -294,11 +299,11 @@ connection_stats = [ TxnStat('txn_begin', 'transaction begins'), TxnStat('txn_checkpoint', 'transaction checkpoints'), TxnStat('txn_checkpoint_fsync_post', 'transaction fsync calls for checkpoint after allocating the transaction ID'), - TxnStat('txn_checkpoint_fsync_post_duration', 'transaction fsync duration for checkpoint after allocating the transaction ID (usecs)'), - TxnStat('txn_checkpoint_fsync_pre', 'transaction fsync calls for checkpoint before allocating the transaction ID'), - TxnStat('txn_checkpoint_fsync_pre_duration', 'transaction fsync duration for checkpoint before allocating the transaction ID (usecs)'), + TxnStat('txn_checkpoint_fsync_post_duration', 'transaction fsync duration for checkpoint after allocating the transaction ID (usecs)', 'no_clear,no_scale'), TxnStat('txn_checkpoint_generation', 'transaction checkpoint generation', 'no_clear,no_scale'), TxnStat('txn_checkpoint_running', 'transaction checkpoint currently running', 'no_clear,no_scale'), + TxnStat('txn_checkpoint_scrub_target', 'transaction checkpoint scrub dirty target', 'no_clear,no_scale'), + TxnStat('txn_checkpoint_scrub_time', 'transaction checkpoint scrub time (msecs)', 'no_clear,no_scale'), TxnStat('txn_checkpoint_time_max', 'transaction checkpoint max time (msecs)', 'no_clear,no_scale'), TxnStat('txn_checkpoint_time_min', 'transaction checkpoint min time (msecs)', 'no_clear,no_scale'), TxnStat('txn_checkpoint_time_recent', 'transaction checkpoint most recent time (msecs)', 'no_clear,no_scale'), @@ -332,6 +337,22 @@ connection_stats = [ ########################################## SessionStat('session_cursor_open', 'open cursor count', 'no_clear,no_scale'), SessionStat('session_open', 'open session count', 'no_clear,no_scale'), + SessionStat('session_table_compact_fail', 'table compact failed calls', 'no_clear,no_scale'), + SessionStat('session_table_compact_success', 'table compact successful calls', 'no_clear,no_scale'), + SessionStat('session_table_create_fail', 'table create failed calls', 'no_clear,no_scale'), + SessionStat('session_table_create_success', 'table create successful calls', 'no_clear,no_scale'), + SessionStat('session_table_drop_fail', 'table drop failed calls', 'no_clear,no_scale'), + SessionStat('session_table_drop_success', 'table drop successful calls', 'no_clear,no_scale'), + SessionStat('session_table_rebalance_fail', 'table rebalance failed calls', 'no_clear,no_scale'), + SessionStat('session_table_rebalance_success', 'table rebalance successful calls', 'no_clear,no_scale'), + SessionStat('session_table_rename_fail', 'table rename failed calls', 'no_clear,no_scale'), + SessionStat('session_table_rename_success', 'table rename successful calls', 'no_clear,no_scale'), + SessionStat('session_table_salvage_fail', 'table salvage failed calls', 'no_clear,no_scale'), + SessionStat('session_table_salvage_success', 'table salvage successful calls', 'no_clear,no_scale'), + SessionStat('session_table_truncate_fail', 'table truncate failed calls', 'no_clear,no_scale'), + SessionStat('session_table_truncate_success', 'table truncate successful calls', 'no_clear,no_scale'), + SessionStat('session_table_verify_fail', 'table verify failed calls', 'no_clear,no_scale'), + SessionStat('session_table_verify_success', 'table verify successful calls', 'no_clear,no_scale'), ########################################## # Total cursor operations @@ -349,11 +370,11 @@ connection_stats = [ CursorStat('cursor_update', 'cursor update calls'), ########################################## - # Thread State statistics + # Thread Count statistics ########################################## - ThreadState('fsync_active', 'active filesystem fsync calls','no_clear,no_scale'), - ThreadState('read_active', 'active filesystem read calls','no_clear,no_scale'), - ThreadState('write_active', 'active filesystem write calls','no_clear,no_scale'), + ThreadStat('thread_fsync_active', 'active filesystem fsync calls','no_clear,no_scale'), + ThreadStat('thread_read_active', 'active filesystem read calls','no_clear,no_scale'), + ThreadStat('thread_write_active', 'active filesystem write calls','no_clear,no_scale'), ########################################## # Yield statistics @@ -400,13 +421,13 @@ dsrc_stats = [ # Btree statistics ########################################## BtreeStat('btree_checkpoint_generation', 'btree checkpoint generation', 'no_clear,no_scale'), - BtreeStat('btree_column_deleted', 'column-store variable-size deleted values', 'no_scale'), - BtreeStat('btree_column_fix', 'column-store fixed-size leaf pages', 'no_scale'), - BtreeStat('btree_column_internal', 'column-store internal pages', 'no_scale'), - BtreeStat('btree_column_rle', 'column-store variable-size RLE encoded values', 'no_scale'), - BtreeStat('btree_column_variable', 'column-store variable-size leaf pages', 'no_scale'), + BtreeStat('btree_column_deleted', 'column-store variable-size deleted values', 'no_scale,all_only'), + BtreeStat('btree_column_fix', 'column-store fixed-size leaf pages', 'no_scale,all_only'), + BtreeStat('btree_column_internal', 'column-store internal pages', 'no_scale,all_only'), + BtreeStat('btree_column_rle', 'column-store variable-size RLE encoded values', 'no_scale,all_only'), + BtreeStat('btree_column_variable', 'column-store variable-size leaf pages', 'no_scale,all_only'), BtreeStat('btree_compact_rewrite', 'pages rewritten by compaction'), - BtreeStat('btree_entries', 'number of key/value pairs', 'no_scale'), + BtreeStat('btree_entries', 'number of key/value pairs', 'no_scale,all_only'), BtreeStat('btree_fixed_len', 'fixed-record size', 'max_aggregate,no_scale,size'), BtreeStat('btree_maximum_depth', 'maximum tree depth', 'max_aggregate,no_scale'), BtreeStat('btree_maxintlkey', 'maximum internal page key size', 'max_aggregate,no_scale,size'), @@ -414,9 +435,9 @@ dsrc_stats = [ BtreeStat('btree_maxleafkey', 'maximum leaf page key size', 'max_aggregate,no_scale,size'), BtreeStat('btree_maxleafpage', 'maximum leaf page size', 'max_aggregate,no_scale,size'), BtreeStat('btree_maxleafvalue', 'maximum leaf page value size', 'max_aggregate,no_scale,size'), - BtreeStat('btree_overflow', 'overflow pages', 'no_scale'), - BtreeStat('btree_row_internal', 'row-store internal pages', 'no_scale'), - BtreeStat('btree_row_leaf', 'row-store leaf pages', 'no_scale'), + BtreeStat('btree_overflow', 'overflow pages', 'no_scale,all_only'), + BtreeStat('btree_row_internal', 'row-store internal pages', 'no_scale,all_only'), + BtreeStat('btree_row_leaf', 'row-store leaf pages', 'no_scale,all_only'), ########################################## # LSM statistics @@ -451,6 +472,7 @@ dsrc_stats = [ ########################################## # Cache and eviction statistics ########################################## + CacheStat('cache_bytes_inuse', 'bytes currently in the cache', 'no_clear,no_scale,size'), CacheStat('cache_bytes_read', 'bytes read into cache', 'size'), CacheStat('cache_bytes_write', 'bytes written from cache', 'size'), CacheStat('cache_eviction_checkpoint', 'checkpoint blocked page eviction'), diff --git a/src/third_party/wiredtiger/examples/c/ex_all.c b/src/third_party/wiredtiger/examples/c/ex_all.c index e8727df3f60..a2042c22bbb 100644 --- a/src/third_party/wiredtiger/examples/c/ex_all.c +++ b/src/third_party/wiredtiger/examples/c/ex_all.c @@ -1126,7 +1126,7 @@ main(void) home, NULL, "create,file_extend=(data=16MB)", &conn); /*! [Configure file_extend] */ if (ret == 0) - (void)conn->close(conn, NULL); + ret = conn->close(conn, NULL); /*! [Eviction configuration] */ /* @@ -1137,7 +1137,7 @@ main(void) "create,eviction_trigger=90,eviction_dirty_target=75", &conn); /*! [Eviction configuration] */ if (ret == 0) - (void)conn->close(conn, NULL); + ret = conn->close(conn, NULL); /*! [Eviction worker configuration] */ /* Configure up to four eviction threads */ @@ -1145,20 +1145,20 @@ main(void) "create,eviction_trigger=90,eviction=(threads_max=4)", &conn); /*! [Eviction worker configuration] */ if (ret == 0) - (void)conn->close(conn, NULL); + ret = conn->close(conn, NULL); /*! [Statistics configuration] */ ret = wiredtiger_open(home, NULL, "create,statistics=(all)", &conn); /*! [Statistics configuration] */ if (ret == 0) - (void)conn->close(conn, NULL); + ret = conn->close(conn, NULL); /*! [Statistics logging] */ ret = wiredtiger_open( home, NULL, "create,statistics_log=(wait=30)", &conn); /*! [Statistics logging] */ if (ret == 0) - (void)conn->close(conn, NULL); + ret = conn->close(conn, NULL); #ifdef MIGHT_NOT_RUN /* @@ -1171,7 +1171,7 @@ main(void) &conn); /*! [Statistics logging with a table] */ if (ret == 0) - (void)conn->close(conn, NULL); + ret = conn->close(conn, NULL); /* * Don't run this code, statistics logging doesn't yet support indexes. @@ -1182,7 +1182,7 @@ main(void) &conn); /*! [Statistics logging with a source type] */ if (ret == 0) - (void)conn->close(conn, NULL); + ret = conn->close(conn, NULL); /* * Don't run this code, because memory checkers get very upset when we diff --git a/src/third_party/wiredtiger/examples/c/ex_encrypt.c b/src/third_party/wiredtiger/examples/c/ex_encrypt.c index 3b3323bc091..5d5cc66c87f 100644 --- a/src/third_party/wiredtiger/examples/c/ex_encrypt.c +++ b/src/third_party/wiredtiger/examples/c/ex_encrypt.c @@ -76,12 +76,12 @@ typedef struct { #define IV_LEN 16 /* - * make_cksum -- + * make_checksum -- * This is where one would call a checksum function on the encrypted * buffer. Here we just put a constant value in it. */ static void -make_cksum(uint8_t *dst) +make_checksum(uint8_t *dst) { int i; /* @@ -220,7 +220,7 @@ rotate_encrypt(WT_ENCRYPTOR *encryptor, WT_SESSION *session, * Checksum the encrypted buffer and add the IV. */ i = 0; - make_cksum(&dst[i]); + make_checksum(&dst[i]); i += CHKSUM_LEN; make_iv(&dst[i]); *result_lenp = dst_len; diff --git a/src/third_party/wiredtiger/examples/c/ex_file_system.c b/src/third_party/wiredtiger/examples/c/ex_file_system.c index 55ee20e9331..524a5d03f89 100644 --- a/src/third_party/wiredtiger/examples/c/ex_file_system.c +++ b/src/third_party/wiredtiger/examples/c/ex_file_system.c @@ -352,8 +352,8 @@ demo_fs_open(WT_FILE_SYSTEM *file_system, WT_SESSION *session, */ file_handle->close = demo_file_close; file_handle->fh_advise = NULL; - file_handle->fh_allocate = NULL; - file_handle->fh_allocate_nolock = NULL; + file_handle->fh_extend = NULL; + file_handle->fh_extend_nolock = NULL; file_handle->fh_lock = demo_file_lock; file_handle->fh_map = NULL; file_handle->fh_map_discard = NULL; diff --git a/src/third_party/wiredtiger/ext/collators/revint/revint_collator.c b/src/third_party/wiredtiger/ext/collators/revint/revint_collator.c index 30b5dc67556..b8ebbdc8585 100644 --- a/src/third_party/wiredtiger/ext/collators/revint/revint_collator.c +++ b/src/third_party/wiredtiger/ext/collators/revint/revint_collator.c @@ -54,8 +54,8 @@ revint_compare(WT_COLLATOR *collator, const REVINT_COLLATOR *revint_collator; WT_EXTENSION_API *wtapi; WT_PACK_STREAM *pstream; - int ret; int64_t i1, i2, p1, p2; + int ret; i1 = i2 = p1 = p2 = 0; revint_collator = (const REVINT_COLLATOR *)collator; @@ -82,23 +82,23 @@ revint_compare(WT_COLLATOR *collator, if ((ret = wtapi->unpack_start( wtapi, session, "ii", k1->data, k1->size, &pstream)) != 0 || (ret = wtapi->unpack_int(wtapi, pstream, &i1)) != 0) - goto err; + return (ret); if ((ret = wtapi->unpack_int(wtapi, pstream, &p1)) != 0) /* A missing primary key is OK and sorts first. */ p1 = INT64_MIN; if ((ret = wtapi->pack_close(wtapi, pstream, NULL)) != 0) - goto err; + return (ret); /* Unpack the second pair of numbers. */ if ((ret = wtapi->unpack_start( wtapi, session, "ii", k2->data, k2->size, &pstream)) != 0 || (ret = wtapi->unpack_int(wtapi, pstream, &i2)) != 0) - goto err; + return (ret); if ((ret = wtapi->unpack_int(wtapi, pstream, &p2)) != 0) /* A missing primary key is OK and sorts first. */ p2 = INT64_MIN; if ((ret = wtapi->pack_close(wtapi, pstream, NULL)) != 0) - goto err; + return (ret); /* sorting is reversed */ if (i1 < i2) @@ -113,7 +113,7 @@ revint_compare(WT_COLLATOR *collator, else *cmp = 0; /* index key and primary key are same */ -err: return (ret); + return (0); } /* diff --git a/src/third_party/wiredtiger/ext/compressors/zlib/zlib_compress.c b/src/third_party/wiredtiger/ext/compressors/zlib/zlib_compress.c index 9aede2ed907..484df0a6785 100644 --- a/src/third_party/wiredtiger/ext/compressors/zlib/zlib_compress.c +++ b/src/third_party/wiredtiger/ext/compressors/zlib/zlib_compress.c @@ -92,7 +92,7 @@ zalloc(void *cookie, uint32_t number, uint32_t size) opaque = cookie; wt_api = ((ZLIB_COMPRESSOR *)opaque->compressor)->wt_api; return (wt_api->scr_alloc( - wt_api, opaque->session, (size_t)(number * size))); + wt_api, opaque->session, (size_t)number * size)); } /* diff --git a/src/third_party/wiredtiger/ext/encryptors/rotn/rotn_encrypt.c b/src/third_party/wiredtiger/ext/encryptors/rotn/rotn_encrypt.c index 9a92ae7b642..4d614e2e409 100644 --- a/src/third_party/wiredtiger/ext/encryptors/rotn/rotn_encrypt.c +++ b/src/third_party/wiredtiger/ext/encryptors/rotn/rotn_encrypt.c @@ -101,12 +101,12 @@ rotn_error(ROTN_ENCRYPTOR *encryptor, WT_SESSION *session, int err, } /* - * make_cksum -- + * make_checksum -- * This is where one would call a checksum function on the encrypted * buffer. Here we just put a constant value in it. */ static void -make_cksum(uint8_t *dst) +make_checksum(uint8_t *dst) { int i; /* @@ -212,7 +212,7 @@ rotn_encrypt(WT_ENCRYPTOR *encryptor, WT_SESSION *session, * Checksum the encrypted buffer and add the IV. */ i = 0; - make_cksum(&dst[i]); + make_checksum(&dst[i]); i += CHKSUM_LEN; make_iv(&dst[i]); *result_lenp = dst_len; @@ -448,9 +448,10 @@ rotn_configure(ROTN_ENCRYPTOR *rotn_encryptor, WT_CONFIG_ARG *config) strlen("rotn_force_error") == k.len) { rotn_encryptor->force_error = v.val == 0 ? 0 : 1; continue; - } - else { - (void)config_parser->close(config_parser); + } else { + if ((ret = config_parser->close(config_parser)) != 0) + return (rotn_error(rotn_encryptor, + NULL, ret, "WT_CONFIG_PARSER.close")); return (rotn_error(rotn_encryptor, NULL, EINVAL, "unknown config key")); } diff --git a/src/third_party/wiredtiger/ext/test/kvs_bdb/kvs_bdb.c b/src/third_party/wiredtiger/ext/test/kvs_bdb/kvs_bdb.c index 3d78bca1d1b..be63b1d7e7d 100644 --- a/src/third_party/wiredtiger/ext/test/kvs_bdb/kvs_bdb.c +++ b/src/third_party/wiredtiger/ext/test/kvs_bdb/kvs_bdb.c @@ -33,6 +33,13 @@ #include #include +/* + * Berkeley DB has an #ifdef we need to provide a value for, we'll see an + * undefined error if it's unset during a strict compile. + */ +#ifndef DB_DBM_HSEARCH +#define DB_DBM_HSEARCH 0 +#endif #include #include #include diff --git a/src/third_party/wiredtiger/lang/java/Makefile.am b/src/third_party/wiredtiger/lang/java/Makefile.am index 192e44a05d2..7184fe610dc 100644 --- a/src/third_party/wiredtiger/lang/java/Makefile.am +++ b/src/third_party/wiredtiger/lang/java/Makefile.am @@ -46,6 +46,7 @@ JAVA_JUNIT = \ $(JAVATEST)/AsyncTest.java \ $(JAVATEST)/BackupCursorTest.java \ $(JAVATEST)/ConfigTest.java \ + $(JAVATEST)/ConcurrentCloseTest.java \ $(JAVATEST)/CursorTest.java \ $(JAVATEST)/CursorTest02.java \ $(JAVATEST)/ExceptionTest.java \ diff --git a/src/third_party/wiredtiger/lang/java/wiredtiger.i b/src/third_party/wiredtiger/lang/java/wiredtiger.i index c04bae63cbc..d6e0660dc2c 100644 --- a/src/third_party/wiredtiger/lang/java/wiredtiger.i +++ b/src/third_party/wiredtiger/lang/java/wiredtiger.i @@ -240,7 +240,6 @@ WT_CLASS(type, class, name) %typemap(freearg, numinputs=0) class ## _CLOSED *name { closeHandler(jenv, savesess2, jcb2); - priv = NULL; } %enddef diff --git a/src/third_party/wiredtiger/src/async/async_api.c b/src/third_party/wiredtiger/src/async/async_api.c index fea8714176b..0a855514a07 100644 --- a/src/third_party/wiredtiger/src/async/async_api.c +++ b/src/third_party/wiredtiger/src/async/async_api.c @@ -89,7 +89,7 @@ setup: op->format = af; err: if (c != NULL) - (void)c->close(c); + WT_TRET(c->close(c)); __wt_free(session, af->uri); __wt_free(session, af->config); __wt_free(session, af->key_format); @@ -489,13 +489,24 @@ __wt_async_flush(WT_SESSION_IMPL *session) { WT_ASYNC *async; WT_CONNECTION_IMPL *conn; - WT_DECL_RET; + uint32_t i, workers; conn = S2C(session); if (!conn->async_cfg) return (0); async = conn->async; + /* + * Only add a flush operation if there are workers who can process + * it. Otherwise we will wait forever. + */ + workers = 0; + for (i = 0; i < conn->async_workers; ++i) + if (async->worker_tids[i] != 0) + ++workers; + if (workers == 0) + return (0); + WT_STAT_FAST_CONN_INCR(session, async_flush); /* * We have to do several things. First we have to prevent @@ -528,16 +539,15 @@ retry: (void)__wt_atomic_add64(&async->flush_gen, 1); WT_ASSERT(session, async->flush_op.state == WT_ASYNCOP_FREE); async->flush_op.state = WT_ASYNCOP_READY; - WT_ERR(__wt_async_op_enqueue(session, &async->flush_op)); + WT_RET(__wt_async_op_enqueue(session, &async->flush_op)); while (async->flush_state != WT_ASYNC_FLUSH_COMPLETE) - WT_ERR(__wt_cond_wait(NULL, async->flush_cond, 100000)); + __wt_cond_wait(session, async->flush_cond, 100000); /* * Flush is done. Clear the flags. */ async->flush_op.state = WT_ASYNCOP_FREE; WT_PUBLISH(async->flush_state, WT_ASYNC_FLUSH_NONE); -err: - return (ret); + return (0); } /* diff --git a/src/third_party/wiredtiger/src/async/async_op.c b/src/third_party/wiredtiger/src/async/async_op.c index 970c33c3360..2bdc9e4ec8e 100644 --- a/src/third_party/wiredtiger/src/async/async_op.c +++ b/src/third_party/wiredtiger/src/async/async_op.c @@ -205,7 +205,7 @@ __async_get_type(WT_ASYNC_OP *asyncop) * __async_op_init -- * Initialize all the op handle fields. */ -static int +static void __async_op_init(WT_CONNECTION_IMPL *conn, WT_ASYNC_OP_IMPL *op, uint32_t id) { WT_ASYNC_OP *asyncop; @@ -243,7 +243,6 @@ __async_op_init(WT_CONNECTION_IMPL *conn, WT_ASYNC_OP_IMPL *op, uint32_t id) op->internal_id = id; op->state = WT_ASYNCOP_FREE; - return (0); } /* @@ -330,7 +329,7 @@ __wt_async_op_init(WT_SESSION_IMPL *session) /* * Initialize the flush op structure. */ - WT_RET(__async_op_init(conn, &async->flush_op, OPS_INVALID_INDEX)); + __async_op_init(conn, &async->flush_op, OPS_INVALID_INDEX); /* * Allocate and initialize the work queue. This is sized so that @@ -346,7 +345,7 @@ __wt_async_op_init(WT_SESSION_IMPL *session) WT_ERR(__wt_calloc_def(session, conn->async_size, &async->async_ops)); for (i = 0; i < conn->async_size; i++) { op = &async->async_ops[i]; - WT_ERR(__async_op_init(conn, op, i)); + __async_op_init(conn, op, i); } return (0); diff --git a/src/third_party/wiredtiger/src/async/async_worker.c b/src/third_party/wiredtiger/src/async/async_worker.c index 90dac557e36..cf83d797738 100644 --- a/src/third_party/wiredtiger/src/async/async_worker.c +++ b/src/third_party/wiredtiger/src/async/async_worker.c @@ -102,13 +102,12 @@ retry: * __async_flush_wait -- * Wait for the final worker to finish flushing. */ -static int +static void __async_flush_wait(WT_SESSION_IMPL *session, WT_ASYNC *async, uint64_t my_gen) { while (async->flush_state == WT_ASYNC_FLUSHING && async->flush_gen == my_gen) - WT_RET(__wt_cond_wait(session, async->flush_cond, 10000)); - return (0); + __wt_cond_wait(session, async->flush_cond, 10000); } /* @@ -326,15 +325,13 @@ __wt_async_worker(void *arg) */ WT_PUBLISH(async->flush_state, WT_ASYNC_FLUSH_COMPLETE); - WT_ERR(__wt_cond_signal(session, - async->flush_cond)); + __wt_cond_signal(session, async->flush_cond); } else /* * We need to wait for the last worker to * signal the condition. */ - WT_ERR(__async_flush_wait( - session, async, flush_gen)); + __async_flush_wait(session, async, flush_gen); } } diff --git a/src/third_party/wiredtiger/src/block/block_addr.c b/src/third_party/wiredtiger/src/block/block_addr.c index d8cc1d627cf..dadd17de4a6 100644 --- a/src/third_party/wiredtiger/src/block/block_addr.c +++ b/src/third_party/wiredtiger/src/block/block_addr.c @@ -15,7 +15,7 @@ */ static int __block_buffer_to_addr(uint32_t allocsize, - const uint8_t **pp, wt_off_t *offsetp, uint32_t *sizep, uint32_t *cksump) + const uint8_t **pp, wt_off_t *offsetp, uint32_t *sizep, uint32_t *checksump) { uint64_t o, s, c; @@ -37,11 +37,11 @@ __block_buffer_to_addr(uint32_t allocsize, */ if (s == 0) { *offsetp = 0; - *sizep = *cksump = 0; + *sizep = *checksump = 0; } else { *offsetp = (wt_off_t)(o + 1) * allocsize; *sizep = (uint32_t)s * allocsize; - *cksump = (uint32_t)c; + *checksump = (uint32_t)c; } return (0); } @@ -52,7 +52,7 @@ __block_buffer_to_addr(uint32_t allocsize, */ int __wt_block_addr_to_buffer(WT_BLOCK *block, - uint8_t **pp, wt_off_t offset, uint32_t size, uint32_t cksum) + uint8_t **pp, wt_off_t offset, uint32_t size, uint32_t checksum) { uint64_t o, s, c; @@ -63,7 +63,7 @@ __wt_block_addr_to_buffer(WT_BLOCK *block, } else { o = (uint64_t)offset / block->allocsize - 1; s = size / block->allocsize; - c = cksum; + c = checksum; } WT_RET(__wt_vpack_uint(pp, 0, o)); WT_RET(__wt_vpack_uint(pp, 0, s)); @@ -78,10 +78,10 @@ __wt_block_addr_to_buffer(WT_BLOCK *block, */ int __wt_block_buffer_to_addr(WT_BLOCK *block, - const uint8_t *p, wt_off_t *offsetp, uint32_t *sizep, uint32_t *cksump) + const uint8_t *p, wt_off_t *offsetp, uint32_t *sizep, uint32_t *checksump) { return (__block_buffer_to_addr( - block->allocsize, &p, offsetp, sizep, cksump)); + block->allocsize, &p, offsetp, sizep, checksump)); } /* @@ -93,14 +93,15 @@ __wt_block_addr_invalid(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr, size_t addr_size, bool live) { wt_off_t offset; - uint32_t cksum, size; + uint32_t checksum, size; WT_UNUSED(session); WT_UNUSED(addr_size); WT_UNUSED(live); /* Crack the cookie. */ - WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &cksum)); + WT_RET( + __wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum)); #ifdef HAVE_DIAGNOSTIC /* @@ -124,17 +125,18 @@ __wt_block_addr_string(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, const uint8_t *addr, size_t addr_size) { wt_off_t offset; - uint32_t cksum, size; + uint32_t checksum, size; WT_UNUSED(addr_size); /* Crack the cookie. */ - WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &cksum)); + WT_RET( + __wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum)); /* Printable representation. */ WT_RET(__wt_buf_fmt(session, buf, "[%" PRIuMAX "-%" PRIuMAX ", %" PRIu32 ", %" PRIu32 "]", - (uintmax_t)offset, (uintmax_t)offset + size, size, cksum)); + (uintmax_t)offset, (uintmax_t)offset + size, size, checksum)); return (0); } @@ -156,13 +158,13 @@ __block_buffer_to_ckpt(WT_SESSION_IMPL *session, pp = &p; WT_RET(__block_buffer_to_addr(allocsize, pp, - &ci->root_offset, &ci->root_size, &ci->root_cksum)); + &ci->root_offset, &ci->root_size, &ci->root_checksum)); WT_RET(__block_buffer_to_addr(allocsize, pp, - &ci->alloc.offset, &ci->alloc.size, &ci->alloc.cksum)); + &ci->alloc.offset, &ci->alloc.size, &ci->alloc.checksum)); WT_RET(__block_buffer_to_addr(allocsize, pp, - &ci->avail.offset, &ci->avail.size, &ci->avail.cksum)); + &ci->avail.offset, &ci->avail.size, &ci->avail.checksum)); WT_RET(__block_buffer_to_addr(allocsize, pp, - &ci->discard.offset, &ci->discard.size, &ci->discard.cksum)); + &ci->discard.offset, &ci->discard.size, &ci->discard.checksum)); WT_RET(__wt_vunpack_uint(pp, 0, &a)); ci->file_size = (wt_off_t)a; WT_RET(__wt_vunpack_uint(pp, 0, &a)); @@ -214,13 +216,13 @@ __wt_block_ckpt_to_buffer(WT_SESSION_IMPL *session, (*pp)++; WT_RET(__wt_block_addr_to_buffer(block, pp, - ci->root_offset, ci->root_size, ci->root_cksum)); + ci->root_offset, ci->root_size, ci->root_checksum)); WT_RET(__wt_block_addr_to_buffer(block, pp, - ci->alloc.offset, ci->alloc.size, ci->alloc.cksum)); + ci->alloc.offset, ci->alloc.size, ci->alloc.checksum)); WT_RET(__wt_block_addr_to_buffer(block, pp, - ci->avail.offset, ci->avail.size, ci->avail.cksum)); + ci->avail.offset, ci->avail.size, ci->avail.checksum)); WT_RET(__wt_block_addr_to_buffer(block, pp, - ci->discard.offset, ci->discard.size, ci->discard.cksum)); + ci->discard.offset, ci->discard.size, ci->discard.checksum)); a = (uint64_t)ci->file_size; WT_RET(__wt_vpack_uint(pp, 0, a)); a = (uint64_t)ci->ckpt_size; diff --git a/src/third_party/wiredtiger/src/block/block_ckpt.c b/src/third_party/wiredtiger/src/block/block_ckpt.c index b9f0ec25d53..b7ac953cdb1 100644 --- a/src/third_party/wiredtiger/src/block/block_ckpt.c +++ b/src/third_party/wiredtiger/src/block/block_ckpt.c @@ -69,9 +69,9 @@ __wt_block_checkpoint_load(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ERR(__wt_scr_alloc(session, 0, &tmp)); WT_ERR(__ckpt_string(session, block, addr, tmp)); } - WT_ERR(__wt_verbose(session, WT_VERB_CHECKPOINT, + __wt_verbose(session, WT_VERB_CHECKPOINT, "%s: load-checkpoint: %s", block->name, - addr == NULL ? "[Empty]" : (const char *)tmp->data)); + addr == NULL ? "[Empty]" : (const char *)tmp->data); } #endif @@ -117,7 +117,7 @@ __wt_block_checkpoint_load(WT_SESSION_IMPL *session, WT_BLOCK *block, if (ci->root_offset != WT_BLOCK_INVALID_OFFSET) { endp = root_addr; WT_ERR(__wt_block_addr_to_buffer(block, &endp, - ci->root_offset, ci->root_size, ci->root_cksum)); + ci->root_offset, ci->root_size, ci->root_checksum)); *root_addr_sizep = WT_PTRDIFF(endp, root_addr); } @@ -137,18 +137,9 @@ __wt_block_checkpoint_load(WT_SESSION_IMPL *session, WT_BLOCK *block, * that was done when the checkpoint was first written (re-writing the * checkpoint might possibly make it relevant here, but it's unlikely * enough I don't bother). - * - * If in-memory, we don't read or write the object, and the truncate - * will unnecessarily allocate buffer space. */ - if (!checkpoint && !F_ISSET(S2C(session), WT_CONN_IN_MEMORY)) { - WT_ERR(__wt_verbose(session, WT_VERB_CHECKPOINT, - "truncate file to %" PRIuMAX, (uintmax_t)ci->file_size)); - - /* The truncate might fail, and that's OK. */ - WT_ERR_BUSY_OK( - __wt_block_truncate(session, block, ci->file_size)); - } + if (!checkpoint) + WT_ERR(__wt_block_truncate(session, block, ci->file_size)); if (0) { err: /* @@ -190,9 +181,7 @@ __wt_block_checkpoint_unload( * checkpoints. */ if (!checkpoint) { - /* The truncate might fail, and that's OK. */ - WT_TRET_BUSY_OK( - __wt_block_truncate(session, block, block->size)); + WT_TRET(__wt_block_truncate(session, block, block->size)); __wt_spin_lock(session, &block->live_lock); __wt_block_ckpt_destroy(session, &block->live); @@ -227,7 +216,7 @@ __wt_block_ckpt_destroy(WT_SESSION_IMPL *session, WT_BLOCK_CKPT *ci) */ int __wt_block_checkpoint(WT_SESSION_IMPL *session, - WT_BLOCK *block, WT_ITEM *buf, WT_CKPT *ckptbase, bool data_cksum) + WT_BLOCK *block, WT_ITEM *buf, WT_CKPT *ckptbase, bool data_checksum) { WT_BLOCK_CKPT *ci; WT_DECL_RET; @@ -248,11 +237,11 @@ __wt_block_checkpoint(WT_SESSION_IMPL *session, */ if (buf == NULL) { ci->root_offset = WT_BLOCK_INVALID_OFFSET; - ci->root_size = ci->root_cksum = 0; + ci->root_size = ci->root_checksum = 0; } else WT_ERR(__wt_block_write_off(session, block, buf, - &ci->root_offset, &ci->root_size, &ci->root_cksum, - data_cksum, false)); + &ci->root_offset, &ci->root_size, &ci->root_checksum, + data_checksum, true, false)); /* * Checkpoints are potentially reading/writing/merging lots of blocks, @@ -373,10 +362,10 @@ __ckpt_process(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_CKPT *ckptbase) WT_DECL_ITEM(tmp); WT_DECL_RET; uint64_t ckpt_size; - bool deleting, locked; + bool deleting, fatal, locked; ci = &block->live; - locked = false; + fatal = locked = false; #ifdef HAVE_DIAGNOSTIC WT_RET(__ckpt_verify(session, ckptbase)); @@ -402,23 +391,20 @@ __ckpt_process(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_CKPT *ckptbase) * This function is the first step, the second step is in the resolve * function. * - * If we're called to checkpoint the same file twice, without the second - * resolution step, it's an error at an upper level and our choices are - * all bad: either leak blocks or risk crashing with our caller not - * having saved the checkpoint information to stable storage. Leaked - * blocks are a safer choice, but that means file verify will fail for - * the rest of "forever", and the chance of us allocating a block and - * then crashing such that it matters is reasonably low: don't leak the - * blocks. + * If we're called to checkpoint the same file twice (without the second + * resolution step), or re-entered for any reason, it's an error in our + * caller, and our choices are all bad: leak blocks or potentially crash + * with our caller not yet having saved previous checkpoint information + * to stable storage. */ - if (block->ckpt_inprogress) { - __wt_errx(session, - "%s: checkpointed without first resolving the previous " - "checkpoint", - block->name); - - WT_RET(__wt_block_checkpoint_resolve(session, block)); - } + __wt_spin_lock(session, &block->live_lock); + if (block->ckpt_inprogress) + ret = __wt_block_panic(session, EINVAL, + "%s: unexpected checkpoint ordering", block->name); + else + block->ckpt_inprogress = true; + __wt_spin_unlock(session, &block->live_lock); + WT_RET(ret); /* * Extents newly available as a result of deleting previous checkpoints @@ -474,6 +460,15 @@ __ckpt_process(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_CKPT *ckptbase) WT_ERR(__ckpt_extlist_read(session, block, next_ckpt)); } + /* + * Failures are now fatal: we can't currently back out the merge of any + * deleted checkpoint extent lists into the live system's extent lists, + * so continuing after error would leave the live system's extent lists + * corrupted for any subsequent checkpoint (and potentially, should a + * subsequent checkpoint succeed, for recovery). + */ + fatal = true; + /* * Hold a lock so the live extent lists and the file size can't change * underneath us. I suspect we'll tighten this if checkpoints take too @@ -515,9 +510,9 @@ __ckpt_process(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_CKPT *ckptbase) WT_ERR(__wt_scr_alloc(session, 0, &tmp)); WT_ERR(__ckpt_string( session, block, ckpt->raw.data, tmp)); - WT_ERR(__wt_verbose(session, WT_VERB_CHECKPOINT, + __wt_verbose(session, WT_VERB_CHECKPOINT, "%s: delete-checkpoint: %s: %s", - block->name, ckpt->name, (const char *)tmp->data)); + block->name, ckpt->name, (const char *)tmp->data); } #endif /* @@ -664,9 +659,11 @@ live_update: "list"); #endif - block->ckpt_inprogress = true; +err: if (ret != 0 && fatal) + ret = __wt_block_panic(session, ret, + "%s: fatal checkpoint failure", block->name); -err: if (locked) + if (locked) __wt_spin_unlock(session, &block->live_lock); /* Discard any checkpoint information we loaded. */ @@ -753,9 +750,9 @@ __ckpt_update(WT_SESSION_IMPL *session, if (WT_VERBOSE_ISSET(session, WT_VERB_CHECKPOINT)) { WT_RET(__wt_scr_alloc(session, 0, &tmp)); WT_ERR(__ckpt_string(session, block, ckpt->raw.data, tmp)); - WT_ERR(__wt_verbose(session, WT_VERB_CHECKPOINT, + __wt_verbose(session, WT_VERB_CHECKPOINT, "%s: create-checkpoint: %s: %s", - block->name, ckpt->name, (const char *)tmp->data)); + block->name, ckpt->name, (const char *)tmp->data); } err: __wt_scr_free(session, &tmp); @@ -778,15 +775,16 @@ __wt_block_checkpoint_resolve(WT_SESSION_IMPL *session, WT_BLOCK *block) * Resolve the checkpoint after our caller has written the checkpoint * information to stable storage. */ - if (!block->ckpt_inprogress) - WT_RET_MSG(session, WT_ERROR, - "%s: checkpoint resolved, but no checkpoint in progress", - block->name); - block->ckpt_inprogress = false; - __wt_spin_lock(session, &block->live_lock); - ret = __wt_block_extlist_merge( - session, block, &ci->ckpt_avail, &ci->avail); + if (!block->ckpt_inprogress) + WT_ERR(__wt_block_panic(session, WT_ERROR, + "%s: checkpoint resolution with no checkpoint in progress", + block->name)); + + if ((ret = __wt_block_extlist_merge( + session, block, &ci->ckpt_avail, &ci->avail)) != 0) + WT_ERR(__wt_block_panic(session, ret, + "%s: fatal checkpoint failure", block->name)); __wt_spin_unlock(session, &block->live_lock); /* Discard the lists remaining after the checkpoint call. */ @@ -794,6 +792,10 @@ __wt_block_checkpoint_resolve(WT_SESSION_IMPL *session, WT_BLOCK *block) __wt_block_extlist_free(session, &ci->ckpt_alloc); __wt_block_extlist_free(session, &ci->ckpt_discard); + __wt_spin_lock(session, &block->live_lock); + block->ckpt_inprogress = 0; +err: __wt_spin_unlock(session, &block->live_lock); + return (ret); } @@ -822,7 +824,7 @@ __ckpt_string(WT_SESSION_IMPL *session, PRIuMAX "-%" PRIuMAX ", %" PRIu32 ", %" PRIu32 "]", (uintmax_t)ci->root_offset, (uintmax_t)(ci->root_offset + ci->root_size), - ci->root_size, ci->root_cksum)); + ci->root_size, ci->root_checksum)); if (ci->alloc.offset == WT_BLOCK_INVALID_OFFSET) WT_RET(__wt_buf_catfmt(session, buf, ", alloc=[Empty]")); else @@ -831,7 +833,7 @@ __ckpt_string(WT_SESSION_IMPL *session, PRIuMAX "-%" PRIuMAX ", %" PRIu32 ", %" PRIu32 "]", (uintmax_t)ci->alloc.offset, (uintmax_t)(ci->alloc.offset + ci->alloc.size), - ci->alloc.size, ci->alloc.cksum)); + ci->alloc.size, ci->alloc.checksum)); if (ci->avail.offset == WT_BLOCK_INVALID_OFFSET) WT_RET(__wt_buf_catfmt(session, buf, ", avail=[Empty]")); else @@ -840,7 +842,7 @@ __ckpt_string(WT_SESSION_IMPL *session, PRIuMAX "-%" PRIuMAX ", %" PRIu32 ", %" PRIu32 "]", (uintmax_t)ci->avail.offset, (uintmax_t)(ci->avail.offset + ci->avail.size), - ci->avail.size, ci->avail.cksum)); + ci->avail.size, ci->avail.checksum)); if (ci->discard.offset == WT_BLOCK_INVALID_OFFSET) WT_RET(__wt_buf_catfmt(session, buf, ", discard=[Empty]")); else @@ -849,7 +851,7 @@ __ckpt_string(WT_SESSION_IMPL *session, PRIuMAX "-%" PRIuMAX ", %" PRIu32 ", %" PRIu32 "]", (uintmax_t)ci->discard.offset, (uintmax_t)(ci->discard.offset + ci->discard.size), - ci->discard.size, ci->discard.cksum)); + ci->discard.size, ci->discard.checksum)); WT_RET(__wt_buf_catfmt(session, buf, ", file size=%" PRIuMAX, (uintmax_t)ci->file_size)); diff --git a/src/third_party/wiredtiger/src/block/block_compact.c b/src/third_party/wiredtiger/src/block/block_compact.c index 02862ea842f..6d5d48bdb22 100644 --- a/src/third_party/wiredtiger/src/block/block_compact.c +++ b/src/third_party/wiredtiger/src/block/block_compact.c @@ -8,7 +8,7 @@ #include "wt_internal.h" -static int __block_dump_avail(WT_SESSION_IMPL *, WT_BLOCK *, bool); +static void __block_dump_avail(WT_SESSION_IMPL *, WT_BLOCK *, bool); /* * __wt_block_compact_start -- @@ -32,8 +32,6 @@ __wt_block_compact_start(WT_SESSION_IMPL *session, WT_BLOCK *block) int __wt_block_compact_end(WT_SESSION_IMPL *session, WT_BLOCK *block) { - WT_DECL_RET; - WT_UNUSED(session); /* Restore the original allocation plan. */ @@ -43,12 +41,11 @@ __wt_block_compact_end(WT_SESSION_IMPL *session, WT_BLOCK *block) /* Dump the results of the compaction pass. */ if (WT_VERBOSE_ISSET(session, WT_VERB_COMPACT)) { __wt_spin_lock(session, &block->live_lock); - ret = __block_dump_avail(session, block, false); + __block_dump_avail(session, block, false); __wt_spin_unlock(session, &block->live_lock); } #endif - - return (ret); + return (0); } /* @@ -88,7 +85,7 @@ __wt_block_compact_skip(WT_SESSION_IMPL *session, WT_BLOCK *block, bool *skipp) /* Dump the current state of the file. */ if (WT_VERBOSE_ISSET(session, WT_VERB_COMPACT)) - WT_ERR(__block_dump_avail(session, block, true)); + __block_dump_avail(session, block, true); /* Sum the available bytes in the initial 80% and 90% of the file. */ avail_eighty = avail_ninety = 0; @@ -125,25 +122,25 @@ __wt_block_compact_skip(WT_SESSION_IMPL *session, WT_BLOCK *block, bool *skipp) block->compact_pct_tenths = 1; } - WT_ERR(__wt_verbose(session, WT_VERB_COMPACT, + __wt_verbose(session, WT_VERB_COMPACT, "%s: %" PRIuMAX "MB (%" PRIuMAX ") available space in the first " "80%% of the file", block->name, - (uintmax_t)avail_eighty / WT_MEGABYTE, (uintmax_t)avail_eighty)); - WT_ERR(__wt_verbose(session, WT_VERB_COMPACT, + (uintmax_t)avail_eighty / WT_MEGABYTE, (uintmax_t)avail_eighty); + __wt_verbose(session, WT_VERB_COMPACT, "%s: %" PRIuMAX "MB (%" PRIuMAX ") available space in the first " "90%% of the file", block->name, - (uintmax_t)avail_ninety / WT_MEGABYTE, (uintmax_t)avail_ninety)); - WT_ERR(__wt_verbose(session, WT_VERB_COMPACT, + (uintmax_t)avail_ninety / WT_MEGABYTE, (uintmax_t)avail_ninety); + __wt_verbose(session, WT_VERB_COMPACT, "%s: require 10%% or %" PRIuMAX "MB (%" PRIuMAX ") in the first " "90%% of the file to perform compaction, compaction %s", block->name, (uintmax_t)(block->size / 10) / WT_MEGABYTE, (uintmax_t)block->size / 10, - *skipp ? "skipped" : "proceeding")); + *skipp ? "skipped" : "proceeding"); -err: __wt_spin_unlock(session, &block->live_lock); + __wt_spin_unlock(session, &block->live_lock); return (ret); } @@ -160,13 +157,14 @@ __wt_block_compact_page_skip(WT_SESSION_IMPL *session, WT_EXT *ext; WT_EXTLIST *el; wt_off_t limit, offset; - uint32_t size, cksum; + uint32_t size, checksum; WT_UNUSED(addr_size); *skipp = true; /* Return a default skip. */ /* Crack the cookie. */ - WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &cksum)); + WT_RET( + __wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum)); /* * If this block is in the chosen percentage of the file and there's a @@ -207,7 +205,7 @@ __wt_block_compact_page_skip(WT_SESSION_IMPL *session, * __block_dump_avail -- * Dump out the avail list so we can see what compaction will look like. */ -static int +static void __block_dump_avail(WT_SESSION_IMPL *session, WT_BLOCK *block, bool start) { WT_EXTLIST *el; @@ -218,29 +216,28 @@ __block_dump_avail(WT_SESSION_IMPL *session, WT_BLOCK *block, bool start) el = &block->live.avail; size = block->size; - WT_RET(__wt_verbose(session, WT_VERB_COMPACT, + __wt_verbose(session, WT_VERB_COMPACT, "============ %s", - start ? "testing for compaction" : "ending compaction pass")); + start ? "testing for compaction" : "ending compaction pass"); if (!start) { - WT_RET(__wt_verbose(session, WT_VERB_COMPACT, - "pages reviewed: %" PRIuMAX, - block->compact_pages_reviewed)); - WT_RET(__wt_verbose(session, WT_VERB_COMPACT, - "pages skipped: %" PRIuMAX, block->compact_pages_skipped)); - WT_RET(__wt_verbose(session, WT_VERB_COMPACT, - "pages written: %" PRIuMAX, block->compact_pages_written)); + __wt_verbose(session, WT_VERB_COMPACT, + "pages reviewed: %" PRIu64, block->compact_pages_reviewed); + __wt_verbose(session, WT_VERB_COMPACT, + "pages skipped: %" PRIu64, block->compact_pages_skipped); + __wt_verbose(session, WT_VERB_COMPACT, + "pages written: %" PRIu64, block->compact_pages_written); } - WT_RET(__wt_verbose(session, WT_VERB_COMPACT, + __wt_verbose(session, WT_VERB_COMPACT, "file size %" PRIuMAX "MB (%" PRIuMAX ") with %" PRIuMAX "%% space available %" PRIuMAX "MB (%" PRIuMAX ")", (uintmax_t)size / WT_MEGABYTE, (uintmax_t)size, ((uintmax_t)el->bytes * 100) / (uintmax_t)size, - (uintmax_t)el->bytes / WT_MEGABYTE, (uintmax_t)el->bytes)); + (uintmax_t)el->bytes / WT_MEGABYTE, (uintmax_t)el->bytes); if (el->entries == 0) - return (0); + return; /* * Bucket the available memory into file deciles/percentiles. Large @@ -262,21 +259,19 @@ __block_dump_avail(WT_SESSION_IMPL *session, WT_BLOCK *block, bool start) */ for (i = 0; i < WT_ELEMENTS(percentile); ++i) { v = percentile[i] * 512; - WT_RET(__wt_verbose(session, WT_VERB_COMPACT, + __wt_verbose(session, WT_VERB_COMPACT, "%2u%%: %12" PRIuMAX "MB, (%" PRIuMAX "B, %" PRIuMAX "%%)", i, (uintmax_t)v / WT_MEGABYTE, (uintmax_t)v, - (uintmax_t)((v * 100) / (wt_off_t)el->bytes))); + (uintmax_t)((v * 100) / (wt_off_t)el->bytes)); } #endif for (i = 0; i < WT_ELEMENTS(decile); ++i) { v = decile[i] * 512; - WT_RET(__wt_verbose(session, WT_VERB_COMPACT, + __wt_verbose(session, WT_VERB_COMPACT, "%2u%%: %12" PRIuMAX "MB, (%" PRIuMAX "B, %" PRIuMAX "%%)", i * 10, (uintmax_t)v / WT_MEGABYTE, (uintmax_t)v, - (uintmax_t)((v * 100) / (wt_off_t)el->bytes))); + (uintmax_t)((v * 100) / (wt_off_t)el->bytes)); } - - return (0); } diff --git a/src/third_party/wiredtiger/src/block/block_ext.c b/src/third_party/wiredtiger/src/block/block_ext.c index 0d3e7b54f17..8a4d2b08bef 100644 --- a/src/third_party/wiredtiger/src/block/block_ext.c +++ b/src/third_party/wiredtiger/src/block/block_ext.c @@ -486,9 +486,9 @@ __block_extend( block->size += size; WT_STAT_FAST_DATA_INCR(session, block_extension); - WT_RET(__wt_verbose(session, WT_VERB_BLOCK, + __wt_verbose(session, WT_VERB_BLOCK, "file extend %" PRIdMAX "B @ %" PRIdMAX, - (intmax_t)size, (intmax_t)*offp)); + (intmax_t)size, (intmax_t)*offp); return (0); } @@ -552,21 +552,21 @@ append: WT_RET(__block_extend(session, block, offp, size)); /* If doing a partial allocation, adjust the record and put it back. */ if (ext->size > size) { - WT_RET(__wt_verbose(session, WT_VERB_BLOCK, + __wt_verbose(session, WT_VERB_BLOCK, "allocate %" PRIdMAX " from range %" PRIdMAX "-%" PRIdMAX ", range shrinks to %" PRIdMAX "-%" PRIdMAX, (intmax_t)size, (intmax_t)ext->off, (intmax_t)(ext->off + ext->size), (intmax_t)(ext->off + size), - (intmax_t)(ext->off + size + ext->size - size))); + (intmax_t)(ext->off + size + ext->size - size)); ext->off += size; ext->size -= size; WT_RET(__block_ext_insert(session, &block->live.avail, ext)); } else { - WT_RET(__wt_verbose(session, WT_VERB_BLOCK, + __wt_verbose(session, WT_VERB_BLOCK, "allocate range %" PRIdMAX "-%" PRIdMAX, - (intmax_t)ext->off, (intmax_t)(ext->off + ext->size))); + (intmax_t)ext->off, (intmax_t)(ext->off + ext->size)); __wt_block_ext_free(session, ext); } @@ -587,16 +587,17 @@ __wt_block_free(WT_SESSION_IMPL *session, { WT_DECL_RET; wt_off_t offset; - uint32_t cksum, size; + uint32_t checksum, size; WT_UNUSED(addr_size); WT_STAT_FAST_DATA_INCR(session, block_free); /* Crack the cookie. */ - WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &cksum)); + WT_RET( + __wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum)); - WT_RET(__wt_verbose(session, WT_VERB_BLOCK, - "free %" PRIdMAX "/%" PRIdMAX, (intmax_t)offset, (intmax_t)size)); + __wt_verbose(session, WT_VERB_BLOCK, + "free %" PRIdMAX "/%" PRIdMAX, (intmax_t)offset, (intmax_t)size); #ifdef HAVE_DIAGNOSTIC WT_RET( @@ -922,8 +923,8 @@ __wt_block_extlist_merge(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_EXTLIST tmp; u_int i; - WT_RET(__wt_verbose( - session, WT_VERB_BLOCK, "merging %s into %s", a->name, b->name)); + __wt_verbose( + session, WT_VERB_BLOCK, "merging %s into %s", a->name, b->name); /* * Sometimes the list we are merging is much bigger than the other: if @@ -1063,9 +1064,9 @@ __block_merge(WT_SESSION_IMPL *session, WT_BLOCK *block, after = NULL; } if (before == NULL && after == NULL) { - WT_RET(__wt_verbose(session, WT_VERB_BLOCK, + __wt_verbose(session, WT_VERB_BLOCK, "%s: insert range %" PRIdMAX "-%" PRIdMAX, - el->name, (intmax_t)off, (intmax_t)(off + size))); + el->name, (intmax_t)off, (intmax_t)(off + size)); return (__block_off_insert(session, el, off, size)); } @@ -1081,12 +1082,12 @@ __block_merge(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_RET(__block_off_remove( session, block, el, after->off, &ext)); - WT_RET(__wt_verbose(session, WT_VERB_BLOCK, + __wt_verbose(session, WT_VERB_BLOCK, "%s: range grows from %" PRIdMAX "-%" PRIdMAX ", to %" PRIdMAX "-%" PRIdMAX, el->name, (intmax_t)ext->off, (intmax_t)(ext->off + ext->size), - (intmax_t)off, (intmax_t)(off + ext->size + size))); + (intmax_t)off, (intmax_t)(off + ext->size + size)); ext->off = off; ext->size += size; @@ -1099,13 +1100,13 @@ __block_merge(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_RET(__block_off_remove( session, block, el, before->off, &ext)); - WT_RET(__wt_verbose(session, WT_VERB_BLOCK, + __wt_verbose(session, WT_VERB_BLOCK, "%s: range grows from %" PRIdMAX "-%" PRIdMAX ", to %" PRIdMAX "-%" PRIdMAX, el->name, (intmax_t)ext->off, (intmax_t)(ext->off + ext->size), (intmax_t)ext->off, - (intmax_t)(ext->off + ext->size + size))); + (intmax_t)(ext->off + ext->size + size)); ext->size += size; } @@ -1174,7 +1175,7 @@ __wt_block_extlist_read(WT_SESSION_IMPL *session, WT_RET(__wt_scr_alloc(session, el->size, &tmp)); WT_ERR(__wt_block_read_off( - session, block, tmp, el->offset, el->size, el->cksum)); + session, block, tmp, el->offset, el->size, el->checksum)); #define WT_EXTLIST_READ(p, v) do { \ uint64_t _v; \ @@ -1245,8 +1246,7 @@ __wt_block_extlist_write(WT_SESSION_IMPL *session, WT_DECL_RET; WT_EXT *ext; WT_PAGE_HEADER *dsk; - size_t size; - uint32_t entries; + size_t entries, size; uint8_t *p; WT_RET(__block_extlist_dump(session, block, el, "write")); @@ -1258,7 +1258,7 @@ __wt_block_extlist_write(WT_SESSION_IMPL *session, entries = el->entries + (additional == NULL ? 0 : additional->entries); if (entries == 0) { el->offset = WT_BLOCK_INVALID_OFFSET; - el->cksum = el->size = 0; + el->checksum = el->size = 0; return (0); } @@ -1310,8 +1310,8 @@ __wt_block_extlist_write(WT_SESSION_IMPL *session, #endif /* Write the extent list to disk. */ - WT_ERR(__wt_block_write_off(session, - block, tmp, &el->offset, &el->size, &el->cksum, true, true)); + WT_ERR(__wt_block_write_off(session, block, + tmp, &el->offset, &el->size, &el->checksum, true, true, true)); /* * Remove the allocated blocks from the system's allocation list, extent @@ -1320,9 +1320,9 @@ __wt_block_extlist_write(WT_SESSION_IMPL *session, WT_TRET(__wt_block_off_remove_overlap( session, block, &block->live.alloc, el->offset, el->size)); - WT_ERR(__wt_verbose(session, WT_VERB_BLOCK, + __wt_verbose(session, WT_VERB_BLOCK, "%s written %" PRIdMAX "/%" PRIu32, - el->name, (intmax_t)el->offset, el->size)); + el->name, (intmax_t)el->offset, el->size); err: __wt_scr_free(session, &tmp); return (ret); @@ -1337,7 +1337,7 @@ __wt_block_extlist_truncate( WT_SESSION_IMPL *session, WT_BLOCK *block, WT_EXTLIST *el) { WT_EXT *ext, **astack[WT_SKIP_MAXDEPTH]; - wt_off_t orig, size; + wt_off_t size; /* * Check if the last available extent is at the end of the file, and if @@ -1354,21 +1354,11 @@ __wt_block_extlist_truncate( * the cached file size, and that can't happen until after the extent * list removal succeeds.) */ - orig = block->size; size = ext->off; WT_RET(__block_off_remove(session, block, el, size, NULL)); - block->size = size; - /* - * Truncate the file. The truncate might fail, and that's OK, we simply - * ignore those blocks. - */ - WT_RET(__wt_verbose(session, WT_VERB_BLOCK, - "truncate file from %" PRIdMAX " to %" PRIdMAX, - (intmax_t)orig, (intmax_t)size)); - WT_RET_BUSY_OK(__wt_block_truncate(session, block, size)); - - return (0); + /* Truncate the file. */ + return (__wt_block_truncate(session, block, size)); } /* @@ -1445,12 +1435,12 @@ __block_extlist_dump( tag, el->name, el->entries, __wt_buf_set_size(session, el->bytes, true, t1))); else - WT_ERR(__wt_verbose(session, WT_VERB_BLOCK, + __wt_verbose(session, WT_VERB_BLOCK, "%s extent list %s, %" PRIu32 " entries, %s bytes", tag, el->name, el->entries, - __wt_buf_set_size(session, el->bytes, true, t1))); + __wt_buf_set_size(session, el->bytes, true, t1)); - if (ret != 0 || el->entries == 0) + if (el->entries == 0) goto done; memset(sizes, 0, sizeof(sizes)); @@ -1476,8 +1466,7 @@ __block_extlist_dump( if (block->verify_layout) WT_ERR(__wt_msg(session, "%s", (char *)t1->data)); else - WT_ERR(__wt_verbose( - session, WT_VERB_BLOCK, "%s", (char *)t1->data)); + __wt_verbose(session, WT_VERB_BLOCK, "%s", (char *)t1->data); done: err: __wt_scr_free(session, &t1); diff --git a/src/third_party/wiredtiger/src/block/block_map.c b/src/third_party/wiredtiger/src/block/block_map.c index d2c70fb4c49..b7afa61cc55 100644 --- a/src/third_party/wiredtiger/src/block/block_map.c +++ b/src/third_party/wiredtiger/src/block/block_map.c @@ -56,7 +56,7 @@ __wt_block_map(WT_SESSION_IMPL *session, WT_BLOCK *block, */ ret = handle->fh_map(handle, (WT_SESSION *)session, mapped_regionp, lengthp, mapped_cookiep); - if (ret == ENOTSUP) { + if (ret == EBUSY || ret == ENOTSUP) { *(void **)mapped_regionp = NULL; ret = 0; } diff --git a/src/third_party/wiredtiger/src/block/block_mgr.c b/src/third_party/wiredtiger/src/block/block_mgr.c index 971fe713f83..653ae3dbb6b 100644 --- a/src/third_party/wiredtiger/src/block/block_mgr.c +++ b/src/third_party/wiredtiger/src/block/block_mgr.c @@ -61,11 +61,11 @@ __bm_block_header(WT_BM *bm) * Write a buffer into a block, creating a checkpoint. */ static int -__bm_checkpoint(WT_BM *bm, - WT_SESSION_IMPL *session, WT_ITEM *buf, WT_CKPT *ckptbase, bool data_cksum) +__bm_checkpoint(WT_BM *bm, WT_SESSION_IMPL *session, + WT_ITEM *buf, WT_CKPT *ckptbase, bool data_checksum) { return (__wt_block_checkpoint( - session, bm->block, buf, ckptbase, data_cksum)); + session, bm->block, buf, ckptbase, data_checksum)); } /* @@ -73,12 +73,12 @@ __bm_checkpoint(WT_BM *bm, * Write a buffer into a block, creating a checkpoint; readonly version. */ static int -__bm_checkpoint_readonly(WT_BM *bm, - WT_SESSION_IMPL *session, WT_ITEM *buf, WT_CKPT *ckptbase, bool data_cksum) +__bm_checkpoint_readonly(WT_BM *bm, WT_SESSION_IMPL *session, + WT_ITEM *buf, WT_CKPT *ckptbase, bool data_checksum) { WT_UNUSED(buf); WT_UNUSED(ckptbase); - WT_UNUSED(data_cksum); + WT_UNUSED(data_checksum); return (__bm_readonly(bm, session)); } @@ -479,11 +479,11 @@ __bm_verify_start(WT_BM *bm, * Write a buffer into a block, returning the block's address cookie. */ static int -__bm_write(WT_BM *bm, WT_SESSION_IMPL *session, - WT_ITEM *buf, uint8_t *addr, size_t *addr_sizep, bool data_cksum) +__bm_write(WT_BM *bm, WT_SESSION_IMPL *session, WT_ITEM *buf, + uint8_t *addr, size_t *addr_sizep, bool data_checksum, bool checkpoint_io) { - return (__wt_block_write( - session, bm->block, buf, addr, addr_sizep, data_cksum)); + return (__wt_block_write(session, + bm->block, buf, addr, addr_sizep, data_checksum, checkpoint_io)); } /* @@ -492,13 +492,14 @@ __bm_write(WT_BM *bm, WT_SESSION_IMPL *session, * readonly version. */ static int -__bm_write_readonly(WT_BM *bm, WT_SESSION_IMPL *session, - WT_ITEM *buf, uint8_t *addr, size_t *addr_sizep, bool data_cksum) +__bm_write_readonly(WT_BM *bm, WT_SESSION_IMPL *session, WT_ITEM *buf, + uint8_t *addr, size_t *addr_sizep, bool data_checksum, bool checkpoint_io) { WT_UNUSED(buf); WT_UNUSED(addr); WT_UNUSED(addr_sizep); - WT_UNUSED(data_cksum); + WT_UNUSED(data_checksum); + WT_UNUSED(checkpoint_io); return (__bm_readonly(bm, session)); } @@ -606,3 +607,28 @@ __wt_block_manager_open(WT_SESSION_IMPL *session, err: WT_TRET(bm->close(bm, session)); return (ret); } + +/* + * __wt_block_panic -- + * Report an error, then panic the handle and the system. + */ +int +__wt_block_panic(WT_SESSION_IMPL *session, int error, const char *fmt, ...) + WT_GCC_FUNC_ATTRIBUTE((cold)) + WT_GCC_FUNC_ATTRIBUTE((format (printf, 3, 4))) +{ + va_list ap; + + /* + * Ignore error returns from underlying event handlers, we already have + * an error value to return. + */ + va_start(ap, fmt); + WT_IGNORE_RET(__wt_eventv(session, false, error, NULL, 0, fmt, ap)); + va_end(ap); + + /* Switch the handle into read-only mode. */ + __bm_method_set(S2BT(session)->bm, true); + + return (__wt_panic(session)); +} diff --git a/src/third_party/wiredtiger/src/block/block_open.c b/src/third_party/wiredtiger/src/block/block_open.c index 7cff7eab629..e369d013437 100644 --- a/src/third_party/wiredtiger/src/block/block_open.c +++ b/src/third_party/wiredtiger/src/block/block_open.c @@ -150,7 +150,7 @@ __wt_block_open(WT_SESSION_IMPL *session, uint64_t bucket, hash; uint32_t flags; - WT_RET(__wt_verbose(session, WT_VERB_BLOCK, "open: %s", filename)); + __wt_verbose(session, WT_VERB_BLOCK, "open: %s", filename); conn = S2C(session); *blockp = block = NULL; @@ -248,14 +248,14 @@ __wt_block_close(WT_SESSION_IMPL *session, WT_BLOCK *block) conn = S2C(session); - WT_TRET(__wt_verbose(session, WT_VERB_BLOCK, - "close: %s", block->name == NULL ? "" : block->name )); + __wt_verbose(session, WT_VERB_BLOCK, + "close: %s", block->name == NULL ? "" : block->name ); __wt_spin_lock(session, &conn->block_lock); /* Reference count is initialized to 1. */ if (block->ref == 0 || --block->ref == 0) - WT_TRET(__block_destroy(session, block)); + ret = __block_destroy(session, block); __wt_spin_unlock(session, &conn->block_lock); @@ -290,11 +290,11 @@ __wt_desc_write(WT_SESSION_IMPL *session, WT_FH *fh, uint32_t allocsize) desc->magic = WT_BLOCK_MAGIC; desc->majorv = WT_BLOCK_MAJOR_VERSION; desc->minorv = WT_BLOCK_MINOR_VERSION; - desc->cksum = 0; + desc->checksum = 0; __wt_block_desc_byteswap(desc); - desc->cksum = __wt_cksum(desc, allocsize); + desc->checksum = __wt_checksum(desc, allocsize); #ifdef WORDS_BIGENDIAN - desc->cksum = __wt_bswap32(desc->cksum); + desc->checksum = __wt_bswap32(desc->checksum); #endif ret = __wt_write(session, fh, (wt_off_t)0, (size_t)allocsize, desc); @@ -312,7 +312,7 @@ __desc_read(WT_SESSION_IMPL *session, WT_BLOCK *block) WT_BLOCK_DESC *desc; WT_DECL_ITEM(buf); WT_DECL_RET; - uint32_t cksum_calculate, cksum_tmp; + uint32_t checksum_calculate, checksum_tmp; /* If in-memory, we don't read or write the descriptor structure. */ if (F_ISSET(S2C(session), WT_CONN_IN_MEMORY)) @@ -333,10 +333,10 @@ __desc_read(WT_SESSION_IMPL *session, WT_BLOCK *block) * a calculated checksum that should match the checksum in the header. */ desc = buf->mem; - cksum_tmp = desc->cksum; - desc->cksum = 0; - cksum_calculate = __wt_cksum(desc, block->allocsize); - desc->cksum = cksum_tmp; + checksum_tmp = desc->checksum; + desc->checksum = 0; + checksum_calculate = __wt_checksum(desc, block->allocsize); + desc->checksum = checksum_tmp; __wt_block_desc_byteswap(desc); /* @@ -348,7 +348,8 @@ __desc_read(WT_SESSION_IMPL *session, WT_BLOCK *block) * may have entered the wrong file name, and is now frantically pounding * their interrupt key. */ - if (desc->magic != WT_BLOCK_MAGIC || desc->cksum != cksum_calculate) + if (desc->magic != WT_BLOCK_MAGIC || + desc->checksum != checksum_calculate) WT_ERR_MSG(session, WT_ERROR, "%s does not appear to be a WiredTiger file", block->name); @@ -362,13 +363,13 @@ __desc_read(WT_SESSION_IMPL *session, WT_BLOCK *block) WT_BLOCK_MAJOR_VERSION, WT_BLOCK_MINOR_VERSION, desc->majorv, desc->minorv); - WT_ERR(__wt_verbose(session, WT_VERB_BLOCK, + __wt_verbose(session, WT_VERB_BLOCK, "%s: magic %" PRIu32 ", major/minor: %" PRIu32 "/%" PRIu32 ", checksum %#" PRIx32, block->name, desc->magic, desc->majorv, desc->minorv, - desc->cksum)); + desc->checksum); err: __wt_scr_free(session, &buf); return (ret); diff --git a/src/third_party/wiredtiger/src/block/block_read.c b/src/third_party/wiredtiger/src/block/block_read.c index 97157e4a0f1..c6005b1f60a 100644 --- a/src/third_party/wiredtiger/src/block/block_read.c +++ b/src/third_party/wiredtiger/src/block/block_read.c @@ -21,7 +21,7 @@ __wt_bm_preload( WT_DECL_RET; WT_FILE_HANDLE *handle; wt_off_t offset; - uint32_t cksum, size; + uint32_t checksum, size; bool mapped; WT_UNUSED(addr_size); @@ -31,7 +31,8 @@ __wt_bm_preload( WT_STAT_FAST_CONN_INCR(session, block_preload); /* Crack the cookie. */ - WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &cksum)); + WT_RET( + __wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum)); handle = block->fh->handle; mapped = bm->map != NULL && offset + size <= (wt_off_t)bm->maplen; @@ -64,14 +65,15 @@ __wt_bm_read(WT_BM *bm, WT_SESSION_IMPL *session, WT_DECL_RET; WT_FILE_HANDLE *handle; wt_off_t offset; - uint32_t cksum, size; + uint32_t checksum, size; bool mapped; WT_UNUSED(addr_size); block = bm->block; /* Crack the cookie. */ - WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &cksum)); + WT_RET( + __wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum)); /* * Map the block if it's possible. @@ -98,7 +100,8 @@ __wt_bm_read(WT_BM *bm, WT_SESSION_IMPL *session, session, block, "read", offset, size, bm->is_live)); #endif /* Read the block. */ - WT_RET(__wt_block_read_off(session, block, buf, offset, size, cksum)); + WT_RET( + __wt_block_read_off(session, block, buf, offset, size, checksum)); /* Optionally discard blocks from the system's buffer cache. */ WT_RET(__wt_block_discard(session, block, (size_t)size)); @@ -117,7 +120,7 @@ __wt_block_read_off_blind( WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_off_t offset) { WT_BLOCK_HEADER *blk; - uint32_t cksum, size; + uint32_t checksum, size; /* * Make sure the buffer is large enough for the header and read the @@ -134,13 +137,14 @@ __wt_block_read_off_blind( * and if the size isn't insane, read the rest of the block. */ size = blk->disk_size; - cksum = blk->cksum; + checksum = blk->checksum; if (__wt_block_offset_invalid(block, offset, size)) WT_RET_MSG(session, EINVAL, "block at offset %" PRIuMAX " cannot be a valid block, no " "read attempted", (uintmax_t)offset); - return (__wt_block_read_off(session, block, buf, offset, size, cksum)); + return ( + __wt_block_read_off(session, block, buf, offset, size, checksum)); } #endif @@ -150,15 +154,15 @@ __wt_block_read_off_blind( */ int __wt_block_read_off(WT_SESSION_IMPL *session, WT_BLOCK *block, - WT_ITEM *buf, wt_off_t offset, uint32_t size, uint32_t cksum) + WT_ITEM *buf, wt_off_t offset, uint32_t size, uint32_t checksum) { WT_BLOCK_HEADER *blk, swap; size_t bufsize; - uint32_t page_cksum; + uint32_t page_checksum; - WT_RET(__wt_verbose(session, WT_VERB_READ, - "off %" PRIuMAX ", size %" PRIu32 ", cksum %" PRIu32, - (uintmax_t)offset, size, cksum)); + __wt_verbose(session, WT_VERB_READ, + "off %" PRIuMAX ", size %" PRIu32 ", checksum %" PRIu32, + (uintmax_t)offset, size, checksum); WT_STAT_FAST_CONN_INCR(session, block_read); WT_STAT_FAST_CONN_INCRV(session, block_byte_read, size); @@ -189,12 +193,12 @@ __wt_block_read_off(WT_SESSION_IMPL *session, WT_BLOCK *block, */ blk = WT_BLOCK_HEADER_REF(buf->mem); __wt_block_header_byteswap_copy(blk, &swap); - if (swap.cksum == cksum) { - blk->cksum = 0; - page_cksum = __wt_cksum(buf->mem, + if (swap.checksum == checksum) { + blk->checksum = 0; + page_checksum = __wt_checksum(buf->mem, F_ISSET(&swap, WT_BLOCK_DATA_CKSUM) ? size : WT_BLOCK_COMPRESS_SKIP); - if (page_cksum == cksum) { + if (page_checksum == checksum) { /* * Swap the page-header as needed; this doesn't belong * here, but it's the best place to catch all callers. @@ -209,7 +213,7 @@ __wt_block_read_off(WT_SESSION_IMPL *session, WT_BLOCK *block, "offset %" PRIuMAX ": calculated block checksum " "of %" PRIu32 " doesn't match expected checksum " "of %" PRIu32, - size, (uintmax_t)offset, page_cksum, cksum); + size, (uintmax_t)offset, page_checksum, checksum); } else if (!F_ISSET(session, WT_SESSION_QUIET_CORRUPT_FILE)) __wt_errx(session, @@ -217,7 +221,7 @@ __wt_block_read_off(WT_SESSION_IMPL *session, WT_BLOCK *block, "offset %" PRIuMAX ": block header checksum " "of %" PRIu32 " doesn't match expected checksum " "of %" PRIu32, - size, (uintmax_t)offset, swap.cksum, cksum); + size, (uintmax_t)offset, swap.checksum, checksum); /* Panic if a checksum fails during an ordinary read. */ return (block->verify || diff --git a/src/third_party/wiredtiger/src/block/block_session.c b/src/third_party/wiredtiger/src/block/block_session.c index 268adb530cf..6223751effa 100644 --- a/src/third_party/wiredtiger/src/block/block_session.c +++ b/src/third_party/wiredtiger/src/block/block_session.c @@ -28,7 +28,7 @@ __block_ext_alloc(WT_SESSION_IMPL *session, WT_EXT **extp) { WT_EXT *ext; - u_int skipdepth; + size_t skipdepth; skipdepth = __wt_skip_choose_depth(session); WT_RET(__wt_calloc(session, 1, diff --git a/src/third_party/wiredtiger/src/block/block_slvg.c b/src/third_party/wiredtiger/src/block/block_slvg.c index 6be3fa73f70..5ba95bb598e 100644 --- a/src/third_party/wiredtiger/src/block/block_slvg.c +++ b/src/third_party/wiredtiger/src/block/block_slvg.c @@ -33,13 +33,10 @@ __wt_block_salvage_start(WT_SESSION_IMPL *session, WT_BLOCK *block) * Truncate the file to an allocation-size multiple of blocks (bytes * trailing the last block must be garbage, by definition). */ - if (block->size > allocsize) { + len = allocsize; + if (block->size > allocsize) len = (block->size / allocsize) * allocsize; - if (len != block->size) - WT_RET(__wt_block_truncate(session, block, len)); - } else - len = allocsize; - block->live.file_size = len; + WT_RET(__wt_block_truncate(session, block, len)); /* * The file's first allocation-sized block is description information, @@ -101,7 +98,7 @@ __wt_block_salvage_next(WT_SESSION_IMPL *session, WT_DECL_RET; WT_FH *fh; wt_off_t max, offset; - uint32_t allocsize, cksum, size; + uint32_t allocsize, checksum, size; uint8_t *endp; *eofp = 0; @@ -128,7 +125,7 @@ __wt_block_salvage_next(WT_SESSION_IMPL *session, blk = WT_BLOCK_HEADER_REF(tmp->mem); __wt_block_header_byteswap(blk); size = blk->disk_size; - cksum = blk->cksum; + checksum = blk->checksum; /* * Check the block size: if it's not insane, read the block. @@ -138,13 +135,13 @@ __wt_block_salvage_next(WT_SESSION_IMPL *session, */ if (!__wt_block_offset_invalid(block, offset, size) && __wt_block_read_off( - session, block, tmp, offset, size, cksum) == 0) + session, block, tmp, offset, size, checksum) == 0) break; /* Free the allocation-size block. */ - WT_ERR(__wt_verbose(session, WT_VERB_SALVAGE, + __wt_verbose(session, WT_VERB_SALVAGE, "skipping %" PRIu32 "B at file offset %" PRIuMAX, - allocsize, (uintmax_t)offset)); + allocsize, (uintmax_t)offset); WT_ERR(__wt_block_off_free( session, block, offset, (wt_off_t)allocsize)); block->slvg_off += allocsize; @@ -152,7 +149,7 @@ __wt_block_salvage_next(WT_SESSION_IMPL *session, /* Re-create the address cookie that should reference this block. */ endp = addr; - WT_ERR(__wt_block_addr_to_buffer(block, &endp, offset, size, cksum)); + WT_ERR(__wt_block_addr_to_buffer(block, &endp, offset, size, checksum)); *addr_sizep = WT_PTRDIFF(endp, addr); done: @@ -169,7 +166,7 @@ __wt_block_salvage_valid(WT_SESSION_IMPL *session, WT_BLOCK *block, uint8_t *addr, size_t addr_size, bool valid) { wt_off_t offset; - uint32_t size, cksum; + uint32_t size, checksum; WT_UNUSED(session); WT_UNUSED(addr_size); @@ -179,7 +176,8 @@ __wt_block_salvage_valid(WT_SESSION_IMPL *session, * If the upper layer took the block, move past it; if the upper layer * rejected the block, move past an allocation size chunk and free it. */ - WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &cksum)); + WT_RET( + __wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum)); if (valid) block->slvg_off = offset + size; else { diff --git a/src/third_party/wiredtiger/src/block/block_vrfy.c b/src/third_party/wiredtiger/src/block/block_vrfy.c index af58864b9dc..58b62247044 100644 --- a/src/third_party/wiredtiger/src/block/block_vrfy.c +++ b/src/third_party/wiredtiger/src/block/block_vrfy.c @@ -344,12 +344,13 @@ __wt_block_verify_addr(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr, size_t addr_size) { wt_off_t offset; - uint32_t cksum, size; + uint32_t checksum, size; WT_UNUSED(addr_size); /* Crack the cookie. */ - WT_RET(__wt_block_buffer_to_addr(block, addr, &offset, &size, &cksum)); + WT_RET( + __wt_block_buffer_to_addr(block, addr, &offset, &size, &checksum)); /* Add to the per-file list. */ WT_RET( @@ -386,12 +387,12 @@ __verify_filefrag_add(WT_SESSION_IMPL *session, WT_BLOCK *block, { uint64_t f, frag, frags, i; - WT_RET(__wt_verbose(session, WT_VERB_VERIFY, + __wt_verbose(session, WT_VERB_VERIFY, "add file block%s%s%s at %" PRIuMAX "-%" PRIuMAX " (%" PRIuMAX ")", type == NULL ? "" : " (", type == NULL ? "" : type, type == NULL ? "" : ")", - (uintmax_t)offset, (uintmax_t)(offset + size), (uintmax_t)size)); + (uintmax_t)offset, (uintmax_t)(offset + size), (uintmax_t)size); /* Check each chunk against the total file size. */ if (offset + size > block->size) @@ -491,9 +492,9 @@ __verify_ckptfrag_add( { uint64_t f, frag, frags, i; - WT_RET(__wt_verbose(session, WT_VERB_VERIFY, + __wt_verbose(session, WT_VERB_VERIFY, "add checkpoint block at %" PRIuMAX "-%" PRIuMAX " (%" PRIuMAX ")", - (uintmax_t)offset, (uintmax_t)(offset + size), (uintmax_t)size)); + (uintmax_t)offset, (uintmax_t)(offset + size), (uintmax_t)size); /* * Check each chunk against the checkpoint's size, a checkpoint should diff --git a/src/third_party/wiredtiger/src/block/block_write.c b/src/third_party/wiredtiger/src/block/block_write.c index 1fefeee09da..032f72d551b 100644 --- a/src/third_party/wiredtiger/src/block/block_write.c +++ b/src/third_party/wiredtiger/src/block/block_write.c @@ -15,29 +15,47 @@ int __wt_block_truncate(WT_SESSION_IMPL *session, WT_BLOCK *block, wt_off_t len) { + WT_CONNECTION_IMPL *conn; + WT_DECL_RET; + + conn = S2C(session); + + __wt_verbose(session, + WT_VERB_BLOCK, "truncate file to %" PRIuMAX, (uintmax_t)len); + + /* + * Truncate requires serialization, we depend on our caller for that. + * + * Truncation isn't a requirement of the block manager, it's only used + * to conserve disk space. Regardless of the underlying file system + * call's result, the in-memory understanding of the file size changes. + */ + block->size = block->extend_size = len; + /* * Backups are done by copying files outside of WiredTiger, potentially * by system utilities. We cannot truncate the file during the backup * window, we might surprise an application. * - * Stop block truncation. This affects files that aren't involved in the - * backup (for example, doing incremental backups, which only copies log - * files, or targeted backups, stops all truncation). We may want a more - * targeted solution at some point. + * This affects files that aren't involved in the backup (for example, + * doing incremental backups, which only copies log files, or targeted + * backups, stops all block truncation unnecessarily). We may want a + * more targeted solution at some point. */ - if (S2C(session)->hot_backup) - return (EBUSY); + if (!conn->hot_backup) { + __wt_readlock(session, conn->hot_backup_lock); + if (!conn->hot_backup) + ret = __wt_ftruncate(session, block->fh, len); + __wt_readunlock(session, conn->hot_backup_lock); + } /* - * Additionally, the truncate might fail if there's a file mapping (if - * there's an open checkpoint on the file), in which case the underlying - * function returns EBUSY. + * The truncate may fail temporarily or permanently (for example, there + * may be a file mapping if there's an open checkpoint on the file on a + * POSIX system, in which case the underlying function returns EBUSY). + * It's OK, we don't have to be able to truncate files. */ - WT_RET(__wt_ftruncate(session, block->fh, len)); - - block->size = block->extend_size = len; - - return (0); + return (ret == EBUSY || ret == ENOTSUP ? 0 : ret); } /* @@ -82,22 +100,18 @@ __wt_block_extend(WT_SESSION_IMPL *session, WT_BLOCK *block, { WT_DECL_RET; WT_FILE_HANDLE *handle; - bool locked; /* * The locking in this function is messy: by definition, the live system * is locked when we're called, but that lock may have been acquired by * our caller or our caller's caller. If our caller's lock, release_lock - * comes in set, indicating this function can unlock it before returning - * (either before extending the file or afterward, depending on the call - * used). If it is our caller's caller, then release_lock comes in not - * set, indicating it cannot be released here. + * comes in set and this function can unlock it before returning (so it + * isn't held while extending the file). If it is our caller's caller, + * then release_lock comes in not set, indicating it cannot be released + * here. * - * If we unlock here, we clear release_lock. But if we then find out we - * need a lock after all, we re-acquire the lock and set release_lock so - * our caller knows to release it. + * If we unlock here, we clear release_lock. */ - locked = true; /* If not configured to extend the file, we're done. */ if (block->extend_len == 0) @@ -122,62 +136,39 @@ __wt_block_extend(WT_SESSION_IMPL *session, WT_BLOCK *block, * used to extend the file initialize the extended space. If a writing * thread races with the extending thread, the extending thread might * overwrite already written data, and that would be very, very bad. - * - * Some variants of the system call to extend the file fail at run-time - * based on the filesystem type, fall back to ftruncate in that case, - * and remember that ftruncate requires locking. */ handle = fh->handle; - if (handle->fh_allocate != NULL || - handle->fh_allocate_nolock != NULL) { - /* - * Release any locally acquired lock if not needed to extend the - * file, extending the file may require updating on-disk file's - * metadata, which can be slow. (It may be a bad idea to - * configure for file extension on systems that require locking - * over the extend call.) - */ - if (handle->fh_allocate_nolock != NULL && *release_lockp) { - *release_lockp = locked = false; - __wt_spin_unlock(session, &block->live_lock); - } - - /* - * Extend the file: there's a race between setting the value of - * extend_size and doing the extension, but it should err on the - * side of extend_size being smaller than the actual file size, - * and that's OK, we simply may do another extension sooner than - * otherwise. - */ - block->extend_size = block->size + block->extend_len * 2; - if ((ret = __wt_fallocate( - session, fh, block->size, block->extend_len * 2)) == 0) - return (0); - WT_RET_ERROR_OK(ret, ENOTSUP); - } + if (handle->fh_extend == NULL && handle->fh_extend_nolock == NULL) + return (0); /* - * We may have a caller lock or a locally acquired lock, but we need a - * lock to call ftruncate. + * Set the extend_size before releasing the lock, I don't want to read + * and manipulate multiple values without holding a lock. + * + * There's a race between the calculation and doing the extension, but + * it should err on the side of extend_size being smaller than the + * actual file size, and that's OK, we simply may do another extension + * sooner than otherwise. */ - if (!locked) { - __wt_spin_lock(session, &block->live_lock); - *release_lockp = true; - } + block->extend_size = block->size + block->extend_len * 2; /* - * The underlying truncate call initializes allocated space, reset the - * extend length after locking so we don't overwrite already-written - * blocks. + * Release any locally acquired lock if not needed to extend the file, + * extending the file may require updating on-disk file's metadata, + * which can be slow. (It may be a bad idea to configure for file + * extension on systems that require locking over the extend call.) */ - block->extend_size = block->size + block->extend_len * 2; + if (handle->fh_extend_nolock != NULL && *release_lockp) { + *release_lockp = false; + __wt_spin_unlock(session, &block->live_lock); + } /* - * The truncate might fail if there's a mapped file (in other words, if - * there's an open checkpoint on the file), that's OK. + * The extend might fail (for example, the file is mapped into memory), + * or discover file extension isn't supported; both are OK. */ - WT_RET_BUSY_OK(__wt_ftruncate(session, fh, block->extend_size)); - return (0); + ret = __wt_fextend(session, fh, block->extend_size); + return (ret == EBUSY || ret == ENOTSUP ? 0 : ret); } /* @@ -210,39 +201,39 @@ __wt_block_write_size(WT_SESSION_IMPL *session, WT_BLOCK *block, size_t *sizep) * Write a buffer into a block, returning the block's address cookie. */ int -__wt_block_write(WT_SESSION_IMPL *session, WT_BLOCK *block, - WT_ITEM *buf, uint8_t *addr, size_t *addr_sizep, bool data_cksum) +__wt_block_write(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, + uint8_t *addr, size_t *addr_sizep, bool data_checksum, bool checkpoint_io) { wt_off_t offset; - uint32_t size, cksum; + uint32_t checksum, size; uint8_t *endp; - WT_RET(__wt_block_write_off( - session, block, buf, &offset, &size, &cksum, data_cksum, false)); + WT_RET(__wt_block_write_off(session, block, buf, + &offset, &size, &checksum, data_checksum, checkpoint_io, false)); endp = addr; - WT_RET(__wt_block_addr_to_buffer(block, &endp, offset, size, cksum)); + WT_RET(__wt_block_addr_to_buffer(block, &endp, offset, size, checksum)); *addr_sizep = WT_PTRDIFF(endp, addr); return (0); } /* - * __wt_block_write_off -- + * __block_write_off -- * Write a buffer into a block, returning the block's offset, size and * checksum. */ -int -__wt_block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, - WT_ITEM *buf, wt_off_t *offsetp, uint32_t *sizep, uint32_t *cksump, - bool data_cksum, bool caller_locked) +static int +__block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, + WT_ITEM *buf, wt_off_t *offsetp, uint32_t *sizep, uint32_t *checksump, + bool data_checksum, bool checkpoint_io, bool caller_locked) { WT_BLOCK_HEADER *blk; WT_DECL_RET; WT_FH *fh; size_t align_size; wt_off_t offset; - uint32_t cksum; + uint32_t checksum; bool local_locked; fh = block->fh; @@ -254,12 +245,6 @@ __wt_block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, blk = WT_BLOCK_HEADER_REF(buf->mem); memset(blk, 0, sizeof(*blk)); - /* - * Swap the page-header as needed; this doesn't belong here, but it's - * the best place to catch all callers. - */ - __wt_page_header_byteswap(buf->mem); - /* Buffers should be aligned for writing. */ if (!F_ISSET(buf, WT_ITEM_ALIGNED)) { WT_ASSERT(session, F_ISSET(buf, WT_ITEM_ALIGNED)); @@ -313,14 +298,14 @@ __wt_block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, * big-endian format, swap it into place in a separate step. */ blk->flags = 0; - if (data_cksum) + if (data_checksum) F_SET(blk, WT_BLOCK_DATA_CKSUM); - blk->cksum = 0; + blk->checksum = 0; __wt_block_header_byteswap(blk); - blk->cksum = cksum = __wt_cksum( - buf->mem, data_cksum ? align_size : WT_BLOCK_COMPRESS_SKIP); + blk->checksum = checksum = __wt_checksum( + buf->mem, data_checksum ? align_size : WT_BLOCK_COMPRESS_SKIP); #ifdef WORDS_BIGENDIAN - blk->cksum = __wt_bswap32(blk->cksum); + blk->checksum = __wt_bswap32(blk->checksum); #endif /* Pre-allocate some number of extension structures. */ @@ -380,14 +365,42 @@ __wt_block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_STAT_FAST_CONN_INCR(session, block_write); WT_STAT_FAST_CONN_INCRV(session, block_byte_write, align_size); + if (checkpoint_io) + WT_STAT_FAST_CONN_INCRV( + session, block_byte_write_checkpoint, align_size); - WT_RET(__wt_verbose(session, WT_VERB_WRITE, - "off %" PRIuMAX ", size %" PRIuMAX ", cksum %" PRIu32, - (uintmax_t)offset, (uintmax_t)align_size, cksum)); + __wt_verbose(session, WT_VERB_WRITE, + "off %" PRIuMAX ", size %" PRIuMAX ", checksum %" PRIu32, + (uintmax_t)offset, (uintmax_t)align_size, checksum); *offsetp = offset; *sizep = WT_STORE_SIZE(align_size); - *cksump = cksum; + *checksump = checksum; return (0); } + +/* + * __wt_block_write_off -- + * Write a buffer into a block, returning the block's offset, size and + * checksum. + */ +int +__wt_block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, + WT_ITEM *buf, wt_off_t *offsetp, uint32_t *sizep, uint32_t *checksump, + bool data_checksum, bool checkpoint_io, bool caller_locked) +{ + WT_DECL_RET; + + /* + * Ensure the page header is in little endian order; this doesn't belong + * here, but it's the best place to catch all callers. After the write, + * swap values back to native order so callers never see anything other + * than their original content. + */ + __wt_page_header_byteswap(buf->mem); + ret = __block_write_off(session, block, buf, offsetp, + sizep, checksump, data_checksum, checkpoint_io, caller_locked); + __wt_page_header_byteswap(buf->mem); + return (ret); +} diff --git a/src/third_party/wiredtiger/src/bloom/bloom.c b/src/third_party/wiredtiger/src/bloom/bloom.c index e32544d5521..3afada05dda 100644 --- a/src/third_party/wiredtiger/src/bloom/bloom.c +++ b/src/third_party/wiredtiger/src/bloom/bloom.c @@ -105,7 +105,7 @@ __wt_bloom_create( *bloomp = bloom; return (0); -err: (void)__wt_bloom_close(bloom); +err: WT_TRET(__wt_bloom_close(bloom)); return (ret); } @@ -166,7 +166,7 @@ __wt_bloom_open(WT_SESSION_IMPL *session, *bloomp = bloom; return (0); -err: (void)__wt_bloom_close(bloom); +err: WT_TRET(__wt_bloom_close(bloom)); return (ret); } @@ -174,7 +174,7 @@ err: (void)__wt_bloom_close(bloom); * __wt_bloom_insert -- * Adds the given key to the Bloom filter. */ -int +void __wt_bloom_insert(WT_BLOOM *bloom, WT_ITEM *key) { uint64_t h1, h2; @@ -182,10 +182,8 @@ __wt_bloom_insert(WT_BLOOM *bloom, WT_ITEM *key) h1 = __wt_hash_fnv64(key->data, key->size); h2 = __wt_hash_city64(key->data, key->size); - for (i = 0; i < bloom->k; i++, h1 += h2) { + for (i = 0; i < bloom->k; i++, h1 += h2) __bit_set(bloom->bitstring, h1 % bloom->m); - } - return (0); } /* @@ -238,15 +236,13 @@ err: WT_TRET(c->close(c)); * __wt_bloom_hash -- * Calculate the hash values for a given key. */ -int +void __wt_bloom_hash(WT_BLOOM *bloom, WT_ITEM *key, WT_BLOOM_HASH *bhash) { WT_UNUSED(bloom); bhash->h1 = __wt_hash_fnv64(key->data, key->size); bhash->h2 = __wt_hash_city64(key->data, key->size); - - return (0); } /* @@ -309,7 +305,7 @@ __wt_bloom_get(WT_BLOOM *bloom, WT_ITEM *key) { WT_BLOOM_HASH bhash; - WT_RET(__wt_bloom_hash(bloom, key, &bhash)); + __wt_bloom_hash(bloom, key, &bhash); return (__wt_bloom_hash_get(bloom, &bhash)); } diff --git a/src/third_party/wiredtiger/src/btree/bt_compact.c b/src/third_party/wiredtiger/src/btree/bt_compact.c index 9cc56c56452..bb1261d94b0 100644 --- a/src/third_party/wiredtiger/src/btree/bt_compact.c +++ b/src/third_party/wiredtiger/src/btree/bt_compact.c @@ -60,7 +60,7 @@ __compact_rewrite(WT_SESSION_IMPL *session, WT_REF *ref, bool *skipp) */ if (mod->rec_result == WT_PM_REC_REPLACE || mod->rec_result == WT_PM_REC_MULTIBLOCK) - WT_RET(__wt_fair_lock(session, &page->page_lock)); + __wt_writelock(session, &page->page_lock); if (mod->rec_result == WT_PM_REC_REPLACE) ret = bm->compact_page_skip(bm, session, @@ -80,7 +80,7 @@ __compact_rewrite(WT_SESSION_IMPL *session, WT_REF *ref, bool *skipp) if (mod->rec_result == WT_PM_REC_REPLACE || mod->rec_result == WT_PM_REC_MULTIBLOCK) - WT_TRET(__wt_fair_unlock(session, &page->page_lock)); + __wt_writeunlock(session, &page->page_lock); return (ret); } diff --git a/src/third_party/wiredtiger/src/btree/bt_curnext.c b/src/third_party/wiredtiger/src/btree/bt_curnext.c index e6f4728a695..c6955dd9ed6 100644 --- a/src/third_party/wiredtiger/src/btree/bt_curnext.c +++ b/src/third_party/wiredtiger/src/btree/bt_curnext.c @@ -665,7 +665,7 @@ __wt_btcur_next(WT_CURSOR_BTREE *cbt, bool truncating) if (page != NULL && (cbt->page_deleted_count > WT_BTREE_DELETE_THRESHOLD || (newpage && cbt->page_deleted_count > 0))) - __wt_page_evict_soon(page); + __wt_page_evict_soon(session, cbt->ref); cbt->page_deleted_count = 0; WT_ERR(__wt_tree_walk(session, &cbt->ref, flags)); diff --git a/src/third_party/wiredtiger/src/btree/bt_curprev.c b/src/third_party/wiredtiger/src/btree/bt_curprev.c index cba0c053b90..79fd067ac7b 100644 --- a/src/third_party/wiredtiger/src/btree/bt_curprev.c +++ b/src/third_party/wiredtiger/src/btree/bt_curprev.c @@ -621,7 +621,7 @@ __wt_btcur_prev(WT_CURSOR_BTREE *cbt, bool truncating) if (page != NULL && (cbt->page_deleted_count > WT_BTREE_DELETE_THRESHOLD || (newpage && cbt->page_deleted_count > 0))) - __wt_page_evict_soon(page); + __wt_page_evict_soon(session, cbt->ref); cbt->page_deleted_count = 0; WT_ERR(__wt_tree_walk(session, &cbt->ref, flags)); diff --git a/src/third_party/wiredtiger/src/btree/bt_cursor.c b/src/third_party/wiredtiger/src/btree/bt_cursor.c index 9a57759570a..982226f589f 100644 --- a/src/third_party/wiredtiger/src/btree/bt_cursor.c +++ b/src/third_party/wiredtiger/src/btree/bt_cursor.c @@ -1212,7 +1212,7 @@ __wt_btcur_range_truncate(WT_CURSOR_BTREE *start, WT_CURSOR_BTREE *stop) } err: if (FLD_ISSET(S2C(session)->log_flags, WT_CONN_LOG_ENABLED)) - WT_TRET(__wt_txn_truncate_end(session)); + __wt_txn_truncate_end(session); return (ret); } diff --git a/src/third_party/wiredtiger/src/btree/bt_debug.c b/src/third_party/wiredtiger/src/btree/bt_debug.c index b1579d25dc6..bcc7d27a569 100644 --- a/src/third_party/wiredtiger/src/btree/bt_debug.c +++ b/src/third_party/wiredtiger/src/btree/bt_debug.c @@ -12,45 +12,47 @@ /* * We pass around a session handle and output information, group it together. */ -typedef struct { +typedef struct __wt_dbg WT_DBG; +struct __wt_dbg { WT_SESSION_IMPL *session; /* Enclosing session */ /* * When using the standard event handlers, the debugging output has to * do its own message handling because its output isn't line-oriented. */ - FILE *fp; + FILE *fp; /* Optional file handle */ WT_ITEM *msg; /* Buffered message */ + int (*f)(WT_DBG *, const char *, ...) /* Function to write */ + WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 2, 3))); + WT_ITEM *tmp; /* Temporary space */ -} WT_DBG; +}; static const /* Output separator */ char * const sep = "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=\n"; -static int __debug_cell(WT_DBG *, const WT_PAGE_HEADER *, WT_CELL_UNPACK *); -static int __debug_cell_data( +static int __debug_cell(WT_DBG *, const WT_PAGE_HEADER *, WT_CELL_UNPACK *); +static int __debug_cell_data( WT_DBG *, WT_PAGE *, int type, const char *, WT_CELL_UNPACK *); -static void __debug_col_skip(WT_DBG *, WT_INSERT_HEAD *, const char *, bool); -static int __debug_config(WT_SESSION_IMPL *, WT_DBG *, const char *); -static int __debug_dsk_cell(WT_DBG *, const WT_PAGE_HEADER *); -static void __debug_dsk_col_fix(WT_DBG *, const WT_PAGE_HEADER *); -static void __debug_item(WT_DBG *, const char *, const void *, size_t); -static int __debug_page(WT_DBG *, WT_REF *, uint32_t); -static void __debug_page_col_fix(WT_DBG *, WT_REF *); -static int __debug_page_col_int(WT_DBG *, WT_PAGE *, uint32_t); -static int __debug_page_col_var(WT_DBG *, WT_REF *); -static int __debug_page_metadata(WT_DBG *, WT_REF *); -static int __debug_page_row_int(WT_DBG *, WT_PAGE *, uint32_t); -static int __debug_page_row_leaf(WT_DBG *, WT_PAGE *); -static void __debug_ref(WT_DBG *, WT_REF *); -static void __debug_row_skip(WT_DBG *, WT_INSERT_HEAD *); -static int __debug_tree( +static int __debug_col_skip(WT_DBG *, WT_INSERT_HEAD *, const char *, bool); +static int __debug_config(WT_SESSION_IMPL *, WT_DBG *, const char *); +static int __debug_dsk_cell(WT_DBG *, const WT_PAGE_HEADER *); +static int __debug_dsk_col_fix(WT_DBG *, const WT_PAGE_HEADER *); +static int __debug_item(WT_DBG *, const char *, const void *, size_t); +static int __debug_page(WT_DBG *, WT_REF *, uint32_t); +static int __debug_page_col_fix(WT_DBG *, WT_REF *); +static int __debug_page_col_int(WT_DBG *, WT_PAGE *, uint32_t); +static int __debug_page_col_var(WT_DBG *, WT_REF *); +static int __debug_page_metadata(WT_DBG *, WT_REF *); +static int __debug_page_row_int(WT_DBG *, WT_PAGE *, uint32_t); +static int __debug_page_row_leaf(WT_DBG *, WT_PAGE *); +static int __debug_ref(WT_DBG *, WT_REF *); +static int __debug_row_skip(WT_DBG *, WT_INSERT_HEAD *); +static int __debug_tree( WT_SESSION_IMPL *, WT_BTREE *, WT_REF *, const char *, uint32_t); -static void __debug_update(WT_DBG *, WT_UPDATE *, bool); -static void __dmsg(WT_DBG *, const char *, ...) - WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 2, 3))); -static void __dmsg_wrapup(WT_DBG *); +static int __debug_update(WT_DBG *, WT_UPDATE *, bool); +static int __dmsg_wrapup(WT_DBG *); /* * __wt_debug_set_verbose -- @@ -71,10 +73,81 @@ __wt_debug_set_verbose(WT_SESSION_IMPL *session, const char *v) * __debug_hex_byte -- * Output a single byte in hex. */ -static inline void +static inline int __debug_hex_byte(WT_DBG *ds, uint8_t v) { - __dmsg(ds, "#%c%c", __wt_hex[(v & 0xf0) >> 4], __wt_hex[v & 0x0f]); + return (ds->f( + ds, "#%c%c", __wt_hex[(v & 0xf0) >> 4], __wt_hex[v & 0x0f])); +} + +/* + * __dmsg_event -- + * Send a debug message to the event handler. + */ +static int +__dmsg_event(WT_DBG *ds, const char *fmt, ...) +{ + WT_ITEM *msg; + WT_SESSION_IMPL *session; + size_t len, space; + va_list ap; + char *p; + + session = ds->session; + + /* + * Debug output chunks are not necessarily terminated with a newline + * character. It's easy if we're dumping to a stream, but if we're + * dumping to an event handler, which is line-oriented, we must buffer + * the output chunk, and pass it to the event handler once we see a + * terminating newline. + */ + msg = ds->msg; + for (;;) { + p = (char *)msg->mem + msg->size; + space = msg->memsize - msg->size; + va_start(ap, fmt); + len = (size_t)vsnprintf(p, space, fmt, ap); + va_end(ap); + + /* Check if there was enough space. */ + if (len < space) { + msg->size += len; + break; + } + + /* + * There's not much to do on error without checking for + * an error return on every single printf. Anyway, it's + * pretty unlikely and this is debugging output, I'm not + * going to worry about it. + */ + WT_RET(__wt_buf_grow(session, msg, msg->memsize + len + 128)); + } + if (((uint8_t *)msg->mem)[msg->size - 1] == '\n') { + ((uint8_t *)msg->mem)[msg->size - 1] = '\0'; + WT_RET(__wt_msg(session, "%s", (char *)msg->mem)); + msg->size = 0; + } + + return (0); +} + +/* + * __dmsg_file -- + * Send a debug message to a file. + */ +static int +__dmsg_file(WT_DBG *ds, const char *fmt, ...) +{ + WT_DECL_RET; + va_list ap; + + va_start(ap, fmt); + ret = vfprintf(ds->fp, fmt, ap) < 0 ? EIO : 0; + va_end(ap); + + return (ret); } /* @@ -94,12 +167,15 @@ __debug_config(WT_SESSION_IMPL *session, WT_DBG *ds, const char *ofile) * If we weren't given a file, we use the default event handler, and * we'll have to buffer messages. */ - if (ofile == NULL) - return (__wt_scr_alloc(session, 512, &ds->msg)); - - if ((ds->fp = fopen(ofile, "w")) == NULL) - return (EIO); - __wt_stream_set_line_buffer(ds->fp); + if (ofile == NULL) { + WT_RET(__wt_scr_alloc(session, 512, &ds->msg)); + ds->f = __dmsg_event; + } else { + if ((ds->fp = fopen(ofile, "w")) == NULL) + return (EIO); + __wt_stream_set_line_buffer(ds->fp); + ds->f = __dmsg_file; + } return (0); } @@ -108,7 +184,7 @@ __debug_config(WT_SESSION_IMPL *session, WT_DBG *ds, const char *ofile) * __dmsg_wrapup -- * Flush any remaining output, release resources. */ -static void +static int __dmsg_wrapup(WT_DBG *ds) { WT_SESSION_IMPL *session; @@ -125,72 +201,15 @@ __dmsg_wrapup(WT_DBG *ds) */ if (msg != NULL) { if (msg->size != 0) - (void)__wt_msg(session, "%s", (char *)msg->mem); + WT_RET(__wt_msg(session, "%s", (char *)msg->mem)); __wt_scr_free(session, &ds->msg); } /* Close any file we opened. */ if (ds->fp != NULL) (void)fclose(ds->fp); -} - -/* - * __dmsg -- - * Debug message. - */ -static void -__dmsg(WT_DBG *ds, const char *fmt, ...) -{ - va_list ap; - WT_ITEM *msg; - WT_SESSION_IMPL *session; - size_t len, space; - char *p; - - session = ds->session; - - /* - * Debug output chunks are not necessarily terminated with a newline - * character. It's easy if we're dumping to a stream, but if we're - * dumping to an event handler, which is line-oriented, we must buffer - * the output chunk, and pass it to the event handler once we see a - * terminating newline. - */ - if (ds->fp == NULL) { - msg = ds->msg; - for (;;) { - p = (char *)msg->mem + msg->size; - space = msg->memsize - msg->size; - va_start(ap, fmt); - len = (size_t)vsnprintf(p, space, fmt, ap); - va_end(ap); - - /* Check if there was enough space. */ - if (len < space) { - msg->size += len; - break; - } - /* - * There's not much to do on error without checking for - * an error return on every single printf. Anyway, it's - * pretty unlikely and this is debugging output, I'm not - * going to worry about it. - */ - if (__wt_buf_grow( - session, msg, msg->memsize + len + 128) != 0) - return; - } - if (((uint8_t *)msg->mem)[msg->size - 1] == '\n') { - ((uint8_t *)msg->mem)[msg->size - 1] = '\0'; - (void)__wt_msg(session, "%s", (char *)msg->mem); - msg->size = 0; - } - } else { - va_start(ap, fmt); - (void)vfprintf(ds->fp, fmt, ap); - va_end(ap); - } + return (0); } /* @@ -272,7 +291,7 @@ err: __wt_scr_free(session, &buf); */ int __wt_debug_offset(WT_SESSION_IMPL *session, - wt_off_t offset, uint32_t size, uint32_t cksum, const char *ofile) + wt_off_t offset, uint32_t size, uint32_t checksum, const char *ofile) { WT_DECL_ITEM(buf); WT_DECL_RET; @@ -291,7 +310,7 @@ __wt_debug_offset(WT_SESSION_IMPL *session, */ endp = addr; WT_RET(__wt_block_addr_to_buffer( - S2BT(session)->bm->block, &endp, offset, size, cksum)); + S2BT(session)->bm->block, &endp, offset, size, checksum)); /* * Read the address through the btree I/O functions (so the block is @@ -314,69 +333,66 @@ __wt_debug_disk( WT_SESSION_IMPL *session, const WT_PAGE_HEADER *dsk, const char *ofile) { WT_DBG *ds, _ds; - WT_DECL_RET; ds = &_ds; WT_RET(__debug_config(session, ds, ofile)); - __dmsg(ds, "%s page", __wt_page_type_string(dsk->type)); + WT_RET(ds->f(ds, "%s page", __wt_page_type_string(dsk->type))); switch (dsk->type) { case WT_PAGE_BLOCK_MANAGER: break; case WT_PAGE_COL_FIX: case WT_PAGE_COL_INT: case WT_PAGE_COL_VAR: - __dmsg(ds, ", recno %" PRIu64, dsk->recno); + WT_RET(ds->f(ds, ", recno %" PRIu64, dsk->recno)); /* FALLTHROUGH */ case WT_PAGE_ROW_INT: case WT_PAGE_ROW_LEAF: - __dmsg(ds, ", entries %" PRIu32, dsk->u.entries); + WT_RET(ds->f(ds, ", entries %" PRIu32, dsk->u.entries)); break; case WT_PAGE_OVFL: - __dmsg(ds, ", datalen %" PRIu32, dsk->u.datalen); + WT_RET(ds->f(ds, ", datalen %" PRIu32, dsk->u.datalen)); break; WT_ILLEGAL_VALUE(session); } if (F_ISSET(dsk, WT_PAGE_COMPRESSED)) - __dmsg(ds, ", compressed"); + WT_RET(ds->f(ds, ", compressed")); if (F_ISSET(dsk, WT_PAGE_ENCRYPTED)) - __dmsg(ds, ", encrypted"); + WT_RET(ds->f(ds, ", encrypted")); if (F_ISSET(dsk, WT_PAGE_EMPTY_V_ALL)) - __dmsg(ds, ", empty-all"); + WT_RET(ds->f(ds, ", empty-all")); if (F_ISSET(dsk, WT_PAGE_EMPTY_V_NONE)) - __dmsg(ds, ", empty-none"); + WT_RET(ds->f(ds, ", empty-none")); if (F_ISSET(dsk, WT_PAGE_LAS_UPDATE)) - __dmsg(ds, ", LAS-update"); + WT_RET(ds->f(ds, ", LAS-update")); - __dmsg(ds, ", generation %" PRIu64 "\n", dsk->write_gen); + WT_RET(ds->f(ds, ", generation %" PRIu64 "\n", dsk->write_gen)); switch (dsk->type) { case WT_PAGE_BLOCK_MANAGER: break; case WT_PAGE_COL_FIX: - __debug_dsk_col_fix(ds, dsk); + WT_RET(__debug_dsk_col_fix(ds, dsk)); break; case WT_PAGE_COL_INT: case WT_PAGE_COL_VAR: case WT_PAGE_ROW_INT: case WT_PAGE_ROW_LEAF: - ret = __debug_dsk_cell(ds, dsk); + WT_RET(__debug_dsk_cell(ds, dsk)); break; default: break; } - __dmsg_wrapup(ds); - - return (ret); + return (__dmsg_wrapup(ds)); } /* * __debug_dsk_col_fix -- * Dump a WT_PAGE_COL_FIX page. */ -static void +static int __debug_dsk_col_fix(WT_DBG *ds, const WT_PAGE_HEADER *dsk) { WT_BTREE *btree; @@ -388,10 +404,11 @@ __debug_dsk_col_fix(WT_DBG *ds, const WT_PAGE_HEADER *dsk) btree = S2BT(ds->session); WT_FIX_FOREACH(btree, dsk, v, i) { - __dmsg(ds, "\t{"); - __debug_hex_byte(ds, v); - __dmsg(ds, "}\n"); + WT_RET(ds->f(ds, "\t{")); + WT_RET(__debug_hex_byte(ds, v)); + WT_RET(ds->f(ds, "}\n")); } + return (0); } /* @@ -444,7 +461,7 @@ __debug_tree_shape_info(WT_PAGE *page) * __debug_tree_shape_worker -- * Dump information about the current page and descend. */ -static void +static int __debug_tree_shape_worker(WT_DBG *ds, WT_PAGE *page, int level) { WT_REF *ref; @@ -453,16 +470,17 @@ __debug_tree_shape_worker(WT_DBG *ds, WT_PAGE *page, int level) session = ds->session; if (WT_PAGE_IS_INTERNAL(page)) { - __dmsg(ds, "%*s" "I" "%d %s\n", - level * 3, " ", level, __debug_tree_shape_info(page)); + WT_RET(ds->f(ds, "%*s" "I" "%d %s\n", + level * 3, " ", level, __debug_tree_shape_info(page))); WT_INTL_FOREACH_BEGIN(session, page, ref) { if (ref->state == WT_REF_MEM) - __debug_tree_shape_worker( - ds, ref->page, level + 1); + WT_RET(__debug_tree_shape_worker( + ds, ref->page, level + 1)); } WT_INTL_FOREACH_END; } else - __dmsg(ds, "%*s" "L" " %s\n", - level * 3, " ", __debug_tree_shape_info(page)); + WT_RET(ds->f(ds, "%*s" "L" " %s\n", + level * 3, " ", __debug_tree_shape_info(page))); + return (0); } /* @@ -474,6 +492,7 @@ __wt_debug_tree_shape( WT_SESSION_IMPL *session, WT_PAGE *page, const char *ofile) { WT_DBG *ds, _ds; + WT_DECL_RET; WT_ASSERT(session, S2BT_SAFE(session) != NULL); @@ -484,10 +503,11 @@ __wt_debug_tree_shape( if (page == NULL) page = S2BT(session)->root.page; - WT_WITH_PAGE_INDEX(session, __debug_tree_shape_worker(ds, page, 1)); + WT_WITH_PAGE_INDEX(session, + ret = __debug_tree_shape_worker(ds, page, 1)); + WT_RET(ret); - __dmsg_wrapup(ds); - return (0); + return (__dmsg_wrapup(ds)); } #define WT_DEBUG_TREE_LEAF 0x01 /* Debug leaf pages */ @@ -530,18 +550,15 @@ int __wt_debug_page(WT_SESSION_IMPL *session, WT_REF *ref, const char *ofile) { WT_DBG *ds, _ds; - WT_DECL_RET; WT_ASSERT(session, S2BT_SAFE(session) != NULL); ds = &_ds; WT_RET(__debug_config(session, ds, ofile)); - ret = __debug_page(ds, ref, WT_DEBUG_TREE_LEAF); - - __dmsg_wrapup(ds); + WT_RET(__debug_page(ds, ref, WT_DEBUG_TREE_LEAF)); - return (ret); + return (__dmsg_wrapup(ds)); } /* @@ -567,10 +584,9 @@ __debug_tree(WT_SESSION_IMPL *session, ref = &btree->root; WT_WITH_BTREE(session, btree, ret = __debug_page(ds, ref, flags)); + WT_RET(ret); - __dmsg_wrapup(ds); - - return (ret); + return (__dmsg_wrapup(ds)); } /* @@ -593,7 +609,7 @@ __debug_page(WT_DBG *ds, WT_REF *ref, uint32_t flags) switch (ref->page->type) { case WT_PAGE_COL_FIX: if (LF_ISSET(WT_DEBUG_TREE_LEAF)) - __debug_page_col_fix(ds, ref); + WT_RET(__debug_page_col_fix(ds, ref)); break; case WT_PAGE_COL_INT: WT_WITH_PAGE_INDEX(session, @@ -636,20 +652,20 @@ __debug_page_metadata(WT_DBG *ds, WT_REF *ref) page = ref->page; mod = page->modify; - __dmsg(ds, "%p", (void *)page); + WT_RET(ds->f(ds, "%p", (void *)page)); switch (page->type) { case WT_PAGE_COL_INT: - __dmsg(ds, " recno %" PRIu64, ref->ref_recno); + WT_RET(ds->f(ds, " recno %" PRIu64, ref->ref_recno)); WT_INTL_INDEX_GET(session, page, pindex); entries = pindex->entries; break; case WT_PAGE_COL_FIX: - __dmsg(ds, " recno %" PRIu64, ref->ref_recno); + WT_RET(ds->f(ds, " recno %" PRIu64, ref->ref_recno)); entries = page->pg_fix_entries; break; case WT_PAGE_COL_VAR: - __dmsg(ds, " recno %" PRIu64, ref->ref_recno); + WT_RET(ds->f(ds, " recno %" PRIu64, ref->ref_recno)); entries = page->pg_var_entries; break; case WT_PAGE_ROW_INT: @@ -662,48 +678,50 @@ __debug_page_metadata(WT_DBG *ds, WT_REF *ref) WT_ILLEGAL_VALUE(session); } - __dmsg(ds, ": %s\n", __wt_page_type_string(page->type)); - __dmsg(ds, - "\t" "disk %p, entries %" PRIu32, (void *)page->dsk, entries); - __dmsg(ds, ", %s", __wt_page_is_modified(page) ? "dirty" : "clean"); - __dmsg(ds, ", %s", __wt_fair_islocked( - session, &page->page_lock) ? "locked" : "unlocked"); + WT_RET(ds->f(ds, ": %s\n", __wt_page_type_string(page->type))); + WT_RET(ds->f(ds, + "\t" "disk %p, entries %" PRIu32, (void *)page->dsk, entries)); + WT_RET(ds->f(ds, + ", %s", __wt_page_is_modified(page) ? "dirty" : "clean")); + WT_RET(ds->f(ds, ", %s", __wt_rwlock_islocked( + session, &page->page_lock) ? "locked" : "unlocked")); if (F_ISSET_ATOMIC(page, WT_PAGE_BUILD_KEYS)) - __dmsg(ds, ", keys-built"); + WT_RET(ds->f(ds, ", keys-built")); if (F_ISSET_ATOMIC(page, WT_PAGE_DISK_ALLOC)) - __dmsg(ds, ", disk-alloc"); + WT_RET(ds->f(ds, ", disk-alloc")); if (F_ISSET_ATOMIC(page, WT_PAGE_DISK_MAPPED)) - __dmsg(ds, ", disk-mapped"); + WT_RET(ds->f(ds, ", disk-mapped")); if (F_ISSET_ATOMIC(page, WT_PAGE_EVICT_LRU)) - __dmsg(ds, ", evict-lru"); + WT_RET(ds->f(ds, ", evict-lru")); if (F_ISSET_ATOMIC(page, WT_PAGE_OVERFLOW_KEYS)) - __dmsg(ds, ", overflow-keys"); + WT_RET(ds->f(ds, ", overflow-keys")); if (F_ISSET_ATOMIC(page, WT_PAGE_SPLIT_BLOCK)) - __dmsg(ds, ", split-block"); + WT_RET(ds->f(ds, ", split-block")); if (F_ISSET_ATOMIC(page, WT_PAGE_SPLIT_INSERT)) - __dmsg(ds, ", split-insert"); + WT_RET(ds->f(ds, ", split-insert")); if (F_ISSET_ATOMIC(page, WT_PAGE_UPDATE_IGNORE)) - __dmsg(ds, ", update-ignore"); + WT_RET(ds->f(ds, ", update-ignore")); if (mod != NULL) switch (mod->rec_result) { case WT_PM_REC_EMPTY: - __dmsg(ds, ", empty"); + WT_RET(ds->f(ds, ", empty")); break; case WT_PM_REC_MULTIBLOCK: - __dmsg(ds, ", multiblock"); + WT_RET(ds->f(ds, ", multiblock")); break; case WT_PM_REC_REPLACE: - __dmsg(ds, ", replaced"); + WT_RET(ds->f(ds, ", replaced")); break; case 0: break; WT_ILLEGAL_VALUE(session); } if (mod != NULL) - __dmsg(ds, ", write generation=%" PRIu32, mod->write_gen); - __dmsg(ds, "\n"); + WT_RET( + ds->f(ds, ", write generation=%" PRIu32, mod->write_gen)); + WT_RET(ds->f(ds, "\n")); return (0); } @@ -712,7 +730,7 @@ __debug_page_metadata(WT_DBG *ds, WT_REF *ref) * __debug_page_col_fix -- * Dump an in-memory WT_PAGE_COL_FIX page. */ -static void +static int __debug_page_col_fix(WT_DBG *ds, WT_REF *ref) { WT_BTREE *btree; @@ -735,16 +753,15 @@ __debug_page_col_fix(WT_DBG *ds, WT_REF *ref) if (dsk != NULL) { ins = WT_SKIP_FIRST(WT_COL_UPDATE_SINGLE(page)); WT_FIX_FOREACH(btree, dsk, v, i) { - __dmsg(ds, "\t%" PRIu64 "\t{", recno); - __debug_hex_byte(ds, v); - __dmsg(ds, "}\n"); + WT_RET(ds->f(ds, "\t%" PRIu64 "\t{", recno)); + WT_RET(__debug_hex_byte(ds, v)); + WT_RET(ds->f(ds, "}\n")); /* Check for a match on the update list. */ if (ins != NULL && WT_INSERT_RECNO(ins) == recno) { - __dmsg(ds, - "\tupdate %" PRIu64 "\n", - WT_INSERT_RECNO(ins)); - __debug_update(ds, ins->upd, true); + WT_RET(ds->f(ds, "\tupdate %" PRIu64 "\n", + WT_INSERT_RECNO(ins))); + WT_RET(__debug_update(ds, ins->upd, true)); ins = WT_SKIP_NEXT(ins); } ++recno; @@ -752,14 +769,16 @@ __debug_page_col_fix(WT_DBG *ds, WT_REF *ref) } if (WT_COL_UPDATE_SINGLE(page) != NULL) { - __dmsg(ds, "%s", sep); - __debug_col_skip( - ds, WT_COL_UPDATE_SINGLE(page), "update", true); + WT_RET(ds->f(ds, "%s", sep)); + WT_RET(__debug_col_skip( + ds, WT_COL_UPDATE_SINGLE(page), "update", true)); } if (WT_COL_APPEND(page) != NULL) { - __dmsg(ds, "%s", sep); - __debug_col_skip(ds, WT_COL_APPEND(page), "append", true); + WT_RET(ds->f(ds, "%s", sep)); + WT_RET(__debug_col_skip(ds, + WT_COL_APPEND(page), "append", true)); } + return (0); } /* @@ -775,14 +794,14 @@ __debug_page_col_int(WT_DBG *ds, WT_PAGE *page, uint32_t flags) session = ds->session; WT_INTL_FOREACH_BEGIN(session, page, ref) { - __dmsg(ds, "\trecno %" PRIu64 "\n", ref->ref_recno); - __debug_ref(ds, ref); + WT_RET(ds->f(ds, "\trecno %" PRIu64 "\n", ref->ref_recno)); + WT_RET(__debug_ref(ds, ref)); } WT_INTL_FOREACH_END; if (LF_ISSET(WT_DEBUG_TREE_WALK)) WT_INTL_FOREACH_BEGIN(session, page, ref) { if (ref->state == WT_REF_MEM) { - __dmsg(ds, "\n"); + WT_RET(ds->f(ds, "\n")); WT_RET(__debug_page(ds, ref, flags)); } } WT_INTL_FOREACH_END; @@ -823,13 +842,14 @@ __debug_page_col_var(WT_DBG *ds, WT_REF *ref) __debug_cell_data(ds, page, WT_PAGE_COL_VAR, tag, unpack)); if ((update = WT_COL_UPDATE(page, cip)) != NULL) - __debug_col_skip(ds, update, "update", false); + WT_RET(__debug_col_skip(ds, update, "update", false)); recno += rle; } if (WT_COL_APPEND(page) != NULL) { - __dmsg(ds, "%s", sep); - __debug_col_skip(ds, WT_COL_APPEND(page), "append", false); + WT_RET(ds->f(ds, "%s", sep)); + WT_RET(__debug_col_skip(ds, + WT_COL_APPEND(page), "append", false)); } return (0); @@ -851,14 +871,14 @@ __debug_page_row_int(WT_DBG *ds, WT_PAGE *page, uint32_t flags) WT_INTL_FOREACH_BEGIN(session, page, ref) { __wt_ref_key(page, ref, &p, &len); - __debug_item(ds, "K", p, len); - __debug_ref(ds, ref); + WT_RET(__debug_item(ds, "K", p, len)); + WT_RET(__debug_ref(ds, ref)); } WT_INTL_FOREACH_END; if (LF_ISSET(WT_DEBUG_TREE_WALK)) WT_INTL_FOREACH_BEGIN(session, page, ref) { if (ref->state == WT_REF_MEM) { - __dmsg(ds, "\n"); + WT_RET(ds->f(ds, "\n")); WT_RET(__debug_page(ds, ref, flags)); } } WT_INTL_FOREACH_END; @@ -891,15 +911,15 @@ __debug_page_row_leaf(WT_DBG *ds, WT_PAGE *page) * key on the page. */ if ((insert = WT_ROW_INSERT_SMALLEST(page)) != NULL) - __debug_row_skip(ds, insert); + WT_ERR(__debug_row_skip(ds, insert)); /* Dump the page's K/V pairs. */ WT_ROW_FOREACH(page, rip, i) { WT_ERR(__wt_row_leaf_key(session, page, rip, key, false)); - __debug_item(ds, "K", key->data, key->size); + WT_ERR(__debug_item(ds, "K", key->data, key->size)); if ((cell = __wt_row_leaf_value_cell(page, rip, NULL)) == NULL) - __dmsg(ds, "\tV {}\n"); + WT_ERR(ds->f(ds, "\tV {}\n")); else { __wt_cell_unpack(cell, unpack); WT_ERR(__debug_cell_data( @@ -907,10 +927,10 @@ __debug_page_row_leaf(WT_DBG *ds, WT_PAGE *page) } if ((upd = WT_ROW_UPDATE(page, rip)) != NULL) - __debug_update(ds, upd, false); + WT_ERR(__debug_update(ds, upd, false)); if ((insert = WT_ROW_INSERT(page, rip)) != NULL) - __debug_row_skip(ds, insert); + WT_ERR(__debug_row_skip(ds, insert)); } err: __wt_scr_free(session, &key); @@ -921,59 +941,63 @@ err: __wt_scr_free(session, &key); * __debug_col_skip -- * Dump a column-store skiplist. */ -static void +static int __debug_col_skip( WT_DBG *ds, WT_INSERT_HEAD *head, const char *tag, bool hexbyte) { WT_INSERT *ins; WT_SKIP_FOREACH(ins, head) { - __dmsg(ds, - "\t%s %" PRIu64 "\n", tag, WT_INSERT_RECNO(ins)); - __debug_update(ds, ins->upd, hexbyte); + WT_RET(ds->f(ds, + "\t%s %" PRIu64 "\n", tag, WT_INSERT_RECNO(ins))); + WT_RET(__debug_update(ds, ins->upd, hexbyte)); } + return (0); } /* * __debug_row_skip -- * Dump an insert list. */ -static void +static int __debug_row_skip(WT_DBG *ds, WT_INSERT_HEAD *head) { WT_INSERT *ins; WT_SKIP_FOREACH(ins, head) { - __debug_item(ds, - "insert", WT_INSERT_KEY(ins), WT_INSERT_KEY_SIZE(ins)); - __debug_update(ds, ins->upd, false); + WT_RET(__debug_item(ds, + "insert", WT_INSERT_KEY(ins), WT_INSERT_KEY_SIZE(ins))); + WT_RET(__debug_update(ds, ins->upd, false)); } + return (0); } /* * __debug_update -- * Dump an update list. */ -static void +static int __debug_update(WT_DBG *ds, WT_UPDATE *upd, bool hexbyte) { for (; upd != NULL; upd = upd->next) if (WT_UPDATE_DELETED_ISSET(upd)) - __dmsg(ds, "\tvalue {deleted}\n"); + WT_RET(ds->f(ds, "\tvalue {deleted}\n")); else if (hexbyte) { - __dmsg(ds, "\t{"); - __debug_hex_byte(ds, *(uint8_t *)WT_UPDATE_DATA(upd)); - __dmsg(ds, "}\n"); + WT_RET(ds->f(ds, "\t{")); + WT_RET(__debug_hex_byte(ds, + *(uint8_t *)WT_UPDATE_DATA(upd))); + WT_RET(ds->f(ds, "}\n")); } else - __debug_item(ds, - "value", WT_UPDATE_DATA(upd), upd->size); + WT_RET(__debug_item(ds, + "value", WT_UPDATE_DATA(upd), upd->size)); + return (0); } /* * __debug_ref -- * Dump a WT_REF structure. */ -static void +static int __debug_ref(WT_DBG *ds, WT_REF *ref) { WT_SESSION_IMPL *session; @@ -982,34 +1006,34 @@ __debug_ref(WT_DBG *ds, WT_REF *ref) session = ds->session; - __dmsg(ds, "\t"); + WT_RET(ds->f(ds, "\t")); switch (ref->state) { case WT_REF_DISK: - __dmsg(ds, "disk"); + WT_RET(ds->f(ds, "disk")); break; case WT_REF_DELETED: - __dmsg(ds, "deleted"); + WT_RET(ds->f(ds, "deleted")); break; case WT_REF_LOCKED: - __dmsg(ds, "locked %p", (void *)ref->page); + WT_RET(ds->f(ds, "locked %p", (void *)ref->page)); break; case WT_REF_MEM: - __dmsg(ds, "memory %p", (void *)ref->page); + WT_RET(ds->f(ds, "memory %p", (void *)ref->page)); break; case WT_REF_READING: - __dmsg(ds, "reading"); + WT_RET(ds->f(ds, "reading")); break; case WT_REF_SPLIT: - __dmsg(ds, "split"); + WT_RET(ds->f(ds, "split")); break; default: - __dmsg(ds, "INVALID"); + WT_RET(ds->f(ds, "INVALID")); break; } __wt_ref_info(ref, &addr, &addr_size, NULL); - __dmsg(ds, " %s\n", - __wt_addr_string(session, addr, addr_size, ds->tmp)); + return (ds->f(ds, " %s\n", + __wt_addr_string(session, addr, addr_size, ds->tmp))); } /* @@ -1026,15 +1050,15 @@ __debug_cell(WT_DBG *ds, const WT_PAGE_HEADER *dsk, WT_CELL_UNPACK *unpack) session = ds->session; - __dmsg(ds, "\t%s: len %" PRIu32, - __wt_cell_type_string(unpack->raw), unpack->size); + WT_RET(ds->f(ds, "\t%s: len %" PRIu32, + __wt_cell_type_string(unpack->raw), unpack->size)); /* Dump cell's per-disk page type information. */ switch (dsk->type) { case WT_PAGE_COL_INT: switch (unpack->type) { case WT_CELL_VALUE: - __dmsg(ds, ", recno: %" PRIu64, unpack->v); + WT_RET(ds->f(ds, ", recno: %" PRIu64, unpack->v)); break; } break; @@ -1045,7 +1069,8 @@ __debug_cell(WT_DBG *ds, const WT_PAGE_HEADER *dsk, WT_CELL_UNPACK *unpack) case WT_CELL_VALUE: case WT_CELL_VALUE_OVFL: case WT_CELL_VALUE_OVFL_RM: - __dmsg(ds, ", rle: %" PRIu64, __wt_cell_rle(unpack)); + WT_RET(ds->f(ds, + ", rle: %" PRIu64, __wt_cell_rle(unpack))); break; } break; @@ -1053,7 +1078,7 @@ __debug_cell(WT_DBG *ds, const WT_PAGE_HEADER *dsk, WT_CELL_UNPACK *unpack) case WT_PAGE_ROW_LEAF: switch (unpack->type) { case WT_CELL_KEY: - __dmsg(ds, ", pfx: %" PRIu8, unpack->prefix); + WT_RET(ds->f(ds, ", pfx: %" PRIu8, unpack->prefix)); break; } break; @@ -1079,13 +1104,14 @@ __debug_cell(WT_DBG *ds, const WT_PAGE_HEADER *dsk, WT_CELL_UNPACK *unpack) case WT_CELL_VALUE_OVFL_RM: type = "ovfl"; addr: WT_RET(__wt_scr_alloc(session, 128, &buf)); - __dmsg(ds, ", %s %s", type, - __wt_addr_string(session, unpack->data, unpack->size, buf)); + WT_RET(ds->f(ds, ", %s %s", type, + __wt_addr_string( + session, unpack->data, unpack->size, buf))); __wt_scr_free(session, &buf); WT_RET(ret); break; } - __dmsg(ds, "\n"); + WT_RET(ds->f(ds, "\n")); return (__debug_cell_data(ds, NULL, dsk->type, NULL, unpack)); } @@ -1110,7 +1136,7 @@ __debug_cell_data(WT_DBG *ds, * reference. */ if (unpack == NULL) { - __debug_item(ds, tag, "deleted", strlen("deleted")); + WT_RET(__debug_item(ds, tag, "deleted", strlen("deleted"))); return (0); } @@ -1123,7 +1149,7 @@ __debug_cell_data(WT_DBG *ds, case WT_CELL_KEY_OVFL_RM: case WT_CELL_VALUE_OVFL_RM: p = __wt_cell_type_string(unpack->raw); - __debug_item(ds, tag, p, strlen(p)); + WT_RET(__debug_item(ds, tag, p, strlen(p))); break; case WT_CELL_KEY: case WT_CELL_KEY_OVFL: @@ -1139,7 +1165,7 @@ __debug_cell_data(WT_DBG *ds, __wt_dsk_cell_data_ref(session, page_type, unpack, buf) : __wt_page_cell_data_ref(session, page, unpack, buf); if (ret == 0) - __debug_item(ds, tag, buf->data, buf->size); + WT_RET(__debug_item(ds, tag, buf->data, buf->size)); __wt_scr_free(session, &buf); break; WT_ILLEGAL_VALUE(session); @@ -1152,21 +1178,23 @@ __debug_cell_data(WT_DBG *ds, * __debug_item -- * Dump a single data/size pair, with an optional tag. */ -static void +static int __debug_item(WT_DBG *ds, const char *tag, const void *data_arg, size_t size) { size_t i; u_char ch; const uint8_t *data; - __dmsg(ds, "\t%s%s{", tag == NULL ? "" : tag, tag == NULL ? "" : " "); + WT_RET(ds->f(ds, + "\t%s%s{", tag == NULL ? "" : tag, tag == NULL ? "" : " ")); for (data = data_arg, i = 0; i < size; ++i, ++data) { ch = data[0]; if (__wt_isprint(ch)) - __dmsg(ds, "%c", (int)ch); + WT_RET(ds->f(ds, "%c", (int)ch)); else - __debug_hex_byte(ds, data[0]); + WT_RET(__debug_hex_byte(ds, data[0])); } - __dmsg(ds, "}\n"); + WT_RET(ds->f(ds, "}\n")); + return (0); } #endif diff --git a/src/third_party/wiredtiger/src/btree/bt_discard.c b/src/third_party/wiredtiger/src/btree/bt_discard.c index a00bb7dc2b5..162bc07a1c2 100644 --- a/src/third_party/wiredtiger/src/btree/bt_discard.c +++ b/src/third_party/wiredtiger/src/btree/bt_discard.c @@ -61,7 +61,7 @@ __wt_page_out(WT_SESSION_IMPL *session, WT_PAGE **pagep) */ WT_ASSERT(session, !__wt_page_is_modified(page)); WT_ASSERT(session, !F_ISSET_ATOMIC(page, WT_PAGE_EVICT_LRU)); - WT_ASSERT(session, !__wt_fair_islocked(session, &page->page_lock)); + WT_ASSERT(session, !__wt_rwlock_islocked(session, &page->page_lock)); #ifdef HAVE_DIAGNOSTIC { @@ -103,6 +103,15 @@ __wt_page_out(WT_SESSION_IMPL *session, WT_PAGE **pagep) /* Update the cache's information. */ __wt_cache_page_evict(session, page); + dsk = (WT_PAGE_HEADER *)page->dsk; + if (F_ISSET_ATOMIC(page, WT_PAGE_DISK_ALLOC)) + __wt_cache_page_image_decr(session, dsk->mem_size); + + /* Discard any mapped image. */ + if (F_ISSET_ATOMIC(page, WT_PAGE_DISK_MAPPED)) + (void)S2BT(session)->bm->map_discard( + S2BT(session)->bm, session, dsk, (size_t)dsk->mem_size); + /* * If discarding the page as part of process exit, the application may * configure to leak the memory rather than do the work. @@ -129,16 +138,10 @@ __wt_page_out(WT_SESSION_IMPL *session, WT_PAGE **pagep) break; } - /* Discard any disk image. */ - dsk = (WT_PAGE_HEADER *)page->dsk; + /* Discard any allocated disk image. */ if (F_ISSET_ATOMIC(page, WT_PAGE_DISK_ALLOC)) __wt_overwrite_and_free_len(session, dsk, dsk->mem_size); - /* Discard any mapped image. */ - if (F_ISSET_ATOMIC(page, WT_PAGE_DISK_MAPPED)) - (void)S2BT(session)->bm->map_discard( - S2BT(session)->bm, session, dsk, (size_t)dsk->mem_size); - __wt_overwrite_and_free(session, page); } diff --git a/src/third_party/wiredtiger/src/btree/bt_handle.c b/src/third_party/wiredtiger/src/btree/bt_handle.c index c97e05d74a7..9591023e163 100644 --- a/src/third_party/wiredtiger/src/btree/bt_handle.c +++ b/src/third_party/wiredtiger/src/btree/bt_handle.c @@ -163,7 +163,7 @@ __wt_btree_close(WT_SESSION_IMPL *session) __wt_btree_huffman_close(session); /* Destroy locks. */ - WT_TRET(__wt_rwlock_destroy(session, &btree->ovfl_lock)); + __wt_rwlock_destroy(session, &btree->ovfl_lock); __wt_spin_destroy(session, &btree->flush_lock); /* Free allocated memory. */ @@ -212,8 +212,8 @@ __btree_conf(WT_SESSION_IMPL *session, WT_CKPT *ckpt) maj_version = cval.val; WT_RET(__wt_config_gets(session, cfg, "version.minor", &cval)); min_version = cval.val; - WT_RET(__wt_verbose(session, WT_VERB_VERSION, - "%" PRIu64 ".%" PRIu64, maj_version, min_version)); + __wt_verbose(session, WT_VERB_VERSION, + "%" PRIu64 ".%" PRIu64, maj_version, min_version); } /* Get the file ID. */ @@ -688,16 +688,21 @@ __btree_page_sizes(WT_SESSION_IMPL *session) /* * Don't let pages grow large compared to the cache size or we can end - * up in a situation where nothing can be evicted. Take care getting - * the cache size: with a shared cache, it may not have been set. + * up in a situation where nothing can be evicted. Make sure at least + * 10 pages fit in cache when it is at the dirty trigger where threads + * stall. + * + * Take care getting the cache size: with a shared cache, it may not + * have been set. Don't forget to update the API documentation if you + * alter the bounds for any of the parameters here. */ WT_RET(__wt_config_gets(session, cfg, "memory_page_max", &cval)); btree->maxmempage = (uint64_t)cval.val; - if (!F_ISSET(conn, WT_CONN_CACHE_POOL)) { - if ((cache_size = conn->cache_size) > 0) - btree->maxmempage = - WT_MIN(btree->maxmempage, cache_size / 10); - } + if (!F_ISSET(conn, WT_CONN_CACHE_POOL) && + (cache_size = conn->cache_size) > 0) + btree->maxmempage = WT_MIN(btree->maxmempage, + (conn->cache->eviction_dirty_trigger * cache_size) / 1000); + /* Enforce a lower bound of a single disk leaf page */ btree->maxmempage = WT_MAX(btree->maxmempage, btree->maxleafpage); diff --git a/src/third_party/wiredtiger/src/btree/bt_io.c b/src/third_party/wiredtiger/src/btree/bt_io.c index 4339de6f25c..8053417f838 100644 --- a/src/third_party/wiredtiger/src/btree/bt_io.c +++ b/src/third_party/wiredtiger/src/btree/bt_io.c @@ -117,7 +117,7 @@ __wt_bt_read(WT_SESSION_IMPL *session, */ if (ret != 0 || result_len != dsk->mem_size - WT_BLOCK_COMPRESS_SKIP) { - fail_msg = "block decryption failed"; + fail_msg = "block decompression failed"; goto corrupt; } } else @@ -168,7 +168,8 @@ err: __wt_scr_free(session, &tmp); */ int __wt_bt_write(WT_SESSION_IMPL *session, WT_ITEM *buf, - uint8_t *addr, size_t *addr_sizep, bool checkpoint, bool compressed) + uint8_t *addr, size_t *addr_sizep, + bool checkpoint, bool checkpoint_io, bool compressed) { WT_BM *bm; WT_BTREE *btree; @@ -181,7 +182,7 @@ __wt_bt_write(WT_SESSION_IMPL *session, WT_ITEM *buf, size_t dst_len, len, result_len, size, src_len; int compression_failed; /* Extension API, so not a bool. */ uint8_t *dst, *src; - bool data_cksum, encrypted; + bool data_checksum, encrypted; btree = S2BT(session); bm = btree->bm; @@ -343,26 +344,28 @@ __wt_bt_write(WT_SESSION_IMPL *session, WT_ITEM *buf, * Checksum the data if the buffer isn't compressed or checksums are * configured. */ - data_cksum = true; /* -Werror=maybe-uninitialized */ + data_checksum = true; /* -Werror=maybe-uninitialized */ switch (btree->checksum) { case CKSUM_ON: - data_cksum = true; + data_checksum = true; break; case CKSUM_OFF: - data_cksum = false; + data_checksum = false; break; case CKSUM_UNCOMPRESSED: - data_cksum = !compressed; + data_checksum = !compressed; break; } /* Call the block manager to write the block. */ WT_ERR(checkpoint ? - bm->checkpoint(bm, session, ip, btree->ckpt, data_cksum) : - bm->write(bm, session, ip, addr, addr_sizep, data_cksum)); + bm->checkpoint(bm, session, ip, btree->ckpt, data_checksum) : + bm->write( + bm, session, ip, addr, addr_sizep, data_checksum, checkpoint_io)); WT_STAT_FAST_CONN_INCR(session, cache_write); WT_STAT_FAST_DATA_INCR(session, cache_write); + S2C(session)->cache->bytes_written += dsk->mem_size; WT_STAT_FAST_CONN_INCRV(session, cache_bytes_write, dsk->mem_size); WT_STAT_FAST_DATA_INCRV(session, cache_bytes_write, dsk->mem_size); diff --git a/src/third_party/wiredtiger/src/btree/bt_ovfl.c b/src/third_party/wiredtiger/src/btree/bt_ovfl.c index fbe361e000a..feb78df75e2 100644 --- a/src/third_party/wiredtiger/src/btree/bt_ovfl.c +++ b/src/third_party/wiredtiger/src/btree/bt_ovfl.c @@ -33,6 +33,7 @@ __ovfl_read(WT_SESSION_IMPL *session, store->data = WT_PAGE_HEADER_BYTE(btree, dsk); store->size = dsk->u.datalen; + WT_STAT_FAST_CONN_INCR(session, cache_read_overflow); WT_STAT_FAST_DATA_INCR(session, cache_read_overflow); return (0); @@ -66,11 +67,11 @@ __wt_ovfl_read(WT_SESSION_IMPL *session, * Acquire the overflow lock, and retest the on-page cell's value inside * the lock. */ - WT_RET(__wt_readlock(session, S2BT(session)->ovfl_lock)); + __wt_readlock(session, S2BT(session)->ovfl_lock); ret = __wt_cell_type_raw(unpack->cell) == WT_CELL_VALUE_OVFL_RM ? __wt_ovfl_txnc_search(page, unpack->data, unpack->size, store) : __ovfl_read(session, unpack->data, unpack->size, store); - WT_TRET(__wt_readunlock(session, S2BT(session)->ovfl_lock)); + __wt_readunlock(session, S2BT(session)->ovfl_lock); return (ret); } @@ -208,6 +209,7 @@ __wt_ovfl_cache(WT_SESSION_IMPL *session, */ if (!visible) { WT_RET(__ovfl_cache(session, page, vpack)); + WT_STAT_FAST_CONN_INCR(session, cache_overflow_value); WT_STAT_FAST_DATA_INCR(session, cache_overflow_value); } @@ -229,7 +231,6 @@ __wt_ovfl_discard(WT_SESSION_IMPL *session, WT_CELL *cell) WT_BM *bm; WT_BTREE *btree; WT_CELL_UNPACK *unpack, _unpack; - WT_DECL_RET; btree = S2BT(session); bm = btree->bm; @@ -248,7 +249,7 @@ __wt_ovfl_discard(WT_SESSION_IMPL *session, WT_CELL *cell) * Acquire the overflow lock to avoid racing with a thread reading the * backing overflow blocks. */ - WT_RET(__wt_writelock(session, btree->ovfl_lock)); + __wt_writelock(session, btree->ovfl_lock); switch (unpack->raw) { case WT_CELL_KEY_OVFL: @@ -262,10 +263,8 @@ __wt_ovfl_discard(WT_SESSION_IMPL *session, WT_CELL *cell) WT_ILLEGAL_VALUE(session); } - WT_TRET(__wt_writeunlock(session, btree->ovfl_lock)); + __wt_writeunlock(session, btree->ovfl_lock); /* Free the backing disk blocks. */ - WT_TRET(bm->free(bm, session, unpack->data, unpack->size)); - - return (ret); + return (bm->free(bm, session, unpack->data, unpack->size)); } diff --git a/src/third_party/wiredtiger/src/btree/bt_page.c b/src/third_party/wiredtiger/src/btree/bt_page.c index 00ec8aa4494..7bac7079fe8 100644 --- a/src/third_party/wiredtiger/src/btree/bt_page.c +++ b/src/third_party/wiredtiger/src/btree/bt_page.c @@ -219,6 +219,7 @@ __wt_page_inmem(WT_SESSION_IMPL *session, WT_REF *ref, /* Update the page's in-memory size and the cache statistics. */ __wt_cache_page_inmem_incr(session, page, size); + __wt_cache_page_image_incr(session, dsk->mem_size); /* Link the new internal page to the parent. */ if (ref != NULL) { @@ -295,7 +296,7 @@ __inmem_col_int(WT_SESSION_IMPL *session, WT_PAGE *page) * __inmem_col_var_repeats -- * Count the number of repeat entries on the page. */ -static int +static void __inmem_col_var_repeats(WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t *np) { WT_BTREE *btree; @@ -315,7 +316,6 @@ __inmem_col_var_repeats(WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t *np) if (__wt_cell_rle(unpack) > 1) ++*np; } - return (0); } /* @@ -366,8 +366,7 @@ __inmem_col_var( rle = __wt_cell_rle(unpack); if (rle > 1) { if (repeats == NULL) { - WT_RET( - __inmem_col_var_repeats(session, page, &n)); + __inmem_col_var_repeats(session, page, &n); WT_RET(__wt_realloc_def(session, &bytes_allocated, n + 1, &repeats)); diff --git a/src/third_party/wiredtiger/src/btree/bt_read.c b/src/third_party/wiredtiger/src/btree/bt_read.c index 086500c8b2f..a23ab0f091f 100644 --- a/src/third_party/wiredtiger/src/btree/bt_read.c +++ b/src/third_party/wiredtiger/src/btree/bt_read.c @@ -147,7 +147,7 @@ __las_page_instantiate(WT_SESSION_IMPL *session, WT_ERR(__wt_scr_alloc(session, 0, &las_value)); /* Open a lookaside table cursor. */ - WT_ERR(__wt_las_cursor(session, &cursor, &session_flags)); + __wt_las_cursor(session, &cursor, &session_flags); /* * The lookaside records are in key and update order, that is, there @@ -296,7 +296,7 @@ err: WT_TRET(__wt_las_cursor_close(session, &cursor, session_flags)); * __evict_force_check -- * Check if a page matches the criteria for forced eviction. */ -static int +static bool __evict_force_check(WT_SESSION_IMPL *session, WT_REF *ref) { WT_BTREE *btree; @@ -307,26 +307,41 @@ __evict_force_check(WT_SESSION_IMPL *session, WT_REF *ref) /* Leaf pages only. */ if (WT_PAGE_IS_INTERNAL(page)) - return (0); + return (false); /* * It's hard to imagine a page with a huge memory footprint that has * never been modified, but check to be sure. */ if (page->modify == NULL) - return (0); + return (false); /* Pages are usually small enough, check that first. */ if (page->memory_footprint < btree->splitmempage) - return (0); - else if (page->memory_footprint < btree->maxmempage) + return (false); + + /* + * If this session has more than one hazard pointer, eviction will fail + * and there is no point trying. + */ + if (__wt_hazard_count(session, page) > 1) + return (false); + + /* + * If we have already tried and the transaction state has not moved on, + * eviction is highly likely to fail. + */ + if (page->modify->last_eviction_id == __wt_txn_oldest_id(session)) + return (false); + + if (page->memory_footprint < btree->maxmempage) return (__wt_leaf_page_can_split(session, page)); /* Trigger eviction on the next page release. */ - __wt_page_evict_soon(page); + __wt_page_evict_soon(session, ref); /* Bump the oldest ID, we're about to do some visibility checks. */ - WT_RET(__wt_txn_update_oldest(session, 0)); + WT_IGNORE_RET(__wt_txn_update_oldest(session, 0)); /* If eviction cannot succeed, don't try. */ return (__wt_page_can_evict(session, ref, NULL)); @@ -461,8 +476,15 @@ __wt_page_in_func(WT_SESSION_IMPL *session, WT_REF *ref, uint32_t flags btree = S2BT(session); - WT_STAT_FAST_CONN_INCR(session, cache_pages_requested); - WT_STAT_FAST_DATA_INCR(session, cache_pages_requested); + /* + * Ignore reads of pages already known to be in cache, otherwise the + * eviction server can dominate these statistics. + */ + if (!LF_ISSET(WT_READ_CACHE)) { + WT_STAT_FAST_CONN_INCR(session, cache_pages_requested); + WT_STAT_FAST_DATA_INCR(session, cache_pages_requested); + } + for (evict_soon = stalled = false, force_attempts = 0, sleep_cnt = wait_cnt = 0;;) { switch (ref->state) { @@ -548,10 +570,14 @@ __wt_page_in_func(WT_SESSION_IMPL *session, WT_REF *ref, uint32_t flags * if the page qualifies for forced eviction and update * the page's generation number. If eviction isn't being * done on this file, we're done. + * In-memory split of large pages is allowed while + * no_eviction is set on btree, whereas reconciliation + * is not allowed. */ if (LF_ISSET(WT_READ_NO_EVICT) || F_ISSET(session, WT_SESSION_NO_EVICTION) || - F_ISSET(btree, WT_BTREE_NO_EVICTION)) + (F_ISSET(btree, WT_BTREE_NO_EVICTION) && + !F_ISSET(btree, WT_BTREE_NO_RECONCILE))) goto skip_evict; /* @@ -595,7 +621,7 @@ __wt_page_in_func(WT_SESSION_IMPL *session, WT_REF *ref, uint32_t flags page = ref->page; if (page->read_gen == WT_READGEN_NOTSET) { if (evict_soon) - __wt_page_evict_soon(page); + __wt_page_evict_soon(session, ref); else __wt_cache_read_gen_new(session, page); } else if (!LF_ISSET(WT_READ_NO_GEN)) diff --git a/src/third_party/wiredtiger/src/btree/bt_rebalance.c b/src/third_party/wiredtiger/src/btree/bt_rebalance.c index de54e8433a8..29380459b94 100644 --- a/src/third_party/wiredtiger/src/btree/bt_rebalance.c +++ b/src/third_party/wiredtiger/src/btree/bt_rebalance.c @@ -65,10 +65,10 @@ __rebalance_leaf_append(WT_SESSION_IMPL *session, WT_ADDR *copy_addr; WT_REF *copy; - WT_RET(__wt_verbose(session, WT_VERB_REBALANCE, + __wt_verbose(session, WT_VERB_REBALANCE, "rebalance leaf-list append %s, %s", __wt_buf_set_printable(session, key, key_len, rs->tmp2), - __wt_addr_string(session, addr, addr_len, rs->tmp1))); + __wt_addr_string(session, addr, addr_len, rs->tmp1)); /* Allocate and initialize a new leaf page reference. */ WT_RET(__wt_realloc_def( @@ -179,10 +179,10 @@ __rebalance_free_original(WT_SESSION_IMPL *session, WT_REBALANCE_STUFF *rs) for (i = 0; i < rs->fl_next; ++i) { addr = &rs->fl[i]; - WT_RET(__wt_verbose(session, WT_VERB_REBALANCE, + __wt_verbose(session, WT_VERB_REBALANCE, "rebalance discarding %s", __wt_addr_string( - session, addr->addr, addr->size, rs->tmp1))); + session, addr->addr, addr->size, rs->tmp1)); WT_RET(__wt_btree_block_free(session, addr->addr, addr->size)); } @@ -225,10 +225,10 @@ __rebalance_col_walk( WT_ERR(__wt_bt_read( session, buf, unpack.data, unpack.size)); WT_ERR(__rebalance_col_walk(session, buf->data, rs)); - WT_ERR(__wt_verbose(session, WT_VERB_REBALANCE, + __wt_verbose(session, WT_VERB_REBALANCE, "free-list append internal page: %s", __wt_addr_string( - session, unpack.data, unpack.size, rs->tmp1))); + session, unpack.data, unpack.size, rs->tmp1)); WT_ERR(__rebalance_fl_append( session, unpack.data, unpack.size, rs)); break; @@ -321,10 +321,10 @@ __rebalance_row_walk( * that's more work to get reconciliation to understand * and overflow keys are (well, should be), uncommon. */ - WT_ERR(__wt_verbose(session, WT_VERB_REBALANCE, + __wt_verbose(session, WT_VERB_REBALANCE, "free-list append overflow key: %s", __wt_addr_string( - session, unpack.data, unpack.size, rs->tmp1))); + session, unpack.data, unpack.size, rs->tmp1)); WT_ERR(__rebalance_fl_append( session, unpack.data, unpack.size, rs)); @@ -342,10 +342,10 @@ __rebalance_row_walk( break; case WT_CELL_ADDR_INT: /* An internal page, schedule its blocks to be freed. */ - WT_ERR(__wt_verbose(session, WT_VERB_REBALANCE, + __wt_verbose(session, WT_VERB_REBALANCE, "free-list append internal page: %s", __wt_addr_string( - session, unpack.data, unpack.size, rs->tmp1))); + session, unpack.data, unpack.size, rs->tmp1)); WT_ERR(__rebalance_fl_append( session, unpack.data, unpack.size, rs)); diff --git a/src/third_party/wiredtiger/src/btree/bt_slvg.c b/src/third_party/wiredtiger/src/btree/bt_slvg.c index 9b5e4daf74a..f269c2d7f43 100644 --- a/src/third_party/wiredtiger/src/btree/bt_slvg.c +++ b/src/third_party/wiredtiger/src/btree/bt_slvg.c @@ -119,7 +119,7 @@ static int __slvg_col_build_leaf(WT_SESSION_IMPL *, WT_TRACK *, WT_REF *); static int __slvg_col_ovfl(WT_SESSION_IMPL *, WT_TRACK *, WT_PAGE *, uint64_t, uint64_t, uint64_t); static int __slvg_col_range(WT_SESSION_IMPL *, WT_STUFF *); -static int __slvg_col_range_missing(WT_SESSION_IMPL *, WT_STUFF *); +static void __slvg_col_range_missing(WT_SESSION_IMPL *, WT_STUFF *); static int __slvg_col_range_overlap( WT_SESSION_IMPL *, uint32_t, uint32_t, WT_STUFF *); static void __slvg_col_trk_update_start(uint32_t, WT_STUFF *); @@ -281,7 +281,7 @@ __wt_bt_salvage(WT_SESSION_IMPL *session, WT_CKPT *ckptbase, const char *cfg[]) switch (ss->page_type) { case WT_PAGE_COL_FIX: case WT_PAGE_COL_VAR: - WT_ERR(__slvg_col_range_missing(session, ss)); + __slvg_col_range_missing(session, ss); break; case WT_PAGE_ROW_LEAF: break; @@ -431,10 +431,10 @@ __slvg_read(WT_SESSION_IMPL *session, WT_STUFF *ss) case WT_PAGE_BLOCK_MANAGER: case WT_PAGE_COL_INT: case WT_PAGE_ROW_INT: - WT_ERR(__wt_verbose(session, WT_VERB_SALVAGE, + __wt_verbose(session, WT_VERB_SALVAGE, "%s page ignored %s", __wt_page_type_string(dsk->type), - (const char *)as->data)); + (const char *)as->data); WT_ERR(bm->free(bm, session, addr, addr_size)); continue; } @@ -449,18 +449,18 @@ __slvg_read(WT_SESSION_IMPL *session, WT_STUFF *ss) * discard these pages now. */ if (__wt_verify_dsk(session, as->data, buf) != 0) { - WT_ERR(__wt_verbose(session, WT_VERB_SALVAGE, + __wt_verbose(session, WT_VERB_SALVAGE, "%s page failed verify %s", __wt_page_type_string(dsk->type), - (const char *)as->data)); + (const char *)as->data); WT_ERR(bm->free(bm, session, addr, addr_size)); continue; } - WT_ERR(__wt_verbose(session, WT_VERB_SALVAGE, + __wt_verbose(session, WT_VERB_SALVAGE, "tracking %s page, generation %" PRIu64 " %s", __wt_page_type_string(dsk->type), dsk->write_gen, - (const char *)as->data)); + (const char *)as->data); switch (dsk->type) { case WT_PAGE_COL_FIX: @@ -562,11 +562,11 @@ __slvg_trk_leaf(WT_SESSION_IMPL *session, trk->col_start = dsk->recno; trk->col_stop = dsk->recno + (dsk->u.entries - 1); - WT_ERR(__wt_verbose(session, WT_VERB_SALVAGE, + __wt_verbose(session, WT_VERB_SALVAGE, "%s records %" PRIu64 "-%" PRIu64, __wt_addr_string( session, trk->trk_addr, trk->trk_addr_size, ss->tmp1), - trk->col_start, trk->col_stop)); + trk->col_start, trk->col_stop); break; case WT_PAGE_COL_VAR: /* @@ -583,11 +583,11 @@ __slvg_trk_leaf(WT_SESSION_IMPL *session, trk->col_start = dsk->recno; trk->col_stop = stop_recno - 1; - WT_ERR(__wt_verbose(session, WT_VERB_SALVAGE, + __wt_verbose(session, WT_VERB_SALVAGE, "%s records %" PRIu64 "-%" PRIu64, __wt_addr_string( session, trk->trk_addr, trk->trk_addr_size, ss->tmp1), - trk->col_start, trk->col_stop)); + trk->col_start, trk->col_stop); /* Column-store pages can contain overflow items. */ WT_ERR(__slvg_trk_leaf_ovfl(session, dsk, trk)); @@ -607,18 +607,18 @@ __slvg_trk_leaf(WT_SESSION_IMPL *session, WT_ERR(__wt_row_leaf_key_copy(session, page, &page->pg_row_d[page->pg_row_entries - 1], &trk->row_stop)); - WT_ERR(__wt_verbose(session, WT_VERB_SALVAGE, + __wt_verbose(session, WT_VERB_SALVAGE, "%s start key %s", __wt_addr_string(session, trk->trk_addr, trk->trk_addr_size, ss->tmp1), __wt_buf_set_printable(session, - trk->row_start.data, trk->row_start.size, ss->tmp2))); - WT_ERR(__wt_verbose(session, WT_VERB_SALVAGE, + trk->row_start.data, trk->row_start.size, ss->tmp2)); + __wt_verbose(session, WT_VERB_SALVAGE, "%s stop key %s", __wt_addr_string(session, trk->trk_addr, trk->trk_addr_size, ss->tmp1), __wt_buf_set_printable(session, - trk->row_stop.data, trk->row_stop.size, ss->tmp2))); + trk->row_stop.data, trk->row_stop.size, ss->tmp2)); /* Row-store pages can contain overflow items. */ WT_ERR(__slvg_trk_leaf_ovfl(session, dsk, trk)); @@ -700,12 +700,12 @@ __slvg_trk_leaf_ovfl( trk->trk_ovfl_addr[ovfl_cnt].size = (uint8_t)unpack->size; - WT_RET(__wt_verbose(session, WT_VERB_SALVAGE, + __wt_verbose(session, WT_VERB_SALVAGE, "%s overflow reference %s", __wt_addr_string(session, trk->trk_addr, trk->trk_addr_size, trk->ss->tmp1), __wt_addr_string(session, - unpack->data, unpack->size, trk->ss->tmp2))); + unpack->data, unpack->size, trk->ss->tmp2)); if (++ovfl_cnt == trk->trk_ovfl_cnt) break; @@ -871,12 +871,12 @@ __slvg_col_range_overlap( a_trk = ss->pages[a_slot]; b_trk = ss->pages[b_slot]; - WT_RET(__wt_verbose(session, WT_VERB_SALVAGE, + __wt_verbose(session, WT_VERB_SALVAGE, "%s and %s range overlap", __wt_addr_string( session, a_trk->trk_addr, a_trk->trk_addr_size, ss->tmp1), __wt_addr_string( - session, b_trk->trk_addr, b_trk->trk_addr_size, ss->tmp2))); + session, b_trk->trk_addr, b_trk->trk_addr_size, ss->tmp2)); /* * The key ranges of two WT_TRACK pages in the array overlap -- choose @@ -1053,12 +1053,12 @@ delete_b: /* F_SET(new, WT_TRACK_MERGE); F_SET(a_trk, WT_TRACK_MERGE); -merge: WT_RET(__wt_verbose(session, WT_VERB_SALVAGE, +merge: __wt_verbose(session, WT_VERB_SALVAGE, "%s and %s require merge", __wt_addr_string( session, a_trk->trk_addr, a_trk->trk_addr_size, ss->tmp1), __wt_addr_string( - session, b_trk->trk_addr, b_trk->trk_addr_size, ss->tmp2))); + session, b_trk->trk_addr, b_trk->trk_addr_size, ss->tmp2)); return (0); } @@ -1107,7 +1107,7 @@ __slvg_col_trk_update_start(uint32_t slot, WT_STUFF *ss) * __slvg_col_range_missing -- * Detect missing ranges from column-store files. */ -static int +static void __slvg_col_range_missing(WT_SESSION_IMPL *session, WT_STUFF *ss) { WT_TRACK *trk; @@ -1118,12 +1118,12 @@ __slvg_col_range_missing(WT_SESSION_IMPL *session, WT_STUFF *ss) if ((trk = ss->pages[i]) == NULL) continue; if (trk->col_start != r + 1) { - WT_RET(__wt_verbose(session, WT_VERB_SALVAGE, + __wt_verbose(session, WT_VERB_SALVAGE, "%s column-store missing range from %" PRIu64 " to %" PRIu64 " inclusive", __wt_addr_string(session, trk->trk_addr, trk->trk_addr_size, ss->tmp1), - r + 1, trk->col_start - 1)); + r + 1, trk->col_start - 1); /* * We need to instantiate deleted items for the missing @@ -1134,7 +1134,6 @@ __slvg_col_range_missing(WT_SESSION_IMPL *session, WT_STUFF *ss) } r = trk->col_stop; } - return (0); } /* @@ -1259,12 +1258,12 @@ __slvg_col_build_leaf(WT_SESSION_IMPL *session, WT_TRACK *trk, WT_REF *ref) cookie->skip = skip = trk->col_start - recno; cookie->take = take = (trk->col_stop - trk->col_start) + 1; - WT_ERR(__wt_verbose(session, WT_VERB_SALVAGE, + __wt_verbose(session, WT_VERB_SALVAGE, "%s merge discarding first %" PRIu64 " records, " "then taking %" PRIu64 " records", __wt_addr_string( session, trk->trk_addr, trk->trk_addr_size, trk->ss->tmp1), - skip, take)); + skip, take); /* Set the referenced flag on overflow pages we're using. */ if (page->type == WT_PAGE_COL_VAR && trk->trk_ovfl_cnt != 0) @@ -1281,11 +1280,11 @@ __slvg_col_build_leaf(WT_SESSION_IMPL *session, WT_TRACK *trk, WT_REF *ref) ref->ref_recno = trk->col_missing; cookie->missing = trk->col_start - trk->col_missing; - WT_ERR(__wt_verbose(session, WT_VERB_SALVAGE, + __wt_verbose(session, WT_VERB_SALVAGE, "%s merge inserting %" PRIu64 " missing records", __wt_addr_string( session, trk->trk_addr, trk->trk_addr_size, trk->ss->tmp1), - cookie->missing)); + cookie->missing); } /* @@ -1501,12 +1500,12 @@ __slvg_row_range_overlap( a_trk = ss->pages[a_slot]; b_trk = ss->pages[b_slot]; - WT_RET(__wt_verbose(session, WT_VERB_SALVAGE, + __wt_verbose(session, WT_VERB_SALVAGE, "%s and %s range overlap", __wt_addr_string( session, a_trk->trk_addr, a_trk->trk_addr_size, ss->tmp1), __wt_addr_string( - session, b_trk->trk_addr, b_trk->trk_addr_size, ss->tmp2))); + session, b_trk->trk_addr, b_trk->trk_addr_size, ss->tmp2)); /* * The key ranges of two WT_TRACK pages in the array overlap -- choose @@ -1698,12 +1697,12 @@ delete_b: /* F_SET(new, WT_TRACK_MERGE); F_SET(a_trk, WT_TRACK_MERGE); -merge: WT_RET(__wt_verbose(session, WT_VERB_SALVAGE, +merge: __wt_verbose(session, WT_VERB_SALVAGE, "%s and %s require merge", __wt_addr_string( session, a_trk->trk_addr, a_trk->trk_addr_size, ss->tmp1), __wt_addr_string( - session, b_trk->trk_addr, b_trk->trk_addr_size, ss->tmp2))); + session, b_trk->trk_addr, b_trk->trk_addr_size, ss->tmp2)); return (0); } @@ -1942,12 +1941,12 @@ __slvg_row_build_leaf( btree->collator, key, &trk->row_start, &cmp)); if (cmp >= 0) break; - WT_ERR(__wt_verbose(session, WT_VERB_SALVAGE, - "%s merge discarding leading key %.*s", + __wt_verbose(session, WT_VERB_SALVAGE, + "%s merge discarding leading key %s", __wt_addr_string(session, trk->trk_addr, trk->trk_addr_size, ss->tmp1), __wt_buf_set_printable( - session, key->data, key->size, ss->tmp2))); + session, key->data, key->size, ss->tmp2)); ++skip_start; } if (F_ISSET(trk, WT_TRACK_CHECK_STOP)) @@ -1962,12 +1961,12 @@ __slvg_row_build_leaf( btree->collator, key, &trk->row_stop, &cmp)); if (cmp < 0) break; - WT_ERR(__wt_verbose(session, WT_VERB_SALVAGE, - "%s merge discarding trailing key %.*s", + __wt_verbose(session, WT_VERB_SALVAGE, + "%s merge discarding trailing key %s", __wt_addr_string(session, trk->trk_addr, trk->trk_addr_size, ss->tmp1), __wt_buf_set_printable( - session, key->data, key->size, ss->tmp2))); + session, key->data, key->size, ss->tmp2)); ++skip_stop; } @@ -2204,12 +2203,12 @@ __slvg_ovfl_reconcile(WT_SESSION_IMPL *session, WT_STUFF *ss) continue; } - WT_ERR(__wt_verbose(session, WT_VERB_SALVAGE, + __wt_verbose(session, WT_VERB_SALVAGE, "%s references unavailable overflow page %s", __wt_addr_string(session, trk->trk_addr, trk->trk_addr_size, ss->tmp1), __wt_addr_string(session, - addr->addr, addr->size, ss->tmp2))); + addr->addr, addr->size, ss->tmp2)); /* * Clear the "referenced" flag for any overflow pages @@ -2405,10 +2404,10 @@ __slvg_ovfl_discard(WT_SESSION_IMPL *session, WT_STUFF *ss) F_CLR(trk, WT_TRACK_OVFL_REFD); continue; } - WT_RET(__wt_verbose(session, WT_VERB_SALVAGE, + __wt_verbose(session, WT_VERB_SALVAGE, "%s unused overflow page", __wt_addr_string( - session, trk->trk_addr, trk->trk_addr_size, ss->tmp1))); + session, trk->trk_addr, trk->trk_addr_size, ss->tmp1)); WT_RET(__slvg_trk_free(session, &ss->ovfl[i], true)); } @@ -2470,10 +2469,10 @@ __slvg_trk_free_block(WT_SESSION_IMPL *session, WT_TRACK *trk) * If freeing underlying file blocks or overflow pages, this is a page * we were tracking but eventually decided not to use. */ - WT_RET(__wt_verbose(session, WT_VERB_SALVAGE, + __wt_verbose(session, WT_VERB_SALVAGE, "%s blocks discarded: discard freed file bytes %" PRIu32, __wt_addr_string(session, - trk->trk_addr, trk->trk_addr_size, trk->ss->tmp1), trk->trk_size)); + trk->trk_addr, trk->trk_addr_size, trk->ss->tmp1), trk->trk_size); return (bm->free(bm, session, trk->trk_addr, trk->trk_addr_size)); } diff --git a/src/third_party/wiredtiger/src/btree/bt_split.c b/src/third_party/wiredtiger/src/btree/bt_split.c index 7a05a883f83..e05f3746052 100644 --- a/src/third_party/wiredtiger/src/btree/bt_split.c +++ b/src/third_party/wiredtiger/src/btree/bt_split.c @@ -298,7 +298,7 @@ static int __split_ref_move(WT_SESSION_IMPL *session, WT_PAGE *from_home, WT_REF **from_refp, size_t *decrp, WT_REF **to_refp, size_t *incrp) { - WT_ADDR *addr; + WT_ADDR *addr, *ref_addr; WT_CELL_UNPACK unpack; WT_DECL_RET; WT_IKEY *ikey; @@ -345,13 +345,18 @@ __split_ref_move(WT_SESSION_IMPL *session, WT_PAGE *from_home, } /* - * If there's no address (the page has never been written), or the - * address has been instantiated, there's no work to do. Otherwise, - * instantiate the address in-memory, from the on-page cell. + * If there's no address at all (the page has never been written), or + * the address has already been instantiated, there's no work to do. + * Otherwise, the address still references a split page on-page cell, + * instantiate it. We can race with reconciliation and/or eviction of + * the child pages, be cautious: read the address and verify it, and + * only update it if the value is unchanged from the original. In the + * case of a race, the address must no longer reference the split page, + * we're done. */ - addr = ref->addr; - if (addr != NULL && !__wt_off_page(from_home, addr)) { - __wt_cell_unpack((WT_CELL *)ref->addr, &unpack); + WT_ORDERED_READ(ref_addr, ref->addr); + if (ref_addr != NULL && !__wt_off_page(from_home, ref_addr)) { + __wt_cell_unpack((WT_CELL *)ref_addr, &unpack); WT_RET(__wt_calloc_one(session, &addr)); if ((ret = __wt_strndup( session, unpack.data, unpack.size, &addr->addr)) != 0) { @@ -371,7 +376,10 @@ __split_ref_move(WT_SESSION_IMPL *session, WT_PAGE *from_home, break; WT_ILLEGAL_VALUE(session); } - ref->addr = addr; + if (!__wt_atomic_cas_ptr(&ref->addr, ref_addr, addr)) { + __wt_free(session, addr->addr); + __wt_free(session, addr); + } } /* And finally, copy the WT_REF pointer itself. */ @@ -569,10 +577,10 @@ __split_root(WT_SESSION_IMPL *session, WT_PAGE *root) chunk = pindex->entries / children; remain = pindex->entries - chunk * (children - 1); - WT_ERR(__wt_verbose(session, WT_VERB_SPLIT, + __wt_verbose(session, WT_VERB_SPLIT, "%p: %" PRIu32 " root page elements, splitting into %" PRIu32 " children", - root, pindex->entries, children)); + (void *)root, pindex->entries, children); /* * Allocate a new WT_PAGE_INDEX and set of WT_REF objects to be inserted @@ -786,7 +794,9 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref, WT_REF **ref_new, */ if (result_entries == 0) { empty_parent = true; - __wt_page_evict_soon(parent); + if (!__wt_ref_is_root(parent->pg_intl_parent_ref)) + __wt_page_evict_soon( + session, parent->pg_intl_parent_ref); goto err; } @@ -878,17 +888,19 @@ __split_parent(WT_SESSION_IMPL *session, WT_REF *ref, WT_REF **ref_new, */ if (ref->page == NULL) - WT_ERR(__wt_verbose(session, WT_VERB_SPLIT, + __wt_verbose(session, WT_VERB_SPLIT, "%p: reverse split into parent %p, %" PRIu32 " -> %" PRIu32 " (-%" PRIu32 ")", - ref->page, parent, parent_entries, result_entries, - parent_entries - result_entries)); + (void *)ref->page, (void *)parent, + parent_entries, result_entries, + parent_entries - result_entries); else - WT_ERR(__wt_verbose(session, WT_VERB_SPLIT, + __wt_verbose(session, WT_VERB_SPLIT, "%p: split into parent %p, %" PRIu32 " -> %" PRIu32 " (+%" PRIu32 ")", - ref->page, parent, parent_entries, result_entries, - result_entries - parent_entries)); + (void *)ref->page, (void *)parent, + parent_entries, result_entries, + result_entries - parent_entries); /* * The new page index is in place, free the WT_REF we were splitting and @@ -1050,10 +1062,10 @@ __split_internal(WT_SESSION_IMPL *session, WT_PAGE *parent, WT_PAGE *page) chunk = pindex->entries / children; remain = pindex->entries - chunk * (children - 1); - WT_ERR(__wt_verbose(session, WT_VERB_SPLIT, + __wt_verbose(session, WT_VERB_SPLIT, "%p: %" PRIu32 " internal page elements, splitting %" PRIu32 " children into parent %p", - page, pindex->entries, children, parent)); + (void *)page, pindex->entries, children, (void *)parent); /* * Ideally, we'd discard the original page, but that's hard since other @@ -1277,12 +1289,12 @@ __split_internal_lock(WT_SESSION_IMPL *session, WT_REF *ref, bool trylock, return (EBUSY); if (trylock) - WT_RET(__wt_fair_trylock(session, &parent->page_lock)); + WT_RET(__wt_try_writelock(session, &parent->page_lock)); else - WT_RET(__wt_fair_lock(session, &parent->page_lock)); + __wt_writelock(session, &parent->page_lock); if (parent == ref->home) break; - WT_RET(__wt_fair_unlock(session, &parent->page_lock)); + __wt_writeunlock(session, &parent->page_lock); } /* @@ -1305,7 +1317,7 @@ __split_internal_lock(WT_SESSION_IMPL *session, WT_REF *ref, bool trylock, *parentp = parent; return (0); -err: WT_TRET(__wt_fair_unlock(session, &parent->page_lock)); +err: __wt_writeunlock(session, &parent->page_lock); return (ret); } @@ -1321,7 +1333,7 @@ __split_internal_unlock(WT_SESSION_IMPL *session, WT_PAGE *parent, bool hazard) if (hazard) ret = __wt_hazard_clear(session, parent); - WT_TRET(__wt_fair_unlock(session, &parent->page_lock)); + __wt_writeunlock(session, &parent->page_lock); return (ret); } @@ -1462,11 +1474,11 @@ err: if (parent != NULL) /* * __split_multi_inmem -- - * Instantiate a page in a multi-block set. + * Instantiate a page from a disk image. */ static int __split_multi_inmem( - WT_SESSION_IMPL *session, WT_PAGE *orig, WT_REF *ref, WT_MULTI *multi) + WT_SESSION_IMPL *session, WT_PAGE *orig, WT_MULTI *multi, WT_REF *ref) { WT_CURSOR_BTREE cbt; WT_DECL_ITEM(key); @@ -1487,13 +1499,12 @@ __split_multi_inmem( orig->type != WT_PAGE_COL_VAR || ref->ref_recno != 0); /* - * This code re-creates an in-memory page that is part of a set created - * while evicting a large page, and adds references to any unresolved - * update chains to the new page. We get here due to choosing to keep - * the results of a split in memory or because and update could not be - * written when attempting to evict a page. + * This code re-creates an in-memory page from a disk image, and adds + * references to any unresolved update chains to the new page. We get + * here either because an update could not be written when evicting a + * page, or eviction chose to keep a page in memory. * - * Clear the disk image and link the page into the passed-in WT_REF to + * Steal the disk image and link the page into the passed-in WT_REF to * simplify error handling: our caller will not discard the disk image * when discarding the original page, and our caller will discard the * allocated page on error, when discarding the allocated WT_REF. @@ -1503,6 +1514,19 @@ __split_multi_inmem( WT_PAGE_DISK_ALLOC, &page)); multi->disk_image = NULL; + /* + * Put the re-instantiated page in the same LRU queue location as the + * original page, unless this was a forced eviction, in which case we + * leave the new page with the read generation unset. Eviction will + * set the read generation next time it visits this page. + */ + if (orig->read_gen != WT_READGEN_OLDEST) + page->read_gen = orig->read_gen; + + /* If there are no updates to apply to the page, we're done. */ + if (multi->supd_entries == 0) + return (0); + if (orig->type == WT_PAGE_ROW_LEAF) WT_RET(__wt_scr_alloc(session, 0, &key)); @@ -1551,14 +1575,12 @@ __split_multi_inmem( } /* - * If we modified the page above, it will have set the first dirty - * transaction to the last transaction currently running. However, the - * updates we installed may be older than that. Set the first dirty - * transaction to an impossibly old value so this page is never skipped - * in a checkpoint. + * When modifying the page we set the first dirty transaction to the + * last transaction currently running. However, the updates we made + * might be older than that. Set the first dirty transaction to an + * impossibly old value so this page is never skipped in a checkpoint. */ - if (page->modify != NULL) - page->modify->first_dirty_txn = WT_TXN_FIRST; + page->modify->first_dirty_txn = WT_TXN_FIRST; err: /* Free any resources that may have been cached in the cursor. */ WT_TRET(__wt_btcur_close(&cbt, true)); @@ -1629,19 +1651,17 @@ __split_multi_inmem_fail(WT_SESSION_IMPL *session, WT_PAGE *orig, WT_REF *ref) */ int __wt_multi_to_ref(WT_SESSION_IMPL *session, - WT_PAGE *page, WT_MULTI *multi, WT_REF **refp, size_t *incrp) + WT_PAGE *page, WT_MULTI *multi, WT_REF **refp, size_t *incrp, bool closing) { WT_ADDR *addr; WT_IKEY *ikey; WT_REF *ref; - size_t incr; - - incr = 0; /* Allocate an underlying WT_REF. */ WT_RET(__wt_calloc_one(session, refp)); ref = *refp; - incr += sizeof(WT_REF); + if (incrp) + *incrp += sizeof(WT_REF); /* * Set the WT_REF key before (optionally) building the page, underlying @@ -1653,21 +1673,34 @@ __wt_multi_to_ref(WT_SESSION_IMPL *session, ikey = multi->key.ikey; WT_RET(__wt_row_ikey( session, 0, WT_IKEY_DATA(ikey), ikey->size, ref)); - incr += sizeof(WT_IKEY) + ikey->size; + if (incrp) + *incrp += sizeof(WT_IKEY) + ikey->size; break; default: ref->ref_recno = multi->key.recno; break; } - /* If there's a disk image, build a page, otherwise set the address. */ - if (multi->disk_image == NULL) { - /* - * Copy the address: we could simply take the buffer, but that - * would complicate error handling, freeing the reference array - * would have to avoid freeing the memory, and it's not worth - * the confusion. - */ + /* There should be an address or a disk image (or both). */ + WT_ASSERT(session, + multi->addr.addr != NULL || multi->disk_image != NULL); + + /* If we're closing the file, there better be an address. */ + WT_ASSERT(session, multi->addr.addr != NULL || !closing); + + /* Verify any disk image we have. */ + WT_ASSERT(session, multi->disk_image == NULL || + __wt_verify_dsk_image(session, + "[page instantiate]", multi->disk_image, 0, false) == 0); + + /* + * If there's an address, the page was written, set it. + * + * Copy the address: we could simply take the buffer, but that would + * complicate error handling, freeing the reference array would have + * to avoid freeing the memory, and it's not worth the confusion. + */ + if (multi->addr.addr != NULL) { WT_RET(__wt_calloc_one(session, &addr)); ref->addr = addr; addr->size = multi->addr.size; @@ -1675,14 +1708,20 @@ __wt_multi_to_ref(WT_SESSION_IMPL *session, WT_RET(__wt_strndup(session, multi->addr.addr, addr->size, &addr->addr)); ref->state = WT_REF_DISK; - } else { - WT_RET(__split_multi_inmem(session, page, ref, multi)); + } + + /* + * If we have a disk image and we're not closing the file, + * re-instantiate the page. + * + * Discard any page image we don't use. + */ + if (multi->disk_image != NULL && !closing) { + WT_RET(__split_multi_inmem(session, page, multi, ref)); ref->state = WT_REF_MEM; } + __wt_free(session, multi->disk_image); - /* Optionally return changes in the memory footprint. */ - if (incrp != NULL) - *incrp += incr; return (0); } @@ -2040,8 +2079,8 @@ __wt_split_insert(WT_SESSION_IMPL *session, WT_REF *ref) WT_PAGE *parent; bool hazard; - WT_RET(__wt_verbose( - session, WT_VERB_SPLIT, "%p: split-insert", ref->page)); + __wt_verbose( + session, WT_VERB_SPLIT, "%p: split-insert", (void *)ref->page); WT_RET(__split_internal_lock(session, ref, true, &parent, &hazard)); if ((ret = __split_insert(session, ref)) != 0) { @@ -2086,8 +2125,8 @@ __split_multi(WT_SESSION_IMPL *session, WT_REF *ref, bool closing) */ WT_RET(__wt_calloc_def(session, new_entries, &ref_new)); for (i = 0; i < new_entries; ++i) - WT_ERR(__wt_multi_to_ref(session, - page, &mod->mod_multi[i], &ref_new[i], &parent_incr)); + WT_ERR(__wt_multi_to_ref(session, page, + &mod->mod_multi[i], &ref_new[i], &parent_incr, closing)); /* * Split into the parent; if we're closing the file, we hold it @@ -2132,8 +2171,8 @@ __wt_split_multi(WT_SESSION_IMPL *session, WT_REF *ref, int closing) WT_PAGE *parent; bool hazard; - WT_RET(__wt_verbose( - session, WT_VERB_SPLIT, "%p: split-multi", ref->page)); + __wt_verbose( + session, WT_VERB_SPLIT, "%p: split-multi", (void *)ref->page); WT_RET(__split_internal_lock(session, ref, false, &parent, &hazard)); if ((ret = __split_multi(session, ref, closing)) != 0 || closing) { @@ -2161,8 +2200,8 @@ __wt_split_reverse(WT_SESSION_IMPL *session, WT_REF *ref) WT_PAGE *parent; bool hazard; - WT_RET(__wt_verbose( - session, WT_VERB_SPLIT, "%p: reverse-split", ref->page)); + __wt_verbose( + session, WT_VERB_SPLIT, "%p: reverse-split", (void *)ref->page); WT_RET(__split_internal_lock(session, ref, false, &parent, &hazard)); ret = __split_parent(session, ref, NULL, 0, 0, false, true); @@ -2175,18 +2214,16 @@ __wt_split_reverse(WT_SESSION_IMPL *session, WT_REF *ref) * Rewrite an in-memory page with a new version. */ int -__wt_split_rewrite(WT_SESSION_IMPL *session, WT_REF *ref) +__wt_split_rewrite(WT_SESSION_IMPL *session, WT_REF *ref, WT_MULTI *multi) { WT_DECL_RET; WT_PAGE *page; - WT_PAGE_MODIFY *mod; WT_REF *new; page = ref->page; - mod = page->modify; - WT_RET(__wt_verbose( - session, WT_VERB_SPLIT, "%p: split-rewrite", ref->page)); + __wt_verbose( + session, WT_VERB_SPLIT, "%p: split-rewrite", (void *)ref->page); /* * This isn't a split: a reconciliation failed because we couldn't write @@ -2198,14 +2235,22 @@ __wt_split_rewrite(WT_SESSION_IMPL *session, WT_REF *ref) * * Build the new page. * - * Allocate a WT_REF because the error path uses routines that will ea - * free memory. The only field we need to set is the record number, as - * it's used by the search routines. + * Allocate a WT_REF, the error path calls routines that free memory. + * The only field we need to set is the record number, as it's used by + * the search routines. */ WT_RET(__wt_calloc_one(session, &new)); new->ref_recno = ref->ref_recno; - WT_ERR(__split_multi_inmem(session, page, new, &mod->mod_multi[0])); + WT_ERR(__split_multi_inmem(session, page, multi, new)); + + /* + * If the new page is modified, save the oldest ID from reconciliation + * to avoid repeatedly attempting eviction on the same page. + */ + if (new->page->modify != NULL) + new->page->modify->last_eviction_id = + page->modify->last_eviction_id; /* * The rewrite succeeded, we can no longer fail. @@ -2213,7 +2258,7 @@ __wt_split_rewrite(WT_SESSION_IMPL *session, WT_REF *ref) * Finalize the move, discarding moved update lists from the original * page. */ - __split_multi_inmem_final(page, &mod->mod_multi[0]); + __split_multi_inmem_final(page, multi); /* * Discard the original page. diff --git a/src/third_party/wiredtiger/src/btree/bt_stat.c b/src/third_party/wiredtiger/src/btree/bt_stat.c index 3d5abf34147..d3ddf33446e 100644 --- a/src/third_party/wiredtiger/src/btree/bt_stat.c +++ b/src/third_party/wiredtiger/src/btree/bt_stat.c @@ -41,6 +41,9 @@ __wt_btree_stat_init(WT_SESSION_IMPL *session, WT_CURSOR_STAT *cst) WT_STAT_SET(session, stats, btree_maxleafpage, btree->maxleafpage); WT_STAT_SET(session, stats, btree_maxleafvalue, btree->maxleafvalue); + WT_STAT_SET(session, stats, cache_bytes_inuse, + __wt_btree_bytes_inuse(session)); + /* Everything else is really, really expensive. */ if (!F_ISSET(cst, WT_CONN_STAT_ALL)) return (0); @@ -139,7 +142,7 @@ __stat_page_col_var( } else { orig_deleted = false; __wt_cell_unpack(cell, unpack); - if (unpack->type == WT_CELL_ADDR_DEL) + if (unpack->type == WT_CELL_DEL) orig_deleted = true; else { entry_cnt += __wt_cell_rle(unpack); diff --git a/src/third_party/wiredtiger/src/btree/bt_sync.c b/src/third_party/wiredtiger/src/btree/bt_sync.c index da6c53aa316..b41179a565d 100644 --- a/src/third_party/wiredtiger/src/btree/bt_sync.c +++ b/src/third_party/wiredtiger/src/btree/bt_sync.c @@ -84,7 +84,8 @@ __sync_file(WT_SESSION_IMPL *session, WT_CACHE_OP syncop) WT_ERR(__wt_txn_get_snapshot(session)); leaf_bytes += page->memory_footprint; ++leaf_pages; - WT_ERR(__wt_reconcile(session, walk, NULL, 0)); + WT_ERR(__wt_reconcile( + session, walk, NULL, WT_CHECKPOINTING)); } } break; @@ -92,7 +93,7 @@ __sync_file(WT_SESSION_IMPL *session, WT_CACHE_OP syncop) /* * If we are flushing a file at read-committed isolation, which * is of particular interest for flushing the metadata to make - * schema-changing operation durable, get a transactional + * a schema-changing operation durable, get a transactional * snapshot now. * * All changes committed up to this point should be included. @@ -126,7 +127,17 @@ __sync_file(WT_SESSION_IMPL *session, WT_CACHE_OP syncop) */ WT_PUBLISH(btree->checkpointing, WT_CKPT_PREPARE); - WT_ERR(__wt_evict_file_exclusive_on(session)); + /* + * Sync for checkpoint allows splits to happen while the queue + * is being drained, but not reconciliation. We need to do this, + * since draining the queue can take long enough for hot pages + * to grow significantly larger than the configured maximum + * size. + */ + F_SET(btree, WT_BTREE_NO_RECONCILE); + ret = __wt_evict_file_exclusive_on(session); + F_CLR(btree, WT_BTREE_NO_RECONCILE); + WT_ERR(ret); __wt_evict_file_exclusive_off(session); WT_PUBLISH(btree->checkpointing, WT_CKPT_RUNNING); @@ -183,7 +194,8 @@ __sync_file(WT_SESSION_IMPL *session, WT_CACHE_OP syncop) leaf_bytes += page->memory_footprint; ++leaf_pages; } - WT_ERR(__wt_reconcile(session, walk, NULL, 0)); + WT_ERR(__wt_reconcile( + session, walk, NULL, WT_CHECKPOINTING)); } break; case WT_SYNC_CLOSE: @@ -194,7 +206,7 @@ __sync_file(WT_SESSION_IMPL *session, WT_CACHE_OP syncop) if (WT_VERBOSE_ISSET(session, WT_VERB_CHECKPOINT)) { WT_ERR(__wt_epoch(session, &end)); - WT_ERR(__wt_verbose(session, WT_VERB_CHECKPOINT, + __wt_verbose(session, WT_VERB_CHECKPOINT, "__sync_file WT_SYNC_%s wrote:\n\t %" PRIu64 " bytes, %" PRIu64 " pages of leaves\n\t %" PRIu64 " bytes, %" PRIu64 " pages of internal\n\t" @@ -202,7 +214,7 @@ __sync_file(WT_SESSION_IMPL *session, WT_CACHE_OP syncop) syncop == WT_SYNC_WRITE_LEAVES ? "WRITE_LEAVES" : "CHECKPOINT", leaf_bytes, leaf_pages, internal_bytes, internal_pages, - WT_TIMEDIFF_MS(end, start))); + WT_TIMEDIFF_MS(end, start)); } err: /* On error, clear any left-over tree walk. */ @@ -217,41 +229,9 @@ err: /* On error, clear any left-over tree walk. */ saved_snap_min == WT_TXN_NONE) __wt_txn_release_snapshot(session); - if (btree->checkpointing != WT_CKPT_OFF) { - /* - * Update the checkpoint generation for this handle so visible - * updates newer than the checkpoint can be evicted. - * - * This has to be published before eviction is enabled again, - * so that eviction knows that the checkpoint has completed. - */ - WT_PUBLISH(btree->checkpoint_gen, - conn->txn_global.checkpoint_gen); - WT_STAT_FAST_DATA_SET(session, - btree_checkpoint_generation, btree->checkpoint_gen); - - /* - * Clear the checkpoint flag and push the change; not required, - * but publishing the change means stalled eviction gets moving - * as soon as possible. - */ - btree->checkpointing = WT_CKPT_OFF; - WT_FULL_BARRIER(); - - /* - * If this tree was being skipped by the eviction server during - * the checkpoint, clear the wait. - */ - btree->evict_walk_period = 0; - - /* - * Wake the eviction server, in case application threads have - * stalled while the eviction server decided it couldn't make - * progress. Without this, application threads will be stalled - * until the eviction server next wakes. - */ - WT_TRET(__wt_evict_server_wake(session)); - } + /* Clear the checkpoint flag and push the change. */ + if (btree->checkpointing != WT_CKPT_OFF) + WT_PUBLISH(btree->checkpointing, WT_CKPT_OFF); __wt_spin_unlock(session, &btree->flush_lock); diff --git a/src/third_party/wiredtiger/src/btree/bt_vrfy.c b/src/third_party/wiredtiger/src/btree/bt_vrfy.c index 0a04c387a0f..340f9bb6f0e 100644 --- a/src/third_party/wiredtiger/src/btree/bt_vrfy.c +++ b/src/third_party/wiredtiger/src/btree/bt_vrfy.c @@ -89,7 +89,7 @@ __verify_config_offsets( *quitp = false; WT_RET(__wt_config_gets(session, cfg, "dump_offsets", &cval)); - WT_RET(__wt_config_subinit(session, &list, &cval)); + __wt_config_subinit(session, &list, &cval); while ((ret = __wt_config_next(&list, &k, &v)) == 0) { /* * Quit after dumping the requested blocks. (That's hopefully @@ -195,8 +195,8 @@ __wt_verify(WT_SESSION_IMPL *session, const char *cfg[]) /* Loop through the file's checkpoints, verifying each one. */ WT_CKPT_FOREACH(ckptbase, ckpt) { - WT_ERR(__wt_verbose(session, WT_VERB_VERIFY, - "%s: checkpoint %s", btree->dhandle->name, ckpt->name)); + __wt_verbose(session, WT_VERB_VERIFY, + "%s: checkpoint %s", btree->dhandle->name, ckpt->name); /* Fake checkpoints require no work. */ if (F_ISSET(ckpt, WT_CKPT_FAKE)) @@ -312,9 +312,9 @@ __verify_tree(WT_SESSION_IMPL *session, WT_REF *ref, WT_VSTUFF *vs) unpack = &_unpack; WT_CLEAR(*unpack); /* -Wuninitialized */ - WT_RET(__wt_verbose(session, WT_VERB_VERIFY, "%s %s", + __wt_verbose(session, WT_VERB_VERIFY, "%s %s", __wt_page_addr_string(session, ref, vs->tmp1), - __wt_page_type_string(page->type))); + __wt_page_type_string(page->type)); /* Optionally dump the address. */ if (vs->dump_address) diff --git a/src/third_party/wiredtiger/src/btree/bt_walk.c b/src/third_party/wiredtiger/src/btree/bt_walk.c index bb8a750d848..dc1cf4e7f98 100644 --- a/src/third_party/wiredtiger/src/btree/bt_walk.c +++ b/src/third_party/wiredtiger/src/btree/bt_walk.c @@ -380,16 +380,6 @@ restart: /* /* Ascend to the parent. */ __ref_ascend(session, &ref, &pindex, &slot); - /* - * If we got all the way through an internal page and - * all of the child pages were deleted, mark it for - * eviction. - */ - if (empty_internal && pindex->entries > 1) { - __wt_page_evict_soon(ref->page); - empty_internal = false; - } - /* * If at the root and returning internal pages, return * the root page, otherwise we're done. Regardless, no @@ -403,6 +393,16 @@ restart: /* goto done; } + /* + * If we got all the way through an internal page and + * all of the child pages were deleted, mark it for + * eviction. + */ + if (empty_internal && pindex->entries > 1) { + __wt_page_evict_soon(session, ref); + empty_internal = false; + } + /* * Optionally return internal pages. Swap our previous * hazard pointer for the page we'll return. We don't diff --git a/src/third_party/wiredtiger/src/btree/row_key.c b/src/third_party/wiredtiger/src/btree/row_key.c index 83fd2dad9e4..99ee34a6c5d 100644 --- a/src/third_party/wiredtiger/src/btree/row_key.c +++ b/src/third_party/wiredtiger/src/btree/row_key.c @@ -282,8 +282,7 @@ switch_and_jump: /* Switching to a forward roll. */ * the tracking cache. */ if (slot_offset == 0) { - WT_ERR( - __wt_readlock(session, btree->ovfl_lock)); + __wt_readlock(session, btree->ovfl_lock); copy = WT_ROW_KEY_COPY(rip); if (!__wt_row_leaf_key_info(page, copy, NULL, &cell, &keyb->data, &keyb->size)) { @@ -291,8 +290,7 @@ switch_and_jump: /* Switching to a forward roll. */ ret = __wt_dsk_cell_data_ref(session, WT_PAGE_ROW_LEAF, unpack, keyb); } - WT_TRET( - __wt_readunlock(session, btree->ovfl_lock)); + __wt_readunlock(session, btree->ovfl_lock); WT_ERR(ret); break; } diff --git a/src/third_party/wiredtiger/src/btree/row_modify.c b/src/third_party/wiredtiger/src/btree/row_modify.c index f0424ff93b4..a1c214e5b8b 100644 --- a/src/third_party/wiredtiger/src/btree/row_modify.c +++ b/src/third_party/wiredtiger/src/btree/row_modify.c @@ -267,22 +267,27 @@ int __wt_update_alloc( WT_SESSION_IMPL *session, WT_ITEM *value, WT_UPDATE **updp, size_t *sizep) { + WT_UPDATE *upd; size_t size; + *updp = NULL; + /* * Allocate the WT_UPDATE structure and room for the value, then copy * the value into place. */ size = value == NULL ? 0 : value->size; - WT_RET(__wt_calloc(session, 1, sizeof(WT_UPDATE) + size, updp)); + WT_RET(__wt_calloc(session, 1, sizeof(WT_UPDATE) + size, &upd)); if (value == NULL) - WT_UPDATE_DELETED_SET(*updp); + WT_UPDATE_DELETED_SET(upd); else { - (*updp)->size = WT_STORE_SIZE(size); - memcpy(WT_UPDATE_DATA(*updp), value->data, size); + upd->size = WT_STORE_SIZE(size); + if (size != 0) + memcpy(WT_UPDATE_DATA(upd), value->data, size); } - *sizep = WT_UPDATE_MEMSIZE(*updp); + *updp = upd; + *sizep = WT_UPDATE_MEMSIZE(upd); return (0); } diff --git a/src/third_party/wiredtiger/src/btree/row_srch.c b/src/third_party/wiredtiger/src/btree/row_srch.c index 4afcd74520f..d4e82c458d4 100644 --- a/src/third_party/wiredtiger/src/btree/row_srch.c +++ b/src/third_party/wiredtiger/src/btree/row_srch.c @@ -775,7 +775,7 @@ __wt_row_random_leaf(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt) * traversing the skip list each time accumulates to real time. */ if (samples > 5000) - __wt_page_evict_soon(page); + __wt_page_evict_soon(session, cbt->ref); return (0); } diff --git a/src/third_party/wiredtiger/src/cache/cache_las.c b/src/third_party/wiredtiger/src/cache/cache_las.c index 27c2900fa98..4c338bc6ad9 100644 --- a/src/third_party/wiredtiger/src/cache/cache_las.c +++ b/src/third_party/wiredtiger/src/cache/cache_las.c @@ -200,7 +200,7 @@ __wt_las_cursor_open(WT_SESSION_IMPL *session, WT_CURSOR **cursorp) * __wt_las_cursor -- * Return a lookaside cursor. */ -int +void __wt_las_cursor( WT_SESSION_IMPL *session, WT_CURSOR **cursorp, uint32_t *session_flags) { @@ -235,8 +235,6 @@ __wt_las_cursor( /* Turn caching and eviction off. */ F_SET(session, WT_SESSION_NO_CACHE | WT_SESSION_NO_EVICTION); - - return (0); } /* @@ -304,7 +302,7 @@ __wt_las_sweep(WT_SESSION_IMPL *session) WT_ERR(__wt_scr_alloc(session, 0, &las_addr)); WT_ERR(__wt_scr_alloc(session, 0, &las_key)); - WT_ERR(__wt_las_cursor(session, &cursor, &session_flags)); + __wt_las_cursor(session, &cursor, &session_flags); /* * If we're not starting a new sweep, position the cursor using the key diff --git a/src/third_party/wiredtiger/src/checksum/arm64/crc32-arm64.c b/src/third_party/wiredtiger/src/checksum/arm64/crc32-arm64.c new file mode 100644 index 00000000000..5d6c5f69c58 --- /dev/null +++ b/src/third_party/wiredtiger/src/checksum/arm64/crc32-arm64.c @@ -0,0 +1,101 @@ +/*- + * Public Domain 2014-2016 MongoDB, Inc. + * Public Domain 2008-2014 WiredTiger, Inc. + * + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "wt_internal.h" + +#if defined(HAVE_CRC32_HARDWARE) +#include +#include + +#define CRC32CX(crc,value) \ + asm("crc32cx %w[c], %w[c], %x[v]" : [c]"+r"(*&crc) : [v]"r"(+value)) +#define CRC32CW(crc,value) \ + asm("crc32cw %w[c], %w[c], %w[v]" : [c]"+r"(*&crc) : [v]"r"(+value)) +#define CRC32CH(crc,value) \ + asm("crc32ch %w[c], %w[c], %w[v]" : [c]"+r"(*&crc) : [v]"r"(+value)) +#define CRC32CB(crc,value) \ + asm("crc32cb %w[c], %w[c], %w[v]" : [c]"+r"(*&crc) : [v]"r"(+value)) + +/* + * __wt_checksum_hw -- + * Return a checksum for a chunk of memory, computed in hardware + * using 8 byte steps. + */ +static uint32_t +__wt_checksum_hw(const void *chunk, size_t len) +{ + uint32_t crc; + size_t nqwords; + const uint8_t *p; + const uint64_t *p64; + + crc = 0xffffffff; + + /* Checksum one byte at a time to the first 4B boundary. */ + for (p = chunk; + ((uintptr_t)p & (sizeof(uint32_t) - 1)) != 0 && + len > 0; ++p, --len) { + CRC32CB(crc, *p); + } + + p64 = (const uint64_t *)p; + /* Checksum in 8B chunks. */ + for (nqwords = len / sizeof(uint64_t); nqwords; nqwords--) { + CRC32CX(crc, *p64); + p64++; + } + + /* Checksum trailing bytes one byte at a time. */ + p = (const uint8_t *)p64; + for (len &= 0x7; len > 0; ++p, len--) { + CRC32CB(crc, *p); + } + + return (~crc); +} +#endif /* HAVE_CRC32_HARDWARE */ + +/* + * __wt_checksum_init -- + * WiredTiger: detect CRC hardware and set the checksum function. + */ +void +__wt_checksum_init(void) +{ +#if defined(HAVE_CRC32_HARDWARE) + unsigned long caps = getauxval(AT_HWCAP); + + if (caps & HWCAP_CRC32) + __wt_process.checksum = __wt_checksum_hw; + else + __wt_process.checksum = __wt_checksum_sw; + +#else /* !HAVE_CRC32_HARDWARE */ + __wt_process.checksum = __wt_checksum_sw; +#endif /* HAVE_CRC32_HARDWARE */ +} diff --git a/src/third_party/wiredtiger/src/checksum/checksum.c b/src/third_party/wiredtiger/src/checksum/checksum.c deleted file mode 100644 index b6a76dacfd8..00000000000 --- a/src/third_party/wiredtiger/src/checksum/checksum.c +++ /dev/null @@ -1,1329 +0,0 @@ -/*- - * Public Domain 2014-2016 MongoDB, Inc. - * Public Domain 2008-2014 WiredTiger, Inc. - * - * This is free and unencumbered software released into the public domain. - * - * Anyone is free to copy, modify, publish, use, compile, sell, or - * distribute this software, either in source code form or as a compiled - * binary, for any purpose, commercial or non-commercial, and by any - * means. - * - * In jurisdictions that recognize copyright laws, the author or authors - * of this software dedicate any and all copyright interest in the - * software to the public domain. We make this dedication for the benefit - * of the public at large and to the detriment of our heirs and - * successors. We intend this dedication to be an overt act of - * relinquishment in perpetuity of all present and future rights to this - * software under copyright law. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ -/* - * Slicing-by-8 algorithm by Michael E. Kounavis and Frank L. Berry, described - * in "Novel Table Lookup-Based Algorithms for High-Performance CRC Generation", - * IEEE Transactions on Computers, Volume 57 Issue 11, November 2008. - * - * See also Peter Kanowski's posting: - * http://www.strchr.com/crc32_popcnt - * - * The big endian version calculates the same result at each step, except the - * value of the crc is byte reversed from what it would be at that step for - * little endian. - */ - -#include "wt_internal.h" - -/* - * This file contains two implementations for computing CRC: one that uses - * hardware CRC instructions, available on newer x86_64/amd64, and one that uses - * a fast software algorithm. __wt_cksum() provides a common entry point that - * indirects to one of these two methods. - */ -static uint32_t (*__wt_cksum_func)(const void *chunk, size_t len); - -/* - * The CRC slicing tables are used by __wt_cksum_sw. - */ -static const uint32_t g_crc_slicing[8][256] = { -#ifdef WORDS_BIGENDIAN - /* - * Big endian tables have entries that are byte reversed from little - * endian tables. - */ - { - 0x00000000, 0x03836bf2, 0xf7703be1, 0xf4f35013, - 0x1f979ac7, 0x1c14f135, 0xe8e7a126, 0xeb64cad4, - 0xcf58d98a, 0xccdbb278, 0x3828e26b, 0x3bab8999, - 0xd0cf434d, 0xd34c28bf, 0x27bf78ac, 0x243c135e, - 0x6fc75e10, 0x6c4435e2, 0x98b765f1, 0x9b340e03, - 0x7050c4d7, 0x73d3af25, 0x8720ff36, 0x84a394c4, - 0xa09f879a, 0xa31cec68, 0x57efbc7b, 0x546cd789, - 0xbf081d5d, 0xbc8b76af, 0x487826bc, 0x4bfb4d4e, - 0xde8ebd20, 0xdd0dd6d2, 0x29fe86c1, 0x2a7ded33, - 0xc11927e7, 0xc29a4c15, 0x36691c06, 0x35ea77f4, - 0x11d664aa, 0x12550f58, 0xe6a65f4b, 0xe52534b9, - 0x0e41fe6d, 0x0dc2959f, 0xf931c58c, 0xfab2ae7e, - 0xb149e330, 0xb2ca88c2, 0x4639d8d1, 0x45bab323, - 0xaede79f7, 0xad5d1205, 0x59ae4216, 0x5a2d29e4, - 0x7e113aba, 0x7d925148, 0x8961015b, 0x8ae26aa9, - 0x6186a07d, 0x6205cb8f, 0x96f69b9c, 0x9575f06e, - 0xbc1d7b41, 0xbf9e10b3, 0x4b6d40a0, 0x48ee2b52, - 0xa38ae186, 0xa0098a74, 0x54fada67, 0x5779b195, - 0x7345a2cb, 0x70c6c939, 0x8435992a, 0x87b6f2d8, - 0x6cd2380c, 0x6f5153fe, 0x9ba203ed, 0x9821681f, - 0xd3da2551, 0xd0594ea3, 0x24aa1eb0, 0x27297542, - 0xcc4dbf96, 0xcfced464, 0x3b3d8477, 0x38beef85, - 0x1c82fcdb, 0x1f019729, 0xebf2c73a, 0xe871acc8, - 0x0315661c, 0x00960dee, 0xf4655dfd, 0xf7e6360f, - 0x6293c661, 0x6110ad93, 0x95e3fd80, 0x96609672, - 0x7d045ca6, 0x7e873754, 0x8a746747, 0x89f70cb5, - 0xadcb1feb, 0xae487419, 0x5abb240a, 0x59384ff8, - 0xb25c852c, 0xb1dfeede, 0x452cbecd, 0x46afd53f, - 0x0d549871, 0x0ed7f383, 0xfa24a390, 0xf9a7c862, - 0x12c302b6, 0x11406944, 0xe5b33957, 0xe63052a5, - 0xc20c41fb, 0xc18f2a09, 0x357c7a1a, 0x36ff11e8, - 0xdd9bdb3c, 0xde18b0ce, 0x2aebe0dd, 0x29688b2f, - 0x783bf682, 0x7bb89d70, 0x8f4bcd63, 0x8cc8a691, - 0x67ac6c45, 0x642f07b7, 0x90dc57a4, 0x935f3c56, - 0xb7632f08, 0xb4e044fa, 0x401314e9, 0x43907f1b, - 0xa8f4b5cf, 0xab77de3d, 0x5f848e2e, 0x5c07e5dc, - 0x17fca892, 0x147fc360, 0xe08c9373, 0xe30ff881, - 0x086b3255, 0x0be859a7, 0xff1b09b4, 0xfc986246, - 0xd8a47118, 0xdb271aea, 0x2fd44af9, 0x2c57210b, - 0xc733ebdf, 0xc4b0802d, 0x3043d03e, 0x33c0bbcc, - 0xa6b54ba2, 0xa5362050, 0x51c57043, 0x52461bb1, - 0xb922d165, 0xbaa1ba97, 0x4e52ea84, 0x4dd18176, - 0x69ed9228, 0x6a6ef9da, 0x9e9da9c9, 0x9d1ec23b, - 0x767a08ef, 0x75f9631d, 0x810a330e, 0x828958fc, - 0xc97215b2, 0xcaf17e40, 0x3e022e53, 0x3d8145a1, - 0xd6e58f75, 0xd566e487, 0x2195b494, 0x2216df66, - 0x062acc38, 0x05a9a7ca, 0xf15af7d9, 0xf2d99c2b, - 0x19bd56ff, 0x1a3e3d0d, 0xeecd6d1e, 0xed4e06ec, - 0xc4268dc3, 0xc7a5e631, 0x3356b622, 0x30d5ddd0, - 0xdbb11704, 0xd8327cf6, 0x2cc12ce5, 0x2f424717, - 0x0b7e5449, 0x08fd3fbb, 0xfc0e6fa8, 0xff8d045a, - 0x14e9ce8e, 0x176aa57c, 0xe399f56f, 0xe01a9e9d, - 0xabe1d3d3, 0xa862b821, 0x5c91e832, 0x5f1283c0, - 0xb4764914, 0xb7f522e6, 0x430672f5, 0x40851907, - 0x64b90a59, 0x673a61ab, 0x93c931b8, 0x904a5a4a, - 0x7b2e909e, 0x78adfb6c, 0x8c5eab7f, 0x8fddc08d, - 0x1aa830e3, 0x192b5b11, 0xedd80b02, 0xee5b60f0, - 0x053faa24, 0x06bcc1d6, 0xf24f91c5, 0xf1ccfa37, - 0xd5f0e969, 0xd673829b, 0x2280d288, 0x2103b97a, - 0xca6773ae, 0xc9e4185c, 0x3d17484f, 0x3e9423bd, - 0x756f6ef3, 0x76ec0501, 0x821f5512, 0x819c3ee0, - 0x6af8f434, 0x697b9fc6, 0x9d88cfd5, 0x9e0ba427, - 0xba37b779, 0xb9b4dc8b, 0x4d478c98, 0x4ec4e76a, - 0xa5a02dbe, 0xa623464c, 0x52d0165f, 0x51537dad - },{ - 0x00000000, 0x7798a213, 0xee304527, 0x99a8e734, - 0xdc618a4e, 0xabf9285d, 0x3251cf69, 0x45c96d7a, - 0xb8c3149d, 0xcf5bb68e, 0x56f351ba, 0x216bf3a9, - 0x64a29ed3, 0x133a3cc0, 0x8a92dbf4, 0xfd0a79e7, - 0x81f1c53f, 0xf669672c, 0x6fc18018, 0x1859220b, - 0x5d904f71, 0x2a08ed62, 0xb3a00a56, 0xc438a845, - 0x3932d1a2, 0x4eaa73b1, 0xd7029485, 0xa09a3696, - 0xe5535bec, 0x92cbf9ff, 0x0b631ecb, 0x7cfbbcd8, - 0x02e38b7f, 0x757b296c, 0xecd3ce58, 0x9b4b6c4b, - 0xde820131, 0xa91aa322, 0x30b24416, 0x472ae605, - 0xba209fe2, 0xcdb83df1, 0x5410dac5, 0x238878d6, - 0x664115ac, 0x11d9b7bf, 0x8871508b, 0xffe9f298, - 0x83124e40, 0xf48aec53, 0x6d220b67, 0x1abaa974, - 0x5f73c40e, 0x28eb661d, 0xb1438129, 0xc6db233a, - 0x3bd15add, 0x4c49f8ce, 0xd5e11ffa, 0xa279bde9, - 0xe7b0d093, 0x90287280, 0x098095b4, 0x7e1837a7, - 0x04c617ff, 0x735eb5ec, 0xeaf652d8, 0x9d6ef0cb, - 0xd8a79db1, 0xaf3f3fa2, 0x3697d896, 0x410f7a85, - 0xbc050362, 0xcb9da171, 0x52354645, 0x25ade456, - 0x6064892c, 0x17fc2b3f, 0x8e54cc0b, 0xf9cc6e18, - 0x8537d2c0, 0xf2af70d3, 0x6b0797e7, 0x1c9f35f4, - 0x5956588e, 0x2ecefa9d, 0xb7661da9, 0xc0febfba, - 0x3df4c65d, 0x4a6c644e, 0xd3c4837a, 0xa45c2169, - 0xe1954c13, 0x960dee00, 0x0fa50934, 0x783dab27, - 0x06259c80, 0x71bd3e93, 0xe815d9a7, 0x9f8d7bb4, - 0xda4416ce, 0xaddcb4dd, 0x347453e9, 0x43ecf1fa, - 0xbee6881d, 0xc97e2a0e, 0x50d6cd3a, 0x274e6f29, - 0x62870253, 0x151fa040, 0x8cb74774, 0xfb2fe567, - 0x87d459bf, 0xf04cfbac, 0x69e41c98, 0x1e7cbe8b, - 0x5bb5d3f1, 0x2c2d71e2, 0xb58596d6, 0xc21d34c5, - 0x3f174d22, 0x488fef31, 0xd1270805, 0xa6bfaa16, - 0xe376c76c, 0x94ee657f, 0x0d46824b, 0x7ade2058, - 0xf9fac3fb, 0x8e6261e8, 0x17ca86dc, 0x605224cf, - 0x259b49b5, 0x5203eba6, 0xcbab0c92, 0xbc33ae81, - 0x4139d766, 0x36a17575, 0xaf099241, 0xd8913052, - 0x9d585d28, 0xeac0ff3b, 0x7368180f, 0x04f0ba1c, - 0x780b06c4, 0x0f93a4d7, 0x963b43e3, 0xe1a3e1f0, - 0xa46a8c8a, 0xd3f22e99, 0x4a5ac9ad, 0x3dc26bbe, - 0xc0c81259, 0xb750b04a, 0x2ef8577e, 0x5960f56d, - 0x1ca99817, 0x6b313a04, 0xf299dd30, 0x85017f23, - 0xfb194884, 0x8c81ea97, 0x15290da3, 0x62b1afb0, - 0x2778c2ca, 0x50e060d9, 0xc94887ed, 0xbed025fe, - 0x43da5c19, 0x3442fe0a, 0xadea193e, 0xda72bb2d, - 0x9fbbd657, 0xe8237444, 0x718b9370, 0x06133163, - 0x7ae88dbb, 0x0d702fa8, 0x94d8c89c, 0xe3406a8f, - 0xa68907f5, 0xd111a5e6, 0x48b942d2, 0x3f21e0c1, - 0xc22b9926, 0xb5b33b35, 0x2c1bdc01, 0x5b837e12, - 0x1e4a1368, 0x69d2b17b, 0xf07a564f, 0x87e2f45c, - 0xfd3cd404, 0x8aa47617, 0x130c9123, 0x64943330, - 0x215d5e4a, 0x56c5fc59, 0xcf6d1b6d, 0xb8f5b97e, - 0x45ffc099, 0x3267628a, 0xabcf85be, 0xdc5727ad, - 0x999e4ad7, 0xee06e8c4, 0x77ae0ff0, 0x0036ade3, - 0x7ccd113b, 0x0b55b328, 0x92fd541c, 0xe565f60f, - 0xa0ac9b75, 0xd7343966, 0x4e9cde52, 0x39047c41, - 0xc40e05a6, 0xb396a7b5, 0x2a3e4081, 0x5da6e292, - 0x186f8fe8, 0x6ff72dfb, 0xf65fcacf, 0x81c768dc, - 0xffdf5f7b, 0x8847fd68, 0x11ef1a5c, 0x6677b84f, - 0x23bed535, 0x54267726, 0xcd8e9012, 0xba163201, - 0x471c4be6, 0x3084e9f5, 0xa92c0ec1, 0xdeb4acd2, - 0x9b7dc1a8, 0xece563bb, 0x754d848f, 0x02d5269c, - 0x7e2e9a44, 0x09b63857, 0x901edf63, 0xe7867d70, - 0xa24f100a, 0xd5d7b219, 0x4c7f552d, 0x3be7f73e, - 0xc6ed8ed9, 0xb1752cca, 0x28ddcbfe, 0x5f4569ed, - 0x1a8c0497, 0x6d14a684, 0xf4bc41b0, 0x8324e3a3 - },{ - 0x00000000, 0x7e9241a5, 0x0d526f4f, 0x73c02eea, - 0x1aa4de9e, 0x64369f3b, 0x17f6b1d1, 0x6964f074, - 0xc53e5138, 0xbbac109d, 0xc86c3e77, 0xb6fe7fd2, - 0xdf9a8fa6, 0xa108ce03, 0xd2c8e0e9, 0xac5aa14c, - 0x8a7da270, 0xf4efe3d5, 0x872fcd3f, 0xf9bd8c9a, - 0x90d97cee, 0xee4b3d4b, 0x9d8b13a1, 0xe3195204, - 0x4f43f348, 0x31d1b2ed, 0x42119c07, 0x3c83dda2, - 0x55e72dd6, 0x2b756c73, 0x58b54299, 0x2627033c, - 0x14fb44e1, 0x6a690544, 0x19a92bae, 0x673b6a0b, - 0x0e5f9a7f, 0x70cddbda, 0x030df530, 0x7d9fb495, - 0xd1c515d9, 0xaf57547c, 0xdc977a96, 0xa2053b33, - 0xcb61cb47, 0xb5f38ae2, 0xc633a408, 0xb8a1e5ad, - 0x9e86e691, 0xe014a734, 0x93d489de, 0xed46c87b, - 0x8422380f, 0xfab079aa, 0x89705740, 0xf7e216e5, - 0x5bb8b7a9, 0x252af60c, 0x56ead8e6, 0x28789943, - 0x411c6937, 0x3f8e2892, 0x4c4e0678, 0x32dc47dd, - 0xd98065c7, 0xa7122462, 0xd4d20a88, 0xaa404b2d, - 0xc324bb59, 0xbdb6fafc, 0xce76d416, 0xb0e495b3, - 0x1cbe34ff, 0x622c755a, 0x11ec5bb0, 0x6f7e1a15, - 0x061aea61, 0x7888abc4, 0x0b48852e, 0x75dac48b, - 0x53fdc7b7, 0x2d6f8612, 0x5eafa8f8, 0x203de95d, - 0x49591929, 0x37cb588c, 0x440b7666, 0x3a9937c3, - 0x96c3968f, 0xe851d72a, 0x9b91f9c0, 0xe503b865, - 0x8c674811, 0xf2f509b4, 0x8135275e, 0xffa766fb, - 0xcd7b2126, 0xb3e96083, 0xc0294e69, 0xbebb0fcc, - 0xd7dfffb8, 0xa94dbe1d, 0xda8d90f7, 0xa41fd152, - 0x0845701e, 0x76d731bb, 0x05171f51, 0x7b855ef4, - 0x12e1ae80, 0x6c73ef25, 0x1fb3c1cf, 0x6121806a, - 0x47068356, 0x3994c2f3, 0x4a54ec19, 0x34c6adbc, - 0x5da25dc8, 0x23301c6d, 0x50f03287, 0x2e627322, - 0x8238d26e, 0xfcaa93cb, 0x8f6abd21, 0xf1f8fc84, - 0x989c0cf0, 0xe60e4d55, 0x95ce63bf, 0xeb5c221a, - 0x4377278b, 0x3de5662e, 0x4e2548c4, 0x30b70961, - 0x59d3f915, 0x2741b8b0, 0x5481965a, 0x2a13d7ff, - 0x864976b3, 0xf8db3716, 0x8b1b19fc, 0xf5895859, - 0x9ceda82d, 0xe27fe988, 0x91bfc762, 0xef2d86c7, - 0xc90a85fb, 0xb798c45e, 0xc458eab4, 0xbacaab11, - 0xd3ae5b65, 0xad3c1ac0, 0xdefc342a, 0xa06e758f, - 0x0c34d4c3, 0x72a69566, 0x0166bb8c, 0x7ff4fa29, - 0x16900a5d, 0x68024bf8, 0x1bc26512, 0x655024b7, - 0x578c636a, 0x291e22cf, 0x5ade0c25, 0x244c4d80, - 0x4d28bdf4, 0x33bafc51, 0x407ad2bb, 0x3ee8931e, - 0x92b23252, 0xec2073f7, 0x9fe05d1d, 0xe1721cb8, - 0x8816eccc, 0xf684ad69, 0x85448383, 0xfbd6c226, - 0xddf1c11a, 0xa36380bf, 0xd0a3ae55, 0xae31eff0, - 0xc7551f84, 0xb9c75e21, 0xca0770cb, 0xb495316e, - 0x18cf9022, 0x665dd187, 0x159dff6d, 0x6b0fbec8, - 0x026b4ebc, 0x7cf90f19, 0x0f3921f3, 0x71ab6056, - 0x9af7424c, 0xe46503e9, 0x97a52d03, 0xe9376ca6, - 0x80539cd2, 0xfec1dd77, 0x8d01f39d, 0xf393b238, - 0x5fc91374, 0x215b52d1, 0x529b7c3b, 0x2c093d9e, - 0x456dcdea, 0x3bff8c4f, 0x483fa2a5, 0x36ade300, - 0x108ae03c, 0x6e18a199, 0x1dd88f73, 0x634aced6, - 0x0a2e3ea2, 0x74bc7f07, 0x077c51ed, 0x79ee1048, - 0xd5b4b104, 0xab26f0a1, 0xd8e6de4b, 0xa6749fee, - 0xcf106f9a, 0xb1822e3f, 0xc24200d5, 0xbcd04170, - 0x8e0c06ad, 0xf09e4708, 0x835e69e2, 0xfdcc2847, - 0x94a8d833, 0xea3a9996, 0x99fab77c, 0xe768f6d9, - 0x4b325795, 0x35a01630, 0x466038da, 0x38f2797f, - 0x5196890b, 0x2f04c8ae, 0x5cc4e644, 0x2256a7e1, - 0x0471a4dd, 0x7ae3e578, 0x0923cb92, 0x77b18a37, - 0x1ed57a43, 0x60473be6, 0x1387150c, 0x6d1554a9, - 0xc14ff5e5, 0xbfddb440, 0xcc1d9aaa, 0xb28fdb0f, - 0xdbeb2b7b, 0xa5796ade, 0xd6b94434, 0xa82b0591 - },{ - 0x00000000, 0xb8aa45dd, 0x812367bf, 0x39892262, - 0xf331227b, 0x4b9b67a6, 0x721245c4, 0xcab80019, - 0xe66344f6, 0x5ec9012b, 0x67402349, 0xdfea6694, - 0x1552668d, 0xadf82350, 0x94710132, 0x2cdb44ef, - 0x3db164e9, 0x851b2134, 0xbc920356, 0x0438468b, - 0xce804692, 0x762a034f, 0x4fa3212d, 0xf70964f0, - 0xdbd2201f, 0x637865c2, 0x5af147a0, 0xe25b027d, - 0x28e30264, 0x904947b9, 0xa9c065db, 0x116a2006, - 0x8b1425d7, 0x33be600a, 0x0a374268, 0xb29d07b5, - 0x782507ac, 0xc08f4271, 0xf9066013, 0x41ac25ce, - 0x6d776121, 0xd5dd24fc, 0xec54069e, 0x54fe4343, - 0x9e46435a, 0x26ec0687, 0x1f6524e5, 0xa7cf6138, - 0xb6a5413e, 0x0e0f04e3, 0x37862681, 0x8f2c635c, - 0x45946345, 0xfd3e2698, 0xc4b704fa, 0x7c1d4127, - 0x50c605c8, 0xe86c4015, 0xd1e56277, 0x694f27aa, - 0xa3f727b3, 0x1b5d626e, 0x22d4400c, 0x9a7e05d1, - 0xe75fa6ab, 0x5ff5e376, 0x667cc114, 0xded684c9, - 0x146e84d0, 0xacc4c10d, 0x954de36f, 0x2de7a6b2, - 0x013ce25d, 0xb996a780, 0x801f85e2, 0x38b5c03f, - 0xf20dc026, 0x4aa785fb, 0x732ea799, 0xcb84e244, - 0xdaeec242, 0x6244879f, 0x5bcda5fd, 0xe367e020, - 0x29dfe039, 0x9175a5e4, 0xa8fc8786, 0x1056c25b, - 0x3c8d86b4, 0x8427c369, 0xbdaee10b, 0x0504a4d6, - 0xcfbca4cf, 0x7716e112, 0x4e9fc370, 0xf63586ad, - 0x6c4b837c, 0xd4e1c6a1, 0xed68e4c3, 0x55c2a11e, - 0x9f7aa107, 0x27d0e4da, 0x1e59c6b8, 0xa6f38365, - 0x8a28c78a, 0x32828257, 0x0b0ba035, 0xb3a1e5e8, - 0x7919e5f1, 0xc1b3a02c, 0xf83a824e, 0x4090c793, - 0x51fae795, 0xe950a248, 0xd0d9802a, 0x6873c5f7, - 0xa2cbc5ee, 0x1a618033, 0x23e8a251, 0x9b42e78c, - 0xb799a363, 0x0f33e6be, 0x36bac4dc, 0x8e108101, - 0x44a88118, 0xfc02c4c5, 0xc58be6a7, 0x7d21a37a, - 0x3fc9a052, 0x8763e58f, 0xbeeac7ed, 0x06408230, - 0xccf88229, 0x7452c7f4, 0x4ddbe596, 0xf571a04b, - 0xd9aae4a4, 0x6100a179, 0x5889831b, 0xe023c6c6, - 0x2a9bc6df, 0x92318302, 0xabb8a160, 0x1312e4bd, - 0x0278c4bb, 0xbad28166, 0x835ba304, 0x3bf1e6d9, - 0xf149e6c0, 0x49e3a31d, 0x706a817f, 0xc8c0c4a2, - 0xe41b804d, 0x5cb1c590, 0x6538e7f2, 0xdd92a22f, - 0x172aa236, 0xaf80e7eb, 0x9609c589, 0x2ea38054, - 0xb4dd8585, 0x0c77c058, 0x35fee23a, 0x8d54a7e7, - 0x47eca7fe, 0xff46e223, 0xc6cfc041, 0x7e65859c, - 0x52bec173, 0xea1484ae, 0xd39da6cc, 0x6b37e311, - 0xa18fe308, 0x1925a6d5, 0x20ac84b7, 0x9806c16a, - 0x896ce16c, 0x31c6a4b1, 0x084f86d3, 0xb0e5c30e, - 0x7a5dc317, 0xc2f786ca, 0xfb7ea4a8, 0x43d4e175, - 0x6f0fa59a, 0xd7a5e047, 0xee2cc225, 0x568687f8, - 0x9c3e87e1, 0x2494c23c, 0x1d1de05e, 0xa5b7a583, - 0xd89606f9, 0x603c4324, 0x59b56146, 0xe11f249b, - 0x2ba72482, 0x930d615f, 0xaa84433d, 0x122e06e0, - 0x3ef5420f, 0x865f07d2, 0xbfd625b0, 0x077c606d, - 0xcdc46074, 0x756e25a9, 0x4ce707cb, 0xf44d4216, - 0xe5276210, 0x5d8d27cd, 0x640405af, 0xdcae4072, - 0x1616406b, 0xaebc05b6, 0x973527d4, 0x2f9f6209, - 0x034426e6, 0xbbee633b, 0x82674159, 0x3acd0484, - 0xf075049d, 0x48df4140, 0x71566322, 0xc9fc26ff, - 0x5382232e, 0xeb2866f3, 0xd2a14491, 0x6a0b014c, - 0xa0b30155, 0x18194488, 0x219066ea, 0x993a2337, - 0xb5e167d8, 0x0d4b2205, 0x34c20067, 0x8c6845ba, - 0x46d045a3, 0xfe7a007e, 0xc7f3221c, 0x7f5967c1, - 0x6e3347c7, 0xd699021a, 0xef102078, 0x57ba65a5, - 0x9d0265bc, 0x25a82061, 0x1c210203, 0xa48b47de, - 0x88500331, 0x30fa46ec, 0x0973648e, 0xb1d92153, - 0x7b61214a, 0xc3cb6497, 0xfa4246f5, 0x42e80328 - },{ - 0x00000000, 0xac6f1138, 0x58df2270, 0xf4b03348, - 0xb0be45e0, 0x1cd154d8, 0xe8616790, 0x440e76a8, - 0x910b67c5, 0x3d6476fd, 0xc9d445b5, 0x65bb548d, - 0x21b52225, 0x8dda331d, 0x796a0055, 0xd505116d, - 0xd361228f, 0x7f0e33b7, 0x8bbe00ff, 0x27d111c7, - 0x63df676f, 0xcfb07657, 0x3b00451f, 0x976f5427, - 0x426a454a, 0xee055472, 0x1ab5673a, 0xb6da7602, - 0xf2d400aa, 0x5ebb1192, 0xaa0b22da, 0x066433e2, - 0x57b5a81b, 0xfbdab923, 0x0f6a8a6b, 0xa3059b53, - 0xe70bedfb, 0x4b64fcc3, 0xbfd4cf8b, 0x13bbdeb3, - 0xc6becfde, 0x6ad1dee6, 0x9e61edae, 0x320efc96, - 0x76008a3e, 0xda6f9b06, 0x2edfa84e, 0x82b0b976, - 0x84d48a94, 0x28bb9bac, 0xdc0ba8e4, 0x7064b9dc, - 0x346acf74, 0x9805de4c, 0x6cb5ed04, 0xc0dafc3c, - 0x15dfed51, 0xb9b0fc69, 0x4d00cf21, 0xe16fde19, - 0xa561a8b1, 0x090eb989, 0xfdbe8ac1, 0x51d19bf9, - 0xae6a5137, 0x0205400f, 0xf6b57347, 0x5ada627f, - 0x1ed414d7, 0xb2bb05ef, 0x460b36a7, 0xea64279f, - 0x3f6136f2, 0x930e27ca, 0x67be1482, 0xcbd105ba, - 0x8fdf7312, 0x23b0622a, 0xd7005162, 0x7b6f405a, - 0x7d0b73b8, 0xd1646280, 0x25d451c8, 0x89bb40f0, - 0xcdb53658, 0x61da2760, 0x956a1428, 0x39050510, - 0xec00147d, 0x406f0545, 0xb4df360d, 0x18b02735, - 0x5cbe519d, 0xf0d140a5, 0x046173ed, 0xa80e62d5, - 0xf9dff92c, 0x55b0e814, 0xa100db5c, 0x0d6fca64, - 0x4961bccc, 0xe50eadf4, 0x11be9ebc, 0xbdd18f84, - 0x68d49ee9, 0xc4bb8fd1, 0x300bbc99, 0x9c64ada1, - 0xd86adb09, 0x7405ca31, 0x80b5f979, 0x2cdae841, - 0x2abedba3, 0x86d1ca9b, 0x7261f9d3, 0xde0ee8eb, - 0x9a009e43, 0x366f8f7b, 0xc2dfbc33, 0x6eb0ad0b, - 0xbbb5bc66, 0x17daad5e, 0xe36a9e16, 0x4f058f2e, - 0x0b0bf986, 0xa764e8be, 0x53d4dbf6, 0xffbbcace, - 0x5cd5a26e, 0xf0bab356, 0x040a801e, 0xa8659126, - 0xec6be78e, 0x4004f6b6, 0xb4b4c5fe, 0x18dbd4c6, - 0xcddec5ab, 0x61b1d493, 0x9501e7db, 0x396ef6e3, - 0x7d60804b, 0xd10f9173, 0x25bfa23b, 0x89d0b303, - 0x8fb480e1, 0x23db91d9, 0xd76ba291, 0x7b04b3a9, - 0x3f0ac501, 0x9365d439, 0x67d5e771, 0xcbbaf649, - 0x1ebfe724, 0xb2d0f61c, 0x4660c554, 0xea0fd46c, - 0xae01a2c4, 0x026eb3fc, 0xf6de80b4, 0x5ab1918c, - 0x0b600a75, 0xa70f1b4d, 0x53bf2805, 0xffd0393d, - 0xbbde4f95, 0x17b15ead, 0xe3016de5, 0x4f6e7cdd, - 0x9a6b6db0, 0x36047c88, 0xc2b44fc0, 0x6edb5ef8, - 0x2ad52850, 0x86ba3968, 0x720a0a20, 0xde651b18, - 0xd80128fa, 0x746e39c2, 0x80de0a8a, 0x2cb11bb2, - 0x68bf6d1a, 0xc4d07c22, 0x30604f6a, 0x9c0f5e52, - 0x490a4f3f, 0xe5655e07, 0x11d56d4f, 0xbdba7c77, - 0xf9b40adf, 0x55db1be7, 0xa16b28af, 0x0d043997, - 0xf2bff359, 0x5ed0e261, 0xaa60d129, 0x060fc011, - 0x4201b6b9, 0xee6ea781, 0x1ade94c9, 0xb6b185f1, - 0x63b4949c, 0xcfdb85a4, 0x3b6bb6ec, 0x9704a7d4, - 0xd30ad17c, 0x7f65c044, 0x8bd5f30c, 0x27bae234, - 0x21ded1d6, 0x8db1c0ee, 0x7901f3a6, 0xd56ee29e, - 0x91609436, 0x3d0f850e, 0xc9bfb646, 0x65d0a77e, - 0xb0d5b613, 0x1cbaa72b, 0xe80a9463, 0x4465855b, - 0x006bf3f3, 0xac04e2cb, 0x58b4d183, 0xf4dbc0bb, - 0xa50a5b42, 0x09654a7a, 0xfdd57932, 0x51ba680a, - 0x15b41ea2, 0xb9db0f9a, 0x4d6b3cd2, 0xe1042dea, - 0x34013c87, 0x986e2dbf, 0x6cde1ef7, 0xc0b10fcf, - 0x84bf7967, 0x28d0685f, 0xdc605b17, 0x700f4a2f, - 0x766b79cd, 0xda0468f5, 0x2eb45bbd, 0x82db4a85, - 0xc6d53c2d, 0x6aba2d15, 0x9e0a1e5d, 0x32650f65, - 0xe7601e08, 0x4b0f0f30, 0xbfbf3c78, 0x13d02d40, - 0x57de5be8, 0xfbb14ad0, 0x0f017998, 0xa36e68a0 - },{ - 0x00000000, 0x196b30ef, 0xc3a08cdb, 0xdacbbc34, - 0x7737f5b2, 0x6e5cc55d, 0xb4977969, 0xadfc4986, - 0x1f180660, 0x0673368f, 0xdcb88abb, 0xc5d3ba54, - 0x682ff3d2, 0x7144c33d, 0xab8f7f09, 0xb2e44fe6, - 0x3e300cc0, 0x275b3c2f, 0xfd90801b, 0xe4fbb0f4, - 0x4907f972, 0x506cc99d, 0x8aa775a9, 0x93cc4546, - 0x21280aa0, 0x38433a4f, 0xe288867b, 0xfbe3b694, - 0x561fff12, 0x4f74cffd, 0x95bf73c9, 0x8cd44326, - 0x8d16f485, 0x947dc46a, 0x4eb6785e, 0x57dd48b1, - 0xfa210137, 0xe34a31d8, 0x39818dec, 0x20eabd03, - 0x920ef2e5, 0x8b65c20a, 0x51ae7e3e, 0x48c54ed1, - 0xe5390757, 0xfc5237b8, 0x26998b8c, 0x3ff2bb63, - 0xb326f845, 0xaa4dc8aa, 0x7086749e, 0x69ed4471, - 0xc4110df7, 0xdd7a3d18, 0x07b1812c, 0x1edab1c3, - 0xac3efe25, 0xb555ceca, 0x6f9e72fe, 0x76f54211, - 0xdb090b97, 0xc2623b78, 0x18a9874c, 0x01c2b7a3, - 0xeb5b040e, 0xf23034e1, 0x28fb88d5, 0x3190b83a, - 0x9c6cf1bc, 0x8507c153, 0x5fcc7d67, 0x46a74d88, - 0xf443026e, 0xed283281, 0x37e38eb5, 0x2e88be5a, - 0x8374f7dc, 0x9a1fc733, 0x40d47b07, 0x59bf4be8, - 0xd56b08ce, 0xcc003821, 0x16cb8415, 0x0fa0b4fa, - 0xa25cfd7c, 0xbb37cd93, 0x61fc71a7, 0x78974148, - 0xca730eae, 0xd3183e41, 0x09d38275, 0x10b8b29a, - 0xbd44fb1c, 0xa42fcbf3, 0x7ee477c7, 0x678f4728, - 0x664df08b, 0x7f26c064, 0xa5ed7c50, 0xbc864cbf, - 0x117a0539, 0x081135d6, 0xd2da89e2, 0xcbb1b90d, - 0x7955f6eb, 0x603ec604, 0xbaf57a30, 0xa39e4adf, - 0x0e620359, 0x170933b6, 0xcdc28f82, 0xd4a9bf6d, - 0x587dfc4b, 0x4116cca4, 0x9bdd7090, 0x82b6407f, - 0x2f4a09f9, 0x36213916, 0xecea8522, 0xf581b5cd, - 0x4765fa2b, 0x5e0ecac4, 0x84c576f0, 0x9dae461f, - 0x30520f99, 0x29393f76, 0xf3f28342, 0xea99b3ad, - 0xd6b7081c, 0xcfdc38f3, 0x151784c7, 0x0c7cb428, - 0xa180fdae, 0xb8ebcd41, 0x62207175, 0x7b4b419a, - 0xc9af0e7c, 0xd0c43e93, 0x0a0f82a7, 0x1364b248, - 0xbe98fbce, 0xa7f3cb21, 0x7d387715, 0x645347fa, - 0xe88704dc, 0xf1ec3433, 0x2b278807, 0x324cb8e8, - 0x9fb0f16e, 0x86dbc181, 0x5c107db5, 0x457b4d5a, - 0xf79f02bc, 0xeef43253, 0x343f8e67, 0x2d54be88, - 0x80a8f70e, 0x99c3c7e1, 0x43087bd5, 0x5a634b3a, - 0x5ba1fc99, 0x42cacc76, 0x98017042, 0x816a40ad, - 0x2c96092b, 0x35fd39c4, 0xef3685f0, 0xf65db51f, - 0x44b9faf9, 0x5dd2ca16, 0x87197622, 0x9e7246cd, - 0x338e0f4b, 0x2ae53fa4, 0xf02e8390, 0xe945b37f, - 0x6591f059, 0x7cfac0b6, 0xa6317c82, 0xbf5a4c6d, - 0x12a605eb, 0x0bcd3504, 0xd1068930, 0xc86db9df, - 0x7a89f639, 0x63e2c6d6, 0xb9297ae2, 0xa0424a0d, - 0x0dbe038b, 0x14d53364, 0xce1e8f50, 0xd775bfbf, - 0x3dec0c12, 0x24873cfd, 0xfe4c80c9, 0xe727b026, - 0x4adbf9a0, 0x53b0c94f, 0x897b757b, 0x90104594, - 0x22f40a72, 0x3b9f3a9d, 0xe15486a9, 0xf83fb646, - 0x55c3ffc0, 0x4ca8cf2f, 0x9663731b, 0x8f0843f4, - 0x03dc00d2, 0x1ab7303d, 0xc07c8c09, 0xd917bce6, - 0x74ebf560, 0x6d80c58f, 0xb74b79bb, 0xae204954, - 0x1cc406b2, 0x05af365d, 0xdf648a69, 0xc60fba86, - 0x6bf3f300, 0x7298c3ef, 0xa8537fdb, 0xb1384f34, - 0xb0faf897, 0xa991c878, 0x735a744c, 0x6a3144a3, - 0xc7cd0d25, 0xdea63dca, 0x046d81fe, 0x1d06b111, - 0xafe2fef7, 0xb689ce18, 0x6c42722c, 0x752942c3, - 0xd8d50b45, 0xc1be3baa, 0x1b75879e, 0x021eb771, - 0x8ecaf457, 0x97a1c4b8, 0x4d6a788c, 0x54014863, - 0xf9fd01e5, 0xe096310a, 0x3a5d8d3e, 0x2336bdd1, - 0x91d2f237, 0x88b9c2d8, 0x52727eec, 0x4b194e03, - 0xe6e50785, 0xff8e376a, 0x25458b5e, 0x3c2ebbb1 - },{ - 0x00000000, 0xc82c0368, 0x905906d0, 0x587505b8, - 0xd1c5e0a5, 0x19e9e3cd, 0x419ce675, 0x89b0e51d, - 0x53fd2d4e, 0x9bd12e26, 0xc3a42b9e, 0x0b8828f6, - 0x8238cdeb, 0x4a14ce83, 0x1261cb3b, 0xda4dc853, - 0xa6fa5b9c, 0x6ed658f4, 0x36a35d4c, 0xfe8f5e24, - 0x773fbb39, 0xbf13b851, 0xe766bde9, 0x2f4abe81, - 0xf50776d2, 0x3d2b75ba, 0x655e7002, 0xad72736a, - 0x24c29677, 0xecee951f, 0xb49b90a7, 0x7cb793cf, - 0xbd835b3d, 0x75af5855, 0x2dda5ded, 0xe5f65e85, - 0x6c46bb98, 0xa46ab8f0, 0xfc1fbd48, 0x3433be20, - 0xee7e7673, 0x2652751b, 0x7e2770a3, 0xb60b73cb, - 0x3fbb96d6, 0xf79795be, 0xafe29006, 0x67ce936e, - 0x1b7900a1, 0xd35503c9, 0x8b200671, 0x430c0519, - 0xcabce004, 0x0290e36c, 0x5ae5e6d4, 0x92c9e5bc, - 0x48842def, 0x80a82e87, 0xd8dd2b3f, 0x10f12857, - 0x9941cd4a, 0x516dce22, 0x0918cb9a, 0xc134c8f2, - 0x7a07b77a, 0xb22bb412, 0xea5eb1aa, 0x2272b2c2, - 0xabc257df, 0x63ee54b7, 0x3b9b510f, 0xf3b75267, - 0x29fa9a34, 0xe1d6995c, 0xb9a39ce4, 0x718f9f8c, - 0xf83f7a91, 0x301379f9, 0x68667c41, 0xa04a7f29, - 0xdcfdece6, 0x14d1ef8e, 0x4ca4ea36, 0x8488e95e, - 0x0d380c43, 0xc5140f2b, 0x9d610a93, 0x554d09fb, - 0x8f00c1a8, 0x472cc2c0, 0x1f59c778, 0xd775c410, - 0x5ec5210d, 0x96e92265, 0xce9c27dd, 0x06b024b5, - 0xc784ec47, 0x0fa8ef2f, 0x57ddea97, 0x9ff1e9ff, - 0x16410ce2, 0xde6d0f8a, 0x86180a32, 0x4e34095a, - 0x9479c109, 0x5c55c261, 0x0420c7d9, 0xcc0cc4b1, - 0x45bc21ac, 0x8d9022c4, 0xd5e5277c, 0x1dc92414, - 0x617eb7db, 0xa952b4b3, 0xf127b10b, 0x390bb263, - 0xb0bb577e, 0x78975416, 0x20e251ae, 0xe8ce52c6, - 0x32839a95, 0xfaaf99fd, 0xa2da9c45, 0x6af69f2d, - 0xe3467a30, 0x2b6a7958, 0x731f7ce0, 0xbb337f88, - 0xf40e6ef5, 0x3c226d9d, 0x64576825, 0xac7b6b4d, - 0x25cb8e50, 0xede78d38, 0xb5928880, 0x7dbe8be8, - 0xa7f343bb, 0x6fdf40d3, 0x37aa456b, 0xff864603, - 0x7636a31e, 0xbe1aa076, 0xe66fa5ce, 0x2e43a6a6, - 0x52f43569, 0x9ad83601, 0xc2ad33b9, 0x0a8130d1, - 0x8331d5cc, 0x4b1dd6a4, 0x1368d31c, 0xdb44d074, - 0x01091827, 0xc9251b4f, 0x91501ef7, 0x597c1d9f, - 0xd0ccf882, 0x18e0fbea, 0x4095fe52, 0x88b9fd3a, - 0x498d35c8, 0x81a136a0, 0xd9d43318, 0x11f83070, - 0x9848d56d, 0x5064d605, 0x0811d3bd, 0xc03dd0d5, - 0x1a701886, 0xd25c1bee, 0x8a291e56, 0x42051d3e, - 0xcbb5f823, 0x0399fb4b, 0x5becfef3, 0x93c0fd9b, - 0xef776e54, 0x275b6d3c, 0x7f2e6884, 0xb7026bec, - 0x3eb28ef1, 0xf69e8d99, 0xaeeb8821, 0x66c78b49, - 0xbc8a431a, 0x74a64072, 0x2cd345ca, 0xe4ff46a2, - 0x6d4fa3bf, 0xa563a0d7, 0xfd16a56f, 0x353aa607, - 0x8e09d98f, 0x4625dae7, 0x1e50df5f, 0xd67cdc37, - 0x5fcc392a, 0x97e03a42, 0xcf953ffa, 0x07b93c92, - 0xddf4f4c1, 0x15d8f7a9, 0x4dadf211, 0x8581f179, - 0x0c311464, 0xc41d170c, 0x9c6812b4, 0x544411dc, - 0x28f38213, 0xe0df817b, 0xb8aa84c3, 0x708687ab, - 0xf93662b6, 0x311a61de, 0x696f6466, 0xa143670e, - 0x7b0eaf5d, 0xb322ac35, 0xeb57a98d, 0x237baae5, - 0xaacb4ff8, 0x62e74c90, 0x3a924928, 0xf2be4a40, - 0x338a82b2, 0xfba681da, 0xa3d38462, 0x6bff870a, - 0xe24f6217, 0x2a63617f, 0x721664c7, 0xba3a67af, - 0x6077affc, 0xa85bac94, 0xf02ea92c, 0x3802aa44, - 0xb1b24f59, 0x799e4c31, 0x21eb4989, 0xe9c74ae1, - 0x9570d92e, 0x5d5cda46, 0x0529dffe, 0xcd05dc96, - 0x44b5398b, 0x8c993ae3, 0xd4ec3f5b, 0x1cc03c33, - 0xc68df460, 0x0ea1f708, 0x56d4f2b0, 0x9ef8f1d8, - 0x174814c5, 0xdf6417ad, 0x87111215, 0x4f3d117d - },{ - 0x00000000, 0x277d3c49, 0x4efa7892, 0x698744db, - 0x6d821d21, 0x4aff2168, 0x237865b3, 0x040559fa, - 0xda043b42, 0xfd79070b, 0x94fe43d0, 0xb3837f99, - 0xb7862663, 0x90fb1a2a, 0xf97c5ef1, 0xde0162b8, - 0xb4097684, 0x93744acd, 0xfaf30e16, 0xdd8e325f, - 0xd98b6ba5, 0xfef657ec, 0x97711337, 0xb00c2f7e, - 0x6e0d4dc6, 0x4970718f, 0x20f73554, 0x078a091d, - 0x038f50e7, 0x24f26cae, 0x4d752875, 0x6a08143c, - 0x9965000d, 0xbe183c44, 0xd79f789f, 0xf0e244d6, - 0xf4e71d2c, 0xd39a2165, 0xba1d65be, 0x9d6059f7, - 0x43613b4f, 0x641c0706, 0x0d9b43dd, 0x2ae67f94, - 0x2ee3266e, 0x099e1a27, 0x60195efc, 0x476462b5, - 0x2d6c7689, 0x0a114ac0, 0x63960e1b, 0x44eb3252, - 0x40ee6ba8, 0x679357e1, 0x0e14133a, 0x29692f73, - 0xf7684dcb, 0xd0157182, 0xb9923559, 0x9eef0910, - 0x9aea50ea, 0xbd976ca3, 0xd4102878, 0xf36d1431, - 0x32cb001a, 0x15b63c53, 0x7c317888, 0x5b4c44c1, - 0x5f491d3b, 0x78342172, 0x11b365a9, 0x36ce59e0, - 0xe8cf3b58, 0xcfb20711, 0xa63543ca, 0x81487f83, - 0x854d2679, 0xa2301a30, 0xcbb75eeb, 0xecca62a2, - 0x86c2769e, 0xa1bf4ad7, 0xc8380e0c, 0xef453245, - 0xeb406bbf, 0xcc3d57f6, 0xa5ba132d, 0x82c72f64, - 0x5cc64ddc, 0x7bbb7195, 0x123c354e, 0x35410907, - 0x314450fd, 0x16396cb4, 0x7fbe286f, 0x58c31426, - 0xabae0017, 0x8cd33c5e, 0xe5547885, 0xc22944cc, - 0xc62c1d36, 0xe151217f, 0x88d665a4, 0xafab59ed, - 0x71aa3b55, 0x56d7071c, 0x3f5043c7, 0x182d7f8e, - 0x1c282674, 0x3b551a3d, 0x52d25ee6, 0x75af62af, - 0x1fa77693, 0x38da4ada, 0x515d0e01, 0x76203248, - 0x72256bb2, 0x555857fb, 0x3cdf1320, 0x1ba22f69, - 0xc5a34dd1, 0xe2de7198, 0x8b593543, 0xac24090a, - 0xa82150f0, 0x8f5c6cb9, 0xe6db2862, 0xc1a6142b, - 0x64960134, 0x43eb3d7d, 0x2a6c79a6, 0x0d1145ef, - 0x09141c15, 0x2e69205c, 0x47ee6487, 0x609358ce, - 0xbe923a76, 0x99ef063f, 0xf06842e4, 0xd7157ead, - 0xd3102757, 0xf46d1b1e, 0x9dea5fc5, 0xba97638c, - 0xd09f77b0, 0xf7e24bf9, 0x9e650f22, 0xb918336b, - 0xbd1d6a91, 0x9a6056d8, 0xf3e71203, 0xd49a2e4a, - 0x0a9b4cf2, 0x2de670bb, 0x44613460, 0x631c0829, - 0x671951d3, 0x40646d9a, 0x29e32941, 0x0e9e1508, - 0xfdf30139, 0xda8e3d70, 0xb30979ab, 0x947445e2, - 0x90711c18, 0xb70c2051, 0xde8b648a, 0xf9f658c3, - 0x27f73a7b, 0x008a0632, 0x690d42e9, 0x4e707ea0, - 0x4a75275a, 0x6d081b13, 0x048f5fc8, 0x23f26381, - 0x49fa77bd, 0x6e874bf4, 0x07000f2f, 0x207d3366, - 0x24786a9c, 0x030556d5, 0x6a82120e, 0x4dff2e47, - 0x93fe4cff, 0xb48370b6, 0xdd04346d, 0xfa790824, - 0xfe7c51de, 0xd9016d97, 0xb086294c, 0x97fb1505, - 0x565d012e, 0x71203d67, 0x18a779bc, 0x3fda45f5, - 0x3bdf1c0f, 0x1ca22046, 0x7525649d, 0x525858d4, - 0x8c593a6c, 0xab240625, 0xc2a342fe, 0xe5de7eb7, - 0xe1db274d, 0xc6a61b04, 0xaf215fdf, 0x885c6396, - 0xe25477aa, 0xc5294be3, 0xacae0f38, 0x8bd33371, - 0x8fd66a8b, 0xa8ab56c2, 0xc12c1219, 0xe6512e50, - 0x38504ce8, 0x1f2d70a1, 0x76aa347a, 0x51d70833, - 0x55d251c9, 0x72af6d80, 0x1b28295b, 0x3c551512, - 0xcf380123, 0xe8453d6a, 0x81c279b1, 0xa6bf45f8, - 0xa2ba1c02, 0x85c7204b, 0xec406490, 0xcb3d58d9, - 0x153c3a61, 0x32410628, 0x5bc642f3, 0x7cbb7eba, - 0x78be2740, 0x5fc31b09, 0x36445fd2, 0x1139639b, - 0x7b3177a7, 0x5c4c4bee, 0x35cb0f35, 0x12b6337c, - 0x16b36a86, 0x31ce56cf, 0x58491214, 0x7f342e5d, - 0xa1354ce5, 0x864870ac, 0xefcf3477, 0xc8b2083e, - 0xccb751c4, 0xebca6d8d, 0x824d2956, 0xa530151f - } -#else - { - 0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, - 0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb, - 0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b, - 0x4d43cfd0, 0xbf284cd3, 0xac78bf27, 0x5e133c24, - 0x105ec76f, 0xe235446c, 0xf165b798, 0x030e349b, - 0xd7c45070, 0x25afd373, 0x36ff2087, 0xc494a384, - 0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54, - 0x5d1d08bf, 0xaf768bbc, 0xbc267848, 0x4e4dfb4b, - 0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a, - 0xe72719c1, 0x154c9ac2, 0x061c6936, 0xf477ea35, - 0xaa64d611, 0x580f5512, 0x4b5fa6e6, 0xb93425e5, - 0x6dfe410e, 0x9f95c20d, 0x8cc531f9, 0x7eaeb2fa, - 0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45, - 0xf779deae, 0x05125dad, 0x1642ae59, 0xe4292d5a, - 0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a, - 0x7da08661, 0x8fcb0562, 0x9c9bf696, 0x6ef07595, - 0x417b1dbc, 0xb3109ebf, 0xa0406d4b, 0x522bee48, - 0x86e18aa3, 0x748a09a0, 0x67dafa54, 0x95b17957, - 0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687, - 0x0c38d26c, 0xfe53516f, 0xed03a29b, 0x1f682198, - 0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927, - 0x96bf4dcc, 0x64d4cecf, 0x77843d3b, 0x85efbe38, - 0xdbfc821c, 0x2997011f, 0x3ac7f2eb, 0xc8ac71e8, - 0x1c661503, 0xee0d9600, 0xfd5d65f4, 0x0f36e6f7, - 0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096, - 0xa65c047d, 0x5437877e, 0x4767748a, 0xb50cf789, - 0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859, - 0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, 0x3fd5af46, - 0x7198540d, 0x83f3d70e, 0x90a324fa, 0x62c8a7f9, - 0xb602c312, 0x44694011, 0x5739b3e5, 0xa55230e6, - 0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36, - 0x3cdb9bdd, 0xceb018de, 0xdde0eb2a, 0x2f8b6829, - 0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c, - 0x456cac67, 0xb7072f64, 0xa457dc90, 0x563c5f93, - 0x082f63b7, 0xfa44e0b4, 0xe9141340, 0x1b7f9043, - 0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, 0xdce5075c, - 0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3, - 0x55326b08, 0xa759e80b, 0xb4091bff, 0x466298fc, - 0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c, - 0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, 0xccbbc033, - 0xa24bb5a6, 0x502036a5, 0x4370c551, 0xb11b4652, - 0x65d122b9, 0x97baa1ba, 0x84ea524e, 0x7681d14d, - 0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d, - 0xef087a76, 0x1d63f975, 0x0e330a81, 0xfc588982, - 0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d, - 0x758fe5d6, 0x87e466d5, 0x94b49521, 0x66df1622, - 0x38cc2a06, 0xcaa7a905, 0xd9f75af1, 0x2b9cd9f2, - 0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, 0xec064eed, - 0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530, - 0x0417b1db, 0xf67c32d8, 0xe52cc12c, 0x1747422f, - 0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff, - 0x8ecee914, 0x7ca56a17, 0x6ff599e3, 0x9d9e1ae0, - 0xd3d3e1ab, 0x21b862a8, 0x32e8915c, 0xc083125f, - 0x144976b4, 0xe622f5b7, 0xf5720643, 0x07198540, - 0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90, - 0x9e902e7b, 0x6cfbad78, 0x7fab5e8c, 0x8dc0dd8f, - 0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee, - 0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, 0x37faccf1, - 0x69e9f0d5, 0x9b8273d6, 0x88d28022, 0x7ab90321, - 0xae7367ca, 0x5c18e4c9, 0x4f48173d, 0xbd23943e, - 0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81, - 0x34f4f86a, 0xc69f7b69, 0xd5cf889d, 0x27a40b9e, - 0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e, - 0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351 - },{ - 0x00000000, 0x13a29877, 0x274530ee, 0x34e7a899, - 0x4e8a61dc, 0x5d28f9ab, 0x69cf5132, 0x7a6dc945, - 0x9d14c3b8, 0x8eb65bcf, 0xba51f356, 0xa9f36b21, - 0xd39ea264, 0xc03c3a13, 0xf4db928a, 0xe7790afd, - 0x3fc5f181, 0x2c6769f6, 0x1880c16f, 0x0b225918, - 0x714f905d, 0x62ed082a, 0x560aa0b3, 0x45a838c4, - 0xa2d13239, 0xb173aa4e, 0x859402d7, 0x96369aa0, - 0xec5b53e5, 0xfff9cb92, 0xcb1e630b, 0xd8bcfb7c, - 0x7f8be302, 0x6c297b75, 0x58ced3ec, 0x4b6c4b9b, - 0x310182de, 0x22a31aa9, 0x1644b230, 0x05e62a47, - 0xe29f20ba, 0xf13db8cd, 0xc5da1054, 0xd6788823, - 0xac154166, 0xbfb7d911, 0x8b507188, 0x98f2e9ff, - 0x404e1283, 0x53ec8af4, 0x670b226d, 0x74a9ba1a, - 0x0ec4735f, 0x1d66eb28, 0x298143b1, 0x3a23dbc6, - 0xdd5ad13b, 0xcef8494c, 0xfa1fe1d5, 0xe9bd79a2, - 0x93d0b0e7, 0x80722890, 0xb4958009, 0xa737187e, - 0xff17c604, 0xecb55e73, 0xd852f6ea, 0xcbf06e9d, - 0xb19da7d8, 0xa23f3faf, 0x96d89736, 0x857a0f41, - 0x620305bc, 0x71a19dcb, 0x45463552, 0x56e4ad25, - 0x2c896460, 0x3f2bfc17, 0x0bcc548e, 0x186eccf9, - 0xc0d23785, 0xd370aff2, 0xe797076b, 0xf4359f1c, - 0x8e585659, 0x9dface2e, 0xa91d66b7, 0xbabffec0, - 0x5dc6f43d, 0x4e646c4a, 0x7a83c4d3, 0x69215ca4, - 0x134c95e1, 0x00ee0d96, 0x3409a50f, 0x27ab3d78, - 0x809c2506, 0x933ebd71, 0xa7d915e8, 0xb47b8d9f, - 0xce1644da, 0xddb4dcad, 0xe9537434, 0xfaf1ec43, - 0x1d88e6be, 0x0e2a7ec9, 0x3acdd650, 0x296f4e27, - 0x53028762, 0x40a01f15, 0x7447b78c, 0x67e52ffb, - 0xbf59d487, 0xacfb4cf0, 0x981ce469, 0x8bbe7c1e, - 0xf1d3b55b, 0xe2712d2c, 0xd69685b5, 0xc5341dc2, - 0x224d173f, 0x31ef8f48, 0x050827d1, 0x16aabfa6, - 0x6cc776e3, 0x7f65ee94, 0x4b82460d, 0x5820de7a, - 0xfbc3faf9, 0xe861628e, 0xdc86ca17, 0xcf245260, - 0xb5499b25, 0xa6eb0352, 0x920cabcb, 0x81ae33bc, - 0x66d73941, 0x7575a136, 0x419209af, 0x523091d8, - 0x285d589d, 0x3bffc0ea, 0x0f186873, 0x1cbaf004, - 0xc4060b78, 0xd7a4930f, 0xe3433b96, 0xf0e1a3e1, - 0x8a8c6aa4, 0x992ef2d3, 0xadc95a4a, 0xbe6bc23d, - 0x5912c8c0, 0x4ab050b7, 0x7e57f82e, 0x6df56059, - 0x1798a91c, 0x043a316b, 0x30dd99f2, 0x237f0185, - 0x844819fb, 0x97ea818c, 0xa30d2915, 0xb0afb162, - 0xcac27827, 0xd960e050, 0xed8748c9, 0xfe25d0be, - 0x195cda43, 0x0afe4234, 0x3e19eaad, 0x2dbb72da, - 0x57d6bb9f, 0x447423e8, 0x70938b71, 0x63311306, - 0xbb8de87a, 0xa82f700d, 0x9cc8d894, 0x8f6a40e3, - 0xf50789a6, 0xe6a511d1, 0xd242b948, 0xc1e0213f, - 0x26992bc2, 0x353bb3b5, 0x01dc1b2c, 0x127e835b, - 0x68134a1e, 0x7bb1d269, 0x4f567af0, 0x5cf4e287, - 0x04d43cfd, 0x1776a48a, 0x23910c13, 0x30339464, - 0x4a5e5d21, 0x59fcc556, 0x6d1b6dcf, 0x7eb9f5b8, - 0x99c0ff45, 0x8a626732, 0xbe85cfab, 0xad2757dc, - 0xd74a9e99, 0xc4e806ee, 0xf00fae77, 0xe3ad3600, - 0x3b11cd7c, 0x28b3550b, 0x1c54fd92, 0x0ff665e5, - 0x759baca0, 0x663934d7, 0x52de9c4e, 0x417c0439, - 0xa6050ec4, 0xb5a796b3, 0x81403e2a, 0x92e2a65d, - 0xe88f6f18, 0xfb2df76f, 0xcfca5ff6, 0xdc68c781, - 0x7b5fdfff, 0x68fd4788, 0x5c1aef11, 0x4fb87766, - 0x35d5be23, 0x26772654, 0x12908ecd, 0x013216ba, - 0xe64b1c47, 0xf5e98430, 0xc10e2ca9, 0xd2acb4de, - 0xa8c17d9b, 0xbb63e5ec, 0x8f844d75, 0x9c26d502, - 0x449a2e7e, 0x5738b609, 0x63df1e90, 0x707d86e7, - 0x0a104fa2, 0x19b2d7d5, 0x2d557f4c, 0x3ef7e73b, - 0xd98eedc6, 0xca2c75b1, 0xfecbdd28, 0xed69455f, - 0x97048c1a, 0x84a6146d, 0xb041bcf4, 0xa3e32483 - },{ - 0x00000000, 0xa541927e, 0x4f6f520d, 0xea2ec073, - 0x9edea41a, 0x3b9f3664, 0xd1b1f617, 0x74f06469, - 0x38513ec5, 0x9d10acbb, 0x773e6cc8, 0xd27ffeb6, - 0xa68f9adf, 0x03ce08a1, 0xe9e0c8d2, 0x4ca15aac, - 0x70a27d8a, 0xd5e3eff4, 0x3fcd2f87, 0x9a8cbdf9, - 0xee7cd990, 0x4b3d4bee, 0xa1138b9d, 0x045219e3, - 0x48f3434f, 0xedb2d131, 0x079c1142, 0xa2dd833c, - 0xd62de755, 0x736c752b, 0x9942b558, 0x3c032726, - 0xe144fb14, 0x4405696a, 0xae2ba919, 0x0b6a3b67, - 0x7f9a5f0e, 0xdadbcd70, 0x30f50d03, 0x95b49f7d, - 0xd915c5d1, 0x7c5457af, 0x967a97dc, 0x333b05a2, - 0x47cb61cb, 0xe28af3b5, 0x08a433c6, 0xade5a1b8, - 0x91e6869e, 0x34a714e0, 0xde89d493, 0x7bc846ed, - 0x0f382284, 0xaa79b0fa, 0x40577089, 0xe516e2f7, - 0xa9b7b85b, 0x0cf62a25, 0xe6d8ea56, 0x43997828, - 0x37691c41, 0x92288e3f, 0x78064e4c, 0xdd47dc32, - 0xc76580d9, 0x622412a7, 0x880ad2d4, 0x2d4b40aa, - 0x59bb24c3, 0xfcfab6bd, 0x16d476ce, 0xb395e4b0, - 0xff34be1c, 0x5a752c62, 0xb05bec11, 0x151a7e6f, - 0x61ea1a06, 0xc4ab8878, 0x2e85480b, 0x8bc4da75, - 0xb7c7fd53, 0x12866f2d, 0xf8a8af5e, 0x5de93d20, - 0x29195949, 0x8c58cb37, 0x66760b44, 0xc337993a, - 0x8f96c396, 0x2ad751e8, 0xc0f9919b, 0x65b803e5, - 0x1148678c, 0xb409f5f2, 0x5e273581, 0xfb66a7ff, - 0x26217bcd, 0x8360e9b3, 0x694e29c0, 0xcc0fbbbe, - 0xb8ffdfd7, 0x1dbe4da9, 0xf7908dda, 0x52d11fa4, - 0x1e704508, 0xbb31d776, 0x511f1705, 0xf45e857b, - 0x80aee112, 0x25ef736c, 0xcfc1b31f, 0x6a802161, - 0x56830647, 0xf3c29439, 0x19ec544a, 0xbcadc634, - 0xc85da25d, 0x6d1c3023, 0x8732f050, 0x2273622e, - 0x6ed23882, 0xcb93aafc, 0x21bd6a8f, 0x84fcf8f1, - 0xf00c9c98, 0x554d0ee6, 0xbf63ce95, 0x1a225ceb, - 0x8b277743, 0x2e66e53d, 0xc448254e, 0x6109b730, - 0x15f9d359, 0xb0b84127, 0x5a968154, 0xffd7132a, - 0xb3764986, 0x1637dbf8, 0xfc191b8b, 0x595889f5, - 0x2da8ed9c, 0x88e97fe2, 0x62c7bf91, 0xc7862def, - 0xfb850ac9, 0x5ec498b7, 0xb4ea58c4, 0x11abcaba, - 0x655baed3, 0xc01a3cad, 0x2a34fcde, 0x8f756ea0, - 0xc3d4340c, 0x6695a672, 0x8cbb6601, 0x29faf47f, - 0x5d0a9016, 0xf84b0268, 0x1265c21b, 0xb7245065, - 0x6a638c57, 0xcf221e29, 0x250cde5a, 0x804d4c24, - 0xf4bd284d, 0x51fcba33, 0xbbd27a40, 0x1e93e83e, - 0x5232b292, 0xf77320ec, 0x1d5de09f, 0xb81c72e1, - 0xccec1688, 0x69ad84f6, 0x83834485, 0x26c2d6fb, - 0x1ac1f1dd, 0xbf8063a3, 0x55aea3d0, 0xf0ef31ae, - 0x841f55c7, 0x215ec7b9, 0xcb7007ca, 0x6e3195b4, - 0x2290cf18, 0x87d15d66, 0x6dff9d15, 0xc8be0f6b, - 0xbc4e6b02, 0x190ff97c, 0xf321390f, 0x5660ab71, - 0x4c42f79a, 0xe90365e4, 0x032da597, 0xa66c37e9, - 0xd29c5380, 0x77ddc1fe, 0x9df3018d, 0x38b293f3, - 0x7413c95f, 0xd1525b21, 0x3b7c9b52, 0x9e3d092c, - 0xeacd6d45, 0x4f8cff3b, 0xa5a23f48, 0x00e3ad36, - 0x3ce08a10, 0x99a1186e, 0x738fd81d, 0xd6ce4a63, - 0xa23e2e0a, 0x077fbc74, 0xed517c07, 0x4810ee79, - 0x04b1b4d5, 0xa1f026ab, 0x4bdee6d8, 0xee9f74a6, - 0x9a6f10cf, 0x3f2e82b1, 0xd50042c2, 0x7041d0bc, - 0xad060c8e, 0x08479ef0, 0xe2695e83, 0x4728ccfd, - 0x33d8a894, 0x96993aea, 0x7cb7fa99, 0xd9f668e7, - 0x9557324b, 0x3016a035, 0xda386046, 0x7f79f238, - 0x0b899651, 0xaec8042f, 0x44e6c45c, 0xe1a75622, - 0xdda47104, 0x78e5e37a, 0x92cb2309, 0x378ab177, - 0x437ad51e, 0xe63b4760, 0x0c158713, 0xa954156d, - 0xe5f54fc1, 0x40b4ddbf, 0xaa9a1dcc, 0x0fdb8fb2, - 0x7b2bebdb, 0xde6a79a5, 0x3444b9d6, 0x91052ba8 - },{ - 0x00000000, 0xdd45aab8, 0xbf672381, 0x62228939, - 0x7b2231f3, 0xa6679b4b, 0xc4451272, 0x1900b8ca, - 0xf64463e6, 0x2b01c95e, 0x49234067, 0x9466eadf, - 0x8d665215, 0x5023f8ad, 0x32017194, 0xef44db2c, - 0xe964b13d, 0x34211b85, 0x560392bc, 0x8b463804, - 0x924680ce, 0x4f032a76, 0x2d21a34f, 0xf06409f7, - 0x1f20d2db, 0xc2657863, 0xa047f15a, 0x7d025be2, - 0x6402e328, 0xb9474990, 0xdb65c0a9, 0x06206a11, - 0xd725148b, 0x0a60be33, 0x6842370a, 0xb5079db2, - 0xac072578, 0x71428fc0, 0x136006f9, 0xce25ac41, - 0x2161776d, 0xfc24ddd5, 0x9e0654ec, 0x4343fe54, - 0x5a43469e, 0x8706ec26, 0xe524651f, 0x3861cfa7, - 0x3e41a5b6, 0xe3040f0e, 0x81268637, 0x5c632c8f, - 0x45639445, 0x98263efd, 0xfa04b7c4, 0x27411d7c, - 0xc805c650, 0x15406ce8, 0x7762e5d1, 0xaa274f69, - 0xb327f7a3, 0x6e625d1b, 0x0c40d422, 0xd1057e9a, - 0xaba65fe7, 0x76e3f55f, 0x14c17c66, 0xc984d6de, - 0xd0846e14, 0x0dc1c4ac, 0x6fe34d95, 0xb2a6e72d, - 0x5de23c01, 0x80a796b9, 0xe2851f80, 0x3fc0b538, - 0x26c00df2, 0xfb85a74a, 0x99a72e73, 0x44e284cb, - 0x42c2eeda, 0x9f874462, 0xfda5cd5b, 0x20e067e3, - 0x39e0df29, 0xe4a57591, 0x8687fca8, 0x5bc25610, - 0xb4868d3c, 0x69c32784, 0x0be1aebd, 0xd6a40405, - 0xcfa4bccf, 0x12e11677, 0x70c39f4e, 0xad8635f6, - 0x7c834b6c, 0xa1c6e1d4, 0xc3e468ed, 0x1ea1c255, - 0x07a17a9f, 0xdae4d027, 0xb8c6591e, 0x6583f3a6, - 0x8ac7288a, 0x57828232, 0x35a00b0b, 0xe8e5a1b3, - 0xf1e51979, 0x2ca0b3c1, 0x4e823af8, 0x93c79040, - 0x95e7fa51, 0x48a250e9, 0x2a80d9d0, 0xf7c57368, - 0xeec5cba2, 0x3380611a, 0x51a2e823, 0x8ce7429b, - 0x63a399b7, 0xbee6330f, 0xdcc4ba36, 0x0181108e, - 0x1881a844, 0xc5c402fc, 0xa7e68bc5, 0x7aa3217d, - 0x52a0c93f, 0x8fe56387, 0xedc7eabe, 0x30824006, - 0x2982f8cc, 0xf4c75274, 0x96e5db4d, 0x4ba071f5, - 0xa4e4aad9, 0x79a10061, 0x1b838958, 0xc6c623e0, - 0xdfc69b2a, 0x02833192, 0x60a1b8ab, 0xbde41213, - 0xbbc47802, 0x6681d2ba, 0x04a35b83, 0xd9e6f13b, - 0xc0e649f1, 0x1da3e349, 0x7f816a70, 0xa2c4c0c8, - 0x4d801be4, 0x90c5b15c, 0xf2e73865, 0x2fa292dd, - 0x36a22a17, 0xebe780af, 0x89c50996, 0x5480a32e, - 0x8585ddb4, 0x58c0770c, 0x3ae2fe35, 0xe7a7548d, - 0xfea7ec47, 0x23e246ff, 0x41c0cfc6, 0x9c85657e, - 0x73c1be52, 0xae8414ea, 0xcca69dd3, 0x11e3376b, - 0x08e38fa1, 0xd5a62519, 0xb784ac20, 0x6ac10698, - 0x6ce16c89, 0xb1a4c631, 0xd3864f08, 0x0ec3e5b0, - 0x17c35d7a, 0xca86f7c2, 0xa8a47efb, 0x75e1d443, - 0x9aa50f6f, 0x47e0a5d7, 0x25c22cee, 0xf8878656, - 0xe1873e9c, 0x3cc29424, 0x5ee01d1d, 0x83a5b7a5, - 0xf90696d8, 0x24433c60, 0x4661b559, 0x9b241fe1, - 0x8224a72b, 0x5f610d93, 0x3d4384aa, 0xe0062e12, - 0x0f42f53e, 0xd2075f86, 0xb025d6bf, 0x6d607c07, - 0x7460c4cd, 0xa9256e75, 0xcb07e74c, 0x16424df4, - 0x106227e5, 0xcd278d5d, 0xaf050464, 0x7240aedc, - 0x6b401616, 0xb605bcae, 0xd4273597, 0x09629f2f, - 0xe6264403, 0x3b63eebb, 0x59416782, 0x8404cd3a, - 0x9d0475f0, 0x4041df48, 0x22635671, 0xff26fcc9, - 0x2e238253, 0xf36628eb, 0x9144a1d2, 0x4c010b6a, - 0x5501b3a0, 0x88441918, 0xea669021, 0x37233a99, - 0xd867e1b5, 0x05224b0d, 0x6700c234, 0xba45688c, - 0xa345d046, 0x7e007afe, 0x1c22f3c7, 0xc167597f, - 0xc747336e, 0x1a0299d6, 0x782010ef, 0xa565ba57, - 0xbc65029d, 0x6120a825, 0x0302211c, 0xde478ba4, - 0x31035088, 0xec46fa30, 0x8e647309, 0x5321d9b1, - 0x4a21617b, 0x9764cbc3, 0xf54642fa, 0x2803e842 - },{ - 0x00000000, 0x38116fac, 0x7022df58, 0x4833b0f4, - 0xe045beb0, 0xd854d11c, 0x906761e8, 0xa8760e44, - 0xc5670b91, 0xfd76643d, 0xb545d4c9, 0x8d54bb65, - 0x2522b521, 0x1d33da8d, 0x55006a79, 0x6d1105d5, - 0x8f2261d3, 0xb7330e7f, 0xff00be8b, 0xc711d127, - 0x6f67df63, 0x5776b0cf, 0x1f45003b, 0x27546f97, - 0x4a456a42, 0x725405ee, 0x3a67b51a, 0x0276dab6, - 0xaa00d4f2, 0x9211bb5e, 0xda220baa, 0xe2336406, - 0x1ba8b557, 0x23b9dafb, 0x6b8a6a0f, 0x539b05a3, - 0xfbed0be7, 0xc3fc644b, 0x8bcfd4bf, 0xb3debb13, - 0xdecfbec6, 0xe6ded16a, 0xaeed619e, 0x96fc0e32, - 0x3e8a0076, 0x069b6fda, 0x4ea8df2e, 0x76b9b082, - 0x948ad484, 0xac9bbb28, 0xe4a80bdc, 0xdcb96470, - 0x74cf6a34, 0x4cde0598, 0x04edb56c, 0x3cfcdac0, - 0x51eddf15, 0x69fcb0b9, 0x21cf004d, 0x19de6fe1, - 0xb1a861a5, 0x89b90e09, 0xc18abefd, 0xf99bd151, - 0x37516aae, 0x0f400502, 0x4773b5f6, 0x7f62da5a, - 0xd714d41e, 0xef05bbb2, 0xa7360b46, 0x9f2764ea, - 0xf236613f, 0xca270e93, 0x8214be67, 0xba05d1cb, - 0x1273df8f, 0x2a62b023, 0x625100d7, 0x5a406f7b, - 0xb8730b7d, 0x806264d1, 0xc851d425, 0xf040bb89, - 0x5836b5cd, 0x6027da61, 0x28146a95, 0x10050539, - 0x7d1400ec, 0x45056f40, 0x0d36dfb4, 0x3527b018, - 0x9d51be5c, 0xa540d1f0, 0xed736104, 0xd5620ea8, - 0x2cf9dff9, 0x14e8b055, 0x5cdb00a1, 0x64ca6f0d, - 0xccbc6149, 0xf4ad0ee5, 0xbc9ebe11, 0x848fd1bd, - 0xe99ed468, 0xd18fbbc4, 0x99bc0b30, 0xa1ad649c, - 0x09db6ad8, 0x31ca0574, 0x79f9b580, 0x41e8da2c, - 0xa3dbbe2a, 0x9bcad186, 0xd3f96172, 0xebe80ede, - 0x439e009a, 0x7b8f6f36, 0x33bcdfc2, 0x0badb06e, - 0x66bcb5bb, 0x5eadda17, 0x169e6ae3, 0x2e8f054f, - 0x86f90b0b, 0xbee864a7, 0xf6dbd453, 0xcecabbff, - 0x6ea2d55c, 0x56b3baf0, 0x1e800a04, 0x269165a8, - 0x8ee76bec, 0xb6f60440, 0xfec5b4b4, 0xc6d4db18, - 0xabc5decd, 0x93d4b161, 0xdbe70195, 0xe3f66e39, - 0x4b80607d, 0x73910fd1, 0x3ba2bf25, 0x03b3d089, - 0xe180b48f, 0xd991db23, 0x91a26bd7, 0xa9b3047b, - 0x01c50a3f, 0x39d46593, 0x71e7d567, 0x49f6bacb, - 0x24e7bf1e, 0x1cf6d0b2, 0x54c56046, 0x6cd40fea, - 0xc4a201ae, 0xfcb36e02, 0xb480def6, 0x8c91b15a, - 0x750a600b, 0x4d1b0fa7, 0x0528bf53, 0x3d39d0ff, - 0x954fdebb, 0xad5eb117, 0xe56d01e3, 0xdd7c6e4f, - 0xb06d6b9a, 0x887c0436, 0xc04fb4c2, 0xf85edb6e, - 0x5028d52a, 0x6839ba86, 0x200a0a72, 0x181b65de, - 0xfa2801d8, 0xc2396e74, 0x8a0ade80, 0xb21bb12c, - 0x1a6dbf68, 0x227cd0c4, 0x6a4f6030, 0x525e0f9c, - 0x3f4f0a49, 0x075e65e5, 0x4f6dd511, 0x777cbabd, - 0xdf0ab4f9, 0xe71bdb55, 0xaf286ba1, 0x9739040d, - 0x59f3bff2, 0x61e2d05e, 0x29d160aa, 0x11c00f06, - 0xb9b60142, 0x81a76eee, 0xc994de1a, 0xf185b1b6, - 0x9c94b463, 0xa485dbcf, 0xecb66b3b, 0xd4a70497, - 0x7cd10ad3, 0x44c0657f, 0x0cf3d58b, 0x34e2ba27, - 0xd6d1de21, 0xeec0b18d, 0xa6f30179, 0x9ee26ed5, - 0x36946091, 0x0e850f3d, 0x46b6bfc9, 0x7ea7d065, - 0x13b6d5b0, 0x2ba7ba1c, 0x63940ae8, 0x5b856544, - 0xf3f36b00, 0xcbe204ac, 0x83d1b458, 0xbbc0dbf4, - 0x425b0aa5, 0x7a4a6509, 0x3279d5fd, 0x0a68ba51, - 0xa21eb415, 0x9a0fdbb9, 0xd23c6b4d, 0xea2d04e1, - 0x873c0134, 0xbf2d6e98, 0xf71ede6c, 0xcf0fb1c0, - 0x6779bf84, 0x5f68d028, 0x175b60dc, 0x2f4a0f70, - 0xcd796b76, 0xf56804da, 0xbd5bb42e, 0x854adb82, - 0x2d3cd5c6, 0x152dba6a, 0x5d1e0a9e, 0x650f6532, - 0x081e60e7, 0x300f0f4b, 0x783cbfbf, 0x402dd013, - 0xe85bde57, 0xd04ab1fb, 0x9879010f, 0xa0686ea3 - },{ - 0x00000000, 0xef306b19, 0xdb8ca0c3, 0x34bccbda, - 0xb2f53777, 0x5dc55c6e, 0x697997b4, 0x8649fcad, - 0x6006181f, 0x8f367306, 0xbb8ab8dc, 0x54bad3c5, - 0xd2f32f68, 0x3dc34471, 0x097f8fab, 0xe64fe4b2, - 0xc00c303e, 0x2f3c5b27, 0x1b8090fd, 0xf4b0fbe4, - 0x72f90749, 0x9dc96c50, 0xa975a78a, 0x4645cc93, - 0xa00a2821, 0x4f3a4338, 0x7b8688e2, 0x94b6e3fb, - 0x12ff1f56, 0xfdcf744f, 0xc973bf95, 0x2643d48c, - 0x85f4168d, 0x6ac47d94, 0x5e78b64e, 0xb148dd57, - 0x370121fa, 0xd8314ae3, 0xec8d8139, 0x03bdea20, - 0xe5f20e92, 0x0ac2658b, 0x3e7eae51, 0xd14ec548, - 0x570739e5, 0xb83752fc, 0x8c8b9926, 0x63bbf23f, - 0x45f826b3, 0xaac84daa, 0x9e748670, 0x7144ed69, - 0xf70d11c4, 0x183d7add, 0x2c81b107, 0xc3b1da1e, - 0x25fe3eac, 0xcace55b5, 0xfe729e6f, 0x1142f576, - 0x970b09db, 0x783b62c2, 0x4c87a918, 0xa3b7c201, - 0x0e045beb, 0xe13430f2, 0xd588fb28, 0x3ab89031, - 0xbcf16c9c, 0x53c10785, 0x677dcc5f, 0x884da746, - 0x6e0243f4, 0x813228ed, 0xb58ee337, 0x5abe882e, - 0xdcf77483, 0x33c71f9a, 0x077bd440, 0xe84bbf59, - 0xce086bd5, 0x213800cc, 0x1584cb16, 0xfab4a00f, - 0x7cfd5ca2, 0x93cd37bb, 0xa771fc61, 0x48419778, - 0xae0e73ca, 0x413e18d3, 0x7582d309, 0x9ab2b810, - 0x1cfb44bd, 0xf3cb2fa4, 0xc777e47e, 0x28478f67, - 0x8bf04d66, 0x64c0267f, 0x507ceda5, 0xbf4c86bc, - 0x39057a11, 0xd6351108, 0xe289dad2, 0x0db9b1cb, - 0xebf65579, 0x04c63e60, 0x307af5ba, 0xdf4a9ea3, - 0x5903620e, 0xb6330917, 0x828fc2cd, 0x6dbfa9d4, - 0x4bfc7d58, 0xa4cc1641, 0x9070dd9b, 0x7f40b682, - 0xf9094a2f, 0x16392136, 0x2285eaec, 0xcdb581f5, - 0x2bfa6547, 0xc4ca0e5e, 0xf076c584, 0x1f46ae9d, - 0x990f5230, 0x763f3929, 0x4283f2f3, 0xadb399ea, - 0x1c08b7d6, 0xf338dccf, 0xc7841715, 0x28b47c0c, - 0xaefd80a1, 0x41cdebb8, 0x75712062, 0x9a414b7b, - 0x7c0eafc9, 0x933ec4d0, 0xa7820f0a, 0x48b26413, - 0xcefb98be, 0x21cbf3a7, 0x1577387d, 0xfa475364, - 0xdc0487e8, 0x3334ecf1, 0x0788272b, 0xe8b84c32, - 0x6ef1b09f, 0x81c1db86, 0xb57d105c, 0x5a4d7b45, - 0xbc029ff7, 0x5332f4ee, 0x678e3f34, 0x88be542d, - 0x0ef7a880, 0xe1c7c399, 0xd57b0843, 0x3a4b635a, - 0x99fca15b, 0x76ccca42, 0x42700198, 0xad406a81, - 0x2b09962c, 0xc439fd35, 0xf08536ef, 0x1fb55df6, - 0xf9fab944, 0x16cad25d, 0x22761987, 0xcd46729e, - 0x4b0f8e33, 0xa43fe52a, 0x90832ef0, 0x7fb345e9, - 0x59f09165, 0xb6c0fa7c, 0x827c31a6, 0x6d4c5abf, - 0xeb05a612, 0x0435cd0b, 0x308906d1, 0xdfb96dc8, - 0x39f6897a, 0xd6c6e263, 0xe27a29b9, 0x0d4a42a0, - 0x8b03be0d, 0x6433d514, 0x508f1ece, 0xbfbf75d7, - 0x120cec3d, 0xfd3c8724, 0xc9804cfe, 0x26b027e7, - 0xa0f9db4a, 0x4fc9b053, 0x7b757b89, 0x94451090, - 0x720af422, 0x9d3a9f3b, 0xa98654e1, 0x46b63ff8, - 0xc0ffc355, 0x2fcfa84c, 0x1b736396, 0xf443088f, - 0xd200dc03, 0x3d30b71a, 0x098c7cc0, 0xe6bc17d9, - 0x60f5eb74, 0x8fc5806d, 0xbb794bb7, 0x544920ae, - 0xb206c41c, 0x5d36af05, 0x698a64df, 0x86ba0fc6, - 0x00f3f36b, 0xefc39872, 0xdb7f53a8, 0x344f38b1, - 0x97f8fab0, 0x78c891a9, 0x4c745a73, 0xa344316a, - 0x250dcdc7, 0xca3da6de, 0xfe816d04, 0x11b1061d, - 0xf7fee2af, 0x18ce89b6, 0x2c72426c, 0xc3422975, - 0x450bd5d8, 0xaa3bbec1, 0x9e87751b, 0x71b71e02, - 0x57f4ca8e, 0xb8c4a197, 0x8c786a4d, 0x63480154, - 0xe501fdf9, 0x0a3196e0, 0x3e8d5d3a, 0xd1bd3623, - 0x37f2d291, 0xd8c2b988, 0xec7e7252, 0x034e194b, - 0x8507e5e6, 0x6a378eff, 0x5e8b4525, 0xb1bb2e3c - },{ - 0x00000000, 0x68032cc8, 0xd0065990, 0xb8057558, - 0xa5e0c5d1, 0xcde3e919, 0x75e69c41, 0x1de5b089, - 0x4e2dfd53, 0x262ed19b, 0x9e2ba4c3, 0xf628880b, - 0xebcd3882, 0x83ce144a, 0x3bcb6112, 0x53c84dda, - 0x9c5bfaa6, 0xf458d66e, 0x4c5da336, 0x245e8ffe, - 0x39bb3f77, 0x51b813bf, 0xe9bd66e7, 0x81be4a2f, - 0xd27607f5, 0xba752b3d, 0x02705e65, 0x6a7372ad, - 0x7796c224, 0x1f95eeec, 0xa7909bb4, 0xcf93b77c, - 0x3d5b83bd, 0x5558af75, 0xed5dda2d, 0x855ef6e5, - 0x98bb466c, 0xf0b86aa4, 0x48bd1ffc, 0x20be3334, - 0x73767eee, 0x1b755226, 0xa370277e, 0xcb730bb6, - 0xd696bb3f, 0xbe9597f7, 0x0690e2af, 0x6e93ce67, - 0xa100791b, 0xc90355d3, 0x7106208b, 0x19050c43, - 0x04e0bcca, 0x6ce39002, 0xd4e6e55a, 0xbce5c992, - 0xef2d8448, 0x872ea880, 0x3f2bddd8, 0x5728f110, - 0x4acd4199, 0x22ce6d51, 0x9acb1809, 0xf2c834c1, - 0x7ab7077a, 0x12b42bb2, 0xaab15eea, 0xc2b27222, - 0xdf57c2ab, 0xb754ee63, 0x0f519b3b, 0x6752b7f3, - 0x349afa29, 0x5c99d6e1, 0xe49ca3b9, 0x8c9f8f71, - 0x917a3ff8, 0xf9791330, 0x417c6668, 0x297f4aa0, - 0xe6ecfddc, 0x8eefd114, 0x36eaa44c, 0x5ee98884, - 0x430c380d, 0x2b0f14c5, 0x930a619d, 0xfb094d55, - 0xa8c1008f, 0xc0c22c47, 0x78c7591f, 0x10c475d7, - 0x0d21c55e, 0x6522e996, 0xdd279cce, 0xb524b006, - 0x47ec84c7, 0x2fefa80f, 0x97eadd57, 0xffe9f19f, - 0xe20c4116, 0x8a0f6dde, 0x320a1886, 0x5a09344e, - 0x09c17994, 0x61c2555c, 0xd9c72004, 0xb1c40ccc, - 0xac21bc45, 0xc422908d, 0x7c27e5d5, 0x1424c91d, - 0xdbb77e61, 0xb3b452a9, 0x0bb127f1, 0x63b20b39, - 0x7e57bbb0, 0x16549778, 0xae51e220, 0xc652cee8, - 0x959a8332, 0xfd99affa, 0x459cdaa2, 0x2d9ff66a, - 0x307a46e3, 0x58796a2b, 0xe07c1f73, 0x887f33bb, - 0xf56e0ef4, 0x9d6d223c, 0x25685764, 0x4d6b7bac, - 0x508ecb25, 0x388de7ed, 0x808892b5, 0xe88bbe7d, - 0xbb43f3a7, 0xd340df6f, 0x6b45aa37, 0x034686ff, - 0x1ea33676, 0x76a01abe, 0xcea56fe6, 0xa6a6432e, - 0x6935f452, 0x0136d89a, 0xb933adc2, 0xd130810a, - 0xccd53183, 0xa4d61d4b, 0x1cd36813, 0x74d044db, - 0x27180901, 0x4f1b25c9, 0xf71e5091, 0x9f1d7c59, - 0x82f8ccd0, 0xeafbe018, 0x52fe9540, 0x3afdb988, - 0xc8358d49, 0xa036a181, 0x1833d4d9, 0x7030f811, - 0x6dd54898, 0x05d66450, 0xbdd31108, 0xd5d03dc0, - 0x8618701a, 0xee1b5cd2, 0x561e298a, 0x3e1d0542, - 0x23f8b5cb, 0x4bfb9903, 0xf3feec5b, 0x9bfdc093, - 0x546e77ef, 0x3c6d5b27, 0x84682e7f, 0xec6b02b7, - 0xf18eb23e, 0x998d9ef6, 0x2188ebae, 0x498bc766, - 0x1a438abc, 0x7240a674, 0xca45d32c, 0xa246ffe4, - 0xbfa34f6d, 0xd7a063a5, 0x6fa516fd, 0x07a63a35, - 0x8fd9098e, 0xe7da2546, 0x5fdf501e, 0x37dc7cd6, - 0x2a39cc5f, 0x423ae097, 0xfa3f95cf, 0x923cb907, - 0xc1f4f4dd, 0xa9f7d815, 0x11f2ad4d, 0x79f18185, - 0x6414310c, 0x0c171dc4, 0xb412689c, 0xdc114454, - 0x1382f328, 0x7b81dfe0, 0xc384aab8, 0xab878670, - 0xb66236f9, 0xde611a31, 0x66646f69, 0x0e6743a1, - 0x5daf0e7b, 0x35ac22b3, 0x8da957eb, 0xe5aa7b23, - 0xf84fcbaa, 0x904ce762, 0x2849923a, 0x404abef2, - 0xb2828a33, 0xda81a6fb, 0x6284d3a3, 0x0a87ff6b, - 0x17624fe2, 0x7f61632a, 0xc7641672, 0xaf673aba, - 0xfcaf7760, 0x94ac5ba8, 0x2ca92ef0, 0x44aa0238, - 0x594fb2b1, 0x314c9e79, 0x8949eb21, 0xe14ac7e9, - 0x2ed97095, 0x46da5c5d, 0xfedf2905, 0x96dc05cd, - 0x8b39b544, 0xe33a998c, 0x5b3fecd4, 0x333cc01c, - 0x60f48dc6, 0x08f7a10e, 0xb0f2d456, 0xd8f1f89e, - 0xc5144817, 0xad1764df, 0x15121187, 0x7d113d4f - },{ - 0x00000000, 0x493c7d27, 0x9278fa4e, 0xdb448769, - 0x211d826d, 0x6821ff4a, 0xb3657823, 0xfa590504, - 0x423b04da, 0x0b0779fd, 0xd043fe94, 0x997f83b3, - 0x632686b7, 0x2a1afb90, 0xf15e7cf9, 0xb86201de, - 0x847609b4, 0xcd4a7493, 0x160ef3fa, 0x5f328edd, - 0xa56b8bd9, 0xec57f6fe, 0x37137197, 0x7e2f0cb0, - 0xc64d0d6e, 0x8f717049, 0x5435f720, 0x1d098a07, - 0xe7508f03, 0xae6cf224, 0x7528754d, 0x3c14086a, - 0x0d006599, 0x443c18be, 0x9f789fd7, 0xd644e2f0, - 0x2c1de7f4, 0x65219ad3, 0xbe651dba, 0xf759609d, - 0x4f3b6143, 0x06071c64, 0xdd439b0d, 0x947fe62a, - 0x6e26e32e, 0x271a9e09, 0xfc5e1960, 0xb5626447, - 0x89766c2d, 0xc04a110a, 0x1b0e9663, 0x5232eb44, - 0xa86bee40, 0xe1579367, 0x3a13140e, 0x732f6929, - 0xcb4d68f7, 0x827115d0, 0x593592b9, 0x1009ef9e, - 0xea50ea9a, 0xa36c97bd, 0x782810d4, 0x31146df3, - 0x1a00cb32, 0x533cb615, 0x8878317c, 0xc1444c5b, - 0x3b1d495f, 0x72213478, 0xa965b311, 0xe059ce36, - 0x583bcfe8, 0x1107b2cf, 0xca4335a6, 0x837f4881, - 0x79264d85, 0x301a30a2, 0xeb5eb7cb, 0xa262caec, - 0x9e76c286, 0xd74abfa1, 0x0c0e38c8, 0x453245ef, - 0xbf6b40eb, 0xf6573dcc, 0x2d13baa5, 0x642fc782, - 0xdc4dc65c, 0x9571bb7b, 0x4e353c12, 0x07094135, - 0xfd504431, 0xb46c3916, 0x6f28be7f, 0x2614c358, - 0x1700aeab, 0x5e3cd38c, 0x857854e5, 0xcc4429c2, - 0x361d2cc6, 0x7f2151e1, 0xa465d688, 0xed59abaf, - 0x553baa71, 0x1c07d756, 0xc743503f, 0x8e7f2d18, - 0x7426281c, 0x3d1a553b, 0xe65ed252, 0xaf62af75, - 0x9376a71f, 0xda4ada38, 0x010e5d51, 0x48322076, - 0xb26b2572, 0xfb575855, 0x2013df3c, 0x692fa21b, - 0xd14da3c5, 0x9871dee2, 0x4335598b, 0x0a0924ac, - 0xf05021a8, 0xb96c5c8f, 0x6228dbe6, 0x2b14a6c1, - 0x34019664, 0x7d3deb43, 0xa6796c2a, 0xef45110d, - 0x151c1409, 0x5c20692e, 0x8764ee47, 0xce589360, - 0x763a92be, 0x3f06ef99, 0xe44268f0, 0xad7e15d7, - 0x572710d3, 0x1e1b6df4, 0xc55fea9d, 0x8c6397ba, - 0xb0779fd0, 0xf94be2f7, 0x220f659e, 0x6b3318b9, - 0x916a1dbd, 0xd856609a, 0x0312e7f3, 0x4a2e9ad4, - 0xf24c9b0a, 0xbb70e62d, 0x60346144, 0x29081c63, - 0xd3511967, 0x9a6d6440, 0x4129e329, 0x08159e0e, - 0x3901f3fd, 0x703d8eda, 0xab7909b3, 0xe2457494, - 0x181c7190, 0x51200cb7, 0x8a648bde, 0xc358f6f9, - 0x7b3af727, 0x32068a00, 0xe9420d69, 0xa07e704e, - 0x5a27754a, 0x131b086d, 0xc85f8f04, 0x8163f223, - 0xbd77fa49, 0xf44b876e, 0x2f0f0007, 0x66337d20, - 0x9c6a7824, 0xd5560503, 0x0e12826a, 0x472eff4d, - 0xff4cfe93, 0xb67083b4, 0x6d3404dd, 0x240879fa, - 0xde517cfe, 0x976d01d9, 0x4c2986b0, 0x0515fb97, - 0x2e015d56, 0x673d2071, 0xbc79a718, 0xf545da3f, - 0x0f1cdf3b, 0x4620a21c, 0x9d642575, 0xd4585852, - 0x6c3a598c, 0x250624ab, 0xfe42a3c2, 0xb77edee5, - 0x4d27dbe1, 0x041ba6c6, 0xdf5f21af, 0x96635c88, - 0xaa7754e2, 0xe34b29c5, 0x380faeac, 0x7133d38b, - 0x8b6ad68f, 0xc256aba8, 0x19122cc1, 0x502e51e6, - 0xe84c5038, 0xa1702d1f, 0x7a34aa76, 0x3308d751, - 0xc951d255, 0x806daf72, 0x5b29281b, 0x1215553c, - 0x230138cf, 0x6a3d45e8, 0xb179c281, 0xf845bfa6, - 0x021cbaa2, 0x4b20c785, 0x906440ec, 0xd9583dcb, - 0x613a3c15, 0x28064132, 0xf342c65b, 0xba7ebb7c, - 0x4027be78, 0x091bc35f, 0xd25f4436, 0x9b633911, - 0xa777317b, 0xee4b4c5c, 0x350fcb35, 0x7c33b612, - 0x866ab316, 0xcf56ce31, 0x14124958, 0x5d2e347f, - 0xe54c35a1, 0xac704886, 0x7734cfef, 0x3e08b2c8, - 0xc451b7cc, 0x8d6dcaeb, 0x56294d82, 0x1f1530a5 - } -#endif -}; - -#if !defined(__powerpc64__) -/* - * __wt_cksum_sw -- - * Return a checksum for a chunk of memory, computed in software. - */ -static uint32_t -__wt_cksum_sw(const void *chunk, size_t len) -{ - uint32_t crc, next; - size_t nqwords; - const uint8_t *p; - - crc = 0xffffffff; - - /* Checksum one byte at a time to the first 4B boundary. */ - for (p = chunk; - ((uintptr_t)p & (sizeof(uint32_t) - 1)) != 0 && - len > 0; ++p, --len) -#ifdef WORDS_BIGENDIAN - crc = g_crc_slicing[0][((crc >> 24) ^ *p) & 0xFF] ^ (crc << 8); -#else - crc = g_crc_slicing[0][(crc ^ *p) & 0xFF] ^ (crc >> 8); -#endif - - /* Checksum in 8B chunks. */ - for (nqwords = len / sizeof(uint64_t); nqwords; nqwords--) { - crc ^= *(uint32_t *)p; - p += sizeof(uint32_t); - next = *(uint32_t *)p; - p += sizeof(uint32_t); - crc = -#ifdef WORDS_BIGENDIAN - g_crc_slicing[4][(crc ) & 0xFF] ^ - g_crc_slicing[5][(crc >> 8) & 0xFF] ^ - g_crc_slicing[6][(crc >> 16) & 0xFF] ^ - g_crc_slicing[7][(crc >> 24)] ^ - g_crc_slicing[0][(next ) & 0xFF] ^ - g_crc_slicing[1][(next >> 8) & 0xFF] ^ - g_crc_slicing[2][(next >> 16) & 0xFF] ^ - g_crc_slicing[3][(next >> 24)]; -#else - g_crc_slicing[7][(crc ) & 0xFF] ^ - g_crc_slicing[6][(crc >> 8) & 0xFF] ^ - g_crc_slicing[5][(crc >> 16) & 0xFF] ^ - g_crc_slicing[4][(crc >> 24)] ^ - g_crc_slicing[3][(next ) & 0xFF] ^ - g_crc_slicing[2][(next >> 8) & 0xFF] ^ - g_crc_slicing[1][(next >> 16) & 0xFF] ^ - g_crc_slicing[0][(next >> 24)]; -#endif - } - - /* Checksum trailing bytes one byte at a time. */ -#ifdef WORDS_BIGENDIAN - for (len &= 0x7; len > 0; ++p, len--) - crc = g_crc_slicing[0][((crc >> 24) ^ *p) & 0xFF] ^ (crc << 8); - - /* Do final byte swap to produce a result identical to little endian */ - crc = - ((crc << 24) & 0xFF000000) | - ((crc << 8) & 0x00FF0000) | - ((crc >> 8) & 0x0000FF00) | - ((crc >> 24) & 0x000000FF); -#else - for (len &= 0x7; len > 0; ++p, len--) - crc = g_crc_slicing[0][(crc ^ *p) & 0xFF] ^ (crc >> 8); -#endif - return (~crc); -} -#endif - -#if (defined(__amd64) || defined(__x86_64)) -/* - * __wt_cksum_hw -- - * Return a checksum for a chunk of memory, computed in hardware - * using 8 byte steps. - */ -static uint32_t -__wt_cksum_hw(const void *chunk, size_t len) -{ - uint32_t crc; - size_t nqwords; - const uint8_t *p; - const uint64_t *p64; - - crc = 0xffffffff; - - /* Checksum one byte at a time to the first 4B boundary. */ - for (p = chunk; - ((uintptr_t)p & (sizeof(uint32_t) - 1)) != 0 && - len > 0; ++p, --len) { - __asm__ __volatile__( - ".byte 0xF2, 0x0F, 0x38, 0xF0, 0xF1" - : "=S" (crc) - : "0" (crc), "c" (*p)); - } - - p64 = (const uint64_t *)p; - /* Checksum in 8B chunks. */ - for (nqwords = len / sizeof(uint64_t); nqwords; nqwords--) { - __asm__ __volatile__ ( - ".byte 0xF2, 0x48, 0x0F, 0x38, 0xF1, 0xF1" - : "=S"(crc) - : "0"(crc), "c" (*p64)); - p64++; - } - - /* Checksum trailing bytes one byte at a time. */ - p = (const uint8_t *)p64; - for (len &= 0x7; len > 0; ++p, len--) { - __asm__ __volatile__( - ".byte 0xF2, 0x0F, 0x38, 0xF0, 0xF1" - : "=S" (crc) - : "0" (crc), "c" (*p)); - } - return (~crc); -} -#endif - -#if defined(_M_AMD64) -/* - * __wt_cksum_hw -- - * Return a checksum for a chunk of memory, computed in hardware - * using 8 byte steps. - */ -static uint32_t -__wt_cksum_hw(const void *chunk, size_t len) -{ - uint32_t crc; - size_t nqwords; - const uint8_t *p; - const uint64_t *p64; - - crc = 0xffffffff; - - /* Checksum one byte at a time to the first 4B boundary. */ - for (p = chunk; - ((uintptr_t)p & (sizeof(uint32_t) - 1)) != 0 && - len > 0; ++p, --len) { - crc = _mm_crc32_u8(crc, *p); - } - - p64 = (const uint64_t *)p; - /* Checksum in 8B chunks. */ - for (nqwords = len / sizeof(uint64_t); nqwords; nqwords--) { - crc = (uint32_t)_mm_crc32_u64(crc, *p64); - p64++; - } - - /* Checksum trailing bytes one byte at a time. */ - p = (const uint8_t *)p64; - for (len &= 0x7; len > 0; ++p, len--) { - crc = _mm_crc32_u8(crc, *p); - } - - return (~crc); -} -#endif - -#if defined(__powerpc64__) - -unsigned int crc32_vpmsum(unsigned int crc, const unsigned char *p, - unsigned long len); - -/* - * __wt_cksum_hw -- - * Return a checksum for a chunk of memory, computed in hardware - * using 8 byte steps. - */ -static uint32_t -__wt_cksum_hw(const void *chunk, size_t len) -{ - return crc32_vpmsum(0, chunk, len); -} -#endif - -/* - * __wt_cksum -- - * Return a checksum for a chunk of memory using the fastest method - * available. - */ -uint32_t -__wt_cksum(const void *chunk, size_t len) -{ - return (*__wt_cksum_func)(chunk, len); -} - -/* - * __wt_cksum_init -- - * Detect CRC hardware and set the checksum function. - */ -void -__wt_cksum_init(void) -{ -#define CPUID_ECX_HAS_SSE42 (1 << 20) - -#if (defined(__amd64) || defined(__x86_64)) - unsigned int eax, ebx, ecx, edx; - - __asm__ __volatile__ ( - "cpuid" - : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) - : "a" (1)); - - if (ecx & CPUID_ECX_HAS_SSE42) - __wt_cksum_func = __wt_cksum_hw; - else - __wt_cksum_func = __wt_cksum_sw; - -#elif defined(_M_AMD64) - int cpuInfo[4]; - - __cpuid(cpuInfo, 1); - - if (cpuInfo[2] & CPUID_ECX_HAS_SSE42) - __wt_cksum_func = __wt_cksum_hw; - else - __wt_cksum_func = __wt_cksum_sw; -#elif defined(__powerpc64__) - __wt_cksum_func = __wt_cksum_hw; -#else - __wt_cksum_func = __wt_cksum_sw; -#endif -} diff --git a/src/third_party/wiredtiger/src/checksum/power8/crc32_wrapper.c b/src/third_party/wiredtiger/src/checksum/power8/crc32_wrapper.c index 62bd3e64f5c..ddfa2bdaeb8 100644 --- a/src/third_party/wiredtiger/src/checksum/power8/crc32_wrapper.c +++ b/src/third_party/wiredtiger/src/checksum/power8/crc32_wrapper.c @@ -6,7 +6,7 @@ #define VMX_ALIGN_MASK (VMX_ALIGN-1) #ifdef REFLECT -static unsigned int crc32_align(unsigned int crc, unsigned char *p, +static unsigned int crc32_align(unsigned int crc, const unsigned char *p, unsigned long len) { while (len--) @@ -14,7 +14,7 @@ static unsigned int crc32_align(unsigned int crc, unsigned char *p, return crc; } #else -static unsigned int crc32_align(unsigned int crc, unsigned char *p, +static unsigned int crc32_align(unsigned int crc, const unsigned char *p, unsigned long len) { while (len--) @@ -23,13 +23,13 @@ static unsigned int crc32_align(unsigned int crc, unsigned char *p, } #endif -unsigned int __crc32_vpmsum(unsigned int crc, unsigned char *p, +unsigned int __crc32_vpmsum(unsigned int crc, const unsigned char *p, unsigned long len); /* -Werror=missing-prototypes */ -unsigned int crc32_vpmsum(unsigned int crc, unsigned char *p, +unsigned int crc32_vpmsum(unsigned int crc, const unsigned char *p, unsigned long len); -unsigned int crc32_vpmsum(unsigned int crc, unsigned char *p, +unsigned int crc32_vpmsum(unsigned int crc, const unsigned char *p, unsigned long len) { unsigned int prealign; @@ -67,3 +67,29 @@ out: return crc; } #endif + +#include "wt_internal.h" + +/* + * __wt_checksum_hw -- + * WiredTiger: return a checksum for a chunk of memory. + */ +static uint32_t +__wt_checksum_hw(const void *chunk, size_t len) +{ + return (crc32_vpmsum(0, chunk, len)); +} + +/* + * __wt_checksum_init -- + * WiredTiger: detect CRC hardware and set the checksum function. + */ +void +__wt_checksum_init(void) +{ +#if defined(HAVE_CRC32_HARDWARE) + __wt_process.checksum = __wt_checksum_hw; +#else + __wt_process.checksum = __wt_checksum_sw; +#endif +} diff --git a/src/third_party/wiredtiger/src/checksum/software/checksum.c b/src/third_party/wiredtiger/src/checksum/software/checksum.c new file mode 100644 index 00000000000..30362584a3e --- /dev/null +++ b/src/third_party/wiredtiger/src/checksum/software/checksum.c @@ -0,0 +1,1165 @@ +/*- + * Public Domain 2014-2016 MongoDB, Inc. + * Public Domain 2008-2014 WiredTiger, Inc. + * + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +/* + * Slicing-by-8 algorithm by Michael E. Kounavis and Frank L. Berry, described + * in "Novel Table Lookup-Based Algorithms for High-Performance CRC Generation", + * IEEE Transactions on Computers, Volume 57 Issue 11, November 2008. + * + * See also Peter Kanowski's posting: + * http://www.strchr.com/crc32_popcnt + * + * The big endian version calculates the same result at each step, except the + * value of the crc is byte reversed from what it would be at that step for + * little endian. + */ + +#include "wt_internal.h" + +/* + * The CRC slicing tables. + */ +static const uint32_t g_crc_slicing[8][256] = { +#ifdef WORDS_BIGENDIAN + /* + * Big endian tables have entries that are byte reversed from little + * endian tables. + */ + { + 0x00000000, 0x03836bf2, 0xf7703be1, 0xf4f35013, + 0x1f979ac7, 0x1c14f135, 0xe8e7a126, 0xeb64cad4, + 0xcf58d98a, 0xccdbb278, 0x3828e26b, 0x3bab8999, + 0xd0cf434d, 0xd34c28bf, 0x27bf78ac, 0x243c135e, + 0x6fc75e10, 0x6c4435e2, 0x98b765f1, 0x9b340e03, + 0x7050c4d7, 0x73d3af25, 0x8720ff36, 0x84a394c4, + 0xa09f879a, 0xa31cec68, 0x57efbc7b, 0x546cd789, + 0xbf081d5d, 0xbc8b76af, 0x487826bc, 0x4bfb4d4e, + 0xde8ebd20, 0xdd0dd6d2, 0x29fe86c1, 0x2a7ded33, + 0xc11927e7, 0xc29a4c15, 0x36691c06, 0x35ea77f4, + 0x11d664aa, 0x12550f58, 0xe6a65f4b, 0xe52534b9, + 0x0e41fe6d, 0x0dc2959f, 0xf931c58c, 0xfab2ae7e, + 0xb149e330, 0xb2ca88c2, 0x4639d8d1, 0x45bab323, + 0xaede79f7, 0xad5d1205, 0x59ae4216, 0x5a2d29e4, + 0x7e113aba, 0x7d925148, 0x8961015b, 0x8ae26aa9, + 0x6186a07d, 0x6205cb8f, 0x96f69b9c, 0x9575f06e, + 0xbc1d7b41, 0xbf9e10b3, 0x4b6d40a0, 0x48ee2b52, + 0xa38ae186, 0xa0098a74, 0x54fada67, 0x5779b195, + 0x7345a2cb, 0x70c6c939, 0x8435992a, 0x87b6f2d8, + 0x6cd2380c, 0x6f5153fe, 0x9ba203ed, 0x9821681f, + 0xd3da2551, 0xd0594ea3, 0x24aa1eb0, 0x27297542, + 0xcc4dbf96, 0xcfced464, 0x3b3d8477, 0x38beef85, + 0x1c82fcdb, 0x1f019729, 0xebf2c73a, 0xe871acc8, + 0x0315661c, 0x00960dee, 0xf4655dfd, 0xf7e6360f, + 0x6293c661, 0x6110ad93, 0x95e3fd80, 0x96609672, + 0x7d045ca6, 0x7e873754, 0x8a746747, 0x89f70cb5, + 0xadcb1feb, 0xae487419, 0x5abb240a, 0x59384ff8, + 0xb25c852c, 0xb1dfeede, 0x452cbecd, 0x46afd53f, + 0x0d549871, 0x0ed7f383, 0xfa24a390, 0xf9a7c862, + 0x12c302b6, 0x11406944, 0xe5b33957, 0xe63052a5, + 0xc20c41fb, 0xc18f2a09, 0x357c7a1a, 0x36ff11e8, + 0xdd9bdb3c, 0xde18b0ce, 0x2aebe0dd, 0x29688b2f, + 0x783bf682, 0x7bb89d70, 0x8f4bcd63, 0x8cc8a691, + 0x67ac6c45, 0x642f07b7, 0x90dc57a4, 0x935f3c56, + 0xb7632f08, 0xb4e044fa, 0x401314e9, 0x43907f1b, + 0xa8f4b5cf, 0xab77de3d, 0x5f848e2e, 0x5c07e5dc, + 0x17fca892, 0x147fc360, 0xe08c9373, 0xe30ff881, + 0x086b3255, 0x0be859a7, 0xff1b09b4, 0xfc986246, + 0xd8a47118, 0xdb271aea, 0x2fd44af9, 0x2c57210b, + 0xc733ebdf, 0xc4b0802d, 0x3043d03e, 0x33c0bbcc, + 0xa6b54ba2, 0xa5362050, 0x51c57043, 0x52461bb1, + 0xb922d165, 0xbaa1ba97, 0x4e52ea84, 0x4dd18176, + 0x69ed9228, 0x6a6ef9da, 0x9e9da9c9, 0x9d1ec23b, + 0x767a08ef, 0x75f9631d, 0x810a330e, 0x828958fc, + 0xc97215b2, 0xcaf17e40, 0x3e022e53, 0x3d8145a1, + 0xd6e58f75, 0xd566e487, 0x2195b494, 0x2216df66, + 0x062acc38, 0x05a9a7ca, 0xf15af7d9, 0xf2d99c2b, + 0x19bd56ff, 0x1a3e3d0d, 0xeecd6d1e, 0xed4e06ec, + 0xc4268dc3, 0xc7a5e631, 0x3356b622, 0x30d5ddd0, + 0xdbb11704, 0xd8327cf6, 0x2cc12ce5, 0x2f424717, + 0x0b7e5449, 0x08fd3fbb, 0xfc0e6fa8, 0xff8d045a, + 0x14e9ce8e, 0x176aa57c, 0xe399f56f, 0xe01a9e9d, + 0xabe1d3d3, 0xa862b821, 0x5c91e832, 0x5f1283c0, + 0xb4764914, 0xb7f522e6, 0x430672f5, 0x40851907, + 0x64b90a59, 0x673a61ab, 0x93c931b8, 0x904a5a4a, + 0x7b2e909e, 0x78adfb6c, 0x8c5eab7f, 0x8fddc08d, + 0x1aa830e3, 0x192b5b11, 0xedd80b02, 0xee5b60f0, + 0x053faa24, 0x06bcc1d6, 0xf24f91c5, 0xf1ccfa37, + 0xd5f0e969, 0xd673829b, 0x2280d288, 0x2103b97a, + 0xca6773ae, 0xc9e4185c, 0x3d17484f, 0x3e9423bd, + 0x756f6ef3, 0x76ec0501, 0x821f5512, 0x819c3ee0, + 0x6af8f434, 0x697b9fc6, 0x9d88cfd5, 0x9e0ba427, + 0xba37b779, 0xb9b4dc8b, 0x4d478c98, 0x4ec4e76a, + 0xa5a02dbe, 0xa623464c, 0x52d0165f, 0x51537dad + },{ + 0x00000000, 0x7798a213, 0xee304527, 0x99a8e734, + 0xdc618a4e, 0xabf9285d, 0x3251cf69, 0x45c96d7a, + 0xb8c3149d, 0xcf5bb68e, 0x56f351ba, 0x216bf3a9, + 0x64a29ed3, 0x133a3cc0, 0x8a92dbf4, 0xfd0a79e7, + 0x81f1c53f, 0xf669672c, 0x6fc18018, 0x1859220b, + 0x5d904f71, 0x2a08ed62, 0xb3a00a56, 0xc438a845, + 0x3932d1a2, 0x4eaa73b1, 0xd7029485, 0xa09a3696, + 0xe5535bec, 0x92cbf9ff, 0x0b631ecb, 0x7cfbbcd8, + 0x02e38b7f, 0x757b296c, 0xecd3ce58, 0x9b4b6c4b, + 0xde820131, 0xa91aa322, 0x30b24416, 0x472ae605, + 0xba209fe2, 0xcdb83df1, 0x5410dac5, 0x238878d6, + 0x664115ac, 0x11d9b7bf, 0x8871508b, 0xffe9f298, + 0x83124e40, 0xf48aec53, 0x6d220b67, 0x1abaa974, + 0x5f73c40e, 0x28eb661d, 0xb1438129, 0xc6db233a, + 0x3bd15add, 0x4c49f8ce, 0xd5e11ffa, 0xa279bde9, + 0xe7b0d093, 0x90287280, 0x098095b4, 0x7e1837a7, + 0x04c617ff, 0x735eb5ec, 0xeaf652d8, 0x9d6ef0cb, + 0xd8a79db1, 0xaf3f3fa2, 0x3697d896, 0x410f7a85, + 0xbc050362, 0xcb9da171, 0x52354645, 0x25ade456, + 0x6064892c, 0x17fc2b3f, 0x8e54cc0b, 0xf9cc6e18, + 0x8537d2c0, 0xf2af70d3, 0x6b0797e7, 0x1c9f35f4, + 0x5956588e, 0x2ecefa9d, 0xb7661da9, 0xc0febfba, + 0x3df4c65d, 0x4a6c644e, 0xd3c4837a, 0xa45c2169, + 0xe1954c13, 0x960dee00, 0x0fa50934, 0x783dab27, + 0x06259c80, 0x71bd3e93, 0xe815d9a7, 0x9f8d7bb4, + 0xda4416ce, 0xaddcb4dd, 0x347453e9, 0x43ecf1fa, + 0xbee6881d, 0xc97e2a0e, 0x50d6cd3a, 0x274e6f29, + 0x62870253, 0x151fa040, 0x8cb74774, 0xfb2fe567, + 0x87d459bf, 0xf04cfbac, 0x69e41c98, 0x1e7cbe8b, + 0x5bb5d3f1, 0x2c2d71e2, 0xb58596d6, 0xc21d34c5, + 0x3f174d22, 0x488fef31, 0xd1270805, 0xa6bfaa16, + 0xe376c76c, 0x94ee657f, 0x0d46824b, 0x7ade2058, + 0xf9fac3fb, 0x8e6261e8, 0x17ca86dc, 0x605224cf, + 0x259b49b5, 0x5203eba6, 0xcbab0c92, 0xbc33ae81, + 0x4139d766, 0x36a17575, 0xaf099241, 0xd8913052, + 0x9d585d28, 0xeac0ff3b, 0x7368180f, 0x04f0ba1c, + 0x780b06c4, 0x0f93a4d7, 0x963b43e3, 0xe1a3e1f0, + 0xa46a8c8a, 0xd3f22e99, 0x4a5ac9ad, 0x3dc26bbe, + 0xc0c81259, 0xb750b04a, 0x2ef8577e, 0x5960f56d, + 0x1ca99817, 0x6b313a04, 0xf299dd30, 0x85017f23, + 0xfb194884, 0x8c81ea97, 0x15290da3, 0x62b1afb0, + 0x2778c2ca, 0x50e060d9, 0xc94887ed, 0xbed025fe, + 0x43da5c19, 0x3442fe0a, 0xadea193e, 0xda72bb2d, + 0x9fbbd657, 0xe8237444, 0x718b9370, 0x06133163, + 0x7ae88dbb, 0x0d702fa8, 0x94d8c89c, 0xe3406a8f, + 0xa68907f5, 0xd111a5e6, 0x48b942d2, 0x3f21e0c1, + 0xc22b9926, 0xb5b33b35, 0x2c1bdc01, 0x5b837e12, + 0x1e4a1368, 0x69d2b17b, 0xf07a564f, 0x87e2f45c, + 0xfd3cd404, 0x8aa47617, 0x130c9123, 0x64943330, + 0x215d5e4a, 0x56c5fc59, 0xcf6d1b6d, 0xb8f5b97e, + 0x45ffc099, 0x3267628a, 0xabcf85be, 0xdc5727ad, + 0x999e4ad7, 0xee06e8c4, 0x77ae0ff0, 0x0036ade3, + 0x7ccd113b, 0x0b55b328, 0x92fd541c, 0xe565f60f, + 0xa0ac9b75, 0xd7343966, 0x4e9cde52, 0x39047c41, + 0xc40e05a6, 0xb396a7b5, 0x2a3e4081, 0x5da6e292, + 0x186f8fe8, 0x6ff72dfb, 0xf65fcacf, 0x81c768dc, + 0xffdf5f7b, 0x8847fd68, 0x11ef1a5c, 0x6677b84f, + 0x23bed535, 0x54267726, 0xcd8e9012, 0xba163201, + 0x471c4be6, 0x3084e9f5, 0xa92c0ec1, 0xdeb4acd2, + 0x9b7dc1a8, 0xece563bb, 0x754d848f, 0x02d5269c, + 0x7e2e9a44, 0x09b63857, 0x901edf63, 0xe7867d70, + 0xa24f100a, 0xd5d7b219, 0x4c7f552d, 0x3be7f73e, + 0xc6ed8ed9, 0xb1752cca, 0x28ddcbfe, 0x5f4569ed, + 0x1a8c0497, 0x6d14a684, 0xf4bc41b0, 0x8324e3a3 + },{ + 0x00000000, 0x7e9241a5, 0x0d526f4f, 0x73c02eea, + 0x1aa4de9e, 0x64369f3b, 0x17f6b1d1, 0x6964f074, + 0xc53e5138, 0xbbac109d, 0xc86c3e77, 0xb6fe7fd2, + 0xdf9a8fa6, 0xa108ce03, 0xd2c8e0e9, 0xac5aa14c, + 0x8a7da270, 0xf4efe3d5, 0x872fcd3f, 0xf9bd8c9a, + 0x90d97cee, 0xee4b3d4b, 0x9d8b13a1, 0xe3195204, + 0x4f43f348, 0x31d1b2ed, 0x42119c07, 0x3c83dda2, + 0x55e72dd6, 0x2b756c73, 0x58b54299, 0x2627033c, + 0x14fb44e1, 0x6a690544, 0x19a92bae, 0x673b6a0b, + 0x0e5f9a7f, 0x70cddbda, 0x030df530, 0x7d9fb495, + 0xd1c515d9, 0xaf57547c, 0xdc977a96, 0xa2053b33, + 0xcb61cb47, 0xb5f38ae2, 0xc633a408, 0xb8a1e5ad, + 0x9e86e691, 0xe014a734, 0x93d489de, 0xed46c87b, + 0x8422380f, 0xfab079aa, 0x89705740, 0xf7e216e5, + 0x5bb8b7a9, 0x252af60c, 0x56ead8e6, 0x28789943, + 0x411c6937, 0x3f8e2892, 0x4c4e0678, 0x32dc47dd, + 0xd98065c7, 0xa7122462, 0xd4d20a88, 0xaa404b2d, + 0xc324bb59, 0xbdb6fafc, 0xce76d416, 0xb0e495b3, + 0x1cbe34ff, 0x622c755a, 0x11ec5bb0, 0x6f7e1a15, + 0x061aea61, 0x7888abc4, 0x0b48852e, 0x75dac48b, + 0x53fdc7b7, 0x2d6f8612, 0x5eafa8f8, 0x203de95d, + 0x49591929, 0x37cb588c, 0x440b7666, 0x3a9937c3, + 0x96c3968f, 0xe851d72a, 0x9b91f9c0, 0xe503b865, + 0x8c674811, 0xf2f509b4, 0x8135275e, 0xffa766fb, + 0xcd7b2126, 0xb3e96083, 0xc0294e69, 0xbebb0fcc, + 0xd7dfffb8, 0xa94dbe1d, 0xda8d90f7, 0xa41fd152, + 0x0845701e, 0x76d731bb, 0x05171f51, 0x7b855ef4, + 0x12e1ae80, 0x6c73ef25, 0x1fb3c1cf, 0x6121806a, + 0x47068356, 0x3994c2f3, 0x4a54ec19, 0x34c6adbc, + 0x5da25dc8, 0x23301c6d, 0x50f03287, 0x2e627322, + 0x8238d26e, 0xfcaa93cb, 0x8f6abd21, 0xf1f8fc84, + 0x989c0cf0, 0xe60e4d55, 0x95ce63bf, 0xeb5c221a, + 0x4377278b, 0x3de5662e, 0x4e2548c4, 0x30b70961, + 0x59d3f915, 0x2741b8b0, 0x5481965a, 0x2a13d7ff, + 0x864976b3, 0xf8db3716, 0x8b1b19fc, 0xf5895859, + 0x9ceda82d, 0xe27fe988, 0x91bfc762, 0xef2d86c7, + 0xc90a85fb, 0xb798c45e, 0xc458eab4, 0xbacaab11, + 0xd3ae5b65, 0xad3c1ac0, 0xdefc342a, 0xa06e758f, + 0x0c34d4c3, 0x72a69566, 0x0166bb8c, 0x7ff4fa29, + 0x16900a5d, 0x68024bf8, 0x1bc26512, 0x655024b7, + 0x578c636a, 0x291e22cf, 0x5ade0c25, 0x244c4d80, + 0x4d28bdf4, 0x33bafc51, 0x407ad2bb, 0x3ee8931e, + 0x92b23252, 0xec2073f7, 0x9fe05d1d, 0xe1721cb8, + 0x8816eccc, 0xf684ad69, 0x85448383, 0xfbd6c226, + 0xddf1c11a, 0xa36380bf, 0xd0a3ae55, 0xae31eff0, + 0xc7551f84, 0xb9c75e21, 0xca0770cb, 0xb495316e, + 0x18cf9022, 0x665dd187, 0x159dff6d, 0x6b0fbec8, + 0x026b4ebc, 0x7cf90f19, 0x0f3921f3, 0x71ab6056, + 0x9af7424c, 0xe46503e9, 0x97a52d03, 0xe9376ca6, + 0x80539cd2, 0xfec1dd77, 0x8d01f39d, 0xf393b238, + 0x5fc91374, 0x215b52d1, 0x529b7c3b, 0x2c093d9e, + 0x456dcdea, 0x3bff8c4f, 0x483fa2a5, 0x36ade300, + 0x108ae03c, 0x6e18a199, 0x1dd88f73, 0x634aced6, + 0x0a2e3ea2, 0x74bc7f07, 0x077c51ed, 0x79ee1048, + 0xd5b4b104, 0xab26f0a1, 0xd8e6de4b, 0xa6749fee, + 0xcf106f9a, 0xb1822e3f, 0xc24200d5, 0xbcd04170, + 0x8e0c06ad, 0xf09e4708, 0x835e69e2, 0xfdcc2847, + 0x94a8d833, 0xea3a9996, 0x99fab77c, 0xe768f6d9, + 0x4b325795, 0x35a01630, 0x466038da, 0x38f2797f, + 0x5196890b, 0x2f04c8ae, 0x5cc4e644, 0x2256a7e1, + 0x0471a4dd, 0x7ae3e578, 0x0923cb92, 0x77b18a37, + 0x1ed57a43, 0x60473be6, 0x1387150c, 0x6d1554a9, + 0xc14ff5e5, 0xbfddb440, 0xcc1d9aaa, 0xb28fdb0f, + 0xdbeb2b7b, 0xa5796ade, 0xd6b94434, 0xa82b0591 + },{ + 0x00000000, 0xb8aa45dd, 0x812367bf, 0x39892262, + 0xf331227b, 0x4b9b67a6, 0x721245c4, 0xcab80019, + 0xe66344f6, 0x5ec9012b, 0x67402349, 0xdfea6694, + 0x1552668d, 0xadf82350, 0x94710132, 0x2cdb44ef, + 0x3db164e9, 0x851b2134, 0xbc920356, 0x0438468b, + 0xce804692, 0x762a034f, 0x4fa3212d, 0xf70964f0, + 0xdbd2201f, 0x637865c2, 0x5af147a0, 0xe25b027d, + 0x28e30264, 0x904947b9, 0xa9c065db, 0x116a2006, + 0x8b1425d7, 0x33be600a, 0x0a374268, 0xb29d07b5, + 0x782507ac, 0xc08f4271, 0xf9066013, 0x41ac25ce, + 0x6d776121, 0xd5dd24fc, 0xec54069e, 0x54fe4343, + 0x9e46435a, 0x26ec0687, 0x1f6524e5, 0xa7cf6138, + 0xb6a5413e, 0x0e0f04e3, 0x37862681, 0x8f2c635c, + 0x45946345, 0xfd3e2698, 0xc4b704fa, 0x7c1d4127, + 0x50c605c8, 0xe86c4015, 0xd1e56277, 0x694f27aa, + 0xa3f727b3, 0x1b5d626e, 0x22d4400c, 0x9a7e05d1, + 0xe75fa6ab, 0x5ff5e376, 0x667cc114, 0xded684c9, + 0x146e84d0, 0xacc4c10d, 0x954de36f, 0x2de7a6b2, + 0x013ce25d, 0xb996a780, 0x801f85e2, 0x38b5c03f, + 0xf20dc026, 0x4aa785fb, 0x732ea799, 0xcb84e244, + 0xdaeec242, 0x6244879f, 0x5bcda5fd, 0xe367e020, + 0x29dfe039, 0x9175a5e4, 0xa8fc8786, 0x1056c25b, + 0x3c8d86b4, 0x8427c369, 0xbdaee10b, 0x0504a4d6, + 0xcfbca4cf, 0x7716e112, 0x4e9fc370, 0xf63586ad, + 0x6c4b837c, 0xd4e1c6a1, 0xed68e4c3, 0x55c2a11e, + 0x9f7aa107, 0x27d0e4da, 0x1e59c6b8, 0xa6f38365, + 0x8a28c78a, 0x32828257, 0x0b0ba035, 0xb3a1e5e8, + 0x7919e5f1, 0xc1b3a02c, 0xf83a824e, 0x4090c793, + 0x51fae795, 0xe950a248, 0xd0d9802a, 0x6873c5f7, + 0xa2cbc5ee, 0x1a618033, 0x23e8a251, 0x9b42e78c, + 0xb799a363, 0x0f33e6be, 0x36bac4dc, 0x8e108101, + 0x44a88118, 0xfc02c4c5, 0xc58be6a7, 0x7d21a37a, + 0x3fc9a052, 0x8763e58f, 0xbeeac7ed, 0x06408230, + 0xccf88229, 0x7452c7f4, 0x4ddbe596, 0xf571a04b, + 0xd9aae4a4, 0x6100a179, 0x5889831b, 0xe023c6c6, + 0x2a9bc6df, 0x92318302, 0xabb8a160, 0x1312e4bd, + 0x0278c4bb, 0xbad28166, 0x835ba304, 0x3bf1e6d9, + 0xf149e6c0, 0x49e3a31d, 0x706a817f, 0xc8c0c4a2, + 0xe41b804d, 0x5cb1c590, 0x6538e7f2, 0xdd92a22f, + 0x172aa236, 0xaf80e7eb, 0x9609c589, 0x2ea38054, + 0xb4dd8585, 0x0c77c058, 0x35fee23a, 0x8d54a7e7, + 0x47eca7fe, 0xff46e223, 0xc6cfc041, 0x7e65859c, + 0x52bec173, 0xea1484ae, 0xd39da6cc, 0x6b37e311, + 0xa18fe308, 0x1925a6d5, 0x20ac84b7, 0x9806c16a, + 0x896ce16c, 0x31c6a4b1, 0x084f86d3, 0xb0e5c30e, + 0x7a5dc317, 0xc2f786ca, 0xfb7ea4a8, 0x43d4e175, + 0x6f0fa59a, 0xd7a5e047, 0xee2cc225, 0x568687f8, + 0x9c3e87e1, 0x2494c23c, 0x1d1de05e, 0xa5b7a583, + 0xd89606f9, 0x603c4324, 0x59b56146, 0xe11f249b, + 0x2ba72482, 0x930d615f, 0xaa84433d, 0x122e06e0, + 0x3ef5420f, 0x865f07d2, 0xbfd625b0, 0x077c606d, + 0xcdc46074, 0x756e25a9, 0x4ce707cb, 0xf44d4216, + 0xe5276210, 0x5d8d27cd, 0x640405af, 0xdcae4072, + 0x1616406b, 0xaebc05b6, 0x973527d4, 0x2f9f6209, + 0x034426e6, 0xbbee633b, 0x82674159, 0x3acd0484, + 0xf075049d, 0x48df4140, 0x71566322, 0xc9fc26ff, + 0x5382232e, 0xeb2866f3, 0xd2a14491, 0x6a0b014c, + 0xa0b30155, 0x18194488, 0x219066ea, 0x993a2337, + 0xb5e167d8, 0x0d4b2205, 0x34c20067, 0x8c6845ba, + 0x46d045a3, 0xfe7a007e, 0xc7f3221c, 0x7f5967c1, + 0x6e3347c7, 0xd699021a, 0xef102078, 0x57ba65a5, + 0x9d0265bc, 0x25a82061, 0x1c210203, 0xa48b47de, + 0x88500331, 0x30fa46ec, 0x0973648e, 0xb1d92153, + 0x7b61214a, 0xc3cb6497, 0xfa4246f5, 0x42e80328 + },{ + 0x00000000, 0xac6f1138, 0x58df2270, 0xf4b03348, + 0xb0be45e0, 0x1cd154d8, 0xe8616790, 0x440e76a8, + 0x910b67c5, 0x3d6476fd, 0xc9d445b5, 0x65bb548d, + 0x21b52225, 0x8dda331d, 0x796a0055, 0xd505116d, + 0xd361228f, 0x7f0e33b7, 0x8bbe00ff, 0x27d111c7, + 0x63df676f, 0xcfb07657, 0x3b00451f, 0x976f5427, + 0x426a454a, 0xee055472, 0x1ab5673a, 0xb6da7602, + 0xf2d400aa, 0x5ebb1192, 0xaa0b22da, 0x066433e2, + 0x57b5a81b, 0xfbdab923, 0x0f6a8a6b, 0xa3059b53, + 0xe70bedfb, 0x4b64fcc3, 0xbfd4cf8b, 0x13bbdeb3, + 0xc6becfde, 0x6ad1dee6, 0x9e61edae, 0x320efc96, + 0x76008a3e, 0xda6f9b06, 0x2edfa84e, 0x82b0b976, + 0x84d48a94, 0x28bb9bac, 0xdc0ba8e4, 0x7064b9dc, + 0x346acf74, 0x9805de4c, 0x6cb5ed04, 0xc0dafc3c, + 0x15dfed51, 0xb9b0fc69, 0x4d00cf21, 0xe16fde19, + 0xa561a8b1, 0x090eb989, 0xfdbe8ac1, 0x51d19bf9, + 0xae6a5137, 0x0205400f, 0xf6b57347, 0x5ada627f, + 0x1ed414d7, 0xb2bb05ef, 0x460b36a7, 0xea64279f, + 0x3f6136f2, 0x930e27ca, 0x67be1482, 0xcbd105ba, + 0x8fdf7312, 0x23b0622a, 0xd7005162, 0x7b6f405a, + 0x7d0b73b8, 0xd1646280, 0x25d451c8, 0x89bb40f0, + 0xcdb53658, 0x61da2760, 0x956a1428, 0x39050510, + 0xec00147d, 0x406f0545, 0xb4df360d, 0x18b02735, + 0x5cbe519d, 0xf0d140a5, 0x046173ed, 0xa80e62d5, + 0xf9dff92c, 0x55b0e814, 0xa100db5c, 0x0d6fca64, + 0x4961bccc, 0xe50eadf4, 0x11be9ebc, 0xbdd18f84, + 0x68d49ee9, 0xc4bb8fd1, 0x300bbc99, 0x9c64ada1, + 0xd86adb09, 0x7405ca31, 0x80b5f979, 0x2cdae841, + 0x2abedba3, 0x86d1ca9b, 0x7261f9d3, 0xde0ee8eb, + 0x9a009e43, 0x366f8f7b, 0xc2dfbc33, 0x6eb0ad0b, + 0xbbb5bc66, 0x17daad5e, 0xe36a9e16, 0x4f058f2e, + 0x0b0bf986, 0xa764e8be, 0x53d4dbf6, 0xffbbcace, + 0x5cd5a26e, 0xf0bab356, 0x040a801e, 0xa8659126, + 0xec6be78e, 0x4004f6b6, 0xb4b4c5fe, 0x18dbd4c6, + 0xcddec5ab, 0x61b1d493, 0x9501e7db, 0x396ef6e3, + 0x7d60804b, 0xd10f9173, 0x25bfa23b, 0x89d0b303, + 0x8fb480e1, 0x23db91d9, 0xd76ba291, 0x7b04b3a9, + 0x3f0ac501, 0x9365d439, 0x67d5e771, 0xcbbaf649, + 0x1ebfe724, 0xb2d0f61c, 0x4660c554, 0xea0fd46c, + 0xae01a2c4, 0x026eb3fc, 0xf6de80b4, 0x5ab1918c, + 0x0b600a75, 0xa70f1b4d, 0x53bf2805, 0xffd0393d, + 0xbbde4f95, 0x17b15ead, 0xe3016de5, 0x4f6e7cdd, + 0x9a6b6db0, 0x36047c88, 0xc2b44fc0, 0x6edb5ef8, + 0x2ad52850, 0x86ba3968, 0x720a0a20, 0xde651b18, + 0xd80128fa, 0x746e39c2, 0x80de0a8a, 0x2cb11bb2, + 0x68bf6d1a, 0xc4d07c22, 0x30604f6a, 0x9c0f5e52, + 0x490a4f3f, 0xe5655e07, 0x11d56d4f, 0xbdba7c77, + 0xf9b40adf, 0x55db1be7, 0xa16b28af, 0x0d043997, + 0xf2bff359, 0x5ed0e261, 0xaa60d129, 0x060fc011, + 0x4201b6b9, 0xee6ea781, 0x1ade94c9, 0xb6b185f1, + 0x63b4949c, 0xcfdb85a4, 0x3b6bb6ec, 0x9704a7d4, + 0xd30ad17c, 0x7f65c044, 0x8bd5f30c, 0x27bae234, + 0x21ded1d6, 0x8db1c0ee, 0x7901f3a6, 0xd56ee29e, + 0x91609436, 0x3d0f850e, 0xc9bfb646, 0x65d0a77e, + 0xb0d5b613, 0x1cbaa72b, 0xe80a9463, 0x4465855b, + 0x006bf3f3, 0xac04e2cb, 0x58b4d183, 0xf4dbc0bb, + 0xa50a5b42, 0x09654a7a, 0xfdd57932, 0x51ba680a, + 0x15b41ea2, 0xb9db0f9a, 0x4d6b3cd2, 0xe1042dea, + 0x34013c87, 0x986e2dbf, 0x6cde1ef7, 0xc0b10fcf, + 0x84bf7967, 0x28d0685f, 0xdc605b17, 0x700f4a2f, + 0x766b79cd, 0xda0468f5, 0x2eb45bbd, 0x82db4a85, + 0xc6d53c2d, 0x6aba2d15, 0x9e0a1e5d, 0x32650f65, + 0xe7601e08, 0x4b0f0f30, 0xbfbf3c78, 0x13d02d40, + 0x57de5be8, 0xfbb14ad0, 0x0f017998, 0xa36e68a0 + },{ + 0x00000000, 0x196b30ef, 0xc3a08cdb, 0xdacbbc34, + 0x7737f5b2, 0x6e5cc55d, 0xb4977969, 0xadfc4986, + 0x1f180660, 0x0673368f, 0xdcb88abb, 0xc5d3ba54, + 0x682ff3d2, 0x7144c33d, 0xab8f7f09, 0xb2e44fe6, + 0x3e300cc0, 0x275b3c2f, 0xfd90801b, 0xe4fbb0f4, + 0x4907f972, 0x506cc99d, 0x8aa775a9, 0x93cc4546, + 0x21280aa0, 0x38433a4f, 0xe288867b, 0xfbe3b694, + 0x561fff12, 0x4f74cffd, 0x95bf73c9, 0x8cd44326, + 0x8d16f485, 0x947dc46a, 0x4eb6785e, 0x57dd48b1, + 0xfa210137, 0xe34a31d8, 0x39818dec, 0x20eabd03, + 0x920ef2e5, 0x8b65c20a, 0x51ae7e3e, 0x48c54ed1, + 0xe5390757, 0xfc5237b8, 0x26998b8c, 0x3ff2bb63, + 0xb326f845, 0xaa4dc8aa, 0x7086749e, 0x69ed4471, + 0xc4110df7, 0xdd7a3d18, 0x07b1812c, 0x1edab1c3, + 0xac3efe25, 0xb555ceca, 0x6f9e72fe, 0x76f54211, + 0xdb090b97, 0xc2623b78, 0x18a9874c, 0x01c2b7a3, + 0xeb5b040e, 0xf23034e1, 0x28fb88d5, 0x3190b83a, + 0x9c6cf1bc, 0x8507c153, 0x5fcc7d67, 0x46a74d88, + 0xf443026e, 0xed283281, 0x37e38eb5, 0x2e88be5a, + 0x8374f7dc, 0x9a1fc733, 0x40d47b07, 0x59bf4be8, + 0xd56b08ce, 0xcc003821, 0x16cb8415, 0x0fa0b4fa, + 0xa25cfd7c, 0xbb37cd93, 0x61fc71a7, 0x78974148, + 0xca730eae, 0xd3183e41, 0x09d38275, 0x10b8b29a, + 0xbd44fb1c, 0xa42fcbf3, 0x7ee477c7, 0x678f4728, + 0x664df08b, 0x7f26c064, 0xa5ed7c50, 0xbc864cbf, + 0x117a0539, 0x081135d6, 0xd2da89e2, 0xcbb1b90d, + 0x7955f6eb, 0x603ec604, 0xbaf57a30, 0xa39e4adf, + 0x0e620359, 0x170933b6, 0xcdc28f82, 0xd4a9bf6d, + 0x587dfc4b, 0x4116cca4, 0x9bdd7090, 0x82b6407f, + 0x2f4a09f9, 0x36213916, 0xecea8522, 0xf581b5cd, + 0x4765fa2b, 0x5e0ecac4, 0x84c576f0, 0x9dae461f, + 0x30520f99, 0x29393f76, 0xf3f28342, 0xea99b3ad, + 0xd6b7081c, 0xcfdc38f3, 0x151784c7, 0x0c7cb428, + 0xa180fdae, 0xb8ebcd41, 0x62207175, 0x7b4b419a, + 0xc9af0e7c, 0xd0c43e93, 0x0a0f82a7, 0x1364b248, + 0xbe98fbce, 0xa7f3cb21, 0x7d387715, 0x645347fa, + 0xe88704dc, 0xf1ec3433, 0x2b278807, 0x324cb8e8, + 0x9fb0f16e, 0x86dbc181, 0x5c107db5, 0x457b4d5a, + 0xf79f02bc, 0xeef43253, 0x343f8e67, 0x2d54be88, + 0x80a8f70e, 0x99c3c7e1, 0x43087bd5, 0x5a634b3a, + 0x5ba1fc99, 0x42cacc76, 0x98017042, 0x816a40ad, + 0x2c96092b, 0x35fd39c4, 0xef3685f0, 0xf65db51f, + 0x44b9faf9, 0x5dd2ca16, 0x87197622, 0x9e7246cd, + 0x338e0f4b, 0x2ae53fa4, 0xf02e8390, 0xe945b37f, + 0x6591f059, 0x7cfac0b6, 0xa6317c82, 0xbf5a4c6d, + 0x12a605eb, 0x0bcd3504, 0xd1068930, 0xc86db9df, + 0x7a89f639, 0x63e2c6d6, 0xb9297ae2, 0xa0424a0d, + 0x0dbe038b, 0x14d53364, 0xce1e8f50, 0xd775bfbf, + 0x3dec0c12, 0x24873cfd, 0xfe4c80c9, 0xe727b026, + 0x4adbf9a0, 0x53b0c94f, 0x897b757b, 0x90104594, + 0x22f40a72, 0x3b9f3a9d, 0xe15486a9, 0xf83fb646, + 0x55c3ffc0, 0x4ca8cf2f, 0x9663731b, 0x8f0843f4, + 0x03dc00d2, 0x1ab7303d, 0xc07c8c09, 0xd917bce6, + 0x74ebf560, 0x6d80c58f, 0xb74b79bb, 0xae204954, + 0x1cc406b2, 0x05af365d, 0xdf648a69, 0xc60fba86, + 0x6bf3f300, 0x7298c3ef, 0xa8537fdb, 0xb1384f34, + 0xb0faf897, 0xa991c878, 0x735a744c, 0x6a3144a3, + 0xc7cd0d25, 0xdea63dca, 0x046d81fe, 0x1d06b111, + 0xafe2fef7, 0xb689ce18, 0x6c42722c, 0x752942c3, + 0xd8d50b45, 0xc1be3baa, 0x1b75879e, 0x021eb771, + 0x8ecaf457, 0x97a1c4b8, 0x4d6a788c, 0x54014863, + 0xf9fd01e5, 0xe096310a, 0x3a5d8d3e, 0x2336bdd1, + 0x91d2f237, 0x88b9c2d8, 0x52727eec, 0x4b194e03, + 0xe6e50785, 0xff8e376a, 0x25458b5e, 0x3c2ebbb1 + },{ + 0x00000000, 0xc82c0368, 0x905906d0, 0x587505b8, + 0xd1c5e0a5, 0x19e9e3cd, 0x419ce675, 0x89b0e51d, + 0x53fd2d4e, 0x9bd12e26, 0xc3a42b9e, 0x0b8828f6, + 0x8238cdeb, 0x4a14ce83, 0x1261cb3b, 0xda4dc853, + 0xa6fa5b9c, 0x6ed658f4, 0x36a35d4c, 0xfe8f5e24, + 0x773fbb39, 0xbf13b851, 0xe766bde9, 0x2f4abe81, + 0xf50776d2, 0x3d2b75ba, 0x655e7002, 0xad72736a, + 0x24c29677, 0xecee951f, 0xb49b90a7, 0x7cb793cf, + 0xbd835b3d, 0x75af5855, 0x2dda5ded, 0xe5f65e85, + 0x6c46bb98, 0xa46ab8f0, 0xfc1fbd48, 0x3433be20, + 0xee7e7673, 0x2652751b, 0x7e2770a3, 0xb60b73cb, + 0x3fbb96d6, 0xf79795be, 0xafe29006, 0x67ce936e, + 0x1b7900a1, 0xd35503c9, 0x8b200671, 0x430c0519, + 0xcabce004, 0x0290e36c, 0x5ae5e6d4, 0x92c9e5bc, + 0x48842def, 0x80a82e87, 0xd8dd2b3f, 0x10f12857, + 0x9941cd4a, 0x516dce22, 0x0918cb9a, 0xc134c8f2, + 0x7a07b77a, 0xb22bb412, 0xea5eb1aa, 0x2272b2c2, + 0xabc257df, 0x63ee54b7, 0x3b9b510f, 0xf3b75267, + 0x29fa9a34, 0xe1d6995c, 0xb9a39ce4, 0x718f9f8c, + 0xf83f7a91, 0x301379f9, 0x68667c41, 0xa04a7f29, + 0xdcfdece6, 0x14d1ef8e, 0x4ca4ea36, 0x8488e95e, + 0x0d380c43, 0xc5140f2b, 0x9d610a93, 0x554d09fb, + 0x8f00c1a8, 0x472cc2c0, 0x1f59c778, 0xd775c410, + 0x5ec5210d, 0x96e92265, 0xce9c27dd, 0x06b024b5, + 0xc784ec47, 0x0fa8ef2f, 0x57ddea97, 0x9ff1e9ff, + 0x16410ce2, 0xde6d0f8a, 0x86180a32, 0x4e34095a, + 0x9479c109, 0x5c55c261, 0x0420c7d9, 0xcc0cc4b1, + 0x45bc21ac, 0x8d9022c4, 0xd5e5277c, 0x1dc92414, + 0x617eb7db, 0xa952b4b3, 0xf127b10b, 0x390bb263, + 0xb0bb577e, 0x78975416, 0x20e251ae, 0xe8ce52c6, + 0x32839a95, 0xfaaf99fd, 0xa2da9c45, 0x6af69f2d, + 0xe3467a30, 0x2b6a7958, 0x731f7ce0, 0xbb337f88, + 0xf40e6ef5, 0x3c226d9d, 0x64576825, 0xac7b6b4d, + 0x25cb8e50, 0xede78d38, 0xb5928880, 0x7dbe8be8, + 0xa7f343bb, 0x6fdf40d3, 0x37aa456b, 0xff864603, + 0x7636a31e, 0xbe1aa076, 0xe66fa5ce, 0x2e43a6a6, + 0x52f43569, 0x9ad83601, 0xc2ad33b9, 0x0a8130d1, + 0x8331d5cc, 0x4b1dd6a4, 0x1368d31c, 0xdb44d074, + 0x01091827, 0xc9251b4f, 0x91501ef7, 0x597c1d9f, + 0xd0ccf882, 0x18e0fbea, 0x4095fe52, 0x88b9fd3a, + 0x498d35c8, 0x81a136a0, 0xd9d43318, 0x11f83070, + 0x9848d56d, 0x5064d605, 0x0811d3bd, 0xc03dd0d5, + 0x1a701886, 0xd25c1bee, 0x8a291e56, 0x42051d3e, + 0xcbb5f823, 0x0399fb4b, 0x5becfef3, 0x93c0fd9b, + 0xef776e54, 0x275b6d3c, 0x7f2e6884, 0xb7026bec, + 0x3eb28ef1, 0xf69e8d99, 0xaeeb8821, 0x66c78b49, + 0xbc8a431a, 0x74a64072, 0x2cd345ca, 0xe4ff46a2, + 0x6d4fa3bf, 0xa563a0d7, 0xfd16a56f, 0x353aa607, + 0x8e09d98f, 0x4625dae7, 0x1e50df5f, 0xd67cdc37, + 0x5fcc392a, 0x97e03a42, 0xcf953ffa, 0x07b93c92, + 0xddf4f4c1, 0x15d8f7a9, 0x4dadf211, 0x8581f179, + 0x0c311464, 0xc41d170c, 0x9c6812b4, 0x544411dc, + 0x28f38213, 0xe0df817b, 0xb8aa84c3, 0x708687ab, + 0xf93662b6, 0x311a61de, 0x696f6466, 0xa143670e, + 0x7b0eaf5d, 0xb322ac35, 0xeb57a98d, 0x237baae5, + 0xaacb4ff8, 0x62e74c90, 0x3a924928, 0xf2be4a40, + 0x338a82b2, 0xfba681da, 0xa3d38462, 0x6bff870a, + 0xe24f6217, 0x2a63617f, 0x721664c7, 0xba3a67af, + 0x6077affc, 0xa85bac94, 0xf02ea92c, 0x3802aa44, + 0xb1b24f59, 0x799e4c31, 0x21eb4989, 0xe9c74ae1, + 0x9570d92e, 0x5d5cda46, 0x0529dffe, 0xcd05dc96, + 0x44b5398b, 0x8c993ae3, 0xd4ec3f5b, 0x1cc03c33, + 0xc68df460, 0x0ea1f708, 0x56d4f2b0, 0x9ef8f1d8, + 0x174814c5, 0xdf6417ad, 0x87111215, 0x4f3d117d + },{ + 0x00000000, 0x277d3c49, 0x4efa7892, 0x698744db, + 0x6d821d21, 0x4aff2168, 0x237865b3, 0x040559fa, + 0xda043b42, 0xfd79070b, 0x94fe43d0, 0xb3837f99, + 0xb7862663, 0x90fb1a2a, 0xf97c5ef1, 0xde0162b8, + 0xb4097684, 0x93744acd, 0xfaf30e16, 0xdd8e325f, + 0xd98b6ba5, 0xfef657ec, 0x97711337, 0xb00c2f7e, + 0x6e0d4dc6, 0x4970718f, 0x20f73554, 0x078a091d, + 0x038f50e7, 0x24f26cae, 0x4d752875, 0x6a08143c, + 0x9965000d, 0xbe183c44, 0xd79f789f, 0xf0e244d6, + 0xf4e71d2c, 0xd39a2165, 0xba1d65be, 0x9d6059f7, + 0x43613b4f, 0x641c0706, 0x0d9b43dd, 0x2ae67f94, + 0x2ee3266e, 0x099e1a27, 0x60195efc, 0x476462b5, + 0x2d6c7689, 0x0a114ac0, 0x63960e1b, 0x44eb3252, + 0x40ee6ba8, 0x679357e1, 0x0e14133a, 0x29692f73, + 0xf7684dcb, 0xd0157182, 0xb9923559, 0x9eef0910, + 0x9aea50ea, 0xbd976ca3, 0xd4102878, 0xf36d1431, + 0x32cb001a, 0x15b63c53, 0x7c317888, 0x5b4c44c1, + 0x5f491d3b, 0x78342172, 0x11b365a9, 0x36ce59e0, + 0xe8cf3b58, 0xcfb20711, 0xa63543ca, 0x81487f83, + 0x854d2679, 0xa2301a30, 0xcbb75eeb, 0xecca62a2, + 0x86c2769e, 0xa1bf4ad7, 0xc8380e0c, 0xef453245, + 0xeb406bbf, 0xcc3d57f6, 0xa5ba132d, 0x82c72f64, + 0x5cc64ddc, 0x7bbb7195, 0x123c354e, 0x35410907, + 0x314450fd, 0x16396cb4, 0x7fbe286f, 0x58c31426, + 0xabae0017, 0x8cd33c5e, 0xe5547885, 0xc22944cc, + 0xc62c1d36, 0xe151217f, 0x88d665a4, 0xafab59ed, + 0x71aa3b55, 0x56d7071c, 0x3f5043c7, 0x182d7f8e, + 0x1c282674, 0x3b551a3d, 0x52d25ee6, 0x75af62af, + 0x1fa77693, 0x38da4ada, 0x515d0e01, 0x76203248, + 0x72256bb2, 0x555857fb, 0x3cdf1320, 0x1ba22f69, + 0xc5a34dd1, 0xe2de7198, 0x8b593543, 0xac24090a, + 0xa82150f0, 0x8f5c6cb9, 0xe6db2862, 0xc1a6142b, + 0x64960134, 0x43eb3d7d, 0x2a6c79a6, 0x0d1145ef, + 0x09141c15, 0x2e69205c, 0x47ee6487, 0x609358ce, + 0xbe923a76, 0x99ef063f, 0xf06842e4, 0xd7157ead, + 0xd3102757, 0xf46d1b1e, 0x9dea5fc5, 0xba97638c, + 0xd09f77b0, 0xf7e24bf9, 0x9e650f22, 0xb918336b, + 0xbd1d6a91, 0x9a6056d8, 0xf3e71203, 0xd49a2e4a, + 0x0a9b4cf2, 0x2de670bb, 0x44613460, 0x631c0829, + 0x671951d3, 0x40646d9a, 0x29e32941, 0x0e9e1508, + 0xfdf30139, 0xda8e3d70, 0xb30979ab, 0x947445e2, + 0x90711c18, 0xb70c2051, 0xde8b648a, 0xf9f658c3, + 0x27f73a7b, 0x008a0632, 0x690d42e9, 0x4e707ea0, + 0x4a75275a, 0x6d081b13, 0x048f5fc8, 0x23f26381, + 0x49fa77bd, 0x6e874bf4, 0x07000f2f, 0x207d3366, + 0x24786a9c, 0x030556d5, 0x6a82120e, 0x4dff2e47, + 0x93fe4cff, 0xb48370b6, 0xdd04346d, 0xfa790824, + 0xfe7c51de, 0xd9016d97, 0xb086294c, 0x97fb1505, + 0x565d012e, 0x71203d67, 0x18a779bc, 0x3fda45f5, + 0x3bdf1c0f, 0x1ca22046, 0x7525649d, 0x525858d4, + 0x8c593a6c, 0xab240625, 0xc2a342fe, 0xe5de7eb7, + 0xe1db274d, 0xc6a61b04, 0xaf215fdf, 0x885c6396, + 0xe25477aa, 0xc5294be3, 0xacae0f38, 0x8bd33371, + 0x8fd66a8b, 0xa8ab56c2, 0xc12c1219, 0xe6512e50, + 0x38504ce8, 0x1f2d70a1, 0x76aa347a, 0x51d70833, + 0x55d251c9, 0x72af6d80, 0x1b28295b, 0x3c551512, + 0xcf380123, 0xe8453d6a, 0x81c279b1, 0xa6bf45f8, + 0xa2ba1c02, 0x85c7204b, 0xec406490, 0xcb3d58d9, + 0x153c3a61, 0x32410628, 0x5bc642f3, 0x7cbb7eba, + 0x78be2740, 0x5fc31b09, 0x36445fd2, 0x1139639b, + 0x7b3177a7, 0x5c4c4bee, 0x35cb0f35, 0x12b6337c, + 0x16b36a86, 0x31ce56cf, 0x58491214, 0x7f342e5d, + 0xa1354ce5, 0x864870ac, 0xefcf3477, 0xc8b2083e, + 0xccb751c4, 0xebca6d8d, 0x824d2956, 0xa530151f + } +#else + { + 0x00000000, 0xf26b8303, 0xe13b70f7, 0x1350f3f4, + 0xc79a971f, 0x35f1141c, 0x26a1e7e8, 0xd4ca64eb, + 0x8ad958cf, 0x78b2dbcc, 0x6be22838, 0x9989ab3b, + 0x4d43cfd0, 0xbf284cd3, 0xac78bf27, 0x5e133c24, + 0x105ec76f, 0xe235446c, 0xf165b798, 0x030e349b, + 0xd7c45070, 0x25afd373, 0x36ff2087, 0xc494a384, + 0x9a879fa0, 0x68ec1ca3, 0x7bbcef57, 0x89d76c54, + 0x5d1d08bf, 0xaf768bbc, 0xbc267848, 0x4e4dfb4b, + 0x20bd8ede, 0xd2d60ddd, 0xc186fe29, 0x33ed7d2a, + 0xe72719c1, 0x154c9ac2, 0x061c6936, 0xf477ea35, + 0xaa64d611, 0x580f5512, 0x4b5fa6e6, 0xb93425e5, + 0x6dfe410e, 0x9f95c20d, 0x8cc531f9, 0x7eaeb2fa, + 0x30e349b1, 0xc288cab2, 0xd1d83946, 0x23b3ba45, + 0xf779deae, 0x05125dad, 0x1642ae59, 0xe4292d5a, + 0xba3a117e, 0x4851927d, 0x5b016189, 0xa96ae28a, + 0x7da08661, 0x8fcb0562, 0x9c9bf696, 0x6ef07595, + 0x417b1dbc, 0xb3109ebf, 0xa0406d4b, 0x522bee48, + 0x86e18aa3, 0x748a09a0, 0x67dafa54, 0x95b17957, + 0xcba24573, 0x39c9c670, 0x2a993584, 0xd8f2b687, + 0x0c38d26c, 0xfe53516f, 0xed03a29b, 0x1f682198, + 0x5125dad3, 0xa34e59d0, 0xb01eaa24, 0x42752927, + 0x96bf4dcc, 0x64d4cecf, 0x77843d3b, 0x85efbe38, + 0xdbfc821c, 0x2997011f, 0x3ac7f2eb, 0xc8ac71e8, + 0x1c661503, 0xee0d9600, 0xfd5d65f4, 0x0f36e6f7, + 0x61c69362, 0x93ad1061, 0x80fde395, 0x72966096, + 0xa65c047d, 0x5437877e, 0x4767748a, 0xb50cf789, + 0xeb1fcbad, 0x197448ae, 0x0a24bb5a, 0xf84f3859, + 0x2c855cb2, 0xdeeedfb1, 0xcdbe2c45, 0x3fd5af46, + 0x7198540d, 0x83f3d70e, 0x90a324fa, 0x62c8a7f9, + 0xb602c312, 0x44694011, 0x5739b3e5, 0xa55230e6, + 0xfb410cc2, 0x092a8fc1, 0x1a7a7c35, 0xe811ff36, + 0x3cdb9bdd, 0xceb018de, 0xdde0eb2a, 0x2f8b6829, + 0x82f63b78, 0x709db87b, 0x63cd4b8f, 0x91a6c88c, + 0x456cac67, 0xb7072f64, 0xa457dc90, 0x563c5f93, + 0x082f63b7, 0xfa44e0b4, 0xe9141340, 0x1b7f9043, + 0xcfb5f4a8, 0x3dde77ab, 0x2e8e845f, 0xdce5075c, + 0x92a8fc17, 0x60c37f14, 0x73938ce0, 0x81f80fe3, + 0x55326b08, 0xa759e80b, 0xb4091bff, 0x466298fc, + 0x1871a4d8, 0xea1a27db, 0xf94ad42f, 0x0b21572c, + 0xdfeb33c7, 0x2d80b0c4, 0x3ed04330, 0xccbbc033, + 0xa24bb5a6, 0x502036a5, 0x4370c551, 0xb11b4652, + 0x65d122b9, 0x97baa1ba, 0x84ea524e, 0x7681d14d, + 0x2892ed69, 0xdaf96e6a, 0xc9a99d9e, 0x3bc21e9d, + 0xef087a76, 0x1d63f975, 0x0e330a81, 0xfc588982, + 0xb21572c9, 0x407ef1ca, 0x532e023e, 0xa145813d, + 0x758fe5d6, 0x87e466d5, 0x94b49521, 0x66df1622, + 0x38cc2a06, 0xcaa7a905, 0xd9f75af1, 0x2b9cd9f2, + 0xff56bd19, 0x0d3d3e1a, 0x1e6dcdee, 0xec064eed, + 0xc38d26c4, 0x31e6a5c7, 0x22b65633, 0xd0ddd530, + 0x0417b1db, 0xf67c32d8, 0xe52cc12c, 0x1747422f, + 0x49547e0b, 0xbb3ffd08, 0xa86f0efc, 0x5a048dff, + 0x8ecee914, 0x7ca56a17, 0x6ff599e3, 0x9d9e1ae0, + 0xd3d3e1ab, 0x21b862a8, 0x32e8915c, 0xc083125f, + 0x144976b4, 0xe622f5b7, 0xf5720643, 0x07198540, + 0x590ab964, 0xab613a67, 0xb831c993, 0x4a5a4a90, + 0x9e902e7b, 0x6cfbad78, 0x7fab5e8c, 0x8dc0dd8f, + 0xe330a81a, 0x115b2b19, 0x020bd8ed, 0xf0605bee, + 0x24aa3f05, 0xd6c1bc06, 0xc5914ff2, 0x37faccf1, + 0x69e9f0d5, 0x9b8273d6, 0x88d28022, 0x7ab90321, + 0xae7367ca, 0x5c18e4c9, 0x4f48173d, 0xbd23943e, + 0xf36e6f75, 0x0105ec76, 0x12551f82, 0xe03e9c81, + 0x34f4f86a, 0xc69f7b69, 0xd5cf889d, 0x27a40b9e, + 0x79b737ba, 0x8bdcb4b9, 0x988c474d, 0x6ae7c44e, + 0xbe2da0a5, 0x4c4623a6, 0x5f16d052, 0xad7d5351 + },{ + 0x00000000, 0x13a29877, 0x274530ee, 0x34e7a899, + 0x4e8a61dc, 0x5d28f9ab, 0x69cf5132, 0x7a6dc945, + 0x9d14c3b8, 0x8eb65bcf, 0xba51f356, 0xa9f36b21, + 0xd39ea264, 0xc03c3a13, 0xf4db928a, 0xe7790afd, + 0x3fc5f181, 0x2c6769f6, 0x1880c16f, 0x0b225918, + 0x714f905d, 0x62ed082a, 0x560aa0b3, 0x45a838c4, + 0xa2d13239, 0xb173aa4e, 0x859402d7, 0x96369aa0, + 0xec5b53e5, 0xfff9cb92, 0xcb1e630b, 0xd8bcfb7c, + 0x7f8be302, 0x6c297b75, 0x58ced3ec, 0x4b6c4b9b, + 0x310182de, 0x22a31aa9, 0x1644b230, 0x05e62a47, + 0xe29f20ba, 0xf13db8cd, 0xc5da1054, 0xd6788823, + 0xac154166, 0xbfb7d911, 0x8b507188, 0x98f2e9ff, + 0x404e1283, 0x53ec8af4, 0x670b226d, 0x74a9ba1a, + 0x0ec4735f, 0x1d66eb28, 0x298143b1, 0x3a23dbc6, + 0xdd5ad13b, 0xcef8494c, 0xfa1fe1d5, 0xe9bd79a2, + 0x93d0b0e7, 0x80722890, 0xb4958009, 0xa737187e, + 0xff17c604, 0xecb55e73, 0xd852f6ea, 0xcbf06e9d, + 0xb19da7d8, 0xa23f3faf, 0x96d89736, 0x857a0f41, + 0x620305bc, 0x71a19dcb, 0x45463552, 0x56e4ad25, + 0x2c896460, 0x3f2bfc17, 0x0bcc548e, 0x186eccf9, + 0xc0d23785, 0xd370aff2, 0xe797076b, 0xf4359f1c, + 0x8e585659, 0x9dface2e, 0xa91d66b7, 0xbabffec0, + 0x5dc6f43d, 0x4e646c4a, 0x7a83c4d3, 0x69215ca4, + 0x134c95e1, 0x00ee0d96, 0x3409a50f, 0x27ab3d78, + 0x809c2506, 0x933ebd71, 0xa7d915e8, 0xb47b8d9f, + 0xce1644da, 0xddb4dcad, 0xe9537434, 0xfaf1ec43, + 0x1d88e6be, 0x0e2a7ec9, 0x3acdd650, 0x296f4e27, + 0x53028762, 0x40a01f15, 0x7447b78c, 0x67e52ffb, + 0xbf59d487, 0xacfb4cf0, 0x981ce469, 0x8bbe7c1e, + 0xf1d3b55b, 0xe2712d2c, 0xd69685b5, 0xc5341dc2, + 0x224d173f, 0x31ef8f48, 0x050827d1, 0x16aabfa6, + 0x6cc776e3, 0x7f65ee94, 0x4b82460d, 0x5820de7a, + 0xfbc3faf9, 0xe861628e, 0xdc86ca17, 0xcf245260, + 0xb5499b25, 0xa6eb0352, 0x920cabcb, 0x81ae33bc, + 0x66d73941, 0x7575a136, 0x419209af, 0x523091d8, + 0x285d589d, 0x3bffc0ea, 0x0f186873, 0x1cbaf004, + 0xc4060b78, 0xd7a4930f, 0xe3433b96, 0xf0e1a3e1, + 0x8a8c6aa4, 0x992ef2d3, 0xadc95a4a, 0xbe6bc23d, + 0x5912c8c0, 0x4ab050b7, 0x7e57f82e, 0x6df56059, + 0x1798a91c, 0x043a316b, 0x30dd99f2, 0x237f0185, + 0x844819fb, 0x97ea818c, 0xa30d2915, 0xb0afb162, + 0xcac27827, 0xd960e050, 0xed8748c9, 0xfe25d0be, + 0x195cda43, 0x0afe4234, 0x3e19eaad, 0x2dbb72da, + 0x57d6bb9f, 0x447423e8, 0x70938b71, 0x63311306, + 0xbb8de87a, 0xa82f700d, 0x9cc8d894, 0x8f6a40e3, + 0xf50789a6, 0xe6a511d1, 0xd242b948, 0xc1e0213f, + 0x26992bc2, 0x353bb3b5, 0x01dc1b2c, 0x127e835b, + 0x68134a1e, 0x7bb1d269, 0x4f567af0, 0x5cf4e287, + 0x04d43cfd, 0x1776a48a, 0x23910c13, 0x30339464, + 0x4a5e5d21, 0x59fcc556, 0x6d1b6dcf, 0x7eb9f5b8, + 0x99c0ff45, 0x8a626732, 0xbe85cfab, 0xad2757dc, + 0xd74a9e99, 0xc4e806ee, 0xf00fae77, 0xe3ad3600, + 0x3b11cd7c, 0x28b3550b, 0x1c54fd92, 0x0ff665e5, + 0x759baca0, 0x663934d7, 0x52de9c4e, 0x417c0439, + 0xa6050ec4, 0xb5a796b3, 0x81403e2a, 0x92e2a65d, + 0xe88f6f18, 0xfb2df76f, 0xcfca5ff6, 0xdc68c781, + 0x7b5fdfff, 0x68fd4788, 0x5c1aef11, 0x4fb87766, + 0x35d5be23, 0x26772654, 0x12908ecd, 0x013216ba, + 0xe64b1c47, 0xf5e98430, 0xc10e2ca9, 0xd2acb4de, + 0xa8c17d9b, 0xbb63e5ec, 0x8f844d75, 0x9c26d502, + 0x449a2e7e, 0x5738b609, 0x63df1e90, 0x707d86e7, + 0x0a104fa2, 0x19b2d7d5, 0x2d557f4c, 0x3ef7e73b, + 0xd98eedc6, 0xca2c75b1, 0xfecbdd28, 0xed69455f, + 0x97048c1a, 0x84a6146d, 0xb041bcf4, 0xa3e32483 + },{ + 0x00000000, 0xa541927e, 0x4f6f520d, 0xea2ec073, + 0x9edea41a, 0x3b9f3664, 0xd1b1f617, 0x74f06469, + 0x38513ec5, 0x9d10acbb, 0x773e6cc8, 0xd27ffeb6, + 0xa68f9adf, 0x03ce08a1, 0xe9e0c8d2, 0x4ca15aac, + 0x70a27d8a, 0xd5e3eff4, 0x3fcd2f87, 0x9a8cbdf9, + 0xee7cd990, 0x4b3d4bee, 0xa1138b9d, 0x045219e3, + 0x48f3434f, 0xedb2d131, 0x079c1142, 0xa2dd833c, + 0xd62de755, 0x736c752b, 0x9942b558, 0x3c032726, + 0xe144fb14, 0x4405696a, 0xae2ba919, 0x0b6a3b67, + 0x7f9a5f0e, 0xdadbcd70, 0x30f50d03, 0x95b49f7d, + 0xd915c5d1, 0x7c5457af, 0x967a97dc, 0x333b05a2, + 0x47cb61cb, 0xe28af3b5, 0x08a433c6, 0xade5a1b8, + 0x91e6869e, 0x34a714e0, 0xde89d493, 0x7bc846ed, + 0x0f382284, 0xaa79b0fa, 0x40577089, 0xe516e2f7, + 0xa9b7b85b, 0x0cf62a25, 0xe6d8ea56, 0x43997828, + 0x37691c41, 0x92288e3f, 0x78064e4c, 0xdd47dc32, + 0xc76580d9, 0x622412a7, 0x880ad2d4, 0x2d4b40aa, + 0x59bb24c3, 0xfcfab6bd, 0x16d476ce, 0xb395e4b0, + 0xff34be1c, 0x5a752c62, 0xb05bec11, 0x151a7e6f, + 0x61ea1a06, 0xc4ab8878, 0x2e85480b, 0x8bc4da75, + 0xb7c7fd53, 0x12866f2d, 0xf8a8af5e, 0x5de93d20, + 0x29195949, 0x8c58cb37, 0x66760b44, 0xc337993a, + 0x8f96c396, 0x2ad751e8, 0xc0f9919b, 0x65b803e5, + 0x1148678c, 0xb409f5f2, 0x5e273581, 0xfb66a7ff, + 0x26217bcd, 0x8360e9b3, 0x694e29c0, 0xcc0fbbbe, + 0xb8ffdfd7, 0x1dbe4da9, 0xf7908dda, 0x52d11fa4, + 0x1e704508, 0xbb31d776, 0x511f1705, 0xf45e857b, + 0x80aee112, 0x25ef736c, 0xcfc1b31f, 0x6a802161, + 0x56830647, 0xf3c29439, 0x19ec544a, 0xbcadc634, + 0xc85da25d, 0x6d1c3023, 0x8732f050, 0x2273622e, + 0x6ed23882, 0xcb93aafc, 0x21bd6a8f, 0x84fcf8f1, + 0xf00c9c98, 0x554d0ee6, 0xbf63ce95, 0x1a225ceb, + 0x8b277743, 0x2e66e53d, 0xc448254e, 0x6109b730, + 0x15f9d359, 0xb0b84127, 0x5a968154, 0xffd7132a, + 0xb3764986, 0x1637dbf8, 0xfc191b8b, 0x595889f5, + 0x2da8ed9c, 0x88e97fe2, 0x62c7bf91, 0xc7862def, + 0xfb850ac9, 0x5ec498b7, 0xb4ea58c4, 0x11abcaba, + 0x655baed3, 0xc01a3cad, 0x2a34fcde, 0x8f756ea0, + 0xc3d4340c, 0x6695a672, 0x8cbb6601, 0x29faf47f, + 0x5d0a9016, 0xf84b0268, 0x1265c21b, 0xb7245065, + 0x6a638c57, 0xcf221e29, 0x250cde5a, 0x804d4c24, + 0xf4bd284d, 0x51fcba33, 0xbbd27a40, 0x1e93e83e, + 0x5232b292, 0xf77320ec, 0x1d5de09f, 0xb81c72e1, + 0xccec1688, 0x69ad84f6, 0x83834485, 0x26c2d6fb, + 0x1ac1f1dd, 0xbf8063a3, 0x55aea3d0, 0xf0ef31ae, + 0x841f55c7, 0x215ec7b9, 0xcb7007ca, 0x6e3195b4, + 0x2290cf18, 0x87d15d66, 0x6dff9d15, 0xc8be0f6b, + 0xbc4e6b02, 0x190ff97c, 0xf321390f, 0x5660ab71, + 0x4c42f79a, 0xe90365e4, 0x032da597, 0xa66c37e9, + 0xd29c5380, 0x77ddc1fe, 0x9df3018d, 0x38b293f3, + 0x7413c95f, 0xd1525b21, 0x3b7c9b52, 0x9e3d092c, + 0xeacd6d45, 0x4f8cff3b, 0xa5a23f48, 0x00e3ad36, + 0x3ce08a10, 0x99a1186e, 0x738fd81d, 0xd6ce4a63, + 0xa23e2e0a, 0x077fbc74, 0xed517c07, 0x4810ee79, + 0x04b1b4d5, 0xa1f026ab, 0x4bdee6d8, 0xee9f74a6, + 0x9a6f10cf, 0x3f2e82b1, 0xd50042c2, 0x7041d0bc, + 0xad060c8e, 0x08479ef0, 0xe2695e83, 0x4728ccfd, + 0x33d8a894, 0x96993aea, 0x7cb7fa99, 0xd9f668e7, + 0x9557324b, 0x3016a035, 0xda386046, 0x7f79f238, + 0x0b899651, 0xaec8042f, 0x44e6c45c, 0xe1a75622, + 0xdda47104, 0x78e5e37a, 0x92cb2309, 0x378ab177, + 0x437ad51e, 0xe63b4760, 0x0c158713, 0xa954156d, + 0xe5f54fc1, 0x40b4ddbf, 0xaa9a1dcc, 0x0fdb8fb2, + 0x7b2bebdb, 0xde6a79a5, 0x3444b9d6, 0x91052ba8 + },{ + 0x00000000, 0xdd45aab8, 0xbf672381, 0x62228939, + 0x7b2231f3, 0xa6679b4b, 0xc4451272, 0x1900b8ca, + 0xf64463e6, 0x2b01c95e, 0x49234067, 0x9466eadf, + 0x8d665215, 0x5023f8ad, 0x32017194, 0xef44db2c, + 0xe964b13d, 0x34211b85, 0x560392bc, 0x8b463804, + 0x924680ce, 0x4f032a76, 0x2d21a34f, 0xf06409f7, + 0x1f20d2db, 0xc2657863, 0xa047f15a, 0x7d025be2, + 0x6402e328, 0xb9474990, 0xdb65c0a9, 0x06206a11, + 0xd725148b, 0x0a60be33, 0x6842370a, 0xb5079db2, + 0xac072578, 0x71428fc0, 0x136006f9, 0xce25ac41, + 0x2161776d, 0xfc24ddd5, 0x9e0654ec, 0x4343fe54, + 0x5a43469e, 0x8706ec26, 0xe524651f, 0x3861cfa7, + 0x3e41a5b6, 0xe3040f0e, 0x81268637, 0x5c632c8f, + 0x45639445, 0x98263efd, 0xfa04b7c4, 0x27411d7c, + 0xc805c650, 0x15406ce8, 0x7762e5d1, 0xaa274f69, + 0xb327f7a3, 0x6e625d1b, 0x0c40d422, 0xd1057e9a, + 0xaba65fe7, 0x76e3f55f, 0x14c17c66, 0xc984d6de, + 0xd0846e14, 0x0dc1c4ac, 0x6fe34d95, 0xb2a6e72d, + 0x5de23c01, 0x80a796b9, 0xe2851f80, 0x3fc0b538, + 0x26c00df2, 0xfb85a74a, 0x99a72e73, 0x44e284cb, + 0x42c2eeda, 0x9f874462, 0xfda5cd5b, 0x20e067e3, + 0x39e0df29, 0xe4a57591, 0x8687fca8, 0x5bc25610, + 0xb4868d3c, 0x69c32784, 0x0be1aebd, 0xd6a40405, + 0xcfa4bccf, 0x12e11677, 0x70c39f4e, 0xad8635f6, + 0x7c834b6c, 0xa1c6e1d4, 0xc3e468ed, 0x1ea1c255, + 0x07a17a9f, 0xdae4d027, 0xb8c6591e, 0x6583f3a6, + 0x8ac7288a, 0x57828232, 0x35a00b0b, 0xe8e5a1b3, + 0xf1e51979, 0x2ca0b3c1, 0x4e823af8, 0x93c79040, + 0x95e7fa51, 0x48a250e9, 0x2a80d9d0, 0xf7c57368, + 0xeec5cba2, 0x3380611a, 0x51a2e823, 0x8ce7429b, + 0x63a399b7, 0xbee6330f, 0xdcc4ba36, 0x0181108e, + 0x1881a844, 0xc5c402fc, 0xa7e68bc5, 0x7aa3217d, + 0x52a0c93f, 0x8fe56387, 0xedc7eabe, 0x30824006, + 0x2982f8cc, 0xf4c75274, 0x96e5db4d, 0x4ba071f5, + 0xa4e4aad9, 0x79a10061, 0x1b838958, 0xc6c623e0, + 0xdfc69b2a, 0x02833192, 0x60a1b8ab, 0xbde41213, + 0xbbc47802, 0x6681d2ba, 0x04a35b83, 0xd9e6f13b, + 0xc0e649f1, 0x1da3e349, 0x7f816a70, 0xa2c4c0c8, + 0x4d801be4, 0x90c5b15c, 0xf2e73865, 0x2fa292dd, + 0x36a22a17, 0xebe780af, 0x89c50996, 0x5480a32e, + 0x8585ddb4, 0x58c0770c, 0x3ae2fe35, 0xe7a7548d, + 0xfea7ec47, 0x23e246ff, 0x41c0cfc6, 0x9c85657e, + 0x73c1be52, 0xae8414ea, 0xcca69dd3, 0x11e3376b, + 0x08e38fa1, 0xd5a62519, 0xb784ac20, 0x6ac10698, + 0x6ce16c89, 0xb1a4c631, 0xd3864f08, 0x0ec3e5b0, + 0x17c35d7a, 0xca86f7c2, 0xa8a47efb, 0x75e1d443, + 0x9aa50f6f, 0x47e0a5d7, 0x25c22cee, 0xf8878656, + 0xe1873e9c, 0x3cc29424, 0x5ee01d1d, 0x83a5b7a5, + 0xf90696d8, 0x24433c60, 0x4661b559, 0x9b241fe1, + 0x8224a72b, 0x5f610d93, 0x3d4384aa, 0xe0062e12, + 0x0f42f53e, 0xd2075f86, 0xb025d6bf, 0x6d607c07, + 0x7460c4cd, 0xa9256e75, 0xcb07e74c, 0x16424df4, + 0x106227e5, 0xcd278d5d, 0xaf050464, 0x7240aedc, + 0x6b401616, 0xb605bcae, 0xd4273597, 0x09629f2f, + 0xe6264403, 0x3b63eebb, 0x59416782, 0x8404cd3a, + 0x9d0475f0, 0x4041df48, 0x22635671, 0xff26fcc9, + 0x2e238253, 0xf36628eb, 0x9144a1d2, 0x4c010b6a, + 0x5501b3a0, 0x88441918, 0xea669021, 0x37233a99, + 0xd867e1b5, 0x05224b0d, 0x6700c234, 0xba45688c, + 0xa345d046, 0x7e007afe, 0x1c22f3c7, 0xc167597f, + 0xc747336e, 0x1a0299d6, 0x782010ef, 0xa565ba57, + 0xbc65029d, 0x6120a825, 0x0302211c, 0xde478ba4, + 0x31035088, 0xec46fa30, 0x8e647309, 0x5321d9b1, + 0x4a21617b, 0x9764cbc3, 0xf54642fa, 0x2803e842 + },{ + 0x00000000, 0x38116fac, 0x7022df58, 0x4833b0f4, + 0xe045beb0, 0xd854d11c, 0x906761e8, 0xa8760e44, + 0xc5670b91, 0xfd76643d, 0xb545d4c9, 0x8d54bb65, + 0x2522b521, 0x1d33da8d, 0x55006a79, 0x6d1105d5, + 0x8f2261d3, 0xb7330e7f, 0xff00be8b, 0xc711d127, + 0x6f67df63, 0x5776b0cf, 0x1f45003b, 0x27546f97, + 0x4a456a42, 0x725405ee, 0x3a67b51a, 0x0276dab6, + 0xaa00d4f2, 0x9211bb5e, 0xda220baa, 0xe2336406, + 0x1ba8b557, 0x23b9dafb, 0x6b8a6a0f, 0x539b05a3, + 0xfbed0be7, 0xc3fc644b, 0x8bcfd4bf, 0xb3debb13, + 0xdecfbec6, 0xe6ded16a, 0xaeed619e, 0x96fc0e32, + 0x3e8a0076, 0x069b6fda, 0x4ea8df2e, 0x76b9b082, + 0x948ad484, 0xac9bbb28, 0xe4a80bdc, 0xdcb96470, + 0x74cf6a34, 0x4cde0598, 0x04edb56c, 0x3cfcdac0, + 0x51eddf15, 0x69fcb0b9, 0x21cf004d, 0x19de6fe1, + 0xb1a861a5, 0x89b90e09, 0xc18abefd, 0xf99bd151, + 0x37516aae, 0x0f400502, 0x4773b5f6, 0x7f62da5a, + 0xd714d41e, 0xef05bbb2, 0xa7360b46, 0x9f2764ea, + 0xf236613f, 0xca270e93, 0x8214be67, 0xba05d1cb, + 0x1273df8f, 0x2a62b023, 0x625100d7, 0x5a406f7b, + 0xb8730b7d, 0x806264d1, 0xc851d425, 0xf040bb89, + 0x5836b5cd, 0x6027da61, 0x28146a95, 0x10050539, + 0x7d1400ec, 0x45056f40, 0x0d36dfb4, 0x3527b018, + 0x9d51be5c, 0xa540d1f0, 0xed736104, 0xd5620ea8, + 0x2cf9dff9, 0x14e8b055, 0x5cdb00a1, 0x64ca6f0d, + 0xccbc6149, 0xf4ad0ee5, 0xbc9ebe11, 0x848fd1bd, + 0xe99ed468, 0xd18fbbc4, 0x99bc0b30, 0xa1ad649c, + 0x09db6ad8, 0x31ca0574, 0x79f9b580, 0x41e8da2c, + 0xa3dbbe2a, 0x9bcad186, 0xd3f96172, 0xebe80ede, + 0x439e009a, 0x7b8f6f36, 0x33bcdfc2, 0x0badb06e, + 0x66bcb5bb, 0x5eadda17, 0x169e6ae3, 0x2e8f054f, + 0x86f90b0b, 0xbee864a7, 0xf6dbd453, 0xcecabbff, + 0x6ea2d55c, 0x56b3baf0, 0x1e800a04, 0x269165a8, + 0x8ee76bec, 0xb6f60440, 0xfec5b4b4, 0xc6d4db18, + 0xabc5decd, 0x93d4b161, 0xdbe70195, 0xe3f66e39, + 0x4b80607d, 0x73910fd1, 0x3ba2bf25, 0x03b3d089, + 0xe180b48f, 0xd991db23, 0x91a26bd7, 0xa9b3047b, + 0x01c50a3f, 0x39d46593, 0x71e7d567, 0x49f6bacb, + 0x24e7bf1e, 0x1cf6d0b2, 0x54c56046, 0x6cd40fea, + 0xc4a201ae, 0xfcb36e02, 0xb480def6, 0x8c91b15a, + 0x750a600b, 0x4d1b0fa7, 0x0528bf53, 0x3d39d0ff, + 0x954fdebb, 0xad5eb117, 0xe56d01e3, 0xdd7c6e4f, + 0xb06d6b9a, 0x887c0436, 0xc04fb4c2, 0xf85edb6e, + 0x5028d52a, 0x6839ba86, 0x200a0a72, 0x181b65de, + 0xfa2801d8, 0xc2396e74, 0x8a0ade80, 0xb21bb12c, + 0x1a6dbf68, 0x227cd0c4, 0x6a4f6030, 0x525e0f9c, + 0x3f4f0a49, 0x075e65e5, 0x4f6dd511, 0x777cbabd, + 0xdf0ab4f9, 0xe71bdb55, 0xaf286ba1, 0x9739040d, + 0x59f3bff2, 0x61e2d05e, 0x29d160aa, 0x11c00f06, + 0xb9b60142, 0x81a76eee, 0xc994de1a, 0xf185b1b6, + 0x9c94b463, 0xa485dbcf, 0xecb66b3b, 0xd4a70497, + 0x7cd10ad3, 0x44c0657f, 0x0cf3d58b, 0x34e2ba27, + 0xd6d1de21, 0xeec0b18d, 0xa6f30179, 0x9ee26ed5, + 0x36946091, 0x0e850f3d, 0x46b6bfc9, 0x7ea7d065, + 0x13b6d5b0, 0x2ba7ba1c, 0x63940ae8, 0x5b856544, + 0xf3f36b00, 0xcbe204ac, 0x83d1b458, 0xbbc0dbf4, + 0x425b0aa5, 0x7a4a6509, 0x3279d5fd, 0x0a68ba51, + 0xa21eb415, 0x9a0fdbb9, 0xd23c6b4d, 0xea2d04e1, + 0x873c0134, 0xbf2d6e98, 0xf71ede6c, 0xcf0fb1c0, + 0x6779bf84, 0x5f68d028, 0x175b60dc, 0x2f4a0f70, + 0xcd796b76, 0xf56804da, 0xbd5bb42e, 0x854adb82, + 0x2d3cd5c6, 0x152dba6a, 0x5d1e0a9e, 0x650f6532, + 0x081e60e7, 0x300f0f4b, 0x783cbfbf, 0x402dd013, + 0xe85bde57, 0xd04ab1fb, 0x9879010f, 0xa0686ea3 + },{ + 0x00000000, 0xef306b19, 0xdb8ca0c3, 0x34bccbda, + 0xb2f53777, 0x5dc55c6e, 0x697997b4, 0x8649fcad, + 0x6006181f, 0x8f367306, 0xbb8ab8dc, 0x54bad3c5, + 0xd2f32f68, 0x3dc34471, 0x097f8fab, 0xe64fe4b2, + 0xc00c303e, 0x2f3c5b27, 0x1b8090fd, 0xf4b0fbe4, + 0x72f90749, 0x9dc96c50, 0xa975a78a, 0x4645cc93, + 0xa00a2821, 0x4f3a4338, 0x7b8688e2, 0x94b6e3fb, + 0x12ff1f56, 0xfdcf744f, 0xc973bf95, 0x2643d48c, + 0x85f4168d, 0x6ac47d94, 0x5e78b64e, 0xb148dd57, + 0x370121fa, 0xd8314ae3, 0xec8d8139, 0x03bdea20, + 0xe5f20e92, 0x0ac2658b, 0x3e7eae51, 0xd14ec548, + 0x570739e5, 0xb83752fc, 0x8c8b9926, 0x63bbf23f, + 0x45f826b3, 0xaac84daa, 0x9e748670, 0x7144ed69, + 0xf70d11c4, 0x183d7add, 0x2c81b107, 0xc3b1da1e, + 0x25fe3eac, 0xcace55b5, 0xfe729e6f, 0x1142f576, + 0x970b09db, 0x783b62c2, 0x4c87a918, 0xa3b7c201, + 0x0e045beb, 0xe13430f2, 0xd588fb28, 0x3ab89031, + 0xbcf16c9c, 0x53c10785, 0x677dcc5f, 0x884da746, + 0x6e0243f4, 0x813228ed, 0xb58ee337, 0x5abe882e, + 0xdcf77483, 0x33c71f9a, 0x077bd440, 0xe84bbf59, + 0xce086bd5, 0x213800cc, 0x1584cb16, 0xfab4a00f, + 0x7cfd5ca2, 0x93cd37bb, 0xa771fc61, 0x48419778, + 0xae0e73ca, 0x413e18d3, 0x7582d309, 0x9ab2b810, + 0x1cfb44bd, 0xf3cb2fa4, 0xc777e47e, 0x28478f67, + 0x8bf04d66, 0x64c0267f, 0x507ceda5, 0xbf4c86bc, + 0x39057a11, 0xd6351108, 0xe289dad2, 0x0db9b1cb, + 0xebf65579, 0x04c63e60, 0x307af5ba, 0xdf4a9ea3, + 0x5903620e, 0xb6330917, 0x828fc2cd, 0x6dbfa9d4, + 0x4bfc7d58, 0xa4cc1641, 0x9070dd9b, 0x7f40b682, + 0xf9094a2f, 0x16392136, 0x2285eaec, 0xcdb581f5, + 0x2bfa6547, 0xc4ca0e5e, 0xf076c584, 0x1f46ae9d, + 0x990f5230, 0x763f3929, 0x4283f2f3, 0xadb399ea, + 0x1c08b7d6, 0xf338dccf, 0xc7841715, 0x28b47c0c, + 0xaefd80a1, 0x41cdebb8, 0x75712062, 0x9a414b7b, + 0x7c0eafc9, 0x933ec4d0, 0xa7820f0a, 0x48b26413, + 0xcefb98be, 0x21cbf3a7, 0x1577387d, 0xfa475364, + 0xdc0487e8, 0x3334ecf1, 0x0788272b, 0xe8b84c32, + 0x6ef1b09f, 0x81c1db86, 0xb57d105c, 0x5a4d7b45, + 0xbc029ff7, 0x5332f4ee, 0x678e3f34, 0x88be542d, + 0x0ef7a880, 0xe1c7c399, 0xd57b0843, 0x3a4b635a, + 0x99fca15b, 0x76ccca42, 0x42700198, 0xad406a81, + 0x2b09962c, 0xc439fd35, 0xf08536ef, 0x1fb55df6, + 0xf9fab944, 0x16cad25d, 0x22761987, 0xcd46729e, + 0x4b0f8e33, 0xa43fe52a, 0x90832ef0, 0x7fb345e9, + 0x59f09165, 0xb6c0fa7c, 0x827c31a6, 0x6d4c5abf, + 0xeb05a612, 0x0435cd0b, 0x308906d1, 0xdfb96dc8, + 0x39f6897a, 0xd6c6e263, 0xe27a29b9, 0x0d4a42a0, + 0x8b03be0d, 0x6433d514, 0x508f1ece, 0xbfbf75d7, + 0x120cec3d, 0xfd3c8724, 0xc9804cfe, 0x26b027e7, + 0xa0f9db4a, 0x4fc9b053, 0x7b757b89, 0x94451090, + 0x720af422, 0x9d3a9f3b, 0xa98654e1, 0x46b63ff8, + 0xc0ffc355, 0x2fcfa84c, 0x1b736396, 0xf443088f, + 0xd200dc03, 0x3d30b71a, 0x098c7cc0, 0xe6bc17d9, + 0x60f5eb74, 0x8fc5806d, 0xbb794bb7, 0x544920ae, + 0xb206c41c, 0x5d36af05, 0x698a64df, 0x86ba0fc6, + 0x00f3f36b, 0xefc39872, 0xdb7f53a8, 0x344f38b1, + 0x97f8fab0, 0x78c891a9, 0x4c745a73, 0xa344316a, + 0x250dcdc7, 0xca3da6de, 0xfe816d04, 0x11b1061d, + 0xf7fee2af, 0x18ce89b6, 0x2c72426c, 0xc3422975, + 0x450bd5d8, 0xaa3bbec1, 0x9e87751b, 0x71b71e02, + 0x57f4ca8e, 0xb8c4a197, 0x8c786a4d, 0x63480154, + 0xe501fdf9, 0x0a3196e0, 0x3e8d5d3a, 0xd1bd3623, + 0x37f2d291, 0xd8c2b988, 0xec7e7252, 0x034e194b, + 0x8507e5e6, 0x6a378eff, 0x5e8b4525, 0xb1bb2e3c + },{ + 0x00000000, 0x68032cc8, 0xd0065990, 0xb8057558, + 0xa5e0c5d1, 0xcde3e919, 0x75e69c41, 0x1de5b089, + 0x4e2dfd53, 0x262ed19b, 0x9e2ba4c3, 0xf628880b, + 0xebcd3882, 0x83ce144a, 0x3bcb6112, 0x53c84dda, + 0x9c5bfaa6, 0xf458d66e, 0x4c5da336, 0x245e8ffe, + 0x39bb3f77, 0x51b813bf, 0xe9bd66e7, 0x81be4a2f, + 0xd27607f5, 0xba752b3d, 0x02705e65, 0x6a7372ad, + 0x7796c224, 0x1f95eeec, 0xa7909bb4, 0xcf93b77c, + 0x3d5b83bd, 0x5558af75, 0xed5dda2d, 0x855ef6e5, + 0x98bb466c, 0xf0b86aa4, 0x48bd1ffc, 0x20be3334, + 0x73767eee, 0x1b755226, 0xa370277e, 0xcb730bb6, + 0xd696bb3f, 0xbe9597f7, 0x0690e2af, 0x6e93ce67, + 0xa100791b, 0xc90355d3, 0x7106208b, 0x19050c43, + 0x04e0bcca, 0x6ce39002, 0xd4e6e55a, 0xbce5c992, + 0xef2d8448, 0x872ea880, 0x3f2bddd8, 0x5728f110, + 0x4acd4199, 0x22ce6d51, 0x9acb1809, 0xf2c834c1, + 0x7ab7077a, 0x12b42bb2, 0xaab15eea, 0xc2b27222, + 0xdf57c2ab, 0xb754ee63, 0x0f519b3b, 0x6752b7f3, + 0x349afa29, 0x5c99d6e1, 0xe49ca3b9, 0x8c9f8f71, + 0x917a3ff8, 0xf9791330, 0x417c6668, 0x297f4aa0, + 0xe6ecfddc, 0x8eefd114, 0x36eaa44c, 0x5ee98884, + 0x430c380d, 0x2b0f14c5, 0x930a619d, 0xfb094d55, + 0xa8c1008f, 0xc0c22c47, 0x78c7591f, 0x10c475d7, + 0x0d21c55e, 0x6522e996, 0xdd279cce, 0xb524b006, + 0x47ec84c7, 0x2fefa80f, 0x97eadd57, 0xffe9f19f, + 0xe20c4116, 0x8a0f6dde, 0x320a1886, 0x5a09344e, + 0x09c17994, 0x61c2555c, 0xd9c72004, 0xb1c40ccc, + 0xac21bc45, 0xc422908d, 0x7c27e5d5, 0x1424c91d, + 0xdbb77e61, 0xb3b452a9, 0x0bb127f1, 0x63b20b39, + 0x7e57bbb0, 0x16549778, 0xae51e220, 0xc652cee8, + 0x959a8332, 0xfd99affa, 0x459cdaa2, 0x2d9ff66a, + 0x307a46e3, 0x58796a2b, 0xe07c1f73, 0x887f33bb, + 0xf56e0ef4, 0x9d6d223c, 0x25685764, 0x4d6b7bac, + 0x508ecb25, 0x388de7ed, 0x808892b5, 0xe88bbe7d, + 0xbb43f3a7, 0xd340df6f, 0x6b45aa37, 0x034686ff, + 0x1ea33676, 0x76a01abe, 0xcea56fe6, 0xa6a6432e, + 0x6935f452, 0x0136d89a, 0xb933adc2, 0xd130810a, + 0xccd53183, 0xa4d61d4b, 0x1cd36813, 0x74d044db, + 0x27180901, 0x4f1b25c9, 0xf71e5091, 0x9f1d7c59, + 0x82f8ccd0, 0xeafbe018, 0x52fe9540, 0x3afdb988, + 0xc8358d49, 0xa036a181, 0x1833d4d9, 0x7030f811, + 0x6dd54898, 0x05d66450, 0xbdd31108, 0xd5d03dc0, + 0x8618701a, 0xee1b5cd2, 0x561e298a, 0x3e1d0542, + 0x23f8b5cb, 0x4bfb9903, 0xf3feec5b, 0x9bfdc093, + 0x546e77ef, 0x3c6d5b27, 0x84682e7f, 0xec6b02b7, + 0xf18eb23e, 0x998d9ef6, 0x2188ebae, 0x498bc766, + 0x1a438abc, 0x7240a674, 0xca45d32c, 0xa246ffe4, + 0xbfa34f6d, 0xd7a063a5, 0x6fa516fd, 0x07a63a35, + 0x8fd9098e, 0xe7da2546, 0x5fdf501e, 0x37dc7cd6, + 0x2a39cc5f, 0x423ae097, 0xfa3f95cf, 0x923cb907, + 0xc1f4f4dd, 0xa9f7d815, 0x11f2ad4d, 0x79f18185, + 0x6414310c, 0x0c171dc4, 0xb412689c, 0xdc114454, + 0x1382f328, 0x7b81dfe0, 0xc384aab8, 0xab878670, + 0xb66236f9, 0xde611a31, 0x66646f69, 0x0e6743a1, + 0x5daf0e7b, 0x35ac22b3, 0x8da957eb, 0xe5aa7b23, + 0xf84fcbaa, 0x904ce762, 0x2849923a, 0x404abef2, + 0xb2828a33, 0xda81a6fb, 0x6284d3a3, 0x0a87ff6b, + 0x17624fe2, 0x7f61632a, 0xc7641672, 0xaf673aba, + 0xfcaf7760, 0x94ac5ba8, 0x2ca92ef0, 0x44aa0238, + 0x594fb2b1, 0x314c9e79, 0x8949eb21, 0xe14ac7e9, + 0x2ed97095, 0x46da5c5d, 0xfedf2905, 0x96dc05cd, + 0x8b39b544, 0xe33a998c, 0x5b3fecd4, 0x333cc01c, + 0x60f48dc6, 0x08f7a10e, 0xb0f2d456, 0xd8f1f89e, + 0xc5144817, 0xad1764df, 0x15121187, 0x7d113d4f + },{ + 0x00000000, 0x493c7d27, 0x9278fa4e, 0xdb448769, + 0x211d826d, 0x6821ff4a, 0xb3657823, 0xfa590504, + 0x423b04da, 0x0b0779fd, 0xd043fe94, 0x997f83b3, + 0x632686b7, 0x2a1afb90, 0xf15e7cf9, 0xb86201de, + 0x847609b4, 0xcd4a7493, 0x160ef3fa, 0x5f328edd, + 0xa56b8bd9, 0xec57f6fe, 0x37137197, 0x7e2f0cb0, + 0xc64d0d6e, 0x8f717049, 0x5435f720, 0x1d098a07, + 0xe7508f03, 0xae6cf224, 0x7528754d, 0x3c14086a, + 0x0d006599, 0x443c18be, 0x9f789fd7, 0xd644e2f0, + 0x2c1de7f4, 0x65219ad3, 0xbe651dba, 0xf759609d, + 0x4f3b6143, 0x06071c64, 0xdd439b0d, 0x947fe62a, + 0x6e26e32e, 0x271a9e09, 0xfc5e1960, 0xb5626447, + 0x89766c2d, 0xc04a110a, 0x1b0e9663, 0x5232eb44, + 0xa86bee40, 0xe1579367, 0x3a13140e, 0x732f6929, + 0xcb4d68f7, 0x827115d0, 0x593592b9, 0x1009ef9e, + 0xea50ea9a, 0xa36c97bd, 0x782810d4, 0x31146df3, + 0x1a00cb32, 0x533cb615, 0x8878317c, 0xc1444c5b, + 0x3b1d495f, 0x72213478, 0xa965b311, 0xe059ce36, + 0x583bcfe8, 0x1107b2cf, 0xca4335a6, 0x837f4881, + 0x79264d85, 0x301a30a2, 0xeb5eb7cb, 0xa262caec, + 0x9e76c286, 0xd74abfa1, 0x0c0e38c8, 0x453245ef, + 0xbf6b40eb, 0xf6573dcc, 0x2d13baa5, 0x642fc782, + 0xdc4dc65c, 0x9571bb7b, 0x4e353c12, 0x07094135, + 0xfd504431, 0xb46c3916, 0x6f28be7f, 0x2614c358, + 0x1700aeab, 0x5e3cd38c, 0x857854e5, 0xcc4429c2, + 0x361d2cc6, 0x7f2151e1, 0xa465d688, 0xed59abaf, + 0x553baa71, 0x1c07d756, 0xc743503f, 0x8e7f2d18, + 0x7426281c, 0x3d1a553b, 0xe65ed252, 0xaf62af75, + 0x9376a71f, 0xda4ada38, 0x010e5d51, 0x48322076, + 0xb26b2572, 0xfb575855, 0x2013df3c, 0x692fa21b, + 0xd14da3c5, 0x9871dee2, 0x4335598b, 0x0a0924ac, + 0xf05021a8, 0xb96c5c8f, 0x6228dbe6, 0x2b14a6c1, + 0x34019664, 0x7d3deb43, 0xa6796c2a, 0xef45110d, + 0x151c1409, 0x5c20692e, 0x8764ee47, 0xce589360, + 0x763a92be, 0x3f06ef99, 0xe44268f0, 0xad7e15d7, + 0x572710d3, 0x1e1b6df4, 0xc55fea9d, 0x8c6397ba, + 0xb0779fd0, 0xf94be2f7, 0x220f659e, 0x6b3318b9, + 0x916a1dbd, 0xd856609a, 0x0312e7f3, 0x4a2e9ad4, + 0xf24c9b0a, 0xbb70e62d, 0x60346144, 0x29081c63, + 0xd3511967, 0x9a6d6440, 0x4129e329, 0x08159e0e, + 0x3901f3fd, 0x703d8eda, 0xab7909b3, 0xe2457494, + 0x181c7190, 0x51200cb7, 0x8a648bde, 0xc358f6f9, + 0x7b3af727, 0x32068a00, 0xe9420d69, 0xa07e704e, + 0x5a27754a, 0x131b086d, 0xc85f8f04, 0x8163f223, + 0xbd77fa49, 0xf44b876e, 0x2f0f0007, 0x66337d20, + 0x9c6a7824, 0xd5560503, 0x0e12826a, 0x472eff4d, + 0xff4cfe93, 0xb67083b4, 0x6d3404dd, 0x240879fa, + 0xde517cfe, 0x976d01d9, 0x4c2986b0, 0x0515fb97, + 0x2e015d56, 0x673d2071, 0xbc79a718, 0xf545da3f, + 0x0f1cdf3b, 0x4620a21c, 0x9d642575, 0xd4585852, + 0x6c3a598c, 0x250624ab, 0xfe42a3c2, 0xb77edee5, + 0x4d27dbe1, 0x041ba6c6, 0xdf5f21af, 0x96635c88, + 0xaa7754e2, 0xe34b29c5, 0x380faeac, 0x7133d38b, + 0x8b6ad68f, 0xc256aba8, 0x19122cc1, 0x502e51e6, + 0xe84c5038, 0xa1702d1f, 0x7a34aa76, 0x3308d751, + 0xc951d255, 0x806daf72, 0x5b29281b, 0x1215553c, + 0x230138cf, 0x6a3d45e8, 0xb179c281, 0xf845bfa6, + 0x021cbaa2, 0x4b20c785, 0x906440ec, 0xd9583dcb, + 0x613a3c15, 0x28064132, 0xf342c65b, 0xba7ebb7c, + 0x4027be78, 0x091bc35f, 0xd25f4436, 0x9b633911, + 0xa777317b, 0xee4b4c5c, 0x350fcb35, 0x7c33b612, + 0x866ab316, 0xcf56ce31, 0x14124958, 0x5d2e347f, + 0xe54c35a1, 0xac704886, 0x7734cfef, 0x3e08b2c8, + 0xc451b7cc, 0x8d6dcaeb, 0x56294d82, 0x1f1530a5 + } +#endif +}; + +/* + * __wt_checksum_sw -- + * Return a checksum for a chunk of memory, computed in software. + */ +uint32_t +__wt_checksum_sw(const void *chunk, size_t len) +{ + uint32_t crc, next; + size_t nqwords; + const uint8_t *p; + + crc = 0xffffffff; + + /* Checksum one byte at a time to the first 4B boundary. */ + for (p = chunk; + ((uintptr_t)p & (sizeof(uint32_t) - 1)) != 0 && + len > 0; ++p, --len) +#ifdef WORDS_BIGENDIAN + crc = g_crc_slicing[0][((crc >> 24) ^ *p) & 0xFF] ^ (crc << 8); +#else + crc = g_crc_slicing[0][(crc ^ *p) & 0xFF] ^ (crc >> 8); +#endif + + /* Checksum in 8B chunks. */ + for (nqwords = len / sizeof(uint64_t); nqwords; nqwords--) { + crc ^= *(uint32_t *)p; + p += sizeof(uint32_t); + next = *(uint32_t *)p; + p += sizeof(uint32_t); + crc = +#ifdef WORDS_BIGENDIAN + g_crc_slicing[4][(crc ) & 0xFF] ^ + g_crc_slicing[5][(crc >> 8) & 0xFF] ^ + g_crc_slicing[6][(crc >> 16) & 0xFF] ^ + g_crc_slicing[7][(crc >> 24)] ^ + g_crc_slicing[0][(next ) & 0xFF] ^ + g_crc_slicing[1][(next >> 8) & 0xFF] ^ + g_crc_slicing[2][(next >> 16) & 0xFF] ^ + g_crc_slicing[3][(next >> 24)]; +#else + g_crc_slicing[7][(crc ) & 0xFF] ^ + g_crc_slicing[6][(crc >> 8) & 0xFF] ^ + g_crc_slicing[5][(crc >> 16) & 0xFF] ^ + g_crc_slicing[4][(crc >> 24)] ^ + g_crc_slicing[3][(next ) & 0xFF] ^ + g_crc_slicing[2][(next >> 8) & 0xFF] ^ + g_crc_slicing[1][(next >> 16) & 0xFF] ^ + g_crc_slicing[0][(next >> 24)]; +#endif + } + + /* Checksum trailing bytes one byte at a time. */ +#ifdef WORDS_BIGENDIAN + for (len &= 0x7; len > 0; ++p, len--) + crc = g_crc_slicing[0][((crc >> 24) ^ *p) & 0xFF] ^ (crc << 8); + + /* Do final byte swap to produce a result identical to little endian */ + crc = + ((crc << 24) & 0xFF000000) | + ((crc << 8) & 0x00FF0000) | + ((crc >> 8) & 0x0000FF00) | + ((crc >> 24) & 0x000000FF); +#else + for (len &= 0x7; len > 0; ++p, len--) + crc = g_crc_slicing[0][(crc ^ *p) & 0xFF] ^ (crc >> 8); +#endif + return (~crc); +} diff --git a/src/third_party/wiredtiger/src/checksum/x86/crc32-x86.c b/src/third_party/wiredtiger/src/checksum/x86/crc32-x86.c new file mode 100644 index 00000000000..82814ecc34d --- /dev/null +++ b/src/third_party/wiredtiger/src/checksum/x86/crc32-x86.c @@ -0,0 +1,160 @@ +/*- + * Public Domain 2014-2016 MongoDB, Inc. + * Public Domain 2008-2014 WiredTiger, Inc. + * + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "wt_internal.h" + +#if defined(HAVE_CRC32_HARDWARE) +#if (defined(__amd64) || defined(__x86_64)) +/* + * __wt_checksum_hw -- + * Return a checksum for a chunk of memory, computed in hardware + * using 8 byte steps. + */ +static uint32_t +__wt_checksum_hw(const void *chunk, size_t len) +{ + uint32_t crc; + size_t nqwords; + const uint8_t *p; + const uint64_t *p64; + + crc = 0xffffffff; + + /* Checksum one byte at a time to the first 4B boundary. */ + for (p = chunk; + ((uintptr_t)p & (sizeof(uint32_t) - 1)) != 0 && + len > 0; ++p, --len) { + __asm__ __volatile__( + ".byte 0xF2, 0x0F, 0x38, 0xF0, 0xF1" + : "=S" (crc) + : "0" (crc), "c" (*p)); + } + + p64 = (const uint64_t *)p; + /* Checksum in 8B chunks. */ + for (nqwords = len / sizeof(uint64_t); nqwords; nqwords--) { + __asm__ __volatile__ ( + ".byte 0xF2, 0x48, 0x0F, 0x38, 0xF1, 0xF1" + : "=S"(crc) + : "0"(crc), "c" (*p64)); + p64++; + } + + /* Checksum trailing bytes one byte at a time. */ + p = (const uint8_t *)p64; + for (len &= 0x7; len > 0; ++p, len--) { + __asm__ __volatile__( + ".byte 0xF2, 0x0F, 0x38, 0xF0, 0xF1" + : "=S" (crc) + : "0" (crc), "c" (*p)); + } + return (~crc); +} +#endif + +#if defined(_M_AMD64) +/* + * __wt_checksum_hw -- + * Return a checksum for a chunk of memory, computed in hardware + * using 8 byte steps. + */ +static uint32_t +__wt_checksum_hw(const void *chunk, size_t len) +{ + uint32_t crc; + size_t nqwords; + const uint8_t *p; + const uint64_t *p64; + + crc = 0xffffffff; + + /* Checksum one byte at a time to the first 4B boundary. */ + for (p = chunk; + ((uintptr_t)p & (sizeof(uint32_t) - 1)) != 0 && + len > 0; ++p, --len) { + crc = _mm_crc32_u8(crc, *p); + } + + p64 = (const uint64_t *)p; + /* Checksum in 8B chunks. */ + for (nqwords = len / sizeof(uint64_t); nqwords; nqwords--) { + crc = (uint32_t)_mm_crc32_u64(crc, *p64); + p64++; + } + + /* Checksum trailing bytes one byte at a time. */ + p = (const uint8_t *)p64; + for (len &= 0x7; len > 0; ++p, len--) { + crc = _mm_crc32_u8(crc, *p); + } + + return (~crc); +} +#endif +#endif /* HAVE_CRC32_HARDWARE */ + +/* + * __wt_checksum_init -- + * WiredTiger: detect CRC hardware and set the checksum function. + */ +void +__wt_checksum_init(void) +{ +#if defined(HAVE_CRC32_HARDWARE) +#if (defined(__amd64) || defined(__x86_64)) + unsigned int eax, ebx, ecx, edx; + + __asm__ __volatile__ ( + "cpuid" + : "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx) + : "a" (1)); + +#define CPUID_ECX_HAS_SSE42 (1 << 20) + if (ecx & CPUID_ECX_HAS_SSE42) + __wt_process.checksum = __wt_checksum_hw; + else + __wt_process.checksum = __wt_checksum_sw; + +#elif defined(_M_AMD64) + int cpuInfo[4]; + + __cpuid(cpuInfo, 1); + +#define CPUID_ECX_HAS_SSE42 (1 << 20) + if (cpuInfo[2] & CPUID_ECX_HAS_SSE42) + __wt_process.checksum = __wt_checksum_hw; + else + __wt_process.checksum = __wt_checksum_sw; +#else + __wt_process.checksum = __wt_checksum_sw; +#endif + +#else /* !HAVE_CRC32_HARDWARE */ + __wt_process.checksum = __wt_checksum_sw; +#endif /* HAVE_CRC32_HARDWARE */ +} diff --git a/src/third_party/wiredtiger/src/checksum/zseries/LICENSE.TXT b/src/third_party/wiredtiger/src/checksum/zseries/LICENSE.TXT new file mode 100644 index 00000000000..9946c98f568 --- /dev/null +++ b/src/third_party/wiredtiger/src/checksum/zseries/LICENSE.TXT @@ -0,0 +1,482 @@ +Copyright (C) 2016 IBM Corp. + +Author(s): + Hendrik Brueckner + Anton Blanchard + Bryan Chan + Chris Zou + +crc32-s390x is free software; you can redistribute it and/or modify it +under the terms of either: + + a) the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) + any later version, or + b) the Apache License, Version 2.0 + + + + + + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + + + + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS diff --git a/src/third_party/wiredtiger/src/checksum/zseries/README.md b/src/third_party/wiredtiger/src/checksum/zseries/README.md new file mode 100644 index 00000000000..5d59ceb6f6a --- /dev/null +++ b/src/third_party/wiredtiger/src/checksum/zseries/README.md @@ -0,0 +1,61 @@ +crc32-s390x +=========== + +A library of functions for accelerating CRC32 calculations using the +Vector Galois Field Multiply instruction family instructions introduced in +the z13. The Vector Extension Facility for z/Architecture provides two +instructions to perform a binary Galois field multiplication. Both +instructions (VGFM and VGFMA) can operate on different element sizes. +For the 32-bit CRC computation, doublewords are used throughout the +implementation. + +Quick start +----------- + +Type make to generate a static library libcrc32\_s390x.a. + +The library provides functions to compute CRC-32 (IEEE 802.3) and +CRC-32C (Castagnoli), with optional bit reflection (with the `*_le` +versions of the functions). + +Function prototypes are declared in crc32-s390x.h. A sample program +crc32-cli.c shows how the library is used. + +Testing +------- + +The correctness of the hardware-accelerated implementation is verified +with the pure-software Rocksoft Model CRC algorithm. There are four +variants of the test, each of which exercise one type of CRC on random +data with random alignment and buffer sizes, in an infinite loop: + + ./crc32_be_test + ./crc32_le_test + ./crc32c_be_test + ./crc32c_le_test + +If the hardware-accelerated algorithm ever returns a different result +than the Rocksoft Model, the test will print messages to indicate the +errors. + +Performance +----------- + +The performance of the hardware-accelerated implemention is compared +with the slicing-by-8 algorithm. Testing 500000 iterations of a CRC +of 32kB of data showed a 70-times speed-up: + + $ time ./crc32_sw_bench 32768 500000 + CRC: a98177aa + + real 0m21.862s + user 0m21.859s + sys 0m0.002s + + $ time ./crc32_vx_bench 32768 500000 + CRC: a98177aa + + real 0m0.323s + user 0m0.323s + sys 0m0.000s + diff --git a/src/third_party/wiredtiger/src/checksum/zseries/crc32-s390x.c b/src/third_party/wiredtiger/src/checksum/zseries/crc32-s390x.c new file mode 100644 index 00000000000..f77d6768d42 --- /dev/null +++ b/src/third_party/wiredtiger/src/checksum/zseries/crc32-s390x.c @@ -0,0 +1,96 @@ +/* + * CRC-32 algorithms implemented with the z/Architecture + * Vector Extension Facility. + * + * Copyright IBM Corp. 2015 + * Author(s): Hendrik Brueckner + * + */ +#include +#include +#include "crc32-s390x.h" +#include "slicing-consts.h" + +#define VX_MIN_LEN 64 +#define VX_ALIGNMENT 16UL +#define VX_ALIGN_MASK (VX_ALIGNMENT - 1) + +/* Prototypes for functions in assembly files */ +unsigned int __wt_crc32c_le_vgfm_16(unsigned int crc, const unsigned char *buf, size_t size); + +/* Pure C implementations of CRC, one byte at a time */ +unsigned int __wt_crc32c_le(unsigned int crc, const unsigned char *buf, size_t len){ + crc = htole32(crc); + while (len--) + crc = crc32ctable_le[0][((crc >> 24) ^ *buf++) & 0xFF] ^ (crc << 8); + crc = le32toh(crc); + return crc; +} + +/* + * DEFINE_CRC32_VX() - Define a CRC-32 function using the vector extension + * + * Creates a function to perform a particular CRC-32 computation. Depending + * on the message buffer, the hardware-accelerated or software implementation + * is used. Note that the message buffer is aligned to improve fetch + * operations of VECTOR LOAD MULTIPLE instructions. + * + */ +#define DEFINE_CRC32_VX(___fname, ___crc32_vx, ___crc32_sw) \ + unsigned int ___fname(unsigned int crc, \ + const unsigned char *data, \ + size_t datalen) \ + { \ + unsigned long prealign, aligned, remaining; \ + \ + if ((unsigned long)data & VX_ALIGN_MASK) { \ + prealign = VX_ALIGNMENT - \ + ((unsigned long)data & VX_ALIGN_MASK); \ + datalen -= prealign; \ + crc = ___crc32_sw(crc, data, prealign); \ + data = data + prealign; \ + } \ + \ + if (datalen < VX_MIN_LEN) \ + return ___crc32_sw(crc, data, datalen); \ + \ + aligned = datalen & ~VX_ALIGN_MASK; \ + remaining = datalen & VX_ALIGN_MASK; \ + \ + crc = ___crc32_vx(crc, data, aligned); \ + data = data + aligned; \ + \ + if (remaining) \ + crc = ___crc32_sw(crc, data, remaining); \ + \ + return crc; \ + } + +/* Main CRC-32 functions */ +DEFINE_CRC32_VX(__wt_crc32c_le_vx, __wt_crc32c_le_vgfm_16, __wt_crc32c_le) + +#include "wt_internal.h" + +/* + * __wt_checksum_hw -- + * WiredTiger: return a checksum for a chunk of memory. + */ +static uint32_t +__wt_checksum_hw(const void *chunk, size_t len) +{ + return (~__wt_crc32c_le_vx(0xffffffff, chunk, len)); +} + +/* + * __wt_checksum_init -- + * WiredTiger: detect CRC hardware and set the checksum function. + */ +void +__wt_checksum_init(void) +{ +#if defined(HAVE_CRC32_HARDWARE) + __wt_process.checksum = __wt_checksum_hw; +#else + __wt_process.checksum = __wt_checksum_sw; +#endif +} diff --git a/src/third_party/wiredtiger/src/checksum/zseries/crc32-s390x.h b/src/third_party/wiredtiger/src/checksum/zseries/crc32-s390x.h new file mode 100644 index 00000000000..14d6c07f62e --- /dev/null +++ b/src/third_party/wiredtiger/src/checksum/zseries/crc32-s390x.h @@ -0,0 +1,12 @@ +/* + * Copyright IBM Corp. 2015 + */ +#include + +/* Portable implementations of CRC-32 (IEEE and Castagnoli), both + big-endian and little-endian variants. */ +unsigned int __wt_crc32c_le(unsigned int, const unsigned char *, size_t); + +/* Hardware-accelerated versions of the above. It is up to the caller + to detect the availability of vector facility and kernel support. */ +unsigned int __wt_crc32c_le_vx(unsigned int, const unsigned char *, size_t); diff --git a/src/third_party/wiredtiger/src/checksum/zseries/crc32le-vx.S b/src/third_party/wiredtiger/src/checksum/zseries/crc32le-vx.S new file mode 100644 index 00000000000..0f1392b0952 --- /dev/null +++ b/src/third_party/wiredtiger/src/checksum/zseries/crc32le-vx.S @@ -0,0 +1,280 @@ +/* + * Hardware-accelerated CRC-32 variants for Linux on z Systems + * + * Use the z/Architecture Vector Extension Facility to accelerate the + * computing of bit-reflected CRC-32 checksums for IEEE 802.3 Ethernet + * and Castagnoli. + * + * This CRC-32 implementation algorithm is bit-reflected and processes + * the least-significant bit first (Little-Endian). + * + * Copyright IBM Corp. 2015 + * Author(s): Hendrik Brueckner + */ + +#include "vx-insn.h" + +/* Vector register range containing CRC-32 constants */ +#define CONST_PERM_LE2BE %v9 +#define CONST_R2R1 %v10 +#define CONST_R4R3 %v11 +#define CONST_R5 %v12 +#define CONST_RU_POLY %v13 +#define CONST_CRC_POLY %v14 + +.data +.align 8 + +/* + * The CRC-32 constant block contains reduction constants to fold and + * process particular chunks of the input data stream in parallel. + * + * For the CRC-32 variants, the constants are precomputed according to + * these definitions: + * + * R1 = [(x4*128+32 mod P'(x) << 32)]' << 1 + * R2 = [(x4*128-32 mod P'(x) << 32)]' << 1 + * R3 = [(x128+32 mod P'(x) << 32)]' << 1 + * R4 = [(x128-32 mod P'(x) << 32)]' << 1 + * R5 = [(x64 mod P'(x) << 32)]' << 1 + * R6 = [(x32 mod P'(x) << 32)]' << 1 + * + * The bit-reflected Barret reduction constant, u', is defined as + * the bit reversal of floor(x**64 / P(x)). + * + * where P(x) is the polynomial in the normal domain and the P'(x) is the + * polynomial in the reversed (bit-reflected) domain. + * + * CRC-32 (IEEE 802.3 Ethernet, ...) polynomials: + * + * P(x) = 0x04C11DB7 + * P'(x) = 0xEDB88320 + * + * CRC-32C (Castagnoli) polynomials: + * + * P(x) = 0x1EDC6F41 + * P'(x) = 0x82F63B78 + */ + +.Lconstants_CRC_32_LE: + .octa 0x0F0E0D0C0B0A09080706050403020100 # BE->LE mask + .quad 0x1c6e41596, 0x154442bd4 # R2, R1 + .quad 0x0ccaa009e, 0x1751997d0 # R4, R3 + .octa 0x163cd6124 # R5 + .octa 0x1F7011641 # u' + .octa 0x1DB710641 # P'(x) << 1 + +.Lconstants_CRC_32C_LE: + .octa 0x0F0E0D0C0B0A09080706050403020100 # BE->LE mask + .quad 0x09e4addf8, 0x740eef02 # R2, R1 + .quad 0x14cd00bd6, 0xf20c0dfe # R4, R3 + .octa 0x0dd45aab8 # R5 + .octa 0x0dea713f1 # u' + .octa 0x105ec76f0 # P'(x) << 1 + +.previous + +.text +/* + * The CRC-32 functions use these calling conventions: + * + * Parameters: + * + * %r2: Initial CRC value, typically ~0; and final CRC (return) value. + * %r3: Input buffer pointer, performance might be improved if the + * buffer is on a doubleword boundary. + * %r4: Length of the buffer, must be 64 bytes or greater. + * + * Register usage: + * + * %r5: CRC-32 constant pool base pointer. + * V0: Initial CRC value and intermediate constants and results. + * V1..V4: Data for CRC computation. + * V5..V8: Next data chunks that are fetched from the input buffer. + * V9: Constant for BE->LE conversion and shift operations + * + * V10..V14: CRC-32 constants. + */ + +WT_CRC32_ENTRY(__wt_crc32c_le_vgfm_16) + larl %r5,.Lconstants_CRC_32C_LE + j crc32_le_vgfm_generic + +crc32_le_vgfm_generic: + /* Preserve non-volatile vector registers. */ + stmg %r14,%r15,112(%r15) + lay %r15,-128(%r15) + VSTM %v8,%v15,0,%r15 + + /* Load CRC-32 constants into multiple vector registers. */ + VLM CONST_PERM_LE2BE,CONST_CRC_POLY,0,%r5 + + /* + * Load the initial CRC value. + * + * The CRC value is loaded into the rightmost word of the + * vector register and is later XORed with the LSB portion + * of the loaded input data. + */ + VZERO %v0 /* Clear V0 */ + VLVGF %v0,%r2,3 /* Load CRC into rightmost word */ + + /* Load a 64-byte data chunk and XOR with CRC */ + VLM %v1,%v4,0,%r3 /* 64-bytes into V1..V4 */ + + /* Reflect the data since the CRC operates in the bit-reflected domain. */ + VPERM %v1,%v1,%v1,CONST_PERM_LE2BE + VPERM %v2,%v2,%v2,CONST_PERM_LE2BE + VPERM %v3,%v3,%v3,CONST_PERM_LE2BE + VPERM %v4,%v4,%v4,CONST_PERM_LE2BE + + VX %v1,%v0,%v1 /* V1 ^= CRC */ + aghi %r3,64 /* BUF = BUF + 64 */ + aghi %r4,-64 /* LEN = LEN - 64 */ + + /* Check remaining buffer size and jump to proper folding method. */ + cghi %r4,64 + jl .Lless_than_64bytes + +.Lfold_64bytes_loop: + /* Load the next 64-byte data chunk into V5 to V8 */ + VLM %v5,%v8,0,%r3 + VPERM %v5,%v5,%v5,CONST_PERM_LE2BE + VPERM %v6,%v6,%v6,CONST_PERM_LE2BE + VPERM %v7,%v7,%v7,CONST_PERM_LE2BE + VPERM %v8,%v8,%v8,CONST_PERM_LE2BE + + /* + * Perform a GF(2) multiplication of the doublewords in V1 with + * the R1 and R2 reduction constants in V10. The intermediate result + * is then folded (accumulated, or XOR-ed) with the next data chunk + * in V5 and stored in V1. Repeat this step for the register contents + * in V2, V3, and V4 respectively. + */ + VGFMAG %v1,CONST_R2R1,%v1,%v5 + VGFMAG %v2,CONST_R2R1,%v2,%v6 + VGFMAG %v3,CONST_R2R1,%v3,%v7 + VGFMAG %v4,CONST_R2R1,%v4,%v8 + + /* Adjust buffer pointer and length for next loop. */ + aghi %r3,64 /* BUF = BUF + 64 */ + aghi %r4,-64 /* LEN = LEN - 64 */ + + cghi %r4,64 + jnl .Lfold_64bytes_loop + +.Lless_than_64bytes: + /* + * Fold V1 to V4 into a single 128-bit value in V1. Multiply V1 with R3 + * and R4 and accumulating the next 128-bit chunk until a single 128-bit + * value remains. + */ + VGFMAG %v1,CONST_R4R3,%v1,%v2 + VGFMAG %v1,CONST_R4R3,%v1,%v3 + VGFMAG %v1,CONST_R4R3,%v1,%v4 + + /* Check whether to continue with 64-bit folding. */ + cghi %r4,16 + jl .Lfinal_fold + +.Lfold_16bytes_loop: + + VL %v2,0,,%r3 /* Load next data chunk */ + VPERM %v2,%v2,%v2,CONST_PERM_LE2BE + VGFMAG %v1,CONST_R4R3,%v1,%v2 /* Fold next data chunk */ + + /* Adjust buffer pointer and size for folding next data chunk. */ + aghi %r3,16 + aghi %r4,-16 + + /* Process remaining data chunks. */ + cghi %r4,16 + jnl .Lfold_16bytes_loop + +.Lfinal_fold: + /* + * Set up a vector register for byte shifts. The shift value must + * be loaded in bits 1-4 in byte element 7 of a vector register. + * Shift by 8 bytes: 0x40 + * Shift by 4 bytes: 0x20 + */ + VLEIB %v9,0x40,7 + + /* + * Prepare V0 for the next GF(2) multiplication: shift V0 by 8 bytes + * to move R4 into the rightmost doubleword and set the leftmost + * doubleword to 0x1. + */ + VSRLB %v0,CONST_R4R3,%v9 + VLEIG %v0,1,0 + + /* + * Compute GF(2) product of V1 and V0. The rightmost doubleword + * of V1 is multiplied with R4. The leftmost doubleword of V1 is + * multiplied by 0x1 and is then XORed with rightmost product. + * Implicitly, the intermediate leftmost product becomes padded + */ + VGFMG %v1,%v0,%v1 + + /* + * Now do the final 32-bit fold by multiplying the rightmost word + * in V1 with R5 and XOR the result with the remaining bits in V1. + * + * To achieve this by a single VGFMAG, right shift V1 by a word + * and store the result in V2 which is then accumulated. Use the + * vector unpack instruction to load the rightmost half of the + * doubleword into the rightmost doubleword element of V1; the other + * half is loaded in the leftmost doubleword. + * The vector register with CONST_R5 contains the R5 constant in the + * rightmost doubleword and the leftmost doubleword is zero to ignore + * the leftmost product of V1. + */ + VLEIB %v9,0x20,7 /* Shift by words */ + VSRLB %v2,%v1,%v9 /* Store remaining bits in V2 */ + VUPLLF %v1,%v1 /* Split rightmost doubleword */ + VGFMAG %v1,CONST_R5,%v1,%v2 /* V1 = (V1 * R5) XOR V2 */ + + /* + * Apply a Barret reduction to compute the final 32-bit CRC value. + * + * The input values to the Barret reduction are the degree-63 polynomial + * in V1 (R(x)), degree-32 generator polynomial, and the reduction + * constant u. The Barret reduction result is the CRC value of R(x) mod + * P(x). + * + * The Barret reduction algorithm is defined as: + * + * 1. T1(x) = floor( R(x) / x^32 ) GF2MUL u + * 2. T2(x) = floor( T1(x) / x^32 ) GF2MUL P(x) + * 3. C(x) = R(x) XOR T2(x) mod x^32 + * + * Note: The leftmost doubleword of vector register containing + * CONST_RU_POLY is zero and, thus, the intermediate GF(2) product + * is zero and does not contribute to the final result. + */ + + /* T1(x) = floor( R(x) / x^32 ) GF2MUL u */ + VUPLLF %v2,%v1 + VGFMG %v2,CONST_RU_POLY,%v2 + + /* + * Compute the GF(2) product of the CRC polynomial with T1(x) in + * V2 and XOR the intermediate result, T2(x), with the value in V1. + * The final result is stored in word element 2 of V2. + */ + VUPLLF %v2,%v2 + VGFMAG %v2,CONST_CRC_POLY,%v2,%v1 + +.Ldone: + /* Move the result to R2, restore preserved registers and return. */ + VLGVF %r2,%v2,2 + VLM %v8,%v15,0,%r15 + lmg %r14,%r15,240(%r15) + br %r14 + +/* + * Make sure the stack isn't executable with GCC (regardless of platform). + */ +#ifndef __clang__ +.section .note.GNU-stack,"",@progbits +#endif diff --git a/src/third_party/wiredtiger/src/checksum/zseries/slicing-consts.h b/src/third_party/wiredtiger/src/checksum/zseries/slicing-consts.h new file mode 100644 index 00000000000..3dc11dc52af --- /dev/null +++ b/src/third_party/wiredtiger/src/checksum/zseries/slicing-consts.h @@ -0,0 +1,2096 @@ +/* CRC-32 and CRC-32C slicing-by-8 constants, for use on big-endian systems. */ +static const unsigned int __attribute__((aligned(128))) crc32table_le[8][256] = { + { + 0x00000000, 0x96300777, 0x2c610eee, 0xba510999, + 0x19c46d07, 0x8ff46a70, 0x35a563e9, 0xa395649e, + 0x3288db0e, 0xa4b8dc79, 0x1ee9d5e0, 0x88d9d297, + 0x2b4cb609, 0xbd7cb17e, 0x072db8e7, 0x911dbf90, + 0x6410b71d, 0xf220b06a, 0x4871b9f3, 0xde41be84, + 0x7dd4da1a, 0xebe4dd6d, 0x51b5d4f4, 0xc785d383, + 0x56986c13, 0xc0a86b64, 0x7af962fd, 0xecc9658a, + 0x4f5c0114, 0xd96c0663, 0x633d0ffa, 0xf50d088d, + 0xc8206e3b, 0x5e10694c, 0xe44160d5, 0x727167a2, + 0xd1e4033c, 0x47d4044b, 0xfd850dd2, 0x6bb50aa5, + 0xfaa8b535, 0x6c98b242, 0xd6c9bbdb, 0x40f9bcac, + 0xe36cd832, 0x755cdf45, 0xcf0dd6dc, 0x593dd1ab, + 0xac30d926, 0x3a00de51, 0x8051d7c8, 0x1661d0bf, + 0xb5f4b421, 0x23c4b356, 0x9995bacf, 0x0fa5bdb8, + 0x9eb80228, 0x0888055f, 0xb2d90cc6, 0x24e90bb1, + 0x877c6f2f, 0x114c6858, 0xab1d61c1, 0x3d2d66b6, + 0x9041dc76, 0x0671db01, 0xbc20d298, 0x2a10d5ef, + 0x8985b171, 0x1fb5b606, 0xa5e4bf9f, 0x33d4b8e8, + 0xa2c90778, 0x34f9000f, 0x8ea80996, 0x18980ee1, + 0xbb0d6a7f, 0x2d3d6d08, 0x976c6491, 0x015c63e6, + 0xf4516b6b, 0x62616c1c, 0xd8306585, 0x4e0062f2, + 0xed95066c, 0x7ba5011b, 0xc1f40882, 0x57c40ff5, + 0xc6d9b065, 0x50e9b712, 0xeab8be8b, 0x7c88b9fc, + 0xdf1ddd62, 0x492dda15, 0xf37cd38c, 0x654cd4fb, + 0x5861b24d, 0xce51b53a, 0x7400bca3, 0xe230bbd4, + 0x41a5df4a, 0xd795d83d, 0x6dc4d1a4, 0xfbf4d6d3, + 0x6ae96943, 0xfcd96e34, 0x468867ad, 0xd0b860da, + 0x732d0444, 0xe51d0333, 0x5f4c0aaa, 0xc97c0ddd, + 0x3c710550, 0xaa410227, 0x10100bbe, 0x86200cc9, + 0x25b56857, 0xb3856f20, 0x09d466b9, 0x9fe461ce, + 0x0ef9de5e, 0x98c9d929, 0x2298d0b0, 0xb4a8d7c7, + 0x173db359, 0x810db42e, 0x3b5cbdb7, 0xad6cbac0, + 0x2083b8ed, 0xb6b3bf9a, 0x0ce2b603, 0x9ad2b174, + 0x3947d5ea, 0xaf77d29d, 0x1526db04, 0x8316dc73, + 0x120b63e3, 0x843b6494, 0x3e6a6d0d, 0xa85a6a7a, + 0x0bcf0ee4, 0x9dff0993, 0x27ae000a, 0xb19e077d, + 0x44930ff0, 0xd2a30887, 0x68f2011e, 0xfec20669, + 0x5d5762f7, 0xcb676580, 0x71366c19, 0xe7066b6e, + 0x761bd4fe, 0xe02bd389, 0x5a7ada10, 0xcc4add67, + 0x6fdfb9f9, 0xf9efbe8e, 0x43beb717, 0xd58eb060, + 0xe8a3d6d6, 0x7e93d1a1, 0xc4c2d838, 0x52f2df4f, + 0xf167bbd1, 0x6757bca6, 0xdd06b53f, 0x4b36b248, + 0xda2b0dd8, 0x4c1b0aaf, 0xf64a0336, 0x607a0441, + 0xc3ef60df, 0x55df67a8, 0xef8e6e31, 0x79be6946, + 0x8cb361cb, 0x1a8366bc, 0xa0d26f25, 0x36e26852, + 0x95770ccc, 0x03470bbb, 0xb9160222, 0x2f260555, + 0xbe3bbac5, 0x280bbdb2, 0x925ab42b, 0x046ab35c, + 0xa7ffd7c2, 0x31cfd0b5, 0x8b9ed92c, 0x1daede5b, + 0xb0c2649b, 0x26f263ec, 0x9ca36a75, 0x0a936d02, + 0xa906099c, 0x3f360eeb, 0x85670772, 0x13570005, + 0x824abf95, 0x147ab8e2, 0xae2bb17b, 0x381bb60c, + 0x9b8ed292, 0x0dbed5e5, 0xb7efdc7c, 0x21dfdb0b, + 0xd4d2d386, 0x42e2d4f1, 0xf8b3dd68, 0x6e83da1f, + 0xcd16be81, 0x5b26b9f6, 0xe177b06f, 0x7747b718, + 0xe65a0888, 0x706a0fff, 0xca3b0666, 0x5c0b0111, + 0xff9e658f, 0x69ae62f8, 0xd3ff6b61, 0x45cf6c16, + 0x78e20aa0, 0xeed20dd7, 0x5483044e, 0xc2b30339, + 0x612667a7, 0xf71660d0, 0x4d476949, 0xdb776e3e, + 0x4a6ad1ae, 0xdc5ad6d9, 0x660bdf40, 0xf03bd837, + 0x53aebca9, 0xc59ebbde, 0x7fcfb247, 0xe9ffb530, + 0x1cf2bdbd, 0x8ac2baca, 0x3093b353, 0xa6a3b424, + 0x0536d0ba, 0x9306d7cd, 0x2957de54, 0xbf67d923, + 0x2e7a66b3, 0xb84a61c4, 0x021b685d, 0x942b6f2a, + 0x37be0bb4, 0xa18e0cc3, 0x1bdf055a, 0x8def022d + },{ + 0x00000000, 0x41311b19, 0x82623632, 0xc3532d2b, + 0x04c56c64, 0x45f4777d, 0x86a75a56, 0xc796414f, + 0x088ad9c8, 0x49bbc2d1, 0x8ae8effa, 0xcbd9f4e3, + 0x0c4fb5ac, 0x4d7eaeb5, 0x8e2d839e, 0xcf1c9887, + 0x5112c24a, 0x1023d953, 0xd370f478, 0x9241ef61, + 0x55d7ae2e, 0x14e6b537, 0xd7b5981c, 0x96848305, + 0x59981b82, 0x18a9009b, 0xdbfa2db0, 0x9acb36a9, + 0x5d5d77e6, 0x1c6c6cff, 0xdf3f41d4, 0x9e0e5acd, + 0xa2248495, 0xe3159f8c, 0x2046b2a7, 0x6177a9be, + 0xa6e1e8f1, 0xe7d0f3e8, 0x2483dec3, 0x65b2c5da, + 0xaaae5d5d, 0xeb9f4644, 0x28cc6b6f, 0x69fd7076, + 0xae6b3139, 0xef5a2a20, 0x2c09070b, 0x6d381c12, + 0xf33646df, 0xb2075dc6, 0x715470ed, 0x30656bf4, + 0xf7f32abb, 0xb6c231a2, 0x75911c89, 0x34a00790, + 0xfbbc9f17, 0xba8d840e, 0x79dea925, 0x38efb23c, + 0xff79f373, 0xbe48e86a, 0x7d1bc541, 0x3c2ade58, + 0x054f79f0, 0x447e62e9, 0x872d4fc2, 0xc61c54db, + 0x018a1594, 0x40bb0e8d, 0x83e823a6, 0xc2d938bf, + 0x0dc5a038, 0x4cf4bb21, 0x8fa7960a, 0xce968d13, + 0x0900cc5c, 0x4831d745, 0x8b62fa6e, 0xca53e177, + 0x545dbbba, 0x156ca0a3, 0xd63f8d88, 0x970e9691, + 0x5098d7de, 0x11a9ccc7, 0xd2fae1ec, 0x93cbfaf5, + 0x5cd76272, 0x1de6796b, 0xdeb55440, 0x9f844f59, + 0x58120e16, 0x1923150f, 0xda703824, 0x9b41233d, + 0xa76bfd65, 0xe65ae67c, 0x2509cb57, 0x6438d04e, + 0xa3ae9101, 0xe29f8a18, 0x21cca733, 0x60fdbc2a, + 0xafe124ad, 0xeed03fb4, 0x2d83129f, 0x6cb20986, + 0xab2448c9, 0xea1553d0, 0x29467efb, 0x687765e2, + 0xf6793f2f, 0xb7482436, 0x741b091d, 0x352a1204, + 0xf2bc534b, 0xb38d4852, 0x70de6579, 0x31ef7e60, + 0xfef3e6e7, 0xbfc2fdfe, 0x7c91d0d5, 0x3da0cbcc, + 0xfa368a83, 0xbb07919a, 0x7854bcb1, 0x3965a7a8, + 0x4b98833b, 0x0aa99822, 0xc9fab509, 0x88cbae10, + 0x4f5def5f, 0x0e6cf446, 0xcd3fd96d, 0x8c0ec274, + 0x43125af3, 0x022341ea, 0xc1706cc1, 0x804177d8, + 0x47d73697, 0x06e62d8e, 0xc5b500a5, 0x84841bbc, + 0x1a8a4171, 0x5bbb5a68, 0x98e87743, 0xd9d96c5a, + 0x1e4f2d15, 0x5f7e360c, 0x9c2d1b27, 0xdd1c003e, + 0x120098b9, 0x533183a0, 0x9062ae8b, 0xd153b592, + 0x16c5f4dd, 0x57f4efc4, 0x94a7c2ef, 0xd596d9f6, + 0xe9bc07ae, 0xa88d1cb7, 0x6bde319c, 0x2aef2a85, + 0xed796bca, 0xac4870d3, 0x6f1b5df8, 0x2e2a46e1, + 0xe136de66, 0xa007c57f, 0x6354e854, 0x2265f34d, + 0xe5f3b202, 0xa4c2a91b, 0x67918430, 0x26a09f29, + 0xb8aec5e4, 0xf99fdefd, 0x3accf3d6, 0x7bfde8cf, + 0xbc6ba980, 0xfd5ab299, 0x3e099fb2, 0x7f3884ab, + 0xb0241c2c, 0xf1150735, 0x32462a1e, 0x73773107, + 0xb4e17048, 0xf5d06b51, 0x3683467a, 0x77b25d63, + 0x4ed7facb, 0x0fe6e1d2, 0xccb5ccf9, 0x8d84d7e0, + 0x4a1296af, 0x0b238db6, 0xc870a09d, 0x8941bb84, + 0x465d2303, 0x076c381a, 0xc43f1531, 0x850e0e28, + 0x42984f67, 0x03a9547e, 0xc0fa7955, 0x81cb624c, + 0x1fc53881, 0x5ef42398, 0x9da70eb3, 0xdc9615aa, + 0x1b0054e5, 0x5a314ffc, 0x996262d7, 0xd85379ce, + 0x174fe149, 0x567efa50, 0x952dd77b, 0xd41ccc62, + 0x138a8d2d, 0x52bb9634, 0x91e8bb1f, 0xd0d9a006, + 0xecf37e5e, 0xadc26547, 0x6e91486c, 0x2fa05375, + 0xe836123a, 0xa9070923, 0x6a542408, 0x2b653f11, + 0xe479a796, 0xa548bc8f, 0x661b91a4, 0x272a8abd, + 0xe0bccbf2, 0xa18dd0eb, 0x62defdc0, 0x23efe6d9, + 0xbde1bc14, 0xfcd0a70d, 0x3f838a26, 0x7eb2913f, + 0xb924d070, 0xf815cb69, 0x3b46e642, 0x7a77fd5b, + 0xb56b65dc, 0xf45a7ec5, 0x370953ee, 0x763848f7, + 0xb1ae09b8, 0xf09f12a1, 0x33cc3f8a, 0x72fd2493 + },{ + 0x00000000, 0x376ac201, 0x6ed48403, 0x59be4602, + 0xdca80907, 0xebc2cb06, 0xb27c8d04, 0x85164f05, + 0xb851130e, 0x8f3bd10f, 0xd685970d, 0xe1ef550c, + 0x64f91a09, 0x5393d808, 0x0a2d9e0a, 0x3d475c0b, + 0x70a3261c, 0x47c9e41d, 0x1e77a21f, 0x291d601e, + 0xac0b2f1b, 0x9b61ed1a, 0xc2dfab18, 0xf5b56919, + 0xc8f23512, 0xff98f713, 0xa626b111, 0x914c7310, + 0x145a3c15, 0x2330fe14, 0x7a8eb816, 0x4de47a17, + 0xe0464d38, 0xd72c8f39, 0x8e92c93b, 0xb9f80b3a, + 0x3cee443f, 0x0b84863e, 0x523ac03c, 0x6550023d, + 0x58175e36, 0x6f7d9c37, 0x36c3da35, 0x01a91834, + 0x84bf5731, 0xb3d59530, 0xea6bd332, 0xdd011133, + 0x90e56b24, 0xa78fa925, 0xfe31ef27, 0xc95b2d26, + 0x4c4d6223, 0x7b27a022, 0x2299e620, 0x15f32421, + 0x28b4782a, 0x1fdeba2b, 0x4660fc29, 0x710a3e28, + 0xf41c712d, 0xc376b32c, 0x9ac8f52e, 0xada2372f, + 0xc08d9a70, 0xf7e75871, 0xae591e73, 0x9933dc72, + 0x1c259377, 0x2b4f5176, 0x72f11774, 0x459bd575, + 0x78dc897e, 0x4fb64b7f, 0x16080d7d, 0x2162cf7c, + 0xa4748079, 0x931e4278, 0xcaa0047a, 0xfdcac67b, + 0xb02ebc6c, 0x87447e6d, 0xdefa386f, 0xe990fa6e, + 0x6c86b56b, 0x5bec776a, 0x02523168, 0x3538f369, + 0x087faf62, 0x3f156d63, 0x66ab2b61, 0x51c1e960, + 0xd4d7a665, 0xe3bd6464, 0xba032266, 0x8d69e067, + 0x20cbd748, 0x17a11549, 0x4e1f534b, 0x7975914a, + 0xfc63de4f, 0xcb091c4e, 0x92b75a4c, 0xa5dd984d, + 0x989ac446, 0xaff00647, 0xf64e4045, 0xc1248244, + 0x4432cd41, 0x73580f40, 0x2ae64942, 0x1d8c8b43, + 0x5068f154, 0x67023355, 0x3ebc7557, 0x09d6b756, + 0x8cc0f853, 0xbbaa3a52, 0xe2147c50, 0xd57ebe51, + 0xe839e25a, 0xdf53205b, 0x86ed6659, 0xb187a458, + 0x3491eb5d, 0x03fb295c, 0x5a456f5e, 0x6d2fad5f, + 0x801b35e1, 0xb771f7e0, 0xeecfb1e2, 0xd9a573e3, + 0x5cb33ce6, 0x6bd9fee7, 0x3267b8e5, 0x050d7ae4, + 0x384a26ef, 0x0f20e4ee, 0x569ea2ec, 0x61f460ed, + 0xe4e22fe8, 0xd388ede9, 0x8a36abeb, 0xbd5c69ea, + 0xf0b813fd, 0xc7d2d1fc, 0x9e6c97fe, 0xa90655ff, + 0x2c101afa, 0x1b7ad8fb, 0x42c49ef9, 0x75ae5cf8, + 0x48e900f3, 0x7f83c2f2, 0x263d84f0, 0x115746f1, + 0x944109f4, 0xa32bcbf5, 0xfa958df7, 0xcdff4ff6, + 0x605d78d9, 0x5737bad8, 0x0e89fcda, 0x39e33edb, + 0xbcf571de, 0x8b9fb3df, 0xd221f5dd, 0xe54b37dc, + 0xd80c6bd7, 0xef66a9d6, 0xb6d8efd4, 0x81b22dd5, + 0x04a462d0, 0x33cea0d1, 0x6a70e6d3, 0x5d1a24d2, + 0x10fe5ec5, 0x27949cc4, 0x7e2adac6, 0x494018c7, + 0xcc5657c2, 0xfb3c95c3, 0xa282d3c1, 0x95e811c0, + 0xa8af4dcb, 0x9fc58fca, 0xc67bc9c8, 0xf1110bc9, + 0x740744cc, 0x436d86cd, 0x1ad3c0cf, 0x2db902ce, + 0x4096af91, 0x77fc6d90, 0x2e422b92, 0x1928e993, + 0x9c3ea696, 0xab546497, 0xf2ea2295, 0xc580e094, + 0xf8c7bc9f, 0xcfad7e9e, 0x9613389c, 0xa179fa9d, + 0x246fb598, 0x13057799, 0x4abb319b, 0x7dd1f39a, + 0x3035898d, 0x075f4b8c, 0x5ee10d8e, 0x698bcf8f, + 0xec9d808a, 0xdbf7428b, 0x82490489, 0xb523c688, + 0x88649a83, 0xbf0e5882, 0xe6b01e80, 0xd1dadc81, + 0x54cc9384, 0x63a65185, 0x3a181787, 0x0d72d586, + 0xa0d0e2a9, 0x97ba20a8, 0xce0466aa, 0xf96ea4ab, + 0x7c78ebae, 0x4b1229af, 0x12ac6fad, 0x25c6adac, + 0x1881f1a7, 0x2feb33a6, 0x765575a4, 0x413fb7a5, + 0xc429f8a0, 0xf3433aa1, 0xaafd7ca3, 0x9d97bea2, + 0xd073c4b5, 0xe71906b4, 0xbea740b6, 0x89cd82b7, + 0x0cdbcdb2, 0x3bb10fb3, 0x620f49b1, 0x55658bb0, + 0x6822d7bb, 0x5f4815ba, 0x06f653b8, 0x319c91b9, + 0xb48adebc, 0x83e01cbd, 0xda5e5abf, 0xed3498be + },{ + 0x00000000, 0x6567bcb8, 0x8bc809aa, 0xeeafb512, + 0x5797628f, 0x32f0de37, 0xdc5f6b25, 0xb938d79d, + 0xef28b4c5, 0x8a4f087d, 0x64e0bd6f, 0x018701d7, + 0xb8bfd64a, 0xddd86af2, 0x3377dfe0, 0x56106358, + 0x9f571950, 0xfa30a5e8, 0x149f10fa, 0x71f8ac42, + 0xc8c07bdf, 0xada7c767, 0x43087275, 0x266fcecd, + 0x707fad95, 0x1518112d, 0xfbb7a43f, 0x9ed01887, + 0x27e8cf1a, 0x428f73a2, 0xac20c6b0, 0xc9477a08, + 0x3eaf32a0, 0x5bc88e18, 0xb5673b0a, 0xd00087b2, + 0x6938502f, 0x0c5fec97, 0xe2f05985, 0x8797e53d, + 0xd1878665, 0xb4e03add, 0x5a4f8fcf, 0x3f283377, + 0x8610e4ea, 0xe3775852, 0x0dd8ed40, 0x68bf51f8, + 0xa1f82bf0, 0xc49f9748, 0x2a30225a, 0x4f579ee2, + 0xf66f497f, 0x9308f5c7, 0x7da740d5, 0x18c0fc6d, + 0x4ed09f35, 0x2bb7238d, 0xc518969f, 0xa07f2a27, + 0x1947fdba, 0x7c204102, 0x928ff410, 0xf7e848a8, + 0x3d58149b, 0x583fa823, 0xb6901d31, 0xd3f7a189, + 0x6acf7614, 0x0fa8caac, 0xe1077fbe, 0x8460c306, + 0xd270a05e, 0xb7171ce6, 0x59b8a9f4, 0x3cdf154c, + 0x85e7c2d1, 0xe0807e69, 0x0e2fcb7b, 0x6b4877c3, + 0xa20f0dcb, 0xc768b173, 0x29c70461, 0x4ca0b8d9, + 0xf5986f44, 0x90ffd3fc, 0x7e5066ee, 0x1b37da56, + 0x4d27b90e, 0x284005b6, 0xc6efb0a4, 0xa3880c1c, + 0x1ab0db81, 0x7fd76739, 0x9178d22b, 0xf41f6e93, + 0x03f7263b, 0x66909a83, 0x883f2f91, 0xed589329, + 0x546044b4, 0x3107f80c, 0xdfa84d1e, 0xbacff1a6, + 0xecdf92fe, 0x89b82e46, 0x67179b54, 0x027027ec, + 0xbb48f071, 0xde2f4cc9, 0x3080f9db, 0x55e74563, + 0x9ca03f6b, 0xf9c783d3, 0x176836c1, 0x720f8a79, + 0xcb375de4, 0xae50e15c, 0x40ff544e, 0x2598e8f6, + 0x73888bae, 0x16ef3716, 0xf8408204, 0x9d273ebc, + 0x241fe921, 0x41785599, 0xafd7e08b, 0xcab05c33, + 0x3bb659ed, 0x5ed1e555, 0xb07e5047, 0xd519ecff, + 0x6c213b62, 0x094687da, 0xe7e932c8, 0x828e8e70, + 0xd49eed28, 0xb1f95190, 0x5f56e482, 0x3a31583a, + 0x83098fa7, 0xe66e331f, 0x08c1860d, 0x6da63ab5, + 0xa4e140bd, 0xc186fc05, 0x2f294917, 0x4a4ef5af, + 0xf3762232, 0x96119e8a, 0x78be2b98, 0x1dd99720, + 0x4bc9f478, 0x2eae48c0, 0xc001fdd2, 0xa566416a, + 0x1c5e96f7, 0x79392a4f, 0x97969f5d, 0xf2f123e5, + 0x05196b4d, 0x607ed7f5, 0x8ed162e7, 0xebb6de5f, + 0x528e09c2, 0x37e9b57a, 0xd9460068, 0xbc21bcd0, + 0xea31df88, 0x8f566330, 0x61f9d622, 0x049e6a9a, + 0xbda6bd07, 0xd8c101bf, 0x366eb4ad, 0x53090815, + 0x9a4e721d, 0xff29cea5, 0x11867bb7, 0x74e1c70f, + 0xcdd91092, 0xa8beac2a, 0x46111938, 0x2376a580, + 0x7566c6d8, 0x10017a60, 0xfeaecf72, 0x9bc973ca, + 0x22f1a457, 0x479618ef, 0xa939adfd, 0xcc5e1145, + 0x06ee4d76, 0x6389f1ce, 0x8d2644dc, 0xe841f864, + 0x51792ff9, 0x341e9341, 0xdab12653, 0xbfd69aeb, + 0xe9c6f9b3, 0x8ca1450b, 0x620ef019, 0x07694ca1, + 0xbe519b3c, 0xdb362784, 0x35999296, 0x50fe2e2e, + 0x99b95426, 0xfcdee89e, 0x12715d8c, 0x7716e134, + 0xce2e36a9, 0xab498a11, 0x45e63f03, 0x208183bb, + 0x7691e0e3, 0x13f65c5b, 0xfd59e949, 0x983e55f1, + 0x2106826c, 0x44613ed4, 0xaace8bc6, 0xcfa9377e, + 0x38417fd6, 0x5d26c36e, 0xb389767c, 0xd6eecac4, + 0x6fd61d59, 0x0ab1a1e1, 0xe41e14f3, 0x8179a84b, + 0xd769cb13, 0xb20e77ab, 0x5ca1c2b9, 0x39c67e01, + 0x80fea99c, 0xe5991524, 0x0b36a036, 0x6e511c8e, + 0xa7166686, 0xc271da3e, 0x2cde6f2c, 0x49b9d394, + 0xf0810409, 0x95e6b8b1, 0x7b490da3, 0x1e2eb11b, + 0x483ed243, 0x2d596efb, 0xc3f6dbe9, 0xa6916751, + 0x1fa9b0cc, 0x7ace0c74, 0x9461b966, 0xf10605de + },{ + 0x00000000, 0xb029603d, 0x6053c07a, 0xd07aa047, + 0xc0a680f5, 0x708fe0c8, 0xa0f5408f, 0x10dc20b2, + 0xc14b7030, 0x7162100d, 0xa118b04a, 0x1131d077, + 0x01edf0c5, 0xb1c490f8, 0x61be30bf, 0xd1975082, + 0x8297e060, 0x32be805d, 0xe2c4201a, 0x52ed4027, + 0x42316095, 0xf21800a8, 0x2262a0ef, 0x924bc0d2, + 0x43dc9050, 0xf3f5f06d, 0x238f502a, 0x93a63017, + 0x837a10a5, 0x33537098, 0xe329d0df, 0x5300b0e2, + 0x042fc1c1, 0xb406a1fc, 0x647c01bb, 0xd4556186, + 0xc4894134, 0x74a02109, 0xa4da814e, 0x14f3e173, + 0xc564b1f1, 0x754dd1cc, 0xa537718b, 0x151e11b6, + 0x05c23104, 0xb5eb5139, 0x6591f17e, 0xd5b89143, + 0x86b821a1, 0x3691419c, 0xe6ebe1db, 0x56c281e6, + 0x461ea154, 0xf637c169, 0x264d612e, 0x96640113, + 0x47f35191, 0xf7da31ac, 0x27a091eb, 0x9789f1d6, + 0x8755d164, 0x377cb159, 0xe706111e, 0x572f7123, + 0x4958f358, 0xf9719365, 0x290b3322, 0x9922531f, + 0x89fe73ad, 0x39d71390, 0xe9adb3d7, 0x5984d3ea, + 0x88138368, 0x383ae355, 0xe8404312, 0x5869232f, + 0x48b5039d, 0xf89c63a0, 0x28e6c3e7, 0x98cfa3da, + 0xcbcf1338, 0x7be67305, 0xab9cd342, 0x1bb5b37f, + 0x0b6993cd, 0xbb40f3f0, 0x6b3a53b7, 0xdb13338a, + 0x0a846308, 0xbaad0335, 0x6ad7a372, 0xdafec34f, + 0xca22e3fd, 0x7a0b83c0, 0xaa712387, 0x1a5843ba, + 0x4d773299, 0xfd5e52a4, 0x2d24f2e3, 0x9d0d92de, + 0x8dd1b26c, 0x3df8d251, 0xed827216, 0x5dab122b, + 0x8c3c42a9, 0x3c152294, 0xec6f82d3, 0x5c46e2ee, + 0x4c9ac25c, 0xfcb3a261, 0x2cc90226, 0x9ce0621b, + 0xcfe0d2f9, 0x7fc9b2c4, 0xafb31283, 0x1f9a72be, + 0x0f46520c, 0xbf6f3231, 0x6f159276, 0xdf3cf24b, + 0x0eaba2c9, 0xbe82c2f4, 0x6ef862b3, 0xded1028e, + 0xce0d223c, 0x7e244201, 0xae5ee246, 0x1e77827b, + 0x92b0e6b1, 0x2299868c, 0xf2e326cb, 0x42ca46f6, + 0x52166644, 0xe23f0679, 0x3245a63e, 0x826cc603, + 0x53fb9681, 0xe3d2f6bc, 0x33a856fb, 0x838136c6, + 0x935d1674, 0x23747649, 0xf30ed60e, 0x4327b633, + 0x102706d1, 0xa00e66ec, 0x7074c6ab, 0xc05da696, + 0xd0818624, 0x60a8e619, 0xb0d2465e, 0x00fb2663, + 0xd16c76e1, 0x614516dc, 0xb13fb69b, 0x0116d6a6, + 0x11caf614, 0xa1e39629, 0x7199366e, 0xc1b05653, + 0x969f2770, 0x26b6474d, 0xf6cce70a, 0x46e58737, + 0x5639a785, 0xe610c7b8, 0x366a67ff, 0x864307c2, + 0x57d45740, 0xe7fd377d, 0x3787973a, 0x87aef707, + 0x9772d7b5, 0x275bb788, 0xf72117cf, 0x470877f2, + 0x1408c710, 0xa421a72d, 0x745b076a, 0xc4726757, + 0xd4ae47e5, 0x648727d8, 0xb4fd879f, 0x04d4e7a2, + 0xd543b720, 0x656ad71d, 0xb510775a, 0x05391767, + 0x15e537d5, 0xa5cc57e8, 0x75b6f7af, 0xc59f9792, + 0xdbe815e9, 0x6bc175d4, 0xbbbbd593, 0x0b92b5ae, + 0x1b4e951c, 0xab67f521, 0x7b1d5566, 0xcb34355b, + 0x1aa365d9, 0xaa8a05e4, 0x7af0a5a3, 0xcad9c59e, + 0xda05e52c, 0x6a2c8511, 0xba562556, 0x0a7f456b, + 0x597ff589, 0xe95695b4, 0x392c35f3, 0x890555ce, + 0x99d9757c, 0x29f01541, 0xf98ab506, 0x49a3d53b, + 0x983485b9, 0x281de584, 0xf86745c3, 0x484e25fe, + 0x5892054c, 0xe8bb6571, 0x38c1c536, 0x88e8a50b, + 0xdfc7d428, 0x6feeb415, 0xbf941452, 0x0fbd746f, + 0x1f6154dd, 0xaf4834e0, 0x7f3294a7, 0xcf1bf49a, + 0x1e8ca418, 0xaea5c425, 0x7edf6462, 0xcef6045f, + 0xde2a24ed, 0x6e0344d0, 0xbe79e497, 0x0e5084aa, + 0x5d503448, 0xed795475, 0x3d03f432, 0x8d2a940f, + 0x9df6b4bd, 0x2ddfd480, 0xfda574c7, 0x4d8c14fa, + 0x9c1b4478, 0x2c322445, 0xfc488402, 0x4c61e43f, + 0x5cbdc48d, 0xec94a4b0, 0x3cee04f7, 0x8cc764ca + },{ + 0x00000000, 0xa5d35ccb, 0x0ba1c84d, 0xae729486, + 0x1642919b, 0xb391cd50, 0x1de359d6, 0xb830051d, + 0x6d8253ec, 0xc8510f27, 0x66239ba1, 0xc3f0c76a, + 0x7bc0c277, 0xde139ebc, 0x70610a3a, 0xd5b256f1, + 0x9b02d603, 0x3ed18ac8, 0x90a31e4e, 0x35704285, + 0x8d404798, 0x28931b53, 0x86e18fd5, 0x2332d31e, + 0xf68085ef, 0x5353d924, 0xfd214da2, 0x58f21169, + 0xe0c21474, 0x451148bf, 0xeb63dc39, 0x4eb080f2, + 0x3605ac07, 0x93d6f0cc, 0x3da4644a, 0x98773881, + 0x20473d9c, 0x85946157, 0x2be6f5d1, 0x8e35a91a, + 0x5b87ffeb, 0xfe54a320, 0x502637a6, 0xf5f56b6d, + 0x4dc56e70, 0xe81632bb, 0x4664a63d, 0xe3b7faf6, + 0xad077a04, 0x08d426cf, 0xa6a6b249, 0x0375ee82, + 0xbb45eb9f, 0x1e96b754, 0xb0e423d2, 0x15377f19, + 0xc08529e8, 0x65567523, 0xcb24e1a5, 0x6ef7bd6e, + 0xd6c7b873, 0x7314e4b8, 0xdd66703e, 0x78b52cf5, + 0x6c0a580f, 0xc9d904c4, 0x67ab9042, 0xc278cc89, + 0x7a48c994, 0xdf9b955f, 0x71e901d9, 0xd43a5d12, + 0x01880be3, 0xa45b5728, 0x0a29c3ae, 0xaffa9f65, + 0x17ca9a78, 0xb219c6b3, 0x1c6b5235, 0xb9b80efe, + 0xf7088e0c, 0x52dbd2c7, 0xfca94641, 0x597a1a8a, + 0xe14a1f97, 0x4499435c, 0xeaebd7da, 0x4f388b11, + 0x9a8adde0, 0x3f59812b, 0x912b15ad, 0x34f84966, + 0x8cc84c7b, 0x291b10b0, 0x87698436, 0x22bad8fd, + 0x5a0ff408, 0xffdca8c3, 0x51ae3c45, 0xf47d608e, + 0x4c4d6593, 0xe99e3958, 0x47ecadde, 0xe23ff115, + 0x378da7e4, 0x925efb2f, 0x3c2c6fa9, 0x99ff3362, + 0x21cf367f, 0x841c6ab4, 0x2a6efe32, 0x8fbda2f9, + 0xc10d220b, 0x64de7ec0, 0xcaacea46, 0x6f7fb68d, + 0xd74fb390, 0x729cef5b, 0xdcee7bdd, 0x793d2716, + 0xac8f71e7, 0x095c2d2c, 0xa72eb9aa, 0x02fde561, + 0xbacde07c, 0x1f1ebcb7, 0xb16c2831, 0x14bf74fa, + 0xd814b01e, 0x7dc7ecd5, 0xd3b57853, 0x76662498, + 0xce562185, 0x6b857d4e, 0xc5f7e9c8, 0x6024b503, + 0xb596e3f2, 0x1045bf39, 0xbe372bbf, 0x1be47774, + 0xa3d47269, 0x06072ea2, 0xa875ba24, 0x0da6e6ef, + 0x4316661d, 0xe6c53ad6, 0x48b7ae50, 0xed64f29b, + 0x5554f786, 0xf087ab4d, 0x5ef53fcb, 0xfb266300, + 0x2e9435f1, 0x8b47693a, 0x2535fdbc, 0x80e6a177, + 0x38d6a46a, 0x9d05f8a1, 0x33776c27, 0x96a430ec, + 0xee111c19, 0x4bc240d2, 0xe5b0d454, 0x4063889f, + 0xf8538d82, 0x5d80d149, 0xf3f245cf, 0x56211904, + 0x83934ff5, 0x2640133e, 0x883287b8, 0x2de1db73, + 0x95d1de6e, 0x300282a5, 0x9e701623, 0x3ba34ae8, + 0x7513ca1a, 0xd0c096d1, 0x7eb20257, 0xdb615e9c, + 0x63515b81, 0xc682074a, 0x68f093cc, 0xcd23cf07, + 0x189199f6, 0xbd42c53d, 0x133051bb, 0xb6e30d70, + 0x0ed3086d, 0xab0054a6, 0x0572c020, 0xa0a19ceb, + 0xb41ee811, 0x11cdb4da, 0xbfbf205c, 0x1a6c7c97, + 0xa25c798a, 0x078f2541, 0xa9fdb1c7, 0x0c2eed0c, + 0xd99cbbfd, 0x7c4fe736, 0xd23d73b0, 0x77ee2f7b, + 0xcfde2a66, 0x6a0d76ad, 0xc47fe22b, 0x61acbee0, + 0x2f1c3e12, 0x8acf62d9, 0x24bdf65f, 0x816eaa94, + 0x395eaf89, 0x9c8df342, 0x32ff67c4, 0x972c3b0f, + 0x429e6dfe, 0xe74d3135, 0x493fa5b3, 0xececf978, + 0x54dcfc65, 0xf10fa0ae, 0x5f7d3428, 0xfaae68e3, + 0x821b4416, 0x27c818dd, 0x89ba8c5b, 0x2c69d090, + 0x9459d58d, 0x318a8946, 0x9ff81dc0, 0x3a2b410b, + 0xef9917fa, 0x4a4a4b31, 0xe438dfb7, 0x41eb837c, + 0xf9db8661, 0x5c08daaa, 0xf27a4e2c, 0x57a912e7, + 0x19199215, 0xbccacede, 0x12b85a58, 0xb76b0693, + 0x0f5b038e, 0xaa885f45, 0x04facbc3, 0xa1299708, + 0x749bc1f9, 0xd1489d32, 0x7f3a09b4, 0xdae9557f, + 0x62d95062, 0xc70a0ca9, 0x6978982f, 0xccabc4e4 + },{ + 0x00000000, 0xb40b77a6, 0x29119f97, 0x9d1ae831, + 0x13244ff4, 0xa72f3852, 0x3a35d063, 0x8e3ea7c5, + 0x674eef33, 0xd3459895, 0x4e5f70a4, 0xfa540702, + 0x746aa0c7, 0xc061d761, 0x5d7b3f50, 0xe97048f6, + 0xce9cde67, 0x7a97a9c1, 0xe78d41f0, 0x53863656, + 0xddb89193, 0x69b3e635, 0xf4a90e04, 0x40a279a2, + 0xa9d23154, 0x1dd946f2, 0x80c3aec3, 0x34c8d965, + 0xbaf67ea0, 0x0efd0906, 0x93e7e137, 0x27ec9691, + 0x9c39bdcf, 0x2832ca69, 0xb5282258, 0x012355fe, + 0x8f1df23b, 0x3b16859d, 0xa60c6dac, 0x12071a0a, + 0xfb7752fc, 0x4f7c255a, 0xd266cd6b, 0x666dbacd, + 0xe8531d08, 0x5c586aae, 0xc142829f, 0x7549f539, + 0x52a563a8, 0xe6ae140e, 0x7bb4fc3f, 0xcfbf8b99, + 0x41812c5c, 0xf58a5bfa, 0x6890b3cb, 0xdc9bc46d, + 0x35eb8c9b, 0x81e0fb3d, 0x1cfa130c, 0xa8f164aa, + 0x26cfc36f, 0x92c4b4c9, 0x0fde5cf8, 0xbbd52b5e, + 0x79750b44, 0xcd7e7ce2, 0x506494d3, 0xe46fe375, + 0x6a5144b0, 0xde5a3316, 0x4340db27, 0xf74bac81, + 0x1e3be477, 0xaa3093d1, 0x372a7be0, 0x83210c46, + 0x0d1fab83, 0xb914dc25, 0x240e3414, 0x900543b2, + 0xb7e9d523, 0x03e2a285, 0x9ef84ab4, 0x2af33d12, + 0xa4cd9ad7, 0x10c6ed71, 0x8ddc0540, 0x39d772e6, + 0xd0a73a10, 0x64ac4db6, 0xf9b6a587, 0x4dbdd221, + 0xc38375e4, 0x77880242, 0xea92ea73, 0x5e999dd5, + 0xe54cb68b, 0x5147c12d, 0xcc5d291c, 0x78565eba, + 0xf668f97f, 0x42638ed9, 0xdf7966e8, 0x6b72114e, + 0x820259b8, 0x36092e1e, 0xab13c62f, 0x1f18b189, + 0x9126164c, 0x252d61ea, 0xb83789db, 0x0c3cfe7d, + 0x2bd068ec, 0x9fdb1f4a, 0x02c1f77b, 0xb6ca80dd, + 0x38f42718, 0x8cff50be, 0x11e5b88f, 0xa5eecf29, + 0x4c9e87df, 0xf895f079, 0x658f1848, 0xd1846fee, + 0x5fbac82b, 0xebb1bf8d, 0x76ab57bc, 0xc2a0201a, + 0xf2ea1688, 0x46e1612e, 0xdbfb891f, 0x6ff0feb9, + 0xe1ce597c, 0x55c52eda, 0xc8dfc6eb, 0x7cd4b14d, + 0x95a4f9bb, 0x21af8e1d, 0xbcb5662c, 0x08be118a, + 0x8680b64f, 0x328bc1e9, 0xaf9129d8, 0x1b9a5e7e, + 0x3c76c8ef, 0x887dbf49, 0x15675778, 0xa16c20de, + 0x2f52871b, 0x9b59f0bd, 0x0643188c, 0xb2486f2a, + 0x5b3827dc, 0xef33507a, 0x7229b84b, 0xc622cfed, + 0x481c6828, 0xfc171f8e, 0x610df7bf, 0xd5068019, + 0x6ed3ab47, 0xdad8dce1, 0x47c234d0, 0xf3c94376, + 0x7df7e4b3, 0xc9fc9315, 0x54e67b24, 0xe0ed0c82, + 0x099d4474, 0xbd9633d2, 0x208cdbe3, 0x9487ac45, + 0x1ab90b80, 0xaeb27c26, 0x33a89417, 0x87a3e3b1, + 0xa04f7520, 0x14440286, 0x895eeab7, 0x3d559d11, + 0xb36b3ad4, 0x07604d72, 0x9a7aa543, 0x2e71d2e5, + 0xc7019a13, 0x730aedb5, 0xee100584, 0x5a1b7222, + 0xd425d5e7, 0x602ea241, 0xfd344a70, 0x493f3dd6, + 0x8b9f1dcc, 0x3f946a6a, 0xa28e825b, 0x1685f5fd, + 0x98bb5238, 0x2cb0259e, 0xb1aacdaf, 0x05a1ba09, + 0xecd1f2ff, 0x58da8559, 0xc5c06d68, 0x71cb1ace, + 0xfff5bd0b, 0x4bfecaad, 0xd6e4229c, 0x62ef553a, + 0x4503c3ab, 0xf108b40d, 0x6c125c3c, 0xd8192b9a, + 0x56278c5f, 0xe22cfbf9, 0x7f3613c8, 0xcb3d646e, + 0x224d2c98, 0x96465b3e, 0x0b5cb30f, 0xbf57c4a9, + 0x3169636c, 0x856214ca, 0x1878fcfb, 0xac738b5d, + 0x17a6a003, 0xa3add7a5, 0x3eb73f94, 0x8abc4832, + 0x0482eff7, 0xb0899851, 0x2d937060, 0x999807c6, + 0x70e84f30, 0xc4e33896, 0x59f9d0a7, 0xedf2a701, + 0x63cc00c4, 0xd7c77762, 0x4add9f53, 0xfed6e8f5, + 0xd93a7e64, 0x6d3109c2, 0xf02be1f3, 0x44209655, + 0xca1e3190, 0x7e154636, 0xe30fae07, 0x5704d9a1, + 0xbe749157, 0x0a7fe6f1, 0x97650ec0, 0x236e7966, + 0xad50dea3, 0x195ba905, 0x84414134, 0x304a3692 + },{ + 0x00000000, 0x9e00aacc, 0x7d072542, 0xe3078f8e, + 0xfa0e4a84, 0x640ee048, 0x87096fc6, 0x1909c50a, + 0xb51be5d3, 0x2b1b4f1f, 0xc81cc091, 0x561c6a5d, + 0x4f15af57, 0xd115059b, 0x32128a15, 0xac1220d9, + 0x2b31bb7c, 0xb53111b0, 0x56369e3e, 0xc83634f2, + 0xd13ff1f8, 0x4f3f5b34, 0xac38d4ba, 0x32387e76, + 0x9e2a5eaf, 0x002af463, 0xe32d7bed, 0x7d2dd121, + 0x6424142b, 0xfa24bee7, 0x19233169, 0x87239ba5, + 0x566276f9, 0xc862dc35, 0x2b6553bb, 0xb565f977, + 0xac6c3c7d, 0x326c96b1, 0xd16b193f, 0x4f6bb3f3, + 0xe379932a, 0x7d7939e6, 0x9e7eb668, 0x007e1ca4, + 0x1977d9ae, 0x87777362, 0x6470fcec, 0xfa705620, + 0x7d53cd85, 0xe3536749, 0x0054e8c7, 0x9e54420b, + 0x875d8701, 0x195d2dcd, 0xfa5aa243, 0x645a088f, + 0xc8482856, 0x5648829a, 0xb54f0d14, 0x2b4fa7d8, + 0x324662d2, 0xac46c81e, 0x4f414790, 0xd141ed5c, + 0xedc29d29, 0x73c237e5, 0x90c5b86b, 0x0ec512a7, + 0x17ccd7ad, 0x89cc7d61, 0x6acbf2ef, 0xf4cb5823, + 0x58d978fa, 0xc6d9d236, 0x25de5db8, 0xbbdef774, + 0xa2d7327e, 0x3cd798b2, 0xdfd0173c, 0x41d0bdf0, + 0xc6f32655, 0x58f38c99, 0xbbf40317, 0x25f4a9db, + 0x3cfd6cd1, 0xa2fdc61d, 0x41fa4993, 0xdffae35f, + 0x73e8c386, 0xede8694a, 0x0eefe6c4, 0x90ef4c08, + 0x89e68902, 0x17e623ce, 0xf4e1ac40, 0x6ae1068c, + 0xbba0ebd0, 0x25a0411c, 0xc6a7ce92, 0x58a7645e, + 0x41aea154, 0xdfae0b98, 0x3ca98416, 0xa2a92eda, + 0x0ebb0e03, 0x90bba4cf, 0x73bc2b41, 0xedbc818d, + 0xf4b54487, 0x6ab5ee4b, 0x89b261c5, 0x17b2cb09, + 0x909150ac, 0x0e91fa60, 0xed9675ee, 0x7396df22, + 0x6a9f1a28, 0xf49fb0e4, 0x17983f6a, 0x899895a6, + 0x258ab57f, 0xbb8a1fb3, 0x588d903d, 0xc68d3af1, + 0xdf84fffb, 0x41845537, 0xa283dab9, 0x3c837075, + 0xda853b53, 0x4485919f, 0xa7821e11, 0x3982b4dd, + 0x208b71d7, 0xbe8bdb1b, 0x5d8c5495, 0xc38cfe59, + 0x6f9ede80, 0xf19e744c, 0x1299fbc2, 0x8c99510e, + 0x95909404, 0x0b903ec8, 0xe897b146, 0x76971b8a, + 0xf1b4802f, 0x6fb42ae3, 0x8cb3a56d, 0x12b30fa1, + 0x0bbacaab, 0x95ba6067, 0x76bdefe9, 0xe8bd4525, + 0x44af65fc, 0xdaafcf30, 0x39a840be, 0xa7a8ea72, + 0xbea12f78, 0x20a185b4, 0xc3a60a3a, 0x5da6a0f6, + 0x8ce74daa, 0x12e7e766, 0xf1e068e8, 0x6fe0c224, + 0x76e9072e, 0xe8e9ade2, 0x0bee226c, 0x95ee88a0, + 0x39fca879, 0xa7fc02b5, 0x44fb8d3b, 0xdafb27f7, + 0xc3f2e2fd, 0x5df24831, 0xbef5c7bf, 0x20f56d73, + 0xa7d6f6d6, 0x39d65c1a, 0xdad1d394, 0x44d17958, + 0x5dd8bc52, 0xc3d8169e, 0x20df9910, 0xbedf33dc, + 0x12cd1305, 0x8ccdb9c9, 0x6fca3647, 0xf1ca9c8b, + 0xe8c35981, 0x76c3f34d, 0x95c47cc3, 0x0bc4d60f, + 0x3747a67a, 0xa9470cb6, 0x4a408338, 0xd44029f4, + 0xcd49ecfe, 0x53494632, 0xb04ec9bc, 0x2e4e6370, + 0x825c43a9, 0x1c5ce965, 0xff5b66eb, 0x615bcc27, + 0x7852092d, 0xe652a3e1, 0x05552c6f, 0x9b5586a3, + 0x1c761d06, 0x8276b7ca, 0x61713844, 0xff719288, + 0xe6785782, 0x7878fd4e, 0x9b7f72c0, 0x057fd80c, + 0xa96df8d5, 0x376d5219, 0xd46add97, 0x4a6a775b, + 0x5363b251, 0xcd63189d, 0x2e649713, 0xb0643ddf, + 0x6125d083, 0xff257a4f, 0x1c22f5c1, 0x82225f0d, + 0x9b2b9a07, 0x052b30cb, 0xe62cbf45, 0x782c1589, + 0xd43e3550, 0x4a3e9f9c, 0xa9391012, 0x3739bade, + 0x2e307fd4, 0xb030d518, 0x53375a96, 0xcd37f05a, + 0x4a146bff, 0xd414c133, 0x37134ebd, 0xa913e471, + 0xb01a217b, 0x2e1a8bb7, 0xcd1d0439, 0x531daef5, + 0xff0f8e2c, 0x610f24e0, 0x8208ab6e, 0x1c0801a2, + 0x0501c4a8, 0x9b016e64, 0x7806e1ea, 0xe6064b26 + } +}; + +static const unsigned int __attribute__((aligned(128))) crc32table_be[8][256] = { + { + 0x00000000, 0x04c11db7, 0x09823b6e, 0x0d4326d9, + 0x130476dc, 0x17c56b6b, 0x1a864db2, 0x1e475005, + 0x2608edb8, 0x22c9f00f, 0x2f8ad6d6, 0x2b4bcb61, + 0x350c9b64, 0x31cd86d3, 0x3c8ea00a, 0x384fbdbd, + 0x4c11db70, 0x48d0c6c7, 0x4593e01e, 0x4152fda9, + 0x5f15adac, 0x5bd4b01b, 0x569796c2, 0x52568b75, + 0x6a1936c8, 0x6ed82b7f, 0x639b0da6, 0x675a1011, + 0x791d4014, 0x7ddc5da3, 0x709f7b7a, 0x745e66cd, + 0x9823b6e0, 0x9ce2ab57, 0x91a18d8e, 0x95609039, + 0x8b27c03c, 0x8fe6dd8b, 0x82a5fb52, 0x8664e6e5, + 0xbe2b5b58, 0xbaea46ef, 0xb7a96036, 0xb3687d81, + 0xad2f2d84, 0xa9ee3033, 0xa4ad16ea, 0xa06c0b5d, + 0xd4326d90, 0xd0f37027, 0xddb056fe, 0xd9714b49, + 0xc7361b4c, 0xc3f706fb, 0xceb42022, 0xca753d95, + 0xf23a8028, 0xf6fb9d9f, 0xfbb8bb46, 0xff79a6f1, + 0xe13ef6f4, 0xe5ffeb43, 0xe8bccd9a, 0xec7dd02d, + 0x34867077, 0x30476dc0, 0x3d044b19, 0x39c556ae, + 0x278206ab, 0x23431b1c, 0x2e003dc5, 0x2ac12072, + 0x128e9dcf, 0x164f8078, 0x1b0ca6a1, 0x1fcdbb16, + 0x018aeb13, 0x054bf6a4, 0x0808d07d, 0x0cc9cdca, + 0x7897ab07, 0x7c56b6b0, 0x71159069, 0x75d48dde, + 0x6b93dddb, 0x6f52c06c, 0x6211e6b5, 0x66d0fb02, + 0x5e9f46bf, 0x5a5e5b08, 0x571d7dd1, 0x53dc6066, + 0x4d9b3063, 0x495a2dd4, 0x44190b0d, 0x40d816ba, + 0xaca5c697, 0xa864db20, 0xa527fdf9, 0xa1e6e04e, + 0xbfa1b04b, 0xbb60adfc, 0xb6238b25, 0xb2e29692, + 0x8aad2b2f, 0x8e6c3698, 0x832f1041, 0x87ee0df6, + 0x99a95df3, 0x9d684044, 0x902b669d, 0x94ea7b2a, + 0xe0b41de7, 0xe4750050, 0xe9362689, 0xedf73b3e, + 0xf3b06b3b, 0xf771768c, 0xfa325055, 0xfef34de2, + 0xc6bcf05f, 0xc27dede8, 0xcf3ecb31, 0xcbffd686, + 0xd5b88683, 0xd1799b34, 0xdc3abded, 0xd8fba05a, + 0x690ce0ee, 0x6dcdfd59, 0x608edb80, 0x644fc637, + 0x7a089632, 0x7ec98b85, 0x738aad5c, 0x774bb0eb, + 0x4f040d56, 0x4bc510e1, 0x46863638, 0x42472b8f, + 0x5c007b8a, 0x58c1663d, 0x558240e4, 0x51435d53, + 0x251d3b9e, 0x21dc2629, 0x2c9f00f0, 0x285e1d47, + 0x36194d42, 0x32d850f5, 0x3f9b762c, 0x3b5a6b9b, + 0x0315d626, 0x07d4cb91, 0x0a97ed48, 0x0e56f0ff, + 0x1011a0fa, 0x14d0bd4d, 0x19939b94, 0x1d528623, + 0xf12f560e, 0xf5ee4bb9, 0xf8ad6d60, 0xfc6c70d7, + 0xe22b20d2, 0xe6ea3d65, 0xeba91bbc, 0xef68060b, + 0xd727bbb6, 0xd3e6a601, 0xdea580d8, 0xda649d6f, + 0xc423cd6a, 0xc0e2d0dd, 0xcda1f604, 0xc960ebb3, + 0xbd3e8d7e, 0xb9ff90c9, 0xb4bcb610, 0xb07daba7, + 0xae3afba2, 0xaafbe615, 0xa7b8c0cc, 0xa379dd7b, + 0x9b3660c6, 0x9ff77d71, 0x92b45ba8, 0x9675461f, + 0x8832161a, 0x8cf30bad, 0x81b02d74, 0x857130c3, + 0x5d8a9099, 0x594b8d2e, 0x5408abf7, 0x50c9b640, + 0x4e8ee645, 0x4a4ffbf2, 0x470cdd2b, 0x43cdc09c, + 0x7b827d21, 0x7f436096, 0x7200464f, 0x76c15bf8, + 0x68860bfd, 0x6c47164a, 0x61043093, 0x65c52d24, + 0x119b4be9, 0x155a565e, 0x18197087, 0x1cd86d30, + 0x029f3d35, 0x065e2082, 0x0b1d065b, 0x0fdc1bec, + 0x3793a651, 0x3352bbe6, 0x3e119d3f, 0x3ad08088, + 0x2497d08d, 0x2056cd3a, 0x2d15ebe3, 0x29d4f654, + 0xc5a92679, 0xc1683bce, 0xcc2b1d17, 0xc8ea00a0, + 0xd6ad50a5, 0xd26c4d12, 0xdf2f6bcb, 0xdbee767c, + 0xe3a1cbc1, 0xe760d676, 0xea23f0af, 0xeee2ed18, + 0xf0a5bd1d, 0xf464a0aa, 0xf9278673, 0xfde69bc4, + 0x89b8fd09, 0x8d79e0be, 0x803ac667, 0x84fbdbd0, + 0x9abc8bd5, 0x9e7d9662, 0x933eb0bb, 0x97ffad0c, + 0xafb010b1, 0xab710d06, 0xa6322bdf, 0xa2f33668, + 0xbcb4666d, 0xb8757bda, 0xb5365d03, 0xb1f740b4 + },{ + 0x00000000, 0xd219c1dc, 0xa0f29e0f, 0x72eb5fd3, + 0x452421a9, 0x973de075, 0xe5d6bfa6, 0x37cf7e7a, + 0x8a484352, 0x5851828e, 0x2abadd5d, 0xf8a31c81, + 0xcf6c62fb, 0x1d75a327, 0x6f9efcf4, 0xbd873d28, + 0x10519b13, 0xc2485acf, 0xb0a3051c, 0x62bac4c0, + 0x5575baba, 0x876c7b66, 0xf58724b5, 0x279ee569, + 0x9a19d841, 0x4800199d, 0x3aeb464e, 0xe8f28792, + 0xdf3df9e8, 0x0d243834, 0x7fcf67e7, 0xadd6a63b, + 0x20a33626, 0xf2baf7fa, 0x8051a829, 0x524869f5, + 0x6587178f, 0xb79ed653, 0xc5758980, 0x176c485c, + 0xaaeb7574, 0x78f2b4a8, 0x0a19eb7b, 0xd8002aa7, + 0xefcf54dd, 0x3dd69501, 0x4f3dcad2, 0x9d240b0e, + 0x30f2ad35, 0xe2eb6ce9, 0x9000333a, 0x4219f2e6, + 0x75d68c9c, 0xa7cf4d40, 0xd5241293, 0x073dd34f, + 0xbabaee67, 0x68a32fbb, 0x1a487068, 0xc851b1b4, + 0xff9ecfce, 0x2d870e12, 0x5f6c51c1, 0x8d75901d, + 0x41466c4c, 0x935fad90, 0xe1b4f243, 0x33ad339f, + 0x04624de5, 0xd67b8c39, 0xa490d3ea, 0x76891236, + 0xcb0e2f1e, 0x1917eec2, 0x6bfcb111, 0xb9e570cd, + 0x8e2a0eb7, 0x5c33cf6b, 0x2ed890b8, 0xfcc15164, + 0x5117f75f, 0x830e3683, 0xf1e56950, 0x23fca88c, + 0x1433d6f6, 0xc62a172a, 0xb4c148f9, 0x66d88925, + 0xdb5fb40d, 0x094675d1, 0x7bad2a02, 0xa9b4ebde, + 0x9e7b95a4, 0x4c625478, 0x3e890bab, 0xec90ca77, + 0x61e55a6a, 0xb3fc9bb6, 0xc117c465, 0x130e05b9, + 0x24c17bc3, 0xf6d8ba1f, 0x8433e5cc, 0x562a2410, + 0xebad1938, 0x39b4d8e4, 0x4b5f8737, 0x994646eb, + 0xae893891, 0x7c90f94d, 0x0e7ba69e, 0xdc626742, + 0x71b4c179, 0xa3ad00a5, 0xd1465f76, 0x035f9eaa, + 0x3490e0d0, 0xe689210c, 0x94627edf, 0x467bbf03, + 0xfbfc822b, 0x29e543f7, 0x5b0e1c24, 0x8917ddf8, + 0xbed8a382, 0x6cc1625e, 0x1e2a3d8d, 0xcc33fc51, + 0x828cd898, 0x50951944, 0x227e4697, 0xf067874b, + 0xc7a8f931, 0x15b138ed, 0x675a673e, 0xb543a6e2, + 0x08c49bca, 0xdadd5a16, 0xa83605c5, 0x7a2fc419, + 0x4de0ba63, 0x9ff97bbf, 0xed12246c, 0x3f0be5b0, + 0x92dd438b, 0x40c48257, 0x322fdd84, 0xe0361c58, + 0xd7f96222, 0x05e0a3fe, 0x770bfc2d, 0xa5123df1, + 0x189500d9, 0xca8cc105, 0xb8679ed6, 0x6a7e5f0a, + 0x5db12170, 0x8fa8e0ac, 0xfd43bf7f, 0x2f5a7ea3, + 0xa22feebe, 0x70362f62, 0x02dd70b1, 0xd0c4b16d, + 0xe70bcf17, 0x35120ecb, 0x47f95118, 0x95e090c4, + 0x2867adec, 0xfa7e6c30, 0x889533e3, 0x5a8cf23f, + 0x6d438c45, 0xbf5a4d99, 0xcdb1124a, 0x1fa8d396, + 0xb27e75ad, 0x6067b471, 0x128ceba2, 0xc0952a7e, + 0xf75a5404, 0x254395d8, 0x57a8ca0b, 0x85b10bd7, + 0x383636ff, 0xea2ff723, 0x98c4a8f0, 0x4add692c, + 0x7d121756, 0xaf0bd68a, 0xdde08959, 0x0ff94885, + 0xc3cab4d4, 0x11d37508, 0x63382adb, 0xb121eb07, + 0x86ee957d, 0x54f754a1, 0x261c0b72, 0xf405caae, + 0x4982f786, 0x9b9b365a, 0xe9706989, 0x3b69a855, + 0x0ca6d62f, 0xdebf17f3, 0xac544820, 0x7e4d89fc, + 0xd39b2fc7, 0x0182ee1b, 0x7369b1c8, 0xa1707014, + 0x96bf0e6e, 0x44a6cfb2, 0x364d9061, 0xe45451bd, + 0x59d36c95, 0x8bcaad49, 0xf921f29a, 0x2b383346, + 0x1cf74d3c, 0xceee8ce0, 0xbc05d333, 0x6e1c12ef, + 0xe36982f2, 0x3170432e, 0x439b1cfd, 0x9182dd21, + 0xa64da35b, 0x74546287, 0x06bf3d54, 0xd4a6fc88, + 0x6921c1a0, 0xbb38007c, 0xc9d35faf, 0x1bca9e73, + 0x2c05e009, 0xfe1c21d5, 0x8cf77e06, 0x5eeebfda, + 0xf33819e1, 0x2121d83d, 0x53ca87ee, 0x81d34632, + 0xb61c3848, 0x6405f994, 0x16eea647, 0xc4f7679b, + 0x79705ab3, 0xab699b6f, 0xd982c4bc, 0x0b9b0560, + 0x3c547b1a, 0xee4dbac6, 0x9ca6e515, 0x4ebf24c9 + },{ + 0x00000000, 0x01d8ac87, 0x03b1590e, 0x0269f589, + 0x0762b21c, 0x06ba1e9b, 0x04d3eb12, 0x050b4795, + 0x0ec56438, 0x0f1dc8bf, 0x0d743d36, 0x0cac91b1, + 0x09a7d624, 0x087f7aa3, 0x0a168f2a, 0x0bce23ad, + 0x1d8ac870, 0x1c5264f7, 0x1e3b917e, 0x1fe33df9, + 0x1ae87a6c, 0x1b30d6eb, 0x19592362, 0x18818fe5, + 0x134fac48, 0x129700cf, 0x10fef546, 0x112659c1, + 0x142d1e54, 0x15f5b2d3, 0x179c475a, 0x1644ebdd, + 0x3b1590e0, 0x3acd3c67, 0x38a4c9ee, 0x397c6569, + 0x3c7722fc, 0x3daf8e7b, 0x3fc67bf2, 0x3e1ed775, + 0x35d0f4d8, 0x3408585f, 0x3661add6, 0x37b90151, + 0x32b246c4, 0x336aea43, 0x31031fca, 0x30dbb34d, + 0x269f5890, 0x2747f417, 0x252e019e, 0x24f6ad19, + 0x21fdea8c, 0x2025460b, 0x224cb382, 0x23941f05, + 0x285a3ca8, 0x2982902f, 0x2beb65a6, 0x2a33c921, + 0x2f388eb4, 0x2ee02233, 0x2c89d7ba, 0x2d517b3d, + 0x762b21c0, 0x77f38d47, 0x759a78ce, 0x7442d449, + 0x714993dc, 0x70913f5b, 0x72f8cad2, 0x73206655, + 0x78ee45f8, 0x7936e97f, 0x7b5f1cf6, 0x7a87b071, + 0x7f8cf7e4, 0x7e545b63, 0x7c3daeea, 0x7de5026d, + 0x6ba1e9b0, 0x6a794537, 0x6810b0be, 0x69c81c39, + 0x6cc35bac, 0x6d1bf72b, 0x6f7202a2, 0x6eaaae25, + 0x65648d88, 0x64bc210f, 0x66d5d486, 0x670d7801, + 0x62063f94, 0x63de9313, 0x61b7669a, 0x606fca1d, + 0x4d3eb120, 0x4ce61da7, 0x4e8fe82e, 0x4f5744a9, + 0x4a5c033c, 0x4b84afbb, 0x49ed5a32, 0x4835f6b5, + 0x43fbd518, 0x4223799f, 0x404a8c16, 0x41922091, + 0x44996704, 0x4541cb83, 0x47283e0a, 0x46f0928d, + 0x50b47950, 0x516cd5d7, 0x5305205e, 0x52dd8cd9, + 0x57d6cb4c, 0x560e67cb, 0x54679242, 0x55bf3ec5, + 0x5e711d68, 0x5fa9b1ef, 0x5dc04466, 0x5c18e8e1, + 0x5913af74, 0x58cb03f3, 0x5aa2f67a, 0x5b7a5afd, + 0xec564380, 0xed8eef07, 0xefe71a8e, 0xee3fb609, + 0xeb34f19c, 0xeaec5d1b, 0xe885a892, 0xe95d0415, + 0xe29327b8, 0xe34b8b3f, 0xe1227eb6, 0xe0fad231, + 0xe5f195a4, 0xe4293923, 0xe640ccaa, 0xe798602d, + 0xf1dc8bf0, 0xf0042777, 0xf26dd2fe, 0xf3b57e79, + 0xf6be39ec, 0xf766956b, 0xf50f60e2, 0xf4d7cc65, + 0xff19efc8, 0xfec1434f, 0xfca8b6c6, 0xfd701a41, + 0xf87b5dd4, 0xf9a3f153, 0xfbca04da, 0xfa12a85d, + 0xd743d360, 0xd69b7fe7, 0xd4f28a6e, 0xd52a26e9, + 0xd021617c, 0xd1f9cdfb, 0xd3903872, 0xd24894f5, + 0xd986b758, 0xd85e1bdf, 0xda37ee56, 0xdbef42d1, + 0xdee40544, 0xdf3ca9c3, 0xdd555c4a, 0xdc8df0cd, + 0xcac91b10, 0xcb11b797, 0xc978421e, 0xc8a0ee99, + 0xcdaba90c, 0xcc73058b, 0xce1af002, 0xcfc25c85, + 0xc40c7f28, 0xc5d4d3af, 0xc7bd2626, 0xc6658aa1, + 0xc36ecd34, 0xc2b661b3, 0xc0df943a, 0xc10738bd, + 0x9a7d6240, 0x9ba5cec7, 0x99cc3b4e, 0x981497c9, + 0x9d1fd05c, 0x9cc77cdb, 0x9eae8952, 0x9f7625d5, + 0x94b80678, 0x9560aaff, 0x97095f76, 0x96d1f3f1, + 0x93dab464, 0x920218e3, 0x906bed6a, 0x91b341ed, + 0x87f7aa30, 0x862f06b7, 0x8446f33e, 0x859e5fb9, + 0x8095182c, 0x814db4ab, 0x83244122, 0x82fceda5, + 0x8932ce08, 0x88ea628f, 0x8a839706, 0x8b5b3b81, + 0x8e507c14, 0x8f88d093, 0x8de1251a, 0x8c39899d, + 0xa168f2a0, 0xa0b05e27, 0xa2d9abae, 0xa3010729, + 0xa60a40bc, 0xa7d2ec3b, 0xa5bb19b2, 0xa463b535, + 0xafad9698, 0xae753a1f, 0xac1ccf96, 0xadc46311, + 0xa8cf2484, 0xa9178803, 0xab7e7d8a, 0xaaa6d10d, + 0xbce23ad0, 0xbd3a9657, 0xbf5363de, 0xbe8bcf59, + 0xbb8088cc, 0xba58244b, 0xb831d1c2, 0xb9e97d45, + 0xb2275ee8, 0xb3fff26f, 0xb19607e6, 0xb04eab61, + 0xb545ecf4, 0xb49d4073, 0xb6f4b5fa, 0xb72c197d + },{ + 0x00000000, 0xdc6d9ab7, 0xbc1a28d9, 0x6077b26e, + 0x7cf54c05, 0xa098d6b2, 0xc0ef64dc, 0x1c82fe6b, + 0xf9ea980a, 0x258702bd, 0x45f0b0d3, 0x999d2a64, + 0x851fd40f, 0x59724eb8, 0x3905fcd6, 0xe5686661, + 0xf7142da3, 0x2b79b714, 0x4b0e057a, 0x97639fcd, + 0x8be161a6, 0x578cfb11, 0x37fb497f, 0xeb96d3c8, + 0x0efeb5a9, 0xd2932f1e, 0xb2e49d70, 0x6e8907c7, + 0x720bf9ac, 0xae66631b, 0xce11d175, 0x127c4bc2, + 0xeae946f1, 0x3684dc46, 0x56f36e28, 0x8a9ef49f, + 0x961c0af4, 0x4a719043, 0x2a06222d, 0xf66bb89a, + 0x1303defb, 0xcf6e444c, 0xaf19f622, 0x73746c95, + 0x6ff692fe, 0xb39b0849, 0xd3ecba27, 0x0f812090, + 0x1dfd6b52, 0xc190f1e5, 0xa1e7438b, 0x7d8ad93c, + 0x61082757, 0xbd65bde0, 0xdd120f8e, 0x017f9539, + 0xe417f358, 0x387a69ef, 0x580ddb81, 0x84604136, + 0x98e2bf5d, 0x448f25ea, 0x24f89784, 0xf8950d33, + 0xd1139055, 0x0d7e0ae2, 0x6d09b88c, 0xb164223b, + 0xade6dc50, 0x718b46e7, 0x11fcf489, 0xcd916e3e, + 0x28f9085f, 0xf49492e8, 0x94e32086, 0x488eba31, + 0x540c445a, 0x8861deed, 0xe8166c83, 0x347bf634, + 0x2607bdf6, 0xfa6a2741, 0x9a1d952f, 0x46700f98, + 0x5af2f1f3, 0x869f6b44, 0xe6e8d92a, 0x3a85439d, + 0xdfed25fc, 0x0380bf4b, 0x63f70d25, 0xbf9a9792, + 0xa31869f9, 0x7f75f34e, 0x1f024120, 0xc36fdb97, + 0x3bfad6a4, 0xe7974c13, 0x87e0fe7d, 0x5b8d64ca, + 0x470f9aa1, 0x9b620016, 0xfb15b278, 0x277828cf, + 0xc2104eae, 0x1e7dd419, 0x7e0a6677, 0xa267fcc0, + 0xbee502ab, 0x6288981c, 0x02ff2a72, 0xde92b0c5, + 0xcceefb07, 0x108361b0, 0x70f4d3de, 0xac994969, + 0xb01bb702, 0x6c762db5, 0x0c019fdb, 0xd06c056c, + 0x3504630d, 0xe969f9ba, 0x891e4bd4, 0x5573d163, + 0x49f12f08, 0x959cb5bf, 0xf5eb07d1, 0x29869d66, + 0xa6e63d1d, 0x7a8ba7aa, 0x1afc15c4, 0xc6918f73, + 0xda137118, 0x067eebaf, 0x660959c1, 0xba64c376, + 0x5f0ca517, 0x83613fa0, 0xe3168dce, 0x3f7b1779, + 0x23f9e912, 0xff9473a5, 0x9fe3c1cb, 0x438e5b7c, + 0x51f210be, 0x8d9f8a09, 0xede83867, 0x3185a2d0, + 0x2d075cbb, 0xf16ac60c, 0x911d7462, 0x4d70eed5, + 0xa81888b4, 0x74751203, 0x1402a06d, 0xc86f3ada, + 0xd4edc4b1, 0x08805e06, 0x68f7ec68, 0xb49a76df, + 0x4c0f7bec, 0x9062e15b, 0xf0155335, 0x2c78c982, + 0x30fa37e9, 0xec97ad5e, 0x8ce01f30, 0x508d8587, + 0xb5e5e3e6, 0x69887951, 0x09ffcb3f, 0xd5925188, + 0xc910afe3, 0x157d3554, 0x750a873a, 0xa9671d8d, + 0xbb1b564f, 0x6776ccf8, 0x07017e96, 0xdb6ce421, + 0xc7ee1a4a, 0x1b8380fd, 0x7bf43293, 0xa799a824, + 0x42f1ce45, 0x9e9c54f2, 0xfeebe69c, 0x22867c2b, + 0x3e048240, 0xe26918f7, 0x821eaa99, 0x5e73302e, + 0x77f5ad48, 0xab9837ff, 0xcbef8591, 0x17821f26, + 0x0b00e14d, 0xd76d7bfa, 0xb71ac994, 0x6b775323, + 0x8e1f3542, 0x5272aff5, 0x32051d9b, 0xee68872c, + 0xf2ea7947, 0x2e87e3f0, 0x4ef0519e, 0x929dcb29, + 0x80e180eb, 0x5c8c1a5c, 0x3cfba832, 0xe0963285, + 0xfc14ccee, 0x20795659, 0x400ee437, 0x9c637e80, + 0x790b18e1, 0xa5668256, 0xc5113038, 0x197caa8f, + 0x05fe54e4, 0xd993ce53, 0xb9e47c3d, 0x6589e68a, + 0x9d1cebb9, 0x4171710e, 0x2106c360, 0xfd6b59d7, + 0xe1e9a7bc, 0x3d843d0b, 0x5df38f65, 0x819e15d2, + 0x64f673b3, 0xb89be904, 0xd8ec5b6a, 0x0481c1dd, + 0x18033fb6, 0xc46ea501, 0xa419176f, 0x78748dd8, + 0x6a08c61a, 0xb6655cad, 0xd612eec3, 0x0a7f7474, + 0x16fd8a1f, 0xca9010a8, 0xaae7a2c6, 0x768a3871, + 0x93e25e10, 0x4f8fc4a7, 0x2ff876c9, 0xf395ec7e, + 0xef171215, 0x337a88a2, 0x530d3acc, 0x8f60a07b + },{ + 0x00000000, 0x490d678d, 0x921acf1a, 0xdb17a897, + 0x20f48383, 0x69f9e40e, 0xb2ee4c99, 0xfbe32b14, + 0x41e90706, 0x08e4608b, 0xd3f3c81c, 0x9afeaf91, + 0x611d8485, 0x2810e308, 0xf3074b9f, 0xba0a2c12, + 0x83d20e0c, 0xcadf6981, 0x11c8c116, 0x58c5a69b, + 0xa3268d8f, 0xea2bea02, 0x313c4295, 0x78312518, + 0xc23b090a, 0x8b366e87, 0x5021c610, 0x192ca19d, + 0xe2cf8a89, 0xabc2ed04, 0x70d54593, 0x39d8221e, + 0x036501af, 0x4a686622, 0x917fceb5, 0xd872a938, + 0x2391822c, 0x6a9ce5a1, 0xb18b4d36, 0xf8862abb, + 0x428c06a9, 0x0b816124, 0xd096c9b3, 0x999bae3e, + 0x6278852a, 0x2b75e2a7, 0xf0624a30, 0xb96f2dbd, + 0x80b70fa3, 0xc9ba682e, 0x12adc0b9, 0x5ba0a734, + 0xa0438c20, 0xe94eebad, 0x3259433a, 0x7b5424b7, + 0xc15e08a5, 0x88536f28, 0x5344c7bf, 0x1a49a032, + 0xe1aa8b26, 0xa8a7ecab, 0x73b0443c, 0x3abd23b1, + 0x06ca035e, 0x4fc764d3, 0x94d0cc44, 0xddddabc9, + 0x263e80dd, 0x6f33e750, 0xb4244fc7, 0xfd29284a, + 0x47230458, 0x0e2e63d5, 0xd539cb42, 0x9c34accf, + 0x67d787db, 0x2edae056, 0xf5cd48c1, 0xbcc02f4c, + 0x85180d52, 0xcc156adf, 0x1702c248, 0x5e0fa5c5, + 0xa5ec8ed1, 0xece1e95c, 0x37f641cb, 0x7efb2646, + 0xc4f10a54, 0x8dfc6dd9, 0x56ebc54e, 0x1fe6a2c3, + 0xe40589d7, 0xad08ee5a, 0x761f46cd, 0x3f122140, + 0x05af02f1, 0x4ca2657c, 0x97b5cdeb, 0xdeb8aa66, + 0x255b8172, 0x6c56e6ff, 0xb7414e68, 0xfe4c29e5, + 0x444605f7, 0x0d4b627a, 0xd65ccaed, 0x9f51ad60, + 0x64b28674, 0x2dbfe1f9, 0xf6a8496e, 0xbfa52ee3, + 0x867d0cfd, 0xcf706b70, 0x1467c3e7, 0x5d6aa46a, + 0xa6898f7e, 0xef84e8f3, 0x34934064, 0x7d9e27e9, + 0xc7940bfb, 0x8e996c76, 0x558ec4e1, 0x1c83a36c, + 0xe7608878, 0xae6deff5, 0x757a4762, 0x3c7720ef, + 0x0d9406bc, 0x44996131, 0x9f8ec9a6, 0xd683ae2b, + 0x2d60853f, 0x646de2b2, 0xbf7a4a25, 0xf6772da8, + 0x4c7d01ba, 0x05706637, 0xde67cea0, 0x976aa92d, + 0x6c898239, 0x2584e5b4, 0xfe934d23, 0xb79e2aae, + 0x8e4608b0, 0xc74b6f3d, 0x1c5cc7aa, 0x5551a027, + 0xaeb28b33, 0xe7bfecbe, 0x3ca84429, 0x75a523a4, + 0xcfaf0fb6, 0x86a2683b, 0x5db5c0ac, 0x14b8a721, + 0xef5b8c35, 0xa656ebb8, 0x7d41432f, 0x344c24a2, + 0x0ef10713, 0x47fc609e, 0x9cebc809, 0xd5e6af84, + 0x2e058490, 0x6708e31d, 0xbc1f4b8a, 0xf5122c07, + 0x4f180015, 0x06156798, 0xdd02cf0f, 0x940fa882, + 0x6fec8396, 0x26e1e41b, 0xfdf64c8c, 0xb4fb2b01, + 0x8d23091f, 0xc42e6e92, 0x1f39c605, 0x5634a188, + 0xadd78a9c, 0xe4daed11, 0x3fcd4586, 0x76c0220b, + 0xccca0e19, 0x85c76994, 0x5ed0c103, 0x17dda68e, + 0xec3e8d9a, 0xa533ea17, 0x7e244280, 0x3729250d, + 0x0b5e05e2, 0x4253626f, 0x9944caf8, 0xd049ad75, + 0x2baa8661, 0x62a7e1ec, 0xb9b0497b, 0xf0bd2ef6, + 0x4ab702e4, 0x03ba6569, 0xd8adcdfe, 0x91a0aa73, + 0x6a438167, 0x234ee6ea, 0xf8594e7d, 0xb15429f0, + 0x888c0bee, 0xc1816c63, 0x1a96c4f4, 0x539ba379, + 0xa878886d, 0xe175efe0, 0x3a624777, 0x736f20fa, + 0xc9650ce8, 0x80686b65, 0x5b7fc3f2, 0x1272a47f, + 0xe9918f6b, 0xa09ce8e6, 0x7b8b4071, 0x328627fc, + 0x083b044d, 0x413663c0, 0x9a21cb57, 0xd32cacda, + 0x28cf87ce, 0x61c2e043, 0xbad548d4, 0xf3d82f59, + 0x49d2034b, 0x00df64c6, 0xdbc8cc51, 0x92c5abdc, + 0x692680c8, 0x202be745, 0xfb3c4fd2, 0xb231285f, + 0x8be90a41, 0xc2e46dcc, 0x19f3c55b, 0x50fea2d6, + 0xab1d89c2, 0xe210ee4f, 0x390746d8, 0x700a2155, + 0xca000d47, 0x830d6aca, 0x581ac25d, 0x1117a5d0, + 0xeaf48ec4, 0xa3f9e949, 0x78ee41de, 0x31e32653 + },{ + 0x00000000, 0x1b280d78, 0x36501af0, 0x2d781788, + 0x6ca035e0, 0x77883898, 0x5af02f10, 0x41d82268, + 0xd9406bc0, 0xc26866b8, 0xef107130, 0xf4387c48, + 0xb5e05e20, 0xaec85358, 0x83b044d0, 0x989849a8, + 0xb641ca37, 0xad69c74f, 0x8011d0c7, 0x9b39ddbf, + 0xdae1ffd7, 0xc1c9f2af, 0xecb1e527, 0xf799e85f, + 0x6f01a1f7, 0x7429ac8f, 0x5951bb07, 0x4279b67f, + 0x03a19417, 0x1889996f, 0x35f18ee7, 0x2ed9839f, + 0x684289d9, 0x736a84a1, 0x5e129329, 0x453a9e51, + 0x04e2bc39, 0x1fcab141, 0x32b2a6c9, 0x299aabb1, + 0xb102e219, 0xaa2aef61, 0x8752f8e9, 0x9c7af591, + 0xdda2d7f9, 0xc68ada81, 0xebf2cd09, 0xf0dac071, + 0xde0343ee, 0xc52b4e96, 0xe853591e, 0xf37b5466, + 0xb2a3760e, 0xa98b7b76, 0x84f36cfe, 0x9fdb6186, + 0x0743282e, 0x1c6b2556, 0x311332de, 0x2a3b3fa6, + 0x6be31dce, 0x70cb10b6, 0x5db3073e, 0x469b0a46, + 0xd08513b2, 0xcbad1eca, 0xe6d50942, 0xfdfd043a, + 0xbc252652, 0xa70d2b2a, 0x8a753ca2, 0x915d31da, + 0x09c57872, 0x12ed750a, 0x3f956282, 0x24bd6ffa, + 0x65654d92, 0x7e4d40ea, 0x53355762, 0x481d5a1a, + 0x66c4d985, 0x7decd4fd, 0x5094c375, 0x4bbcce0d, + 0x0a64ec65, 0x114ce11d, 0x3c34f695, 0x271cfbed, + 0xbf84b245, 0xa4acbf3d, 0x89d4a8b5, 0x92fca5cd, + 0xd32487a5, 0xc80c8add, 0xe5749d55, 0xfe5c902d, + 0xb8c79a6b, 0xa3ef9713, 0x8e97809b, 0x95bf8de3, + 0xd467af8b, 0xcf4fa2f3, 0xe237b57b, 0xf91fb803, + 0x6187f1ab, 0x7aaffcd3, 0x57d7eb5b, 0x4cffe623, + 0x0d27c44b, 0x160fc933, 0x3b77debb, 0x205fd3c3, + 0x0e86505c, 0x15ae5d24, 0x38d64aac, 0x23fe47d4, + 0x622665bc, 0x790e68c4, 0x54767f4c, 0x4f5e7234, + 0xd7c63b9c, 0xccee36e4, 0xe196216c, 0xfabe2c14, + 0xbb660e7c, 0xa04e0304, 0x8d36148c, 0x961e19f4, + 0xa5cb3ad3, 0xbee337ab, 0x939b2023, 0x88b32d5b, + 0xc96b0f33, 0xd243024b, 0xff3b15c3, 0xe41318bb, + 0x7c8b5113, 0x67a35c6b, 0x4adb4be3, 0x51f3469b, + 0x102b64f3, 0x0b03698b, 0x267b7e03, 0x3d53737b, + 0x138af0e4, 0x08a2fd9c, 0x25daea14, 0x3ef2e76c, + 0x7f2ac504, 0x6402c87c, 0x497adff4, 0x5252d28c, + 0xcaca9b24, 0xd1e2965c, 0xfc9a81d4, 0xe7b28cac, + 0xa66aaec4, 0xbd42a3bc, 0x903ab434, 0x8b12b94c, + 0xcd89b30a, 0xd6a1be72, 0xfbd9a9fa, 0xe0f1a482, + 0xa12986ea, 0xba018b92, 0x97799c1a, 0x8c519162, + 0x14c9d8ca, 0x0fe1d5b2, 0x2299c23a, 0x39b1cf42, + 0x7869ed2a, 0x6341e052, 0x4e39f7da, 0x5511faa2, + 0x7bc8793d, 0x60e07445, 0x4d9863cd, 0x56b06eb5, + 0x17684cdd, 0x0c4041a5, 0x2138562d, 0x3a105b55, + 0xa28812fd, 0xb9a01f85, 0x94d8080d, 0x8ff00575, + 0xce28271d, 0xd5002a65, 0xf8783ded, 0xe3503095, + 0x754e2961, 0x6e662419, 0x431e3391, 0x58363ee9, + 0x19ee1c81, 0x02c611f9, 0x2fbe0671, 0x34960b09, + 0xac0e42a1, 0xb7264fd9, 0x9a5e5851, 0x81765529, + 0xc0ae7741, 0xdb867a39, 0xf6fe6db1, 0xedd660c9, + 0xc30fe356, 0xd827ee2e, 0xf55ff9a6, 0xee77f4de, + 0xafafd6b6, 0xb487dbce, 0x99ffcc46, 0x82d7c13e, + 0x1a4f8896, 0x016785ee, 0x2c1f9266, 0x37379f1e, + 0x76efbd76, 0x6dc7b00e, 0x40bfa786, 0x5b97aafe, + 0x1d0ca0b8, 0x0624adc0, 0x2b5cba48, 0x3074b730, + 0x71ac9558, 0x6a849820, 0x47fc8fa8, 0x5cd482d0, + 0xc44ccb78, 0xdf64c600, 0xf21cd188, 0xe934dcf0, + 0xa8ecfe98, 0xb3c4f3e0, 0x9ebce468, 0x8594e910, + 0xab4d6a8f, 0xb06567f7, 0x9d1d707f, 0x86357d07, + 0xc7ed5f6f, 0xdcc55217, 0xf1bd459f, 0xea9548e7, + 0x720d014f, 0x69250c37, 0x445d1bbf, 0x5f7516c7, + 0x1ead34af, 0x058539d7, 0x28fd2e5f, 0x33d52327 + },{ + 0x00000000, 0x4f576811, 0x9eaed022, 0xd1f9b833, + 0x399cbdf3, 0x76cbd5e2, 0xa7326dd1, 0xe86505c0, + 0x73397be6, 0x3c6e13f7, 0xed97abc4, 0xa2c0c3d5, + 0x4aa5c615, 0x05f2ae04, 0xd40b1637, 0x9b5c7e26, + 0xe672f7cc, 0xa9259fdd, 0x78dc27ee, 0x378b4fff, + 0xdfee4a3f, 0x90b9222e, 0x41409a1d, 0x0e17f20c, + 0x954b8c2a, 0xda1ce43b, 0x0be55c08, 0x44b23419, + 0xacd731d9, 0xe38059c8, 0x3279e1fb, 0x7d2e89ea, + 0xc824f22f, 0x87739a3e, 0x568a220d, 0x19dd4a1c, + 0xf1b84fdc, 0xbeef27cd, 0x6f169ffe, 0x2041f7ef, + 0xbb1d89c9, 0xf44ae1d8, 0x25b359eb, 0x6ae431fa, + 0x8281343a, 0xcdd65c2b, 0x1c2fe418, 0x53788c09, + 0x2e5605e3, 0x61016df2, 0xb0f8d5c1, 0xffafbdd0, + 0x17cab810, 0x589dd001, 0x89646832, 0xc6330023, + 0x5d6f7e05, 0x12381614, 0xc3c1ae27, 0x8c96c636, + 0x64f3c3f6, 0x2ba4abe7, 0xfa5d13d4, 0xb50a7bc5, + 0x9488f9e9, 0xdbdf91f8, 0x0a2629cb, 0x457141da, + 0xad14441a, 0xe2432c0b, 0x33ba9438, 0x7cedfc29, + 0xe7b1820f, 0xa8e6ea1e, 0x791f522d, 0x36483a3c, + 0xde2d3ffc, 0x917a57ed, 0x4083efde, 0x0fd487cf, + 0x72fa0e25, 0x3dad6634, 0xec54de07, 0xa303b616, + 0x4b66b3d6, 0x0431dbc7, 0xd5c863f4, 0x9a9f0be5, + 0x01c375c3, 0x4e941dd2, 0x9f6da5e1, 0xd03acdf0, + 0x385fc830, 0x7708a021, 0xa6f11812, 0xe9a67003, + 0x5cac0bc6, 0x13fb63d7, 0xc202dbe4, 0x8d55b3f5, + 0x6530b635, 0x2a67de24, 0xfb9e6617, 0xb4c90e06, + 0x2f957020, 0x60c21831, 0xb13ba002, 0xfe6cc813, + 0x1609cdd3, 0x595ea5c2, 0x88a71df1, 0xc7f075e0, + 0xbadefc0a, 0xf589941b, 0x24702c28, 0x6b274439, + 0x834241f9, 0xcc1529e8, 0x1dec91db, 0x52bbf9ca, + 0xc9e787ec, 0x86b0effd, 0x574957ce, 0x181e3fdf, + 0xf07b3a1f, 0xbf2c520e, 0x6ed5ea3d, 0x2182822c, + 0x2dd0ee65, 0x62878674, 0xb37e3e47, 0xfc295656, + 0x144c5396, 0x5b1b3b87, 0x8ae283b4, 0xc5b5eba5, + 0x5ee99583, 0x11befd92, 0xc04745a1, 0x8f102db0, + 0x67752870, 0x28224061, 0xf9dbf852, 0xb68c9043, + 0xcba219a9, 0x84f571b8, 0x550cc98b, 0x1a5ba19a, + 0xf23ea45a, 0xbd69cc4b, 0x6c907478, 0x23c71c69, + 0xb89b624f, 0xf7cc0a5e, 0x2635b26d, 0x6962da7c, + 0x8107dfbc, 0xce50b7ad, 0x1fa90f9e, 0x50fe678f, + 0xe5f41c4a, 0xaaa3745b, 0x7b5acc68, 0x340da479, + 0xdc68a1b9, 0x933fc9a8, 0x42c6719b, 0x0d91198a, + 0x96cd67ac, 0xd99a0fbd, 0x0863b78e, 0x4734df9f, + 0xaf51da5f, 0xe006b24e, 0x31ff0a7d, 0x7ea8626c, + 0x0386eb86, 0x4cd18397, 0x9d283ba4, 0xd27f53b5, + 0x3a1a5675, 0x754d3e64, 0xa4b48657, 0xebe3ee46, + 0x70bf9060, 0x3fe8f871, 0xee114042, 0xa1462853, + 0x49232d93, 0x06744582, 0xd78dfdb1, 0x98da95a0, + 0xb958178c, 0xf60f7f9d, 0x27f6c7ae, 0x68a1afbf, + 0x80c4aa7f, 0xcf93c26e, 0x1e6a7a5d, 0x513d124c, + 0xca616c6a, 0x8536047b, 0x54cfbc48, 0x1b98d459, + 0xf3fdd199, 0xbcaab988, 0x6d5301bb, 0x220469aa, + 0x5f2ae040, 0x107d8851, 0xc1843062, 0x8ed35873, + 0x66b65db3, 0x29e135a2, 0xf8188d91, 0xb74fe580, + 0x2c139ba6, 0x6344f3b7, 0xb2bd4b84, 0xfdea2395, + 0x158f2655, 0x5ad84e44, 0x8b21f677, 0xc4769e66, + 0x717ce5a3, 0x3e2b8db2, 0xefd23581, 0xa0855d90, + 0x48e05850, 0x07b73041, 0xd64e8872, 0x9919e063, + 0x02459e45, 0x4d12f654, 0x9ceb4e67, 0xd3bc2676, + 0x3bd923b6, 0x748e4ba7, 0xa577f394, 0xea209b85, + 0x970e126f, 0xd8597a7e, 0x09a0c24d, 0x46f7aa5c, + 0xae92af9c, 0xe1c5c78d, 0x303c7fbe, 0x7f6b17af, + 0xe4376989, 0xab600198, 0x7a99b9ab, 0x35ced1ba, + 0xddabd47a, 0x92fcbc6b, 0x43050458, 0x0c526c49 + },{ + 0x00000000, 0x5ba1dcca, 0xb743b994, 0xece2655e, + 0x6a466e9f, 0x31e7b255, 0xdd05d70b, 0x86a40bc1, + 0xd48cdd3e, 0x8f2d01f4, 0x63cf64aa, 0x386eb860, + 0xbecab3a1, 0xe56b6f6b, 0x09890a35, 0x5228d6ff, + 0xadd8a7cb, 0xf6797b01, 0x1a9b1e5f, 0x413ac295, + 0xc79ec954, 0x9c3f159e, 0x70dd70c0, 0x2b7cac0a, + 0x79547af5, 0x22f5a63f, 0xce17c361, 0x95b61fab, + 0x1312146a, 0x48b3c8a0, 0xa451adfe, 0xfff07134, + 0x5f705221, 0x04d18eeb, 0xe833ebb5, 0xb392377f, + 0x35363cbe, 0x6e97e074, 0x8275852a, 0xd9d459e0, + 0x8bfc8f1f, 0xd05d53d5, 0x3cbf368b, 0x671eea41, + 0xe1bae180, 0xba1b3d4a, 0x56f95814, 0x0d5884de, + 0xf2a8f5ea, 0xa9092920, 0x45eb4c7e, 0x1e4a90b4, + 0x98ee9b75, 0xc34f47bf, 0x2fad22e1, 0x740cfe2b, + 0x262428d4, 0x7d85f41e, 0x91679140, 0xcac64d8a, + 0x4c62464b, 0x17c39a81, 0xfb21ffdf, 0xa0802315, + 0xbee0a442, 0xe5417888, 0x09a31dd6, 0x5202c11c, + 0xd4a6cadd, 0x8f071617, 0x63e57349, 0x3844af83, + 0x6a6c797c, 0x31cda5b6, 0xdd2fc0e8, 0x868e1c22, + 0x002a17e3, 0x5b8bcb29, 0xb769ae77, 0xecc872bd, + 0x13380389, 0x4899df43, 0xa47bba1d, 0xffda66d7, + 0x797e6d16, 0x22dfb1dc, 0xce3dd482, 0x959c0848, + 0xc7b4deb7, 0x9c15027d, 0x70f76723, 0x2b56bbe9, + 0xadf2b028, 0xf6536ce2, 0x1ab109bc, 0x4110d576, + 0xe190f663, 0xba312aa9, 0x56d34ff7, 0x0d72933d, + 0x8bd698fc, 0xd0774436, 0x3c952168, 0x6734fda2, + 0x351c2b5d, 0x6ebdf797, 0x825f92c9, 0xd9fe4e03, + 0x5f5a45c2, 0x04fb9908, 0xe819fc56, 0xb3b8209c, + 0x4c4851a8, 0x17e98d62, 0xfb0be83c, 0xa0aa34f6, + 0x260e3f37, 0x7dafe3fd, 0x914d86a3, 0xcaec5a69, + 0x98c48c96, 0xc365505c, 0x2f873502, 0x7426e9c8, + 0xf282e209, 0xa9233ec3, 0x45c15b9d, 0x1e608757, + 0x79005533, 0x22a189f9, 0xce43eca7, 0x95e2306d, + 0x13463bac, 0x48e7e766, 0xa4058238, 0xffa45ef2, + 0xad8c880d, 0xf62d54c7, 0x1acf3199, 0x416eed53, + 0xc7cae692, 0x9c6b3a58, 0x70895f06, 0x2b2883cc, + 0xd4d8f2f8, 0x8f792e32, 0x639b4b6c, 0x383a97a6, + 0xbe9e9c67, 0xe53f40ad, 0x09dd25f3, 0x527cf939, + 0x00542fc6, 0x5bf5f30c, 0xb7179652, 0xecb64a98, + 0x6a124159, 0x31b39d93, 0xdd51f8cd, 0x86f02407, + 0x26700712, 0x7dd1dbd8, 0x9133be86, 0xca92624c, + 0x4c36698d, 0x1797b547, 0xfb75d019, 0xa0d40cd3, + 0xf2fcda2c, 0xa95d06e6, 0x45bf63b8, 0x1e1ebf72, + 0x98bab4b3, 0xc31b6879, 0x2ff90d27, 0x7458d1ed, + 0x8ba8a0d9, 0xd0097c13, 0x3ceb194d, 0x674ac587, + 0xe1eece46, 0xba4f128c, 0x56ad77d2, 0x0d0cab18, + 0x5f247de7, 0x0485a12d, 0xe867c473, 0xb3c618b9, + 0x35621378, 0x6ec3cfb2, 0x8221aaec, 0xd9807626, + 0xc7e0f171, 0x9c412dbb, 0x70a348e5, 0x2b02942f, + 0xada69fee, 0xf6074324, 0x1ae5267a, 0x4144fab0, + 0x136c2c4f, 0x48cdf085, 0xa42f95db, 0xff8e4911, + 0x792a42d0, 0x228b9e1a, 0xce69fb44, 0x95c8278e, + 0x6a3856ba, 0x31998a70, 0xdd7bef2e, 0x86da33e4, + 0x007e3825, 0x5bdfe4ef, 0xb73d81b1, 0xec9c5d7b, + 0xbeb48b84, 0xe515574e, 0x09f73210, 0x5256eeda, + 0xd4f2e51b, 0x8f5339d1, 0x63b15c8f, 0x38108045, + 0x9890a350, 0xc3317f9a, 0x2fd31ac4, 0x7472c60e, + 0xf2d6cdcf, 0xa9771105, 0x4595745b, 0x1e34a891, + 0x4c1c7e6e, 0x17bda2a4, 0xfb5fc7fa, 0xa0fe1b30, + 0x265a10f1, 0x7dfbcc3b, 0x9119a965, 0xcab875af, + 0x3548049b, 0x6ee9d851, 0x820bbd0f, 0xd9aa61c5, + 0x5f0e6a04, 0x04afb6ce, 0xe84dd390, 0xb3ec0f5a, + 0xe1c4d9a5, 0xba65056f, 0x56876031, 0x0d26bcfb, + 0x8b82b73a, 0xd0236bf0, 0x3cc10eae, 0x6760d264 + } +}; + +static const unsigned int __attribute__((aligned(128))) crc32ctable_le[8][256] = { + { + 0x00000000, 0x03836bf2, 0xf7703be1, 0xf4f35013, + 0x1f979ac7, 0x1c14f135, 0xe8e7a126, 0xeb64cad4, + 0xcf58d98a, 0xccdbb278, 0x3828e26b, 0x3bab8999, + 0xd0cf434d, 0xd34c28bf, 0x27bf78ac, 0x243c135e, + 0x6fc75e10, 0x6c4435e2, 0x98b765f1, 0x9b340e03, + 0x7050c4d7, 0x73d3af25, 0x8720ff36, 0x84a394c4, + 0xa09f879a, 0xa31cec68, 0x57efbc7b, 0x546cd789, + 0xbf081d5d, 0xbc8b76af, 0x487826bc, 0x4bfb4d4e, + 0xde8ebd20, 0xdd0dd6d2, 0x29fe86c1, 0x2a7ded33, + 0xc11927e7, 0xc29a4c15, 0x36691c06, 0x35ea77f4, + 0x11d664aa, 0x12550f58, 0xe6a65f4b, 0xe52534b9, + 0x0e41fe6d, 0x0dc2959f, 0xf931c58c, 0xfab2ae7e, + 0xb149e330, 0xb2ca88c2, 0x4639d8d1, 0x45bab323, + 0xaede79f7, 0xad5d1205, 0x59ae4216, 0x5a2d29e4, + 0x7e113aba, 0x7d925148, 0x8961015b, 0x8ae26aa9, + 0x6186a07d, 0x6205cb8f, 0x96f69b9c, 0x9575f06e, + 0xbc1d7b41, 0xbf9e10b3, 0x4b6d40a0, 0x48ee2b52, + 0xa38ae186, 0xa0098a74, 0x54fada67, 0x5779b195, + 0x7345a2cb, 0x70c6c939, 0x8435992a, 0x87b6f2d8, + 0x6cd2380c, 0x6f5153fe, 0x9ba203ed, 0x9821681f, + 0xd3da2551, 0xd0594ea3, 0x24aa1eb0, 0x27297542, + 0xcc4dbf96, 0xcfced464, 0x3b3d8477, 0x38beef85, + 0x1c82fcdb, 0x1f019729, 0xebf2c73a, 0xe871acc8, + 0x0315661c, 0x00960dee, 0xf4655dfd, 0xf7e6360f, + 0x6293c661, 0x6110ad93, 0x95e3fd80, 0x96609672, + 0x7d045ca6, 0x7e873754, 0x8a746747, 0x89f70cb5, + 0xadcb1feb, 0xae487419, 0x5abb240a, 0x59384ff8, + 0xb25c852c, 0xb1dfeede, 0x452cbecd, 0x46afd53f, + 0x0d549871, 0x0ed7f383, 0xfa24a390, 0xf9a7c862, + 0x12c302b6, 0x11406944, 0xe5b33957, 0xe63052a5, + 0xc20c41fb, 0xc18f2a09, 0x357c7a1a, 0x36ff11e8, + 0xdd9bdb3c, 0xde18b0ce, 0x2aebe0dd, 0x29688b2f, + 0x783bf682, 0x7bb89d70, 0x8f4bcd63, 0x8cc8a691, + 0x67ac6c45, 0x642f07b7, 0x90dc57a4, 0x935f3c56, + 0xb7632f08, 0xb4e044fa, 0x401314e9, 0x43907f1b, + 0xa8f4b5cf, 0xab77de3d, 0x5f848e2e, 0x5c07e5dc, + 0x17fca892, 0x147fc360, 0xe08c9373, 0xe30ff881, + 0x086b3255, 0x0be859a7, 0xff1b09b4, 0xfc986246, + 0xd8a47118, 0xdb271aea, 0x2fd44af9, 0x2c57210b, + 0xc733ebdf, 0xc4b0802d, 0x3043d03e, 0x33c0bbcc, + 0xa6b54ba2, 0xa5362050, 0x51c57043, 0x52461bb1, + 0xb922d165, 0xbaa1ba97, 0x4e52ea84, 0x4dd18176, + 0x69ed9228, 0x6a6ef9da, 0x9e9da9c9, 0x9d1ec23b, + 0x767a08ef, 0x75f9631d, 0x810a330e, 0x828958fc, + 0xc97215b2, 0xcaf17e40, 0x3e022e53, 0x3d8145a1, + 0xd6e58f75, 0xd566e487, 0x2195b494, 0x2216df66, + 0x062acc38, 0x05a9a7ca, 0xf15af7d9, 0xf2d99c2b, + 0x19bd56ff, 0x1a3e3d0d, 0xeecd6d1e, 0xed4e06ec, + 0xc4268dc3, 0xc7a5e631, 0x3356b622, 0x30d5ddd0, + 0xdbb11704, 0xd8327cf6, 0x2cc12ce5, 0x2f424717, + 0x0b7e5449, 0x08fd3fbb, 0xfc0e6fa8, 0xff8d045a, + 0x14e9ce8e, 0x176aa57c, 0xe399f56f, 0xe01a9e9d, + 0xabe1d3d3, 0xa862b821, 0x5c91e832, 0x5f1283c0, + 0xb4764914, 0xb7f522e6, 0x430672f5, 0x40851907, + 0x64b90a59, 0x673a61ab, 0x93c931b8, 0x904a5a4a, + 0x7b2e909e, 0x78adfb6c, 0x8c5eab7f, 0x8fddc08d, + 0x1aa830e3, 0x192b5b11, 0xedd80b02, 0xee5b60f0, + 0x053faa24, 0x06bcc1d6, 0xf24f91c5, 0xf1ccfa37, + 0xd5f0e969, 0xd673829b, 0x2280d288, 0x2103b97a, + 0xca6773ae, 0xc9e4185c, 0x3d17484f, 0x3e9423bd, + 0x756f6ef3, 0x76ec0501, 0x821f5512, 0x819c3ee0, + 0x6af8f434, 0x697b9fc6, 0x9d88cfd5, 0x9e0ba427, + 0xba37b779, 0xb9b4dc8b, 0x4d478c98, 0x4ec4e76a, + 0xa5a02dbe, 0xa623464c, 0x52d0165f, 0x51537dad + },{ + 0x00000000, 0x7798a213, 0xee304527, 0x99a8e734, + 0xdc618a4e, 0xabf9285d, 0x3251cf69, 0x45c96d7a, + 0xb8c3149d, 0xcf5bb68e, 0x56f351ba, 0x216bf3a9, + 0x64a29ed3, 0x133a3cc0, 0x8a92dbf4, 0xfd0a79e7, + 0x81f1c53f, 0xf669672c, 0x6fc18018, 0x1859220b, + 0x5d904f71, 0x2a08ed62, 0xb3a00a56, 0xc438a845, + 0x3932d1a2, 0x4eaa73b1, 0xd7029485, 0xa09a3696, + 0xe5535bec, 0x92cbf9ff, 0x0b631ecb, 0x7cfbbcd8, + 0x02e38b7f, 0x757b296c, 0xecd3ce58, 0x9b4b6c4b, + 0xde820131, 0xa91aa322, 0x30b24416, 0x472ae605, + 0xba209fe2, 0xcdb83df1, 0x5410dac5, 0x238878d6, + 0x664115ac, 0x11d9b7bf, 0x8871508b, 0xffe9f298, + 0x83124e40, 0xf48aec53, 0x6d220b67, 0x1abaa974, + 0x5f73c40e, 0x28eb661d, 0xb1438129, 0xc6db233a, + 0x3bd15add, 0x4c49f8ce, 0xd5e11ffa, 0xa279bde9, + 0xe7b0d093, 0x90287280, 0x098095b4, 0x7e1837a7, + 0x04c617ff, 0x735eb5ec, 0xeaf652d8, 0x9d6ef0cb, + 0xd8a79db1, 0xaf3f3fa2, 0x3697d896, 0x410f7a85, + 0xbc050362, 0xcb9da171, 0x52354645, 0x25ade456, + 0x6064892c, 0x17fc2b3f, 0x8e54cc0b, 0xf9cc6e18, + 0x8537d2c0, 0xf2af70d3, 0x6b0797e7, 0x1c9f35f4, + 0x5956588e, 0x2ecefa9d, 0xb7661da9, 0xc0febfba, + 0x3df4c65d, 0x4a6c644e, 0xd3c4837a, 0xa45c2169, + 0xe1954c13, 0x960dee00, 0x0fa50934, 0x783dab27, + 0x06259c80, 0x71bd3e93, 0xe815d9a7, 0x9f8d7bb4, + 0xda4416ce, 0xaddcb4dd, 0x347453e9, 0x43ecf1fa, + 0xbee6881d, 0xc97e2a0e, 0x50d6cd3a, 0x274e6f29, + 0x62870253, 0x151fa040, 0x8cb74774, 0xfb2fe567, + 0x87d459bf, 0xf04cfbac, 0x69e41c98, 0x1e7cbe8b, + 0x5bb5d3f1, 0x2c2d71e2, 0xb58596d6, 0xc21d34c5, + 0x3f174d22, 0x488fef31, 0xd1270805, 0xa6bfaa16, + 0xe376c76c, 0x94ee657f, 0x0d46824b, 0x7ade2058, + 0xf9fac3fb, 0x8e6261e8, 0x17ca86dc, 0x605224cf, + 0x259b49b5, 0x5203eba6, 0xcbab0c92, 0xbc33ae81, + 0x4139d766, 0x36a17575, 0xaf099241, 0xd8913052, + 0x9d585d28, 0xeac0ff3b, 0x7368180f, 0x04f0ba1c, + 0x780b06c4, 0x0f93a4d7, 0x963b43e3, 0xe1a3e1f0, + 0xa46a8c8a, 0xd3f22e99, 0x4a5ac9ad, 0x3dc26bbe, + 0xc0c81259, 0xb750b04a, 0x2ef8577e, 0x5960f56d, + 0x1ca99817, 0x6b313a04, 0xf299dd30, 0x85017f23, + 0xfb194884, 0x8c81ea97, 0x15290da3, 0x62b1afb0, + 0x2778c2ca, 0x50e060d9, 0xc94887ed, 0xbed025fe, + 0x43da5c19, 0x3442fe0a, 0xadea193e, 0xda72bb2d, + 0x9fbbd657, 0xe8237444, 0x718b9370, 0x06133163, + 0x7ae88dbb, 0x0d702fa8, 0x94d8c89c, 0xe3406a8f, + 0xa68907f5, 0xd111a5e6, 0x48b942d2, 0x3f21e0c1, + 0xc22b9926, 0xb5b33b35, 0x2c1bdc01, 0x5b837e12, + 0x1e4a1368, 0x69d2b17b, 0xf07a564f, 0x87e2f45c, + 0xfd3cd404, 0x8aa47617, 0x130c9123, 0x64943330, + 0x215d5e4a, 0x56c5fc59, 0xcf6d1b6d, 0xb8f5b97e, + 0x45ffc099, 0x3267628a, 0xabcf85be, 0xdc5727ad, + 0x999e4ad7, 0xee06e8c4, 0x77ae0ff0, 0x0036ade3, + 0x7ccd113b, 0x0b55b328, 0x92fd541c, 0xe565f60f, + 0xa0ac9b75, 0xd7343966, 0x4e9cde52, 0x39047c41, + 0xc40e05a6, 0xb396a7b5, 0x2a3e4081, 0x5da6e292, + 0x186f8fe8, 0x6ff72dfb, 0xf65fcacf, 0x81c768dc, + 0xffdf5f7b, 0x8847fd68, 0x11ef1a5c, 0x6677b84f, + 0x23bed535, 0x54267726, 0xcd8e9012, 0xba163201, + 0x471c4be6, 0x3084e9f5, 0xa92c0ec1, 0xdeb4acd2, + 0x9b7dc1a8, 0xece563bb, 0x754d848f, 0x02d5269c, + 0x7e2e9a44, 0x09b63857, 0x901edf63, 0xe7867d70, + 0xa24f100a, 0xd5d7b219, 0x4c7f552d, 0x3be7f73e, + 0xc6ed8ed9, 0xb1752cca, 0x28ddcbfe, 0x5f4569ed, + 0x1a8c0497, 0x6d14a684, 0xf4bc41b0, 0x8324e3a3 + },{ + 0x00000000, 0x7e9241a5, 0x0d526f4f, 0x73c02eea, + 0x1aa4de9e, 0x64369f3b, 0x17f6b1d1, 0x6964f074, + 0xc53e5138, 0xbbac109d, 0xc86c3e77, 0xb6fe7fd2, + 0xdf9a8fa6, 0xa108ce03, 0xd2c8e0e9, 0xac5aa14c, + 0x8a7da270, 0xf4efe3d5, 0x872fcd3f, 0xf9bd8c9a, + 0x90d97cee, 0xee4b3d4b, 0x9d8b13a1, 0xe3195204, + 0x4f43f348, 0x31d1b2ed, 0x42119c07, 0x3c83dda2, + 0x55e72dd6, 0x2b756c73, 0x58b54299, 0x2627033c, + 0x14fb44e1, 0x6a690544, 0x19a92bae, 0x673b6a0b, + 0x0e5f9a7f, 0x70cddbda, 0x030df530, 0x7d9fb495, + 0xd1c515d9, 0xaf57547c, 0xdc977a96, 0xa2053b33, + 0xcb61cb47, 0xb5f38ae2, 0xc633a408, 0xb8a1e5ad, + 0x9e86e691, 0xe014a734, 0x93d489de, 0xed46c87b, + 0x8422380f, 0xfab079aa, 0x89705740, 0xf7e216e5, + 0x5bb8b7a9, 0x252af60c, 0x56ead8e6, 0x28789943, + 0x411c6937, 0x3f8e2892, 0x4c4e0678, 0x32dc47dd, + 0xd98065c7, 0xa7122462, 0xd4d20a88, 0xaa404b2d, + 0xc324bb59, 0xbdb6fafc, 0xce76d416, 0xb0e495b3, + 0x1cbe34ff, 0x622c755a, 0x11ec5bb0, 0x6f7e1a15, + 0x061aea61, 0x7888abc4, 0x0b48852e, 0x75dac48b, + 0x53fdc7b7, 0x2d6f8612, 0x5eafa8f8, 0x203de95d, + 0x49591929, 0x37cb588c, 0x440b7666, 0x3a9937c3, + 0x96c3968f, 0xe851d72a, 0x9b91f9c0, 0xe503b865, + 0x8c674811, 0xf2f509b4, 0x8135275e, 0xffa766fb, + 0xcd7b2126, 0xb3e96083, 0xc0294e69, 0xbebb0fcc, + 0xd7dfffb8, 0xa94dbe1d, 0xda8d90f7, 0xa41fd152, + 0x0845701e, 0x76d731bb, 0x05171f51, 0x7b855ef4, + 0x12e1ae80, 0x6c73ef25, 0x1fb3c1cf, 0x6121806a, + 0x47068356, 0x3994c2f3, 0x4a54ec19, 0x34c6adbc, + 0x5da25dc8, 0x23301c6d, 0x50f03287, 0x2e627322, + 0x8238d26e, 0xfcaa93cb, 0x8f6abd21, 0xf1f8fc84, + 0x989c0cf0, 0xe60e4d55, 0x95ce63bf, 0xeb5c221a, + 0x4377278b, 0x3de5662e, 0x4e2548c4, 0x30b70961, + 0x59d3f915, 0x2741b8b0, 0x5481965a, 0x2a13d7ff, + 0x864976b3, 0xf8db3716, 0x8b1b19fc, 0xf5895859, + 0x9ceda82d, 0xe27fe988, 0x91bfc762, 0xef2d86c7, + 0xc90a85fb, 0xb798c45e, 0xc458eab4, 0xbacaab11, + 0xd3ae5b65, 0xad3c1ac0, 0xdefc342a, 0xa06e758f, + 0x0c34d4c3, 0x72a69566, 0x0166bb8c, 0x7ff4fa29, + 0x16900a5d, 0x68024bf8, 0x1bc26512, 0x655024b7, + 0x578c636a, 0x291e22cf, 0x5ade0c25, 0x244c4d80, + 0x4d28bdf4, 0x33bafc51, 0x407ad2bb, 0x3ee8931e, + 0x92b23252, 0xec2073f7, 0x9fe05d1d, 0xe1721cb8, + 0x8816eccc, 0xf684ad69, 0x85448383, 0xfbd6c226, + 0xddf1c11a, 0xa36380bf, 0xd0a3ae55, 0xae31eff0, + 0xc7551f84, 0xb9c75e21, 0xca0770cb, 0xb495316e, + 0x18cf9022, 0x665dd187, 0x159dff6d, 0x6b0fbec8, + 0x026b4ebc, 0x7cf90f19, 0x0f3921f3, 0x71ab6056, + 0x9af7424c, 0xe46503e9, 0x97a52d03, 0xe9376ca6, + 0x80539cd2, 0xfec1dd77, 0x8d01f39d, 0xf393b238, + 0x5fc91374, 0x215b52d1, 0x529b7c3b, 0x2c093d9e, + 0x456dcdea, 0x3bff8c4f, 0x483fa2a5, 0x36ade300, + 0x108ae03c, 0x6e18a199, 0x1dd88f73, 0x634aced6, + 0x0a2e3ea2, 0x74bc7f07, 0x077c51ed, 0x79ee1048, + 0xd5b4b104, 0xab26f0a1, 0xd8e6de4b, 0xa6749fee, + 0xcf106f9a, 0xb1822e3f, 0xc24200d5, 0xbcd04170, + 0x8e0c06ad, 0xf09e4708, 0x835e69e2, 0xfdcc2847, + 0x94a8d833, 0xea3a9996, 0x99fab77c, 0xe768f6d9, + 0x4b325795, 0x35a01630, 0x466038da, 0x38f2797f, + 0x5196890b, 0x2f04c8ae, 0x5cc4e644, 0x2256a7e1, + 0x0471a4dd, 0x7ae3e578, 0x0923cb92, 0x77b18a37, + 0x1ed57a43, 0x60473be6, 0x1387150c, 0x6d1554a9, + 0xc14ff5e5, 0xbfddb440, 0xcc1d9aaa, 0xb28fdb0f, + 0xdbeb2b7b, 0xa5796ade, 0xd6b94434, 0xa82b0591 + },{ + 0x00000000, 0xb8aa45dd, 0x812367bf, 0x39892262, + 0xf331227b, 0x4b9b67a6, 0x721245c4, 0xcab80019, + 0xe66344f6, 0x5ec9012b, 0x67402349, 0xdfea6694, + 0x1552668d, 0xadf82350, 0x94710132, 0x2cdb44ef, + 0x3db164e9, 0x851b2134, 0xbc920356, 0x0438468b, + 0xce804692, 0x762a034f, 0x4fa3212d, 0xf70964f0, + 0xdbd2201f, 0x637865c2, 0x5af147a0, 0xe25b027d, + 0x28e30264, 0x904947b9, 0xa9c065db, 0x116a2006, + 0x8b1425d7, 0x33be600a, 0x0a374268, 0xb29d07b5, + 0x782507ac, 0xc08f4271, 0xf9066013, 0x41ac25ce, + 0x6d776121, 0xd5dd24fc, 0xec54069e, 0x54fe4343, + 0x9e46435a, 0x26ec0687, 0x1f6524e5, 0xa7cf6138, + 0xb6a5413e, 0x0e0f04e3, 0x37862681, 0x8f2c635c, + 0x45946345, 0xfd3e2698, 0xc4b704fa, 0x7c1d4127, + 0x50c605c8, 0xe86c4015, 0xd1e56277, 0x694f27aa, + 0xa3f727b3, 0x1b5d626e, 0x22d4400c, 0x9a7e05d1, + 0xe75fa6ab, 0x5ff5e376, 0x667cc114, 0xded684c9, + 0x146e84d0, 0xacc4c10d, 0x954de36f, 0x2de7a6b2, + 0x013ce25d, 0xb996a780, 0x801f85e2, 0x38b5c03f, + 0xf20dc026, 0x4aa785fb, 0x732ea799, 0xcb84e244, + 0xdaeec242, 0x6244879f, 0x5bcda5fd, 0xe367e020, + 0x29dfe039, 0x9175a5e4, 0xa8fc8786, 0x1056c25b, + 0x3c8d86b4, 0x8427c369, 0xbdaee10b, 0x0504a4d6, + 0xcfbca4cf, 0x7716e112, 0x4e9fc370, 0xf63586ad, + 0x6c4b837c, 0xd4e1c6a1, 0xed68e4c3, 0x55c2a11e, + 0x9f7aa107, 0x27d0e4da, 0x1e59c6b8, 0xa6f38365, + 0x8a28c78a, 0x32828257, 0x0b0ba035, 0xb3a1e5e8, + 0x7919e5f1, 0xc1b3a02c, 0xf83a824e, 0x4090c793, + 0x51fae795, 0xe950a248, 0xd0d9802a, 0x6873c5f7, + 0xa2cbc5ee, 0x1a618033, 0x23e8a251, 0x9b42e78c, + 0xb799a363, 0x0f33e6be, 0x36bac4dc, 0x8e108101, + 0x44a88118, 0xfc02c4c5, 0xc58be6a7, 0x7d21a37a, + 0x3fc9a052, 0x8763e58f, 0xbeeac7ed, 0x06408230, + 0xccf88229, 0x7452c7f4, 0x4ddbe596, 0xf571a04b, + 0xd9aae4a4, 0x6100a179, 0x5889831b, 0xe023c6c6, + 0x2a9bc6df, 0x92318302, 0xabb8a160, 0x1312e4bd, + 0x0278c4bb, 0xbad28166, 0x835ba304, 0x3bf1e6d9, + 0xf149e6c0, 0x49e3a31d, 0x706a817f, 0xc8c0c4a2, + 0xe41b804d, 0x5cb1c590, 0x6538e7f2, 0xdd92a22f, + 0x172aa236, 0xaf80e7eb, 0x9609c589, 0x2ea38054, + 0xb4dd8585, 0x0c77c058, 0x35fee23a, 0x8d54a7e7, + 0x47eca7fe, 0xff46e223, 0xc6cfc041, 0x7e65859c, + 0x52bec173, 0xea1484ae, 0xd39da6cc, 0x6b37e311, + 0xa18fe308, 0x1925a6d5, 0x20ac84b7, 0x9806c16a, + 0x896ce16c, 0x31c6a4b1, 0x084f86d3, 0xb0e5c30e, + 0x7a5dc317, 0xc2f786ca, 0xfb7ea4a8, 0x43d4e175, + 0x6f0fa59a, 0xd7a5e047, 0xee2cc225, 0x568687f8, + 0x9c3e87e1, 0x2494c23c, 0x1d1de05e, 0xa5b7a583, + 0xd89606f9, 0x603c4324, 0x59b56146, 0xe11f249b, + 0x2ba72482, 0x930d615f, 0xaa84433d, 0x122e06e0, + 0x3ef5420f, 0x865f07d2, 0xbfd625b0, 0x077c606d, + 0xcdc46074, 0x756e25a9, 0x4ce707cb, 0xf44d4216, + 0xe5276210, 0x5d8d27cd, 0x640405af, 0xdcae4072, + 0x1616406b, 0xaebc05b6, 0x973527d4, 0x2f9f6209, + 0x034426e6, 0xbbee633b, 0x82674159, 0x3acd0484, + 0xf075049d, 0x48df4140, 0x71566322, 0xc9fc26ff, + 0x5382232e, 0xeb2866f3, 0xd2a14491, 0x6a0b014c, + 0xa0b30155, 0x18194488, 0x219066ea, 0x993a2337, + 0xb5e167d8, 0x0d4b2205, 0x34c20067, 0x8c6845ba, + 0x46d045a3, 0xfe7a007e, 0xc7f3221c, 0x7f5967c1, + 0x6e3347c7, 0xd699021a, 0xef102078, 0x57ba65a5, + 0x9d0265bc, 0x25a82061, 0x1c210203, 0xa48b47de, + 0x88500331, 0x30fa46ec, 0x0973648e, 0xb1d92153, + 0x7b61214a, 0xc3cb6497, 0xfa4246f5, 0x42e80328 + },{ + 0x00000000, 0xac6f1138, 0x58df2270, 0xf4b03348, + 0xb0be45e0, 0x1cd154d8, 0xe8616790, 0x440e76a8, + 0x910b67c5, 0x3d6476fd, 0xc9d445b5, 0x65bb548d, + 0x21b52225, 0x8dda331d, 0x796a0055, 0xd505116d, + 0xd361228f, 0x7f0e33b7, 0x8bbe00ff, 0x27d111c7, + 0x63df676f, 0xcfb07657, 0x3b00451f, 0x976f5427, + 0x426a454a, 0xee055472, 0x1ab5673a, 0xb6da7602, + 0xf2d400aa, 0x5ebb1192, 0xaa0b22da, 0x066433e2, + 0x57b5a81b, 0xfbdab923, 0x0f6a8a6b, 0xa3059b53, + 0xe70bedfb, 0x4b64fcc3, 0xbfd4cf8b, 0x13bbdeb3, + 0xc6becfde, 0x6ad1dee6, 0x9e61edae, 0x320efc96, + 0x76008a3e, 0xda6f9b06, 0x2edfa84e, 0x82b0b976, + 0x84d48a94, 0x28bb9bac, 0xdc0ba8e4, 0x7064b9dc, + 0x346acf74, 0x9805de4c, 0x6cb5ed04, 0xc0dafc3c, + 0x15dfed51, 0xb9b0fc69, 0x4d00cf21, 0xe16fde19, + 0xa561a8b1, 0x090eb989, 0xfdbe8ac1, 0x51d19bf9, + 0xae6a5137, 0x0205400f, 0xf6b57347, 0x5ada627f, + 0x1ed414d7, 0xb2bb05ef, 0x460b36a7, 0xea64279f, + 0x3f6136f2, 0x930e27ca, 0x67be1482, 0xcbd105ba, + 0x8fdf7312, 0x23b0622a, 0xd7005162, 0x7b6f405a, + 0x7d0b73b8, 0xd1646280, 0x25d451c8, 0x89bb40f0, + 0xcdb53658, 0x61da2760, 0x956a1428, 0x39050510, + 0xec00147d, 0x406f0545, 0xb4df360d, 0x18b02735, + 0x5cbe519d, 0xf0d140a5, 0x046173ed, 0xa80e62d5, + 0xf9dff92c, 0x55b0e814, 0xa100db5c, 0x0d6fca64, + 0x4961bccc, 0xe50eadf4, 0x11be9ebc, 0xbdd18f84, + 0x68d49ee9, 0xc4bb8fd1, 0x300bbc99, 0x9c64ada1, + 0xd86adb09, 0x7405ca31, 0x80b5f979, 0x2cdae841, + 0x2abedba3, 0x86d1ca9b, 0x7261f9d3, 0xde0ee8eb, + 0x9a009e43, 0x366f8f7b, 0xc2dfbc33, 0x6eb0ad0b, + 0xbbb5bc66, 0x17daad5e, 0xe36a9e16, 0x4f058f2e, + 0x0b0bf986, 0xa764e8be, 0x53d4dbf6, 0xffbbcace, + 0x5cd5a26e, 0xf0bab356, 0x040a801e, 0xa8659126, + 0xec6be78e, 0x4004f6b6, 0xb4b4c5fe, 0x18dbd4c6, + 0xcddec5ab, 0x61b1d493, 0x9501e7db, 0x396ef6e3, + 0x7d60804b, 0xd10f9173, 0x25bfa23b, 0x89d0b303, + 0x8fb480e1, 0x23db91d9, 0xd76ba291, 0x7b04b3a9, + 0x3f0ac501, 0x9365d439, 0x67d5e771, 0xcbbaf649, + 0x1ebfe724, 0xb2d0f61c, 0x4660c554, 0xea0fd46c, + 0xae01a2c4, 0x026eb3fc, 0xf6de80b4, 0x5ab1918c, + 0x0b600a75, 0xa70f1b4d, 0x53bf2805, 0xffd0393d, + 0xbbde4f95, 0x17b15ead, 0xe3016de5, 0x4f6e7cdd, + 0x9a6b6db0, 0x36047c88, 0xc2b44fc0, 0x6edb5ef8, + 0x2ad52850, 0x86ba3968, 0x720a0a20, 0xde651b18, + 0xd80128fa, 0x746e39c2, 0x80de0a8a, 0x2cb11bb2, + 0x68bf6d1a, 0xc4d07c22, 0x30604f6a, 0x9c0f5e52, + 0x490a4f3f, 0xe5655e07, 0x11d56d4f, 0xbdba7c77, + 0xf9b40adf, 0x55db1be7, 0xa16b28af, 0x0d043997, + 0xf2bff359, 0x5ed0e261, 0xaa60d129, 0x060fc011, + 0x4201b6b9, 0xee6ea781, 0x1ade94c9, 0xb6b185f1, + 0x63b4949c, 0xcfdb85a4, 0x3b6bb6ec, 0x9704a7d4, + 0xd30ad17c, 0x7f65c044, 0x8bd5f30c, 0x27bae234, + 0x21ded1d6, 0x8db1c0ee, 0x7901f3a6, 0xd56ee29e, + 0x91609436, 0x3d0f850e, 0xc9bfb646, 0x65d0a77e, + 0xb0d5b613, 0x1cbaa72b, 0xe80a9463, 0x4465855b, + 0x006bf3f3, 0xac04e2cb, 0x58b4d183, 0xf4dbc0bb, + 0xa50a5b42, 0x09654a7a, 0xfdd57932, 0x51ba680a, + 0x15b41ea2, 0xb9db0f9a, 0x4d6b3cd2, 0xe1042dea, + 0x34013c87, 0x986e2dbf, 0x6cde1ef7, 0xc0b10fcf, + 0x84bf7967, 0x28d0685f, 0xdc605b17, 0x700f4a2f, + 0x766b79cd, 0xda0468f5, 0x2eb45bbd, 0x82db4a85, + 0xc6d53c2d, 0x6aba2d15, 0x9e0a1e5d, 0x32650f65, + 0xe7601e08, 0x4b0f0f30, 0xbfbf3c78, 0x13d02d40, + 0x57de5be8, 0xfbb14ad0, 0x0f017998, 0xa36e68a0 + },{ + 0x00000000, 0x196b30ef, 0xc3a08cdb, 0xdacbbc34, + 0x7737f5b2, 0x6e5cc55d, 0xb4977969, 0xadfc4986, + 0x1f180660, 0x0673368f, 0xdcb88abb, 0xc5d3ba54, + 0x682ff3d2, 0x7144c33d, 0xab8f7f09, 0xb2e44fe6, + 0x3e300cc0, 0x275b3c2f, 0xfd90801b, 0xe4fbb0f4, + 0x4907f972, 0x506cc99d, 0x8aa775a9, 0x93cc4546, + 0x21280aa0, 0x38433a4f, 0xe288867b, 0xfbe3b694, + 0x561fff12, 0x4f74cffd, 0x95bf73c9, 0x8cd44326, + 0x8d16f485, 0x947dc46a, 0x4eb6785e, 0x57dd48b1, + 0xfa210137, 0xe34a31d8, 0x39818dec, 0x20eabd03, + 0x920ef2e5, 0x8b65c20a, 0x51ae7e3e, 0x48c54ed1, + 0xe5390757, 0xfc5237b8, 0x26998b8c, 0x3ff2bb63, + 0xb326f845, 0xaa4dc8aa, 0x7086749e, 0x69ed4471, + 0xc4110df7, 0xdd7a3d18, 0x07b1812c, 0x1edab1c3, + 0xac3efe25, 0xb555ceca, 0x6f9e72fe, 0x76f54211, + 0xdb090b97, 0xc2623b78, 0x18a9874c, 0x01c2b7a3, + 0xeb5b040e, 0xf23034e1, 0x28fb88d5, 0x3190b83a, + 0x9c6cf1bc, 0x8507c153, 0x5fcc7d67, 0x46a74d88, + 0xf443026e, 0xed283281, 0x37e38eb5, 0x2e88be5a, + 0x8374f7dc, 0x9a1fc733, 0x40d47b07, 0x59bf4be8, + 0xd56b08ce, 0xcc003821, 0x16cb8415, 0x0fa0b4fa, + 0xa25cfd7c, 0xbb37cd93, 0x61fc71a7, 0x78974148, + 0xca730eae, 0xd3183e41, 0x09d38275, 0x10b8b29a, + 0xbd44fb1c, 0xa42fcbf3, 0x7ee477c7, 0x678f4728, + 0x664df08b, 0x7f26c064, 0xa5ed7c50, 0xbc864cbf, + 0x117a0539, 0x081135d6, 0xd2da89e2, 0xcbb1b90d, + 0x7955f6eb, 0x603ec604, 0xbaf57a30, 0xa39e4adf, + 0x0e620359, 0x170933b6, 0xcdc28f82, 0xd4a9bf6d, + 0x587dfc4b, 0x4116cca4, 0x9bdd7090, 0x82b6407f, + 0x2f4a09f9, 0x36213916, 0xecea8522, 0xf581b5cd, + 0x4765fa2b, 0x5e0ecac4, 0x84c576f0, 0x9dae461f, + 0x30520f99, 0x29393f76, 0xf3f28342, 0xea99b3ad, + 0xd6b7081c, 0xcfdc38f3, 0x151784c7, 0x0c7cb428, + 0xa180fdae, 0xb8ebcd41, 0x62207175, 0x7b4b419a, + 0xc9af0e7c, 0xd0c43e93, 0x0a0f82a7, 0x1364b248, + 0xbe98fbce, 0xa7f3cb21, 0x7d387715, 0x645347fa, + 0xe88704dc, 0xf1ec3433, 0x2b278807, 0x324cb8e8, + 0x9fb0f16e, 0x86dbc181, 0x5c107db5, 0x457b4d5a, + 0xf79f02bc, 0xeef43253, 0x343f8e67, 0x2d54be88, + 0x80a8f70e, 0x99c3c7e1, 0x43087bd5, 0x5a634b3a, + 0x5ba1fc99, 0x42cacc76, 0x98017042, 0x816a40ad, + 0x2c96092b, 0x35fd39c4, 0xef3685f0, 0xf65db51f, + 0x44b9faf9, 0x5dd2ca16, 0x87197622, 0x9e7246cd, + 0x338e0f4b, 0x2ae53fa4, 0xf02e8390, 0xe945b37f, + 0x6591f059, 0x7cfac0b6, 0xa6317c82, 0xbf5a4c6d, + 0x12a605eb, 0x0bcd3504, 0xd1068930, 0xc86db9df, + 0x7a89f639, 0x63e2c6d6, 0xb9297ae2, 0xa0424a0d, + 0x0dbe038b, 0x14d53364, 0xce1e8f50, 0xd775bfbf, + 0x3dec0c12, 0x24873cfd, 0xfe4c80c9, 0xe727b026, + 0x4adbf9a0, 0x53b0c94f, 0x897b757b, 0x90104594, + 0x22f40a72, 0x3b9f3a9d, 0xe15486a9, 0xf83fb646, + 0x55c3ffc0, 0x4ca8cf2f, 0x9663731b, 0x8f0843f4, + 0x03dc00d2, 0x1ab7303d, 0xc07c8c09, 0xd917bce6, + 0x74ebf560, 0x6d80c58f, 0xb74b79bb, 0xae204954, + 0x1cc406b2, 0x05af365d, 0xdf648a69, 0xc60fba86, + 0x6bf3f300, 0x7298c3ef, 0xa8537fdb, 0xb1384f34, + 0xb0faf897, 0xa991c878, 0x735a744c, 0x6a3144a3, + 0xc7cd0d25, 0xdea63dca, 0x046d81fe, 0x1d06b111, + 0xafe2fef7, 0xb689ce18, 0x6c42722c, 0x752942c3, + 0xd8d50b45, 0xc1be3baa, 0x1b75879e, 0x021eb771, + 0x8ecaf457, 0x97a1c4b8, 0x4d6a788c, 0x54014863, + 0xf9fd01e5, 0xe096310a, 0x3a5d8d3e, 0x2336bdd1, + 0x91d2f237, 0x88b9c2d8, 0x52727eec, 0x4b194e03, + 0xe6e50785, 0xff8e376a, 0x25458b5e, 0x3c2ebbb1 + },{ + 0x00000000, 0xc82c0368, 0x905906d0, 0x587505b8, + 0xd1c5e0a5, 0x19e9e3cd, 0x419ce675, 0x89b0e51d, + 0x53fd2d4e, 0x9bd12e26, 0xc3a42b9e, 0x0b8828f6, + 0x8238cdeb, 0x4a14ce83, 0x1261cb3b, 0xda4dc853, + 0xa6fa5b9c, 0x6ed658f4, 0x36a35d4c, 0xfe8f5e24, + 0x773fbb39, 0xbf13b851, 0xe766bde9, 0x2f4abe81, + 0xf50776d2, 0x3d2b75ba, 0x655e7002, 0xad72736a, + 0x24c29677, 0xecee951f, 0xb49b90a7, 0x7cb793cf, + 0xbd835b3d, 0x75af5855, 0x2dda5ded, 0xe5f65e85, + 0x6c46bb98, 0xa46ab8f0, 0xfc1fbd48, 0x3433be20, + 0xee7e7673, 0x2652751b, 0x7e2770a3, 0xb60b73cb, + 0x3fbb96d6, 0xf79795be, 0xafe29006, 0x67ce936e, + 0x1b7900a1, 0xd35503c9, 0x8b200671, 0x430c0519, + 0xcabce004, 0x0290e36c, 0x5ae5e6d4, 0x92c9e5bc, + 0x48842def, 0x80a82e87, 0xd8dd2b3f, 0x10f12857, + 0x9941cd4a, 0x516dce22, 0x0918cb9a, 0xc134c8f2, + 0x7a07b77a, 0xb22bb412, 0xea5eb1aa, 0x2272b2c2, + 0xabc257df, 0x63ee54b7, 0x3b9b510f, 0xf3b75267, + 0x29fa9a34, 0xe1d6995c, 0xb9a39ce4, 0x718f9f8c, + 0xf83f7a91, 0x301379f9, 0x68667c41, 0xa04a7f29, + 0xdcfdece6, 0x14d1ef8e, 0x4ca4ea36, 0x8488e95e, + 0x0d380c43, 0xc5140f2b, 0x9d610a93, 0x554d09fb, + 0x8f00c1a8, 0x472cc2c0, 0x1f59c778, 0xd775c410, + 0x5ec5210d, 0x96e92265, 0xce9c27dd, 0x06b024b5, + 0xc784ec47, 0x0fa8ef2f, 0x57ddea97, 0x9ff1e9ff, + 0x16410ce2, 0xde6d0f8a, 0x86180a32, 0x4e34095a, + 0x9479c109, 0x5c55c261, 0x0420c7d9, 0xcc0cc4b1, + 0x45bc21ac, 0x8d9022c4, 0xd5e5277c, 0x1dc92414, + 0x617eb7db, 0xa952b4b3, 0xf127b10b, 0x390bb263, + 0xb0bb577e, 0x78975416, 0x20e251ae, 0xe8ce52c6, + 0x32839a95, 0xfaaf99fd, 0xa2da9c45, 0x6af69f2d, + 0xe3467a30, 0x2b6a7958, 0x731f7ce0, 0xbb337f88, + 0xf40e6ef5, 0x3c226d9d, 0x64576825, 0xac7b6b4d, + 0x25cb8e50, 0xede78d38, 0xb5928880, 0x7dbe8be8, + 0xa7f343bb, 0x6fdf40d3, 0x37aa456b, 0xff864603, + 0x7636a31e, 0xbe1aa076, 0xe66fa5ce, 0x2e43a6a6, + 0x52f43569, 0x9ad83601, 0xc2ad33b9, 0x0a8130d1, + 0x8331d5cc, 0x4b1dd6a4, 0x1368d31c, 0xdb44d074, + 0x01091827, 0xc9251b4f, 0x91501ef7, 0x597c1d9f, + 0xd0ccf882, 0x18e0fbea, 0x4095fe52, 0x88b9fd3a, + 0x498d35c8, 0x81a136a0, 0xd9d43318, 0x11f83070, + 0x9848d56d, 0x5064d605, 0x0811d3bd, 0xc03dd0d5, + 0x1a701886, 0xd25c1bee, 0x8a291e56, 0x42051d3e, + 0xcbb5f823, 0x0399fb4b, 0x5becfef3, 0x93c0fd9b, + 0xef776e54, 0x275b6d3c, 0x7f2e6884, 0xb7026bec, + 0x3eb28ef1, 0xf69e8d99, 0xaeeb8821, 0x66c78b49, + 0xbc8a431a, 0x74a64072, 0x2cd345ca, 0xe4ff46a2, + 0x6d4fa3bf, 0xa563a0d7, 0xfd16a56f, 0x353aa607, + 0x8e09d98f, 0x4625dae7, 0x1e50df5f, 0xd67cdc37, + 0x5fcc392a, 0x97e03a42, 0xcf953ffa, 0x07b93c92, + 0xddf4f4c1, 0x15d8f7a9, 0x4dadf211, 0x8581f179, + 0x0c311464, 0xc41d170c, 0x9c6812b4, 0x544411dc, + 0x28f38213, 0xe0df817b, 0xb8aa84c3, 0x708687ab, + 0xf93662b6, 0x311a61de, 0x696f6466, 0xa143670e, + 0x7b0eaf5d, 0xb322ac35, 0xeb57a98d, 0x237baae5, + 0xaacb4ff8, 0x62e74c90, 0x3a924928, 0xf2be4a40, + 0x338a82b2, 0xfba681da, 0xa3d38462, 0x6bff870a, + 0xe24f6217, 0x2a63617f, 0x721664c7, 0xba3a67af, + 0x6077affc, 0xa85bac94, 0xf02ea92c, 0x3802aa44, + 0xb1b24f59, 0x799e4c31, 0x21eb4989, 0xe9c74ae1, + 0x9570d92e, 0x5d5cda46, 0x0529dffe, 0xcd05dc96, + 0x44b5398b, 0x8c993ae3, 0xd4ec3f5b, 0x1cc03c33, + 0xc68df460, 0x0ea1f708, 0x56d4f2b0, 0x9ef8f1d8, + 0x174814c5, 0xdf6417ad, 0x87111215, 0x4f3d117d + },{ + 0x00000000, 0x277d3c49, 0x4efa7892, 0x698744db, + 0x6d821d21, 0x4aff2168, 0x237865b3, 0x040559fa, + 0xda043b42, 0xfd79070b, 0x94fe43d0, 0xb3837f99, + 0xb7862663, 0x90fb1a2a, 0xf97c5ef1, 0xde0162b8, + 0xb4097684, 0x93744acd, 0xfaf30e16, 0xdd8e325f, + 0xd98b6ba5, 0xfef657ec, 0x97711337, 0xb00c2f7e, + 0x6e0d4dc6, 0x4970718f, 0x20f73554, 0x078a091d, + 0x038f50e7, 0x24f26cae, 0x4d752875, 0x6a08143c, + 0x9965000d, 0xbe183c44, 0xd79f789f, 0xf0e244d6, + 0xf4e71d2c, 0xd39a2165, 0xba1d65be, 0x9d6059f7, + 0x43613b4f, 0x641c0706, 0x0d9b43dd, 0x2ae67f94, + 0x2ee3266e, 0x099e1a27, 0x60195efc, 0x476462b5, + 0x2d6c7689, 0x0a114ac0, 0x63960e1b, 0x44eb3252, + 0x40ee6ba8, 0x679357e1, 0x0e14133a, 0x29692f73, + 0xf7684dcb, 0xd0157182, 0xb9923559, 0x9eef0910, + 0x9aea50ea, 0xbd976ca3, 0xd4102878, 0xf36d1431, + 0x32cb001a, 0x15b63c53, 0x7c317888, 0x5b4c44c1, + 0x5f491d3b, 0x78342172, 0x11b365a9, 0x36ce59e0, + 0xe8cf3b58, 0xcfb20711, 0xa63543ca, 0x81487f83, + 0x854d2679, 0xa2301a30, 0xcbb75eeb, 0xecca62a2, + 0x86c2769e, 0xa1bf4ad7, 0xc8380e0c, 0xef453245, + 0xeb406bbf, 0xcc3d57f6, 0xa5ba132d, 0x82c72f64, + 0x5cc64ddc, 0x7bbb7195, 0x123c354e, 0x35410907, + 0x314450fd, 0x16396cb4, 0x7fbe286f, 0x58c31426, + 0xabae0017, 0x8cd33c5e, 0xe5547885, 0xc22944cc, + 0xc62c1d36, 0xe151217f, 0x88d665a4, 0xafab59ed, + 0x71aa3b55, 0x56d7071c, 0x3f5043c7, 0x182d7f8e, + 0x1c282674, 0x3b551a3d, 0x52d25ee6, 0x75af62af, + 0x1fa77693, 0x38da4ada, 0x515d0e01, 0x76203248, + 0x72256bb2, 0x555857fb, 0x3cdf1320, 0x1ba22f69, + 0xc5a34dd1, 0xe2de7198, 0x8b593543, 0xac24090a, + 0xa82150f0, 0x8f5c6cb9, 0xe6db2862, 0xc1a6142b, + 0x64960134, 0x43eb3d7d, 0x2a6c79a6, 0x0d1145ef, + 0x09141c15, 0x2e69205c, 0x47ee6487, 0x609358ce, + 0xbe923a76, 0x99ef063f, 0xf06842e4, 0xd7157ead, + 0xd3102757, 0xf46d1b1e, 0x9dea5fc5, 0xba97638c, + 0xd09f77b0, 0xf7e24bf9, 0x9e650f22, 0xb918336b, + 0xbd1d6a91, 0x9a6056d8, 0xf3e71203, 0xd49a2e4a, + 0x0a9b4cf2, 0x2de670bb, 0x44613460, 0x631c0829, + 0x671951d3, 0x40646d9a, 0x29e32941, 0x0e9e1508, + 0xfdf30139, 0xda8e3d70, 0xb30979ab, 0x947445e2, + 0x90711c18, 0xb70c2051, 0xde8b648a, 0xf9f658c3, + 0x27f73a7b, 0x008a0632, 0x690d42e9, 0x4e707ea0, + 0x4a75275a, 0x6d081b13, 0x048f5fc8, 0x23f26381, + 0x49fa77bd, 0x6e874bf4, 0x07000f2f, 0x207d3366, + 0x24786a9c, 0x030556d5, 0x6a82120e, 0x4dff2e47, + 0x93fe4cff, 0xb48370b6, 0xdd04346d, 0xfa790824, + 0xfe7c51de, 0xd9016d97, 0xb086294c, 0x97fb1505, + 0x565d012e, 0x71203d67, 0x18a779bc, 0x3fda45f5, + 0x3bdf1c0f, 0x1ca22046, 0x7525649d, 0x525858d4, + 0x8c593a6c, 0xab240625, 0xc2a342fe, 0xe5de7eb7, + 0xe1db274d, 0xc6a61b04, 0xaf215fdf, 0x885c6396, + 0xe25477aa, 0xc5294be3, 0xacae0f38, 0x8bd33371, + 0x8fd66a8b, 0xa8ab56c2, 0xc12c1219, 0xe6512e50, + 0x38504ce8, 0x1f2d70a1, 0x76aa347a, 0x51d70833, + 0x55d251c9, 0x72af6d80, 0x1b28295b, 0x3c551512, + 0xcf380123, 0xe8453d6a, 0x81c279b1, 0xa6bf45f8, + 0xa2ba1c02, 0x85c7204b, 0xec406490, 0xcb3d58d9, + 0x153c3a61, 0x32410628, 0x5bc642f3, 0x7cbb7eba, + 0x78be2740, 0x5fc31b09, 0x36445fd2, 0x1139639b, + 0x7b3177a7, 0x5c4c4bee, 0x35cb0f35, 0x12b6337c, + 0x16b36a86, 0x31ce56cf, 0x58491214, 0x7f342e5d, + 0xa1354ce5, 0x864870ac, 0xefcf3477, 0xc8b2083e, + 0xccb751c4, 0xebca6d8d, 0x824d2956, 0xa530151f + } +}; + +static const unsigned int __attribute__((aligned(128))) crc32ctable_be[8][256] = { + { + 0x00000000, 0x1edc6f41, 0x3db8de82, 0x2364b1c3, + 0x7b71bd04, 0x65add245, 0x46c96386, 0x58150cc7, + 0xf6e37a08, 0xe83f1549, 0xcb5ba48a, 0xd587cbcb, + 0x8d92c70c, 0x934ea84d, 0xb02a198e, 0xaef676cf, + 0xf31a9b51, 0xedc6f410, 0xcea245d3, 0xd07e2a92, + 0x886b2655, 0x96b74914, 0xb5d3f8d7, 0xab0f9796, + 0x05f9e159, 0x1b258e18, 0x38413fdb, 0x269d509a, + 0x7e885c5d, 0x6054331c, 0x433082df, 0x5deced9e, + 0xf8e959e3, 0xe63536a2, 0xc5518761, 0xdb8de820, + 0x8398e4e7, 0x9d448ba6, 0xbe203a65, 0xa0fc5524, + 0x0e0a23eb, 0x10d64caa, 0x33b2fd69, 0x2d6e9228, + 0x757b9eef, 0x6ba7f1ae, 0x48c3406d, 0x561f2f2c, + 0x0bf3c2b2, 0x152fadf3, 0x364b1c30, 0x28977371, + 0x70827fb6, 0x6e5e10f7, 0x4d3aa134, 0x53e6ce75, + 0xfd10b8ba, 0xe3ccd7fb, 0xc0a86638, 0xde740979, + 0x866105be, 0x98bd6aff, 0xbbd9db3c, 0xa505b47d, + 0xef0edc87, 0xf1d2b3c6, 0xd2b60205, 0xcc6a6d44, + 0x947f6183, 0x8aa30ec2, 0xa9c7bf01, 0xb71bd040, + 0x19eda68f, 0x0731c9ce, 0x2455780d, 0x3a89174c, + 0x629c1b8b, 0x7c4074ca, 0x5f24c509, 0x41f8aa48, + 0x1c1447d6, 0x02c82897, 0x21ac9954, 0x3f70f615, + 0x6765fad2, 0x79b99593, 0x5add2450, 0x44014b11, + 0xeaf73dde, 0xf42b529f, 0xd74fe35c, 0xc9938c1d, + 0x918680da, 0x8f5aef9b, 0xac3e5e58, 0xb2e23119, + 0x17e78564, 0x093bea25, 0x2a5f5be6, 0x348334a7, + 0x6c963860, 0x724a5721, 0x512ee6e2, 0x4ff289a3, + 0xe104ff6c, 0xffd8902d, 0xdcbc21ee, 0xc2604eaf, + 0x9a754268, 0x84a92d29, 0xa7cd9cea, 0xb911f3ab, + 0xe4fd1e35, 0xfa217174, 0xd945c0b7, 0xc799aff6, + 0x9f8ca331, 0x8150cc70, 0xa2347db3, 0xbce812f2, + 0x121e643d, 0x0cc20b7c, 0x2fa6babf, 0x317ad5fe, + 0x696fd939, 0x77b3b678, 0x54d707bb, 0x4a0b68fa, + 0xc0c1d64f, 0xde1db90e, 0xfd7908cd, 0xe3a5678c, + 0xbbb06b4b, 0xa56c040a, 0x8608b5c9, 0x98d4da88, + 0x3622ac47, 0x28fec306, 0x0b9a72c5, 0x15461d84, + 0x4d531143, 0x538f7e02, 0x70ebcfc1, 0x6e37a080, + 0x33db4d1e, 0x2d07225f, 0x0e63939c, 0x10bffcdd, + 0x48aaf01a, 0x56769f5b, 0x75122e98, 0x6bce41d9, + 0xc5383716, 0xdbe45857, 0xf880e994, 0xe65c86d5, + 0xbe498a12, 0xa095e553, 0x83f15490, 0x9d2d3bd1, + 0x38288fac, 0x26f4e0ed, 0x0590512e, 0x1b4c3e6f, + 0x435932a8, 0x5d855de9, 0x7ee1ec2a, 0x603d836b, + 0xcecbf5a4, 0xd0179ae5, 0xf3732b26, 0xedaf4467, + 0xb5ba48a0, 0xab6627e1, 0x88029622, 0x96def963, + 0xcb3214fd, 0xd5ee7bbc, 0xf68aca7f, 0xe856a53e, + 0xb043a9f9, 0xae9fc6b8, 0x8dfb777b, 0x9327183a, + 0x3dd16ef5, 0x230d01b4, 0x0069b077, 0x1eb5df36, + 0x46a0d3f1, 0x587cbcb0, 0x7b180d73, 0x65c46232, + 0x2fcf0ac8, 0x31136589, 0x1277d44a, 0x0cabbb0b, + 0x54beb7cc, 0x4a62d88d, 0x6906694e, 0x77da060f, + 0xd92c70c0, 0xc7f01f81, 0xe494ae42, 0xfa48c103, + 0xa25dcdc4, 0xbc81a285, 0x9fe51346, 0x81397c07, + 0xdcd59199, 0xc209fed8, 0xe16d4f1b, 0xffb1205a, + 0xa7a42c9d, 0xb97843dc, 0x9a1cf21f, 0x84c09d5e, + 0x2a36eb91, 0x34ea84d0, 0x178e3513, 0x09525a52, + 0x51475695, 0x4f9b39d4, 0x6cff8817, 0x7223e756, + 0xd726532b, 0xc9fa3c6a, 0xea9e8da9, 0xf442e2e8, + 0xac57ee2f, 0xb28b816e, 0x91ef30ad, 0x8f335fec, + 0x21c52923, 0x3f194662, 0x1c7df7a1, 0x02a198e0, + 0x5ab49427, 0x4468fb66, 0x670c4aa5, 0x79d025e4, + 0x243cc87a, 0x3ae0a73b, 0x198416f8, 0x075879b9, + 0x5f4d757e, 0x41911a3f, 0x62f5abfc, 0x7c29c4bd, + 0xd2dfb272, 0xcc03dd33, 0xef676cf0, 0xf1bb03b1, + 0xa9ae0f76, 0xb7726037, 0x9416d1f4, 0x8acabeb5 + },{ + 0x00000000, 0x9f5fc3df, 0x2063e8ff, 0xbf3c2b20, + 0x40c7d1fe, 0xdf981221, 0x60a43901, 0xfffbfade, + 0x818fa3fc, 0x1ed06023, 0xa1ec4b03, 0x3eb388dc, + 0xc1487202, 0x5e17b1dd, 0xe12b9afd, 0x7e745922, + 0x1dc328b9, 0x829ceb66, 0x3da0c046, 0xa2ff0399, + 0x5d04f947, 0xc25b3a98, 0x7d6711b8, 0xe238d267, + 0x9c4c8b45, 0x0313489a, 0xbc2f63ba, 0x2370a065, + 0xdc8b5abb, 0x43d49964, 0xfce8b244, 0x63b7719b, + 0x3b865172, 0xa4d992ad, 0x1be5b98d, 0x84ba7a52, + 0x7b41808c, 0xe41e4353, 0x5b226873, 0xc47dabac, + 0xba09f28e, 0x25563151, 0x9a6a1a71, 0x0535d9ae, + 0xface2370, 0x6591e0af, 0xdaadcb8f, 0x45f20850, + 0x264579cb, 0xb91aba14, 0x06269134, 0x997952eb, + 0x6682a835, 0xf9dd6bea, 0x46e140ca, 0xd9be8315, + 0xa7cada37, 0x389519e8, 0x87a932c8, 0x18f6f117, + 0xe70d0bc9, 0x7852c816, 0xc76ee336, 0x583120e9, + 0x770ca2e4, 0xe853613b, 0x576f4a1b, 0xc83089c4, + 0x37cb731a, 0xa894b0c5, 0x17a89be5, 0x88f7583a, + 0xf6830118, 0x69dcc2c7, 0xd6e0e9e7, 0x49bf2a38, + 0xb644d0e6, 0x291b1339, 0x96273819, 0x0978fbc6, + 0x6acf8a5d, 0xf5904982, 0x4aac62a2, 0xd5f3a17d, + 0x2a085ba3, 0xb557987c, 0x0a6bb35c, 0x95347083, + 0xeb4029a1, 0x741fea7e, 0xcb23c15e, 0x547c0281, + 0xab87f85f, 0x34d83b80, 0x8be410a0, 0x14bbd37f, + 0x4c8af396, 0xd3d53049, 0x6ce91b69, 0xf3b6d8b6, + 0x0c4d2268, 0x9312e1b7, 0x2c2eca97, 0xb3710948, + 0xcd05506a, 0x525a93b5, 0xed66b895, 0x72397b4a, + 0x8dc28194, 0x129d424b, 0xada1696b, 0x32feaab4, + 0x5149db2f, 0xce1618f0, 0x712a33d0, 0xee75f00f, + 0x118e0ad1, 0x8ed1c90e, 0x31ede22e, 0xaeb221f1, + 0xd0c678d3, 0x4f99bb0c, 0xf0a5902c, 0x6ffa53f3, + 0x9001a92d, 0x0f5e6af2, 0xb06241d2, 0x2f3d820d, + 0xee1945c8, 0x71468617, 0xce7aad37, 0x51256ee8, + 0xaede9436, 0x318157e9, 0x8ebd7cc9, 0x11e2bf16, + 0x6f96e634, 0xf0c925eb, 0x4ff50ecb, 0xd0aacd14, + 0x2f5137ca, 0xb00ef415, 0x0f32df35, 0x906d1cea, + 0xf3da6d71, 0x6c85aeae, 0xd3b9858e, 0x4ce64651, + 0xb31dbc8f, 0x2c427f50, 0x937e5470, 0x0c2197af, + 0x7255ce8d, 0xed0a0d52, 0x52362672, 0xcd69e5ad, + 0x32921f73, 0xadcddcac, 0x12f1f78c, 0x8dae3453, + 0xd59f14ba, 0x4ac0d765, 0xf5fcfc45, 0x6aa33f9a, + 0x9558c544, 0x0a07069b, 0xb53b2dbb, 0x2a64ee64, + 0x5410b746, 0xcb4f7499, 0x74735fb9, 0xeb2c9c66, + 0x14d766b8, 0x8b88a567, 0x34b48e47, 0xabeb4d98, + 0xc85c3c03, 0x5703ffdc, 0xe83fd4fc, 0x77601723, + 0x889bedfd, 0x17c42e22, 0xa8f80502, 0x37a7c6dd, + 0x49d39fff, 0xd68c5c20, 0x69b07700, 0xf6efb4df, + 0x09144e01, 0x964b8dde, 0x2977a6fe, 0xb6286521, + 0x9915e72c, 0x064a24f3, 0xb9760fd3, 0x2629cc0c, + 0xd9d236d2, 0x468df50d, 0xf9b1de2d, 0x66ee1df2, + 0x189a44d0, 0x87c5870f, 0x38f9ac2f, 0xa7a66ff0, + 0x585d952e, 0xc70256f1, 0x783e7dd1, 0xe761be0e, + 0x84d6cf95, 0x1b890c4a, 0xa4b5276a, 0x3beae4b5, + 0xc4111e6b, 0x5b4eddb4, 0xe472f694, 0x7b2d354b, + 0x05596c69, 0x9a06afb6, 0x253a8496, 0xba654749, + 0x459ebd97, 0xdac17e48, 0x65fd5568, 0xfaa296b7, + 0xa293b65e, 0x3dcc7581, 0x82f05ea1, 0x1daf9d7e, + 0xe25467a0, 0x7d0ba47f, 0xc2378f5f, 0x5d684c80, + 0x231c15a2, 0xbc43d67d, 0x037ffd5d, 0x9c203e82, + 0x63dbc45c, 0xfc840783, 0x43b82ca3, 0xdce7ef7c, + 0xbf509ee7, 0x200f5d38, 0x9f337618, 0x006cb5c7, + 0xff974f19, 0x60c88cc6, 0xdff4a7e6, 0x40ab6439, + 0x3edf3d1b, 0xa180fec4, 0x1ebcd5e4, 0x81e3163b, + 0x7e18ece5, 0xe1472f3a, 0x5e7b041a, 0xc124c7c5 + },{ + 0x00000000, 0xc2eee4d1, 0x9b01a6e3, 0x59ef4232, + 0x28df2287, 0xea31c656, 0xb3de8464, 0x713060b5, + 0x51be450e, 0x9350a1df, 0xcabfe3ed, 0x0851073c, + 0x79616789, 0xbb8f8358, 0xe260c16a, 0x208e25bb, + 0xa37c8a1c, 0x61926ecd, 0x387d2cff, 0xfa93c82e, + 0x8ba3a89b, 0x494d4c4a, 0x10a20e78, 0xd24ceaa9, + 0xf2c2cf12, 0x302c2bc3, 0x69c369f1, 0xab2d8d20, + 0xda1ded95, 0x18f30944, 0x411c4b76, 0x83f2afa7, + 0x58257b79, 0x9acb9fa8, 0xc324dd9a, 0x01ca394b, + 0x70fa59fe, 0xb214bd2f, 0xebfbff1d, 0x29151bcc, + 0x099b3e77, 0xcb75daa6, 0x929a9894, 0x50747c45, + 0x21441cf0, 0xe3aaf821, 0xba45ba13, 0x78ab5ec2, + 0xfb59f165, 0x39b715b4, 0x60585786, 0xa2b6b357, + 0xd386d3e2, 0x11683733, 0x48877501, 0x8a6991d0, + 0xaae7b46b, 0x680950ba, 0x31e61288, 0xf308f659, + 0x823896ec, 0x40d6723d, 0x1939300f, 0xdbd7d4de, + 0xb04af6f2, 0x72a41223, 0x2b4b5011, 0xe9a5b4c0, + 0x9895d475, 0x5a7b30a4, 0x03947296, 0xc17a9647, + 0xe1f4b3fc, 0x231a572d, 0x7af5151f, 0xb81bf1ce, + 0xc92b917b, 0x0bc575aa, 0x522a3798, 0x90c4d349, + 0x13367cee, 0xd1d8983f, 0x8837da0d, 0x4ad93edc, + 0x3be95e69, 0xf907bab8, 0xa0e8f88a, 0x62061c5b, + 0x428839e0, 0x8066dd31, 0xd9899f03, 0x1b677bd2, + 0x6a571b67, 0xa8b9ffb6, 0xf156bd84, 0x33b85955, + 0xe86f8d8b, 0x2a81695a, 0x736e2b68, 0xb180cfb9, + 0xc0b0af0c, 0x025e4bdd, 0x5bb109ef, 0x995fed3e, + 0xb9d1c885, 0x7b3f2c54, 0x22d06e66, 0xe03e8ab7, + 0x910eea02, 0x53e00ed3, 0x0a0f4ce1, 0xc8e1a830, + 0x4b130797, 0x89fde346, 0xd012a174, 0x12fc45a5, + 0x63cc2510, 0xa122c1c1, 0xf8cd83f3, 0x3a236722, + 0x1aad4299, 0xd843a648, 0x81ace47a, 0x434200ab, + 0x3272601e, 0xf09c84cf, 0xa973c6fd, 0x6b9d222c, + 0x7e4982a5, 0xbca76674, 0xe5482446, 0x27a6c097, + 0x5696a022, 0x947844f3, 0xcd9706c1, 0x0f79e210, + 0x2ff7c7ab, 0xed19237a, 0xb4f66148, 0x76188599, + 0x0728e52c, 0xc5c601fd, 0x9c2943cf, 0x5ec7a71e, + 0xdd3508b9, 0x1fdbec68, 0x4634ae5a, 0x84da4a8b, + 0xf5ea2a3e, 0x3704ceef, 0x6eeb8cdd, 0xac05680c, + 0x8c8b4db7, 0x4e65a966, 0x178aeb54, 0xd5640f85, + 0xa4546f30, 0x66ba8be1, 0x3f55c9d3, 0xfdbb2d02, + 0x266cf9dc, 0xe4821d0d, 0xbd6d5f3f, 0x7f83bbee, + 0x0eb3db5b, 0xcc5d3f8a, 0x95b27db8, 0x575c9969, + 0x77d2bcd2, 0xb53c5803, 0xecd31a31, 0x2e3dfee0, + 0x5f0d9e55, 0x9de37a84, 0xc40c38b6, 0x06e2dc67, + 0x851073c0, 0x47fe9711, 0x1e11d523, 0xdcff31f2, + 0xadcf5147, 0x6f21b596, 0x36cef7a4, 0xf4201375, + 0xd4ae36ce, 0x1640d21f, 0x4faf902d, 0x8d4174fc, + 0xfc711449, 0x3e9ff098, 0x6770b2aa, 0xa59e567b, + 0xce037457, 0x0ced9086, 0x5502d2b4, 0x97ec3665, + 0xe6dc56d0, 0x2432b201, 0x7dddf033, 0xbf3314e2, + 0x9fbd3159, 0x5d53d588, 0x04bc97ba, 0xc652736b, + 0xb76213de, 0x758cf70f, 0x2c63b53d, 0xee8d51ec, + 0x6d7ffe4b, 0xaf911a9a, 0xf67e58a8, 0x3490bc79, + 0x45a0dccc, 0x874e381d, 0xdea17a2f, 0x1c4f9efe, + 0x3cc1bb45, 0xfe2f5f94, 0xa7c01da6, 0x652ef977, + 0x141e99c2, 0xd6f07d13, 0x8f1f3f21, 0x4df1dbf0, + 0x96260f2e, 0x54c8ebff, 0x0d27a9cd, 0xcfc94d1c, + 0xbef92da9, 0x7c17c978, 0x25f88b4a, 0xe7166f9b, + 0xc7984a20, 0x0576aef1, 0x5c99ecc3, 0x9e770812, + 0xef4768a7, 0x2da98c76, 0x7446ce44, 0xb6a82a95, + 0x355a8532, 0xf7b461e3, 0xae5b23d1, 0x6cb5c700, + 0x1d85a7b5, 0xdf6b4364, 0x86840156, 0x446ae587, + 0x64e4c03c, 0xa60a24ed, 0xffe566df, 0x3d0b820e, + 0x4c3be2bb, 0x8ed5066a, 0xd73a4458, 0x15d4a089 + },{ + 0x00000000, 0xfc93054a, 0xe7fa65d5, 0x1b69609f, + 0xd128a4eb, 0x2dbba1a1, 0x36d2c13e, 0xca41c474, + 0xbc8d2697, 0x401e23dd, 0x5b774342, 0xa7e44608, + 0x6da5827c, 0x91368736, 0x8a5fe7a9, 0x76cce2e3, + 0x67c6226f, 0x9b552725, 0x803c47ba, 0x7caf42f0, + 0xb6ee8684, 0x4a7d83ce, 0x5114e351, 0xad87e61b, + 0xdb4b04f8, 0x27d801b2, 0x3cb1612d, 0xc0226467, + 0x0a63a013, 0xf6f0a559, 0xed99c5c6, 0x110ac08c, + 0xcf8c44de, 0x331f4194, 0x2876210b, 0xd4e52441, + 0x1ea4e035, 0xe237e57f, 0xf95e85e0, 0x05cd80aa, + 0x73016249, 0x8f926703, 0x94fb079c, 0x686802d6, + 0xa229c6a2, 0x5ebac3e8, 0x45d3a377, 0xb940a63d, + 0xa84a66b1, 0x54d963fb, 0x4fb00364, 0xb323062e, + 0x7962c25a, 0x85f1c710, 0x9e98a78f, 0x620ba2c5, + 0x14c74026, 0xe854456c, 0xf33d25f3, 0x0fae20b9, + 0xc5efe4cd, 0x397ce187, 0x22158118, 0xde868452, + 0x81c4e6fd, 0x7d57e3b7, 0x663e8328, 0x9aad8662, + 0x50ec4216, 0xac7f475c, 0xb71627c3, 0x4b852289, + 0x3d49c06a, 0xc1dac520, 0xdab3a5bf, 0x2620a0f5, + 0xec616481, 0x10f261cb, 0x0b9b0154, 0xf708041e, + 0xe602c492, 0x1a91c1d8, 0x01f8a147, 0xfd6ba40d, + 0x372a6079, 0xcbb96533, 0xd0d005ac, 0x2c4300e6, + 0x5a8fe205, 0xa61ce74f, 0xbd7587d0, 0x41e6829a, + 0x8ba746ee, 0x773443a4, 0x6c5d233b, 0x90ce2671, + 0x4e48a223, 0xb2dba769, 0xa9b2c7f6, 0x5521c2bc, + 0x9f6006c8, 0x63f30382, 0x789a631d, 0x84096657, + 0xf2c584b4, 0x0e5681fe, 0x153fe161, 0xe9ace42b, + 0x23ed205f, 0xdf7e2515, 0xc417458a, 0x388440c0, + 0x298e804c, 0xd51d8506, 0xce74e599, 0x32e7e0d3, + 0xf8a624a7, 0x043521ed, 0x1f5c4172, 0xe3cf4438, + 0x9503a6db, 0x6990a391, 0x72f9c30e, 0x8e6ac644, + 0x442b0230, 0xb8b8077a, 0xa3d167e5, 0x5f4262af, + 0x1d55a2bb, 0xe1c6a7f1, 0xfaafc76e, 0x063cc224, + 0xcc7d0650, 0x30ee031a, 0x2b876385, 0xd71466cf, + 0xa1d8842c, 0x5d4b8166, 0x4622e1f9, 0xbab1e4b3, + 0x70f020c7, 0x8c63258d, 0x970a4512, 0x6b994058, + 0x7a9380d4, 0x8600859e, 0x9d69e501, 0x61fae04b, + 0xabbb243f, 0x57282175, 0x4c4141ea, 0xb0d244a0, + 0xc61ea643, 0x3a8da309, 0x21e4c396, 0xdd77c6dc, + 0x173602a8, 0xeba507e2, 0xf0cc677d, 0x0c5f6237, + 0xd2d9e665, 0x2e4ae32f, 0x352383b0, 0xc9b086fa, + 0x03f1428e, 0xff6247c4, 0xe40b275b, 0x18982211, + 0x6e54c0f2, 0x92c7c5b8, 0x89aea527, 0x753da06d, + 0xbf7c6419, 0x43ef6153, 0x588601cc, 0xa4150486, + 0xb51fc40a, 0x498cc140, 0x52e5a1df, 0xae76a495, + 0x643760e1, 0x98a465ab, 0x83cd0534, 0x7f5e007e, + 0x0992e29d, 0xf501e7d7, 0xee688748, 0x12fb8202, + 0xd8ba4676, 0x2429433c, 0x3f4023a3, 0xc3d326e9, + 0x9c914446, 0x6002410c, 0x7b6b2193, 0x87f824d9, + 0x4db9e0ad, 0xb12ae5e7, 0xaa438578, 0x56d08032, + 0x201c62d1, 0xdc8f679b, 0xc7e60704, 0x3b75024e, + 0xf134c63a, 0x0da7c370, 0x16cea3ef, 0xea5da6a5, + 0xfb576629, 0x07c46363, 0x1cad03fc, 0xe03e06b6, + 0x2a7fc2c2, 0xd6ecc788, 0xcd85a717, 0x3116a25d, + 0x47da40be, 0xbb4945f4, 0xa020256b, 0x5cb32021, + 0x96f2e455, 0x6a61e11f, 0x71088180, 0x8d9b84ca, + 0x531d0098, 0xaf8e05d2, 0xb4e7654d, 0x48746007, + 0x8235a473, 0x7ea6a139, 0x65cfc1a6, 0x995cc4ec, + 0xef90260f, 0x13032345, 0x086a43da, 0xf4f94690, + 0x3eb882e4, 0xc22b87ae, 0xd942e731, 0x25d1e27b, + 0x34db22f7, 0xc84827bd, 0xd3214722, 0x2fb24268, + 0xe5f3861c, 0x19608356, 0x0209e3c9, 0xfe9ae683, + 0x88560460, 0x74c5012a, 0x6fac61b5, 0x933f64ff, + 0x597ea08b, 0xa5eda5c1, 0xbe84c55e, 0x4217c014 + },{ + 0x00000000, 0x3aab4576, 0x75568aec, 0x4ffdcf9a, + 0xeaad15d8, 0xd00650ae, 0x9ffb9f34, 0xa550da42, + 0xcb8644f1, 0xf12d0187, 0xbed0ce1d, 0x847b8b6b, + 0x212b5129, 0x1b80145f, 0x547ddbc5, 0x6ed69eb3, + 0x89d0e6a3, 0xb37ba3d5, 0xfc866c4f, 0xc62d2939, + 0x637df37b, 0x59d6b60d, 0x162b7997, 0x2c803ce1, + 0x4256a252, 0x78fde724, 0x370028be, 0x0dab6dc8, + 0xa8fbb78a, 0x9250f2fc, 0xddad3d66, 0xe7067810, + 0x0d7da207, 0x37d6e771, 0x782b28eb, 0x42806d9d, + 0xe7d0b7df, 0xdd7bf2a9, 0x92863d33, 0xa82d7845, + 0xc6fbe6f6, 0xfc50a380, 0xb3ad6c1a, 0x8906296c, + 0x2c56f32e, 0x16fdb658, 0x590079c2, 0x63ab3cb4, + 0x84ad44a4, 0xbe0601d2, 0xf1fbce48, 0xcb508b3e, + 0x6e00517c, 0x54ab140a, 0x1b56db90, 0x21fd9ee6, + 0x4f2b0055, 0x75804523, 0x3a7d8ab9, 0x00d6cfcf, + 0xa586158d, 0x9f2d50fb, 0xd0d09f61, 0xea7bda17, + 0x1afb440e, 0x20500178, 0x6fadcee2, 0x55068b94, + 0xf05651d6, 0xcafd14a0, 0x8500db3a, 0xbfab9e4c, + 0xd17d00ff, 0xebd64589, 0xa42b8a13, 0x9e80cf65, + 0x3bd01527, 0x017b5051, 0x4e869fcb, 0x742ddabd, + 0x932ba2ad, 0xa980e7db, 0xe67d2841, 0xdcd66d37, + 0x7986b775, 0x432df203, 0x0cd03d99, 0x367b78ef, + 0x58ade65c, 0x6206a32a, 0x2dfb6cb0, 0x175029c6, + 0xb200f384, 0x88abb6f2, 0xc7567968, 0xfdfd3c1e, + 0x1786e609, 0x2d2da37f, 0x62d06ce5, 0x587b2993, + 0xfd2bf3d1, 0xc780b6a7, 0x887d793d, 0xb2d63c4b, + 0xdc00a2f8, 0xe6abe78e, 0xa9562814, 0x93fd6d62, + 0x36adb720, 0x0c06f256, 0x43fb3dcc, 0x795078ba, + 0x9e5600aa, 0xa4fd45dc, 0xeb008a46, 0xd1abcf30, + 0x74fb1572, 0x4e505004, 0x01ad9f9e, 0x3b06dae8, + 0x55d0445b, 0x6f7b012d, 0x2086ceb7, 0x1a2d8bc1, + 0xbf7d5183, 0x85d614f5, 0xca2bdb6f, 0xf0809e19, + 0x35f6881c, 0x0f5dcd6a, 0x40a002f0, 0x7a0b4786, + 0xdf5b9dc4, 0xe5f0d8b2, 0xaa0d1728, 0x90a6525e, + 0xfe70cced, 0xc4db899b, 0x8b264601, 0xb18d0377, + 0x14ddd935, 0x2e769c43, 0x618b53d9, 0x5b2016af, + 0xbc266ebf, 0x868d2bc9, 0xc970e453, 0xf3dba125, + 0x568b7b67, 0x6c203e11, 0x23ddf18b, 0x1976b4fd, + 0x77a02a4e, 0x4d0b6f38, 0x02f6a0a2, 0x385de5d4, + 0x9d0d3f96, 0xa7a67ae0, 0xe85bb57a, 0xd2f0f00c, + 0x388b2a1b, 0x02206f6d, 0x4ddda0f7, 0x7776e581, + 0xd2263fc3, 0xe88d7ab5, 0xa770b52f, 0x9ddbf059, + 0xf30d6eea, 0xc9a62b9c, 0x865be406, 0xbcf0a170, + 0x19a07b32, 0x230b3e44, 0x6cf6f1de, 0x565db4a8, + 0xb15bccb8, 0x8bf089ce, 0xc40d4654, 0xfea60322, + 0x5bf6d960, 0x615d9c16, 0x2ea0538c, 0x140b16fa, + 0x7add8849, 0x4076cd3f, 0x0f8b02a5, 0x352047d3, + 0x90709d91, 0xaadbd8e7, 0xe526177d, 0xdf8d520b, + 0x2f0dcc12, 0x15a68964, 0x5a5b46fe, 0x60f00388, + 0xc5a0d9ca, 0xff0b9cbc, 0xb0f65326, 0x8a5d1650, + 0xe48b88e3, 0xde20cd95, 0x91dd020f, 0xab764779, + 0x0e269d3b, 0x348dd84d, 0x7b7017d7, 0x41db52a1, + 0xa6dd2ab1, 0x9c766fc7, 0xd38ba05d, 0xe920e52b, + 0x4c703f69, 0x76db7a1f, 0x3926b585, 0x038df0f3, + 0x6d5b6e40, 0x57f02b36, 0x180de4ac, 0x22a6a1da, + 0x87f67b98, 0xbd5d3eee, 0xf2a0f174, 0xc80bb402, + 0x22706e15, 0x18db2b63, 0x5726e4f9, 0x6d8da18f, + 0xc8dd7bcd, 0xf2763ebb, 0xbd8bf121, 0x8720b457, + 0xe9f62ae4, 0xd35d6f92, 0x9ca0a008, 0xa60be57e, + 0x035b3f3c, 0x39f07a4a, 0x760db5d0, 0x4ca6f0a6, + 0xaba088b6, 0x910bcdc0, 0xdef6025a, 0xe45d472c, + 0x410d9d6e, 0x7ba6d818, 0x345b1782, 0x0ef052f4, + 0x6026cc47, 0x5a8d8931, 0x157046ab, 0x2fdb03dd, + 0x8a8bd99f, 0xb0209ce9, 0xffdd5373, 0xc5761605 + },{ + 0x00000000, 0x6bed1038, 0xd7da2070, 0xbc373048, + 0xb1682fa1, 0xda853f99, 0x66b20fd1, 0x0d5f1fe9, + 0x7c0c3003, 0x17e1203b, 0xabd61073, 0xc03b004b, + 0xcd641fa2, 0xa6890f9a, 0x1abe3fd2, 0x71532fea, + 0xf8186006, 0x93f5703e, 0x2fc24076, 0x442f504e, + 0x49704fa7, 0x229d5f9f, 0x9eaa6fd7, 0xf5477fef, + 0x84145005, 0xeff9403d, 0x53ce7075, 0x3823604d, + 0x357c7fa4, 0x5e916f9c, 0xe2a65fd4, 0x894b4fec, + 0xeeecaf4d, 0x8501bf75, 0x39368f3d, 0x52db9f05, + 0x5f8480ec, 0x346990d4, 0x885ea09c, 0xe3b3b0a4, + 0x92e09f4e, 0xf90d8f76, 0x453abf3e, 0x2ed7af06, + 0x2388b0ef, 0x4865a0d7, 0xf452909f, 0x9fbf80a7, + 0x16f4cf4b, 0x7d19df73, 0xc12eef3b, 0xaac3ff03, + 0xa79ce0ea, 0xcc71f0d2, 0x7046c09a, 0x1babd0a2, + 0x6af8ff48, 0x0115ef70, 0xbd22df38, 0xd6cfcf00, + 0xdb90d0e9, 0xb07dc0d1, 0x0c4af099, 0x67a7e0a1, + 0xc30531db, 0xa8e821e3, 0x14df11ab, 0x7f320193, + 0x726d1e7a, 0x19800e42, 0xa5b73e0a, 0xce5a2e32, + 0xbf0901d8, 0xd4e411e0, 0x68d321a8, 0x033e3190, + 0x0e612e79, 0x658c3e41, 0xd9bb0e09, 0xb2561e31, + 0x3b1d51dd, 0x50f041e5, 0xecc771ad, 0x872a6195, + 0x8a757e7c, 0xe1986e44, 0x5daf5e0c, 0x36424e34, + 0x471161de, 0x2cfc71e6, 0x90cb41ae, 0xfb265196, + 0xf6794e7f, 0x9d945e47, 0x21a36e0f, 0x4a4e7e37, + 0x2de99e96, 0x46048eae, 0xfa33bee6, 0x91deaede, + 0x9c81b137, 0xf76ca10f, 0x4b5b9147, 0x20b6817f, + 0x51e5ae95, 0x3a08bead, 0x863f8ee5, 0xedd29edd, + 0xe08d8134, 0x8b60910c, 0x3757a144, 0x5cbab17c, + 0xd5f1fe90, 0xbe1ceea8, 0x022bdee0, 0x69c6ced8, + 0x6499d131, 0x0f74c109, 0xb343f141, 0xd8aee179, + 0xa9fdce93, 0xc210deab, 0x7e27eee3, 0x15cafedb, + 0x1895e132, 0x7378f10a, 0xcf4fc142, 0xa4a2d17a, + 0x98d60cf7, 0xf33b1ccf, 0x4f0c2c87, 0x24e13cbf, + 0x29be2356, 0x4253336e, 0xfe640326, 0x9589131e, + 0xe4da3cf4, 0x8f372ccc, 0x33001c84, 0x58ed0cbc, + 0x55b21355, 0x3e5f036d, 0x82683325, 0xe985231d, + 0x60ce6cf1, 0x0b237cc9, 0xb7144c81, 0xdcf95cb9, + 0xd1a64350, 0xba4b5368, 0x067c6320, 0x6d917318, + 0x1cc25cf2, 0x772f4cca, 0xcb187c82, 0xa0f56cba, + 0xadaa7353, 0xc647636b, 0x7a705323, 0x119d431b, + 0x763aa3ba, 0x1dd7b382, 0xa1e083ca, 0xca0d93f2, + 0xc7528c1b, 0xacbf9c23, 0x1088ac6b, 0x7b65bc53, + 0x0a3693b9, 0x61db8381, 0xddecb3c9, 0xb601a3f1, + 0xbb5ebc18, 0xd0b3ac20, 0x6c849c68, 0x07698c50, + 0x8e22c3bc, 0xe5cfd384, 0x59f8e3cc, 0x3215f3f4, + 0x3f4aec1d, 0x54a7fc25, 0xe890cc6d, 0x837ddc55, + 0xf22ef3bf, 0x99c3e387, 0x25f4d3cf, 0x4e19c3f7, + 0x4346dc1e, 0x28abcc26, 0x949cfc6e, 0xff71ec56, + 0x5bd33d2c, 0x303e2d14, 0x8c091d5c, 0xe7e40d64, + 0xeabb128d, 0x815602b5, 0x3d6132fd, 0x568c22c5, + 0x27df0d2f, 0x4c321d17, 0xf0052d5f, 0x9be83d67, + 0x96b7228e, 0xfd5a32b6, 0x416d02fe, 0x2a8012c6, + 0xa3cb5d2a, 0xc8264d12, 0x74117d5a, 0x1ffc6d62, + 0x12a3728b, 0x794e62b3, 0xc57952fb, 0xae9442c3, + 0xdfc76d29, 0xb42a7d11, 0x081d4d59, 0x63f05d61, + 0x6eaf4288, 0x054252b0, 0xb97562f8, 0xd29872c0, + 0xb53f9261, 0xded28259, 0x62e5b211, 0x0908a229, + 0x0457bdc0, 0x6fbaadf8, 0xd38d9db0, 0xb8608d88, + 0xc933a262, 0xa2deb25a, 0x1ee98212, 0x7504922a, + 0x785b8dc3, 0x13b69dfb, 0xaf81adb3, 0xc46cbd8b, + 0x4d27f267, 0x26cae25f, 0x9afdd217, 0xf110c22f, + 0xfc4fddc6, 0x97a2cdfe, 0x2b95fdb6, 0x4078ed8e, + 0x312bc264, 0x5ac6d25c, 0xe6f1e214, 0x8d1cf22c, + 0x8043edc5, 0xebaefdfd, 0x5799cdb5, 0x3c74dd8d + },{ + 0x00000000, 0x2f7076af, 0x5ee0ed5e, 0x71909bf1, + 0xbdc1dabc, 0x92b1ac13, 0xe32137e2, 0xcc51414d, + 0x655fda39, 0x4a2fac96, 0x3bbf3767, 0x14cf41c8, + 0xd89e0085, 0xf7ee762a, 0x867eeddb, 0xa90e9b74, + 0xcabfb472, 0xe5cfc2dd, 0x945f592c, 0xbb2f2f83, + 0x777e6ece, 0x580e1861, 0x299e8390, 0x06eef53f, + 0xafe06e4b, 0x809018e4, 0xf1008315, 0xde70f5ba, + 0x1221b4f7, 0x3d51c258, 0x4cc159a9, 0x63b12f06, + 0x8ba307a5, 0xa4d3710a, 0xd543eafb, 0xfa339c54, + 0x3662dd19, 0x1912abb6, 0x68823047, 0x47f246e8, + 0xeefcdd9c, 0xc18cab33, 0xb01c30c2, 0x9f6c466d, + 0x533d0720, 0x7c4d718f, 0x0dddea7e, 0x22ad9cd1, + 0x411cb3d7, 0x6e6cc578, 0x1ffc5e89, 0x308c2826, + 0xfcdd696b, 0xd3ad1fc4, 0xa23d8435, 0x8d4df29a, + 0x244369ee, 0x0b331f41, 0x7aa384b0, 0x55d3f21f, + 0x9982b352, 0xb6f2c5fd, 0xc7625e0c, 0xe81228a3, + 0x099a600b, 0x26ea16a4, 0x577a8d55, 0x780afbfa, + 0xb45bbab7, 0x9b2bcc18, 0xeabb57e9, 0xc5cb2146, + 0x6cc5ba32, 0x43b5cc9d, 0x3225576c, 0x1d5521c3, + 0xd104608e, 0xfe741621, 0x8fe48dd0, 0xa094fb7f, + 0xc325d479, 0xec55a2d6, 0x9dc53927, 0xb2b54f88, + 0x7ee40ec5, 0x5194786a, 0x2004e39b, 0x0f749534, + 0xa67a0e40, 0x890a78ef, 0xf89ae31e, 0xd7ea95b1, + 0x1bbbd4fc, 0x34cba253, 0x455b39a2, 0x6a2b4f0d, + 0x823967ae, 0xad491101, 0xdcd98af0, 0xf3a9fc5f, + 0x3ff8bd12, 0x1088cbbd, 0x6118504c, 0x4e6826e3, + 0xe766bd97, 0xc816cb38, 0xb98650c9, 0x96f62666, + 0x5aa7672b, 0x75d71184, 0x04478a75, 0x2b37fcda, + 0x4886d3dc, 0x67f6a573, 0x16663e82, 0x3916482d, + 0xf5470960, 0xda377fcf, 0xaba7e43e, 0x84d79291, + 0x2dd909e5, 0x02a97f4a, 0x7339e4bb, 0x5c499214, + 0x9018d359, 0xbf68a5f6, 0xcef83e07, 0xe18848a8, + 0x1334c016, 0x3c44b6b9, 0x4dd42d48, 0x62a45be7, + 0xaef51aaa, 0x81856c05, 0xf015f7f4, 0xdf65815b, + 0x766b1a2f, 0x591b6c80, 0x288bf771, 0x07fb81de, + 0xcbaac093, 0xe4dab63c, 0x954a2dcd, 0xba3a5b62, + 0xd98b7464, 0xf6fb02cb, 0x876b993a, 0xa81bef95, + 0x644aaed8, 0x4b3ad877, 0x3aaa4386, 0x15da3529, + 0xbcd4ae5d, 0x93a4d8f2, 0xe2344303, 0xcd4435ac, + 0x011574e1, 0x2e65024e, 0x5ff599bf, 0x7085ef10, + 0x9897c7b3, 0xb7e7b11c, 0xc6772aed, 0xe9075c42, + 0x25561d0f, 0x0a266ba0, 0x7bb6f051, 0x54c686fe, + 0xfdc81d8a, 0xd2b86b25, 0xa328f0d4, 0x8c58867b, + 0x4009c736, 0x6f79b199, 0x1ee92a68, 0x31995cc7, + 0x522873c1, 0x7d58056e, 0x0cc89e9f, 0x23b8e830, + 0xefe9a97d, 0xc099dfd2, 0xb1094423, 0x9e79328c, + 0x3777a9f8, 0x1807df57, 0x699744a6, 0x46e73209, + 0x8ab67344, 0xa5c605eb, 0xd4569e1a, 0xfb26e8b5, + 0x1aaea01d, 0x35ded6b2, 0x444e4d43, 0x6b3e3bec, + 0xa76f7aa1, 0x881f0c0e, 0xf98f97ff, 0xd6ffe150, + 0x7ff17a24, 0x50810c8b, 0x2111977a, 0x0e61e1d5, + 0xc230a098, 0xed40d637, 0x9cd04dc6, 0xb3a03b69, + 0xd011146f, 0xff6162c0, 0x8ef1f931, 0xa1818f9e, + 0x6dd0ced3, 0x42a0b87c, 0x3330238d, 0x1c405522, + 0xb54ece56, 0x9a3eb8f9, 0xebae2308, 0xc4de55a7, + 0x088f14ea, 0x27ff6245, 0x566ff9b4, 0x791f8f1b, + 0x910da7b8, 0xbe7dd117, 0xcfed4ae6, 0xe09d3c49, + 0x2ccc7d04, 0x03bc0bab, 0x722c905a, 0x5d5ce6f5, + 0xf4527d81, 0xdb220b2e, 0xaab290df, 0x85c2e670, + 0x4993a73d, 0x66e3d192, 0x17734a63, 0x38033ccc, + 0x5bb213ca, 0x74c26565, 0x0552fe94, 0x2a22883b, + 0xe673c976, 0xc903bfd9, 0xb8932428, 0x97e35287, + 0x3eedc9f3, 0x119dbf5c, 0x600d24ad, 0x4f7d5202, + 0x832c134f, 0xac5c65e0, 0xddccfe11, 0xf2bc88be + },{ + 0x00000000, 0x2669802c, 0x4cd30058, 0x6aba8074, + 0x99a600b0, 0xbfcf809c, 0xd57500e8, 0xf31c80c4, + 0x2d906e21, 0x0bf9ee0d, 0x61436e79, 0x472aee55, + 0xb4366e91, 0x925feebd, 0xf8e56ec9, 0xde8ceee5, + 0x5b20dc42, 0x7d495c6e, 0x17f3dc1a, 0x319a5c36, + 0xc286dcf2, 0xe4ef5cde, 0x8e55dcaa, 0xa83c5c86, + 0x76b0b263, 0x50d9324f, 0x3a63b23b, 0x1c0a3217, + 0xef16b2d3, 0xc97f32ff, 0xa3c5b28b, 0x85ac32a7, + 0xb641b884, 0x902838a8, 0xfa92b8dc, 0xdcfb38f0, + 0x2fe7b834, 0x098e3818, 0x6334b86c, 0x455d3840, + 0x9bd1d6a5, 0xbdb85689, 0xd702d6fd, 0xf16b56d1, + 0x0277d615, 0x241e5639, 0x4ea4d64d, 0x68cd5661, + 0xed6164c6, 0xcb08e4ea, 0xa1b2649e, 0x87dbe4b2, + 0x74c76476, 0x52aee45a, 0x3814642e, 0x1e7de402, + 0xc0f10ae7, 0xe6988acb, 0x8c220abf, 0xaa4b8a93, + 0x59570a57, 0x7f3e8a7b, 0x15840a0f, 0x33ed8a23, + 0x725f1e49, 0x54369e65, 0x3e8c1e11, 0x18e59e3d, + 0xebf91ef9, 0xcd909ed5, 0xa72a1ea1, 0x81439e8d, + 0x5fcf7068, 0x79a6f044, 0x131c7030, 0x3575f01c, + 0xc66970d8, 0xe000f0f4, 0x8aba7080, 0xacd3f0ac, + 0x297fc20b, 0x0f164227, 0x65acc253, 0x43c5427f, + 0xb0d9c2bb, 0x96b04297, 0xfc0ac2e3, 0xda6342cf, + 0x04efac2a, 0x22862c06, 0x483cac72, 0x6e552c5e, + 0x9d49ac9a, 0xbb202cb6, 0xd19aacc2, 0xf7f32cee, + 0xc41ea6cd, 0xe27726e1, 0x88cda695, 0xaea426b9, + 0x5db8a67d, 0x7bd12651, 0x116ba625, 0x37022609, + 0xe98ec8ec, 0xcfe748c0, 0xa55dc8b4, 0x83344898, + 0x7028c85c, 0x56414870, 0x3cfbc804, 0x1a924828, + 0x9f3e7a8f, 0xb957faa3, 0xd3ed7ad7, 0xf584fafb, + 0x06987a3f, 0x20f1fa13, 0x4a4b7a67, 0x6c22fa4b, + 0xb2ae14ae, 0x94c79482, 0xfe7d14f6, 0xd81494da, + 0x2b08141e, 0x0d619432, 0x67db1446, 0x41b2946a, + 0xe4be3c92, 0xc2d7bcbe, 0xa86d3cca, 0x8e04bce6, + 0x7d183c22, 0x5b71bc0e, 0x31cb3c7a, 0x17a2bc56, + 0xc92e52b3, 0xef47d29f, 0x85fd52eb, 0xa394d2c7, + 0x50885203, 0x76e1d22f, 0x1c5b525b, 0x3a32d277, + 0xbf9ee0d0, 0x99f760fc, 0xf34de088, 0xd52460a4, + 0x2638e060, 0x0051604c, 0x6aebe038, 0x4c826014, + 0x920e8ef1, 0xb4670edd, 0xdedd8ea9, 0xf8b40e85, + 0x0ba88e41, 0x2dc10e6d, 0x477b8e19, 0x61120e35, + 0x52ff8416, 0x7496043a, 0x1e2c844e, 0x38450462, + 0xcb5984a6, 0xed30048a, 0x878a84fe, 0xa1e304d2, + 0x7f6fea37, 0x59066a1b, 0x33bcea6f, 0x15d56a43, + 0xe6c9ea87, 0xc0a06aab, 0xaa1aeadf, 0x8c736af3, + 0x09df5854, 0x2fb6d878, 0x450c580c, 0x6365d820, + 0x907958e4, 0xb610d8c8, 0xdcaa58bc, 0xfac3d890, + 0x244f3675, 0x0226b659, 0x689c362d, 0x4ef5b601, + 0xbde936c5, 0x9b80b6e9, 0xf13a369d, 0xd753b6b1, + 0x96e122db, 0xb088a2f7, 0xda322283, 0xfc5ba2af, + 0x0f47226b, 0x292ea247, 0x43942233, 0x65fda21f, + 0xbb714cfa, 0x9d18ccd6, 0xf7a24ca2, 0xd1cbcc8e, + 0x22d74c4a, 0x04becc66, 0x6e044c12, 0x486dcc3e, + 0xcdc1fe99, 0xeba87eb5, 0x8112fec1, 0xa77b7eed, + 0x5467fe29, 0x720e7e05, 0x18b4fe71, 0x3edd7e5d, + 0xe05190b8, 0xc6381094, 0xac8290e0, 0x8aeb10cc, + 0x79f79008, 0x5f9e1024, 0x35249050, 0x134d107c, + 0x20a09a5f, 0x06c91a73, 0x6c739a07, 0x4a1a1a2b, + 0xb9069aef, 0x9f6f1ac3, 0xf5d59ab7, 0xd3bc1a9b, + 0x0d30f47e, 0x2b597452, 0x41e3f426, 0x678a740a, + 0x9496f4ce, 0xb2ff74e2, 0xd845f496, 0xfe2c74ba, + 0x7b80461d, 0x5de9c631, 0x37534645, 0x113ac669, + 0xe22646ad, 0xc44fc681, 0xaef546f5, 0x889cc6d9, + 0x5610283c, 0x7079a810, 0x1ac32864, 0x3caaa848, + 0xcfb6288c, 0xe9dfa8a0, 0x836528d4, 0xa50ca8f8 + } +}; diff --git a/src/third_party/wiredtiger/src/checksum/zseries/vx-insn.h b/src/third_party/wiredtiger/src/checksum/zseries/vx-insn.h new file mode 100644 index 00000000000..4c78290b58b --- /dev/null +++ b/src/third_party/wiredtiger/src/checksum/zseries/vx-insn.h @@ -0,0 +1,480 @@ +/* + * Support for Vector Instructions + * + * Assembler macros to generate .byte/.word code for particular + * vector instructions that are supported by recent binutils (>= 2.26) only. + * + * Copyright IBM Corp. 2015 + * Author(s): Hendrik Brueckner + */ + +#ifndef __ASM_S390_VX_INSN_H +#define __ASM_S390_VX_INSN_H + +/* Boilerplate for function entry points */ +#define WT_CRC32_ENTRY(name) \ +.globl name; \ +.align 4, 0x90; \ +name: + +/* Macros to generate vector instruction byte code */ + +#define REG_NUM_INVALID 255 + +/* GR_NUM - Retrieve general-purpose register number + * + * @opd: Operand to store register number + * @r64: String designation register in the format "%rN" + */ +.macro GR_NUM opd gr + \opd = REG_NUM_INVALID + .ifc \gr,%r0 + \opd = 0 + .endif + .ifc \gr,%r1 + \opd = 1 + .endif + .ifc \gr,%r2 + \opd = 2 + .endif + .ifc \gr,%r3 + \opd = 3 + .endif + .ifc \gr,%r4 + \opd = 4 + .endif + .ifc \gr,%r5 + \opd = 5 + .endif + .ifc \gr,%r6 + \opd = 6 + .endif + .ifc \gr,%r7 + \opd = 7 + .endif + .ifc \gr,%r8 + \opd = 8 + .endif + .ifc \gr,%r9 + \opd = 9 + .endif + .ifc \gr,%r10 + \opd = 10 + .endif + .ifc \gr,%r11 + \opd = 11 + .endif + .ifc \gr,%r12 + \opd = 12 + .endif + .ifc \gr,%r13 + \opd = 13 + .endif + .ifc \gr,%r14 + \opd = 14 + .endif + .ifc \gr,%r15 + \opd = 15 + .endif + .if \opd == REG_NUM_INVALID + .error "Invalid general-purpose register designation: \gr" + .endif +.endm + +/* VX_R() - Macro to encode the VX_NUM into the instruction */ +#define VX_R(v) (v & 0x0F) + +/* VX_NUM - Retrieve vector register number + * + * @opd: Operand to store register number + * @vxr: String designation register in the format "%vN" + * + * The vector register number is used for as input number to the + * instruction and, as well as, to compute the RXB field of the + * instruction. To encode the particular vector register number, + * use the VX_R(v) macro to extract the instruction opcode. + */ +.macro VX_NUM opd vxr + \opd = REG_NUM_INVALID + .ifc \vxr,%v0 + \opd = 0 + .endif + .ifc \vxr,%v1 + \opd = 1 + .endif + .ifc \vxr,%v2 + \opd = 2 + .endif + .ifc \vxr,%v3 + \opd = 3 + .endif + .ifc \vxr,%v4 + \opd = 4 + .endif + .ifc \vxr,%v5 + \opd = 5 + .endif + .ifc \vxr,%v6 + \opd = 6 + .endif + .ifc \vxr,%v7 + \opd = 7 + .endif + .ifc \vxr,%v8 + \opd = 8 + .endif + .ifc \vxr,%v9 + \opd = 9 + .endif + .ifc \vxr,%v10 + \opd = 10 + .endif + .ifc \vxr,%v11 + \opd = 11 + .endif + .ifc \vxr,%v12 + \opd = 12 + .endif + .ifc \vxr,%v13 + \opd = 13 + .endif + .ifc \vxr,%v14 + \opd = 14 + .endif + .ifc \vxr,%v15 + \opd = 15 + .endif + .ifc \vxr,%v16 + \opd = 16 + .endif + .ifc \vxr,%v17 + \opd = 17 + .endif + .ifc \vxr,%v18 + \opd = 18 + .endif + .ifc \vxr,%v19 + \opd = 19 + .endif + .ifc \vxr,%v20 + \opd = 20 + .endif + .ifc \vxr,%v21 + \opd = 21 + .endif + .ifc \vxr,%v22 + \opd = 22 + .endif + .ifc \vxr,%v23 + \opd = 23 + .endif + .ifc \vxr,%v24 + \opd = 24 + .endif + .ifc \vxr,%v25 + \opd = 25 + .endif + .ifc \vxr,%v26 + \opd = 26 + .endif + .ifc \vxr,%v27 + \opd = 27 + .endif + .ifc \vxr,%v28 + \opd = 28 + .endif + .ifc \vxr,%v29 + \opd = 29 + .endif + .ifc \vxr,%v30 + \opd = 30 + .endif + .ifc \vxr,%v31 + \opd = 31 + .endif + .if \opd == REG_NUM_INVALID + .error "Invalid vector register designation: \vxr" + .endif +.endm + +/* RXB - Compute most significant bit used vector registers + * + * @rxb: Operand to store computed RXB value + * @v1: First vector register designated operand + * @v2: Second vector register designated operand + * @v3: Third vector register designated operand + * @v4: Fourth vector register designated operand + */ +.macro RXB rxb v1 v2=0 v3=0 v4=0 + \rxb = 0 + .if \v1 & 0x10 + \rxb = \rxb | 0x08 + .endif + .if \v2 & 0x10 + \rxb = \rxb | 0x04 + .endif + .if \v3 & 0x10 + \rxb = \rxb | 0x02 + .endif + .if \v4 & 0x10 + \rxb = \rxb | 0x01 + .endif +.endm + +/* MRXB - Generate Element Size Control and RXB value + * + * @m: Element size control + * @v1: First vector register designated operand (for RXB) + * @v2: Second vector register designated operand (for RXB) + * @v3: Third vector register designated operand (for RXB) + * @v4: Fourth vector register designated operand (for RXB) + */ +.macro MRXB m v1 v2=0 v3=0 v4=0 + rxb = 0 + RXB rxb, \v1, \v2, \v3, \v4 + .byte (\m << 4) | rxb +.endm + +/* MRXBOPC - Generate Element Size Control, RXB, and final Opcode fields + * + * @m: Element size control + * @opc: Opcode + * @v1: First vector register designated operand (for RXB) + * @v2: Second vector register designated operand (for RXB) + * @v3: Third vector register designated operand (for RXB) + * @v4: Fourth vector register designated operand (for RXB) + */ +.macro MRXBOPC m opc v1 v2=0 v3=0 v4=0 + MRXB \m, \v1, \v2, \v3, \v4 + .byte \opc +.endm + +/* Vector support instructions */ + +/* VECTOR GENERATE BYTE MASK */ +.macro VGBM vr imm2 + VX_NUM v1, \vr + .word (0xE700 | (VX_R(v1) << 4)) + .word \imm2 + MRXBOPC 0, 0x44, v1 +.endm +.macro VZERO vxr + VGBM \vxr, 0 +.endm +.macro VONE vxr + VGBM \vxr, 0xFFFF +.endm + +/* VECTOR LOAD VR ELEMENT FROM GR */ +.macro VLVG v, gr, disp, m + VX_NUM v1, \v + GR_NUM b2, "%r0" + GR_NUM r3, \gr + .word 0xE700 | (VX_R(v1) << 4) | r3 + .word (b2 << 12) | (\disp) + MRXBOPC \m, 0x22, v1 +.endm +.macro VLVGB v, gr, index, base + VLVG \v, \gr, \index, \base, 0 +.endm +.macro VLVGH v, gr, index + VLVG \v, \gr, \index, 1 +.endm +.macro VLVGF v, gr, index + VLVG \v, \gr, \index, 2 +.endm +.macro VLVGG v, gr, index + VLVG \v, \gr, \index, 3 +.endm + +/* VECTOR LOAD */ +.macro VL v, disp, index="%r0", base + VX_NUM v1, \v + GR_NUM x2, \index + GR_NUM b2, \base + .word 0xE700 | (VX_R(v1) << 4) | x2 + .word (b2 << 12) | (\disp) + MRXBOPC 0, 0x06, v1 +.endm + +/* VECTOR LOAD ELEMENT */ +.macro VLEx vr1, disp, index="%r0", base, m3, opc + VX_NUM v1, \vr1 + GR_NUM x2, \index + GR_NUM b2, \base + .word 0xE700 | (VX_R(v1) << 4) | x2 + .word (b2 << 12) | (\disp) + MRXBOPC \m3, \opc, v1 +.endm +.macro VLEB vr1, disp, index="%r0", base, m3 + VLEx \vr1, \disp, \index, \base, \m3, 0x00 +.endm +.macro VLEH vr1, disp, index="%r0", base, m3 + VLEx \vr1, \disp, \index, \base, \m3, 0x01 +.endm +.macro VLEF vr1, disp, index="%r0", base, m3 + VLEx \vr1, \disp, \index, \base, \m3, 0x03 +.endm +.macro VLEG vr1, disp, index="%r0", base, m3 + VLEx \vr1, \disp, \index, \base, \m3, 0x02 +.endm + +/* VECTOR LOAD ELEMENT IMMEDIATE */ +.macro VLEIx vr1, imm2, m3, opc + VX_NUM v1, \vr1 + .word 0xE700 | (VX_R(v1) << 4) + .word \imm2 + MRXBOPC \m3, \opc, v1 +.endm +.macro VLEIB vr1, imm2, index + VLEIx \vr1, \imm2, \index, 0x40 +.endm +.macro VLEIH vr1, imm2, index + VLEIx \vr1, \imm2, \index, 0x41 +.endm +.macro VLEIF vr1, imm2, index + VLEIx \vr1, \imm2, \index, 0x43 +.endm +.macro VLEIG vr1, imm2, index + VLEIx \vr1, \imm2, \index, 0x42 +.endm + +/* VECTOR LOAD GR FROM VR ELEMENT */ +.macro VLGV gr, vr, disp, base="%r0", m + GR_NUM r1, \gr + GR_NUM b2, \base + VX_NUM v3, \vr + .word 0xE700 | (r1 << 4) | VX_R(v3) + .word (b2 << 12) | (\disp) + MRXBOPC \m, 0x21, v3 +.endm +.macro VLGVB gr, vr, disp, base="%r0" + VLGV \gr, \vr, \disp, \base, 0 +.endm +.macro VLGVH gr, vr, disp, base="%r0" + VLGV \gr, \vr, \disp, \base, 1 +.endm +.macro VLGVF gr, vr, disp, base="%r0" + VLGV \gr, \vr, \disp, \base, 2 +.endm +.macro VLGVG gr, vr, disp, base="%r0" + VLGV \gr, \vr, \disp, \base, 3 +.endm + +/* VECTOR LOAD MULTIPLE */ +.macro VLM vfrom, vto, disp, base + VX_NUM v1, \vfrom + VX_NUM v3, \vto + GR_NUM b2, \base /* Base register */ + .word 0xE700 | (VX_R(v1) << 4) | VX_R(v3) + .word (b2 << 12) | (\disp) + MRXBOPC 0, 0x36, v1, v3 +.endm + +/* VECTOR STORE MULTIPLE */ +.macro VSTM vfrom, vto, disp, base + VX_NUM v1, \vfrom + VX_NUM v3, \vto + GR_NUM b2, \base /* Base register */ + .word 0xE700 | (VX_R(v1) << 4) | VX_R(v3) + .word (b2 << 12) | (\disp) + MRXBOPC 0, 0x3E, v1, v3 +.endm + +/* VECTOR PERMUTE */ +.macro VPERM vr1, vr2, vr3, vr4 + VX_NUM v1, \vr1 + VX_NUM v2, \vr2 + VX_NUM v3, \vr3 + VX_NUM v4, \vr4 + .word 0xE700 | (VX_R(v1) << 4) | VX_R(v2) + .word (VX_R(v3) << 12) + MRXBOPC VX_R(v4), 0x8C, v1, v2, v3, v4 +.endm + +/* VECTOR UNPACK LOGICAL LOW */ +.macro VUPLL vr1, vr2, m3 + VX_NUM v1, \vr1 + VX_NUM v2, \vr2 + .word 0xE700 | (VX_R(v1) << 4) | VX_R(v2) + .word 0x0000 + MRXBOPC \m3, 0xD4, v1, v2 +.endm +.macro VUPLLB vr1, vr2 + VUPLL \vr1, \vr2, 0 +.endm +.macro VUPLLH vr1, vr2 + VUPLL \vr1, \vr2, 1 +.endm +.macro VUPLLF vr1, vr2 + VUPLL \vr1, \vr2, 2 +.endm + +/* Vector integer instructions */ + +/* VECTOR EXCLUSIVE OR */ +.macro VX vr1, vr2, vr3 + VX_NUM v1, \vr1 + VX_NUM v2, \vr2 + VX_NUM v3, \vr3 + .word 0xE700 | (VX_R(v1) << 4) | VX_R(v2) + .word (VX_R(v3) << 12) + MRXBOPC 0, 0x6D, v1, v2, v3 +.endm + +/* VECTOR GALOIS FIELD MULTIPLY SUM */ +.macro VGFM vr1, vr2, vr3, m4 + VX_NUM v1, \vr1 + VX_NUM v2, \vr2 + VX_NUM v3, \vr3 + .word 0xE700 | (VX_R(v1) << 4) | VX_R(v2) + .word (VX_R(v3) << 12) + MRXBOPC \m4, 0xB4, v1, v2, v3 +.endm +.macro VGFMB vr1, vr2, vr3 + VGFM \vr1, \vr2, \vr3, 0 +.endm +.macro VGFMH vr1, vr2, vr3 + VGFM \vr1, \vr2, \vr3, 1 +.endm +.macro VGFMF vr1, vr2, vr3 + VGFM \vr1, \vr2, \vr3, 2 +.endm +.macro VGFMG vr1, vr2, vr3 + VGFM \vr1, \vr2, \vr3, 3 +.endm + +/* VECTOR GALOIS FIELD MULTIPLY SUM AND ACCUMULATE */ +.macro VGFMA vr1, vr2, vr3, vr4, m5 + VX_NUM v1, \vr1 + VX_NUM v2, \vr2 + VX_NUM v3, \vr3 + VX_NUM v4, \vr4 + .word 0xE700 | (VX_R(v1) << 4) | VX_R(v2) + .word (VX_R(v3) << 12) | (\m5 << 8) + MRXBOPC VX_R(v4), 0xBC, v1, v2, v3, v4 +.endm +.macro VGFMAB vr1, vr2, vr3, vr4 + VGFMA \vr1, \vr2, \vr3, \vr4, 0 +.endm +.macro VGFMAH vr1, vr2, vr3, vr4 + VGFMA \vr1, \vr2, \vr3, \vr4, 1 +.endm +.macro VGFMAF vr1, vr2, vr3, vr4 + VGFMA \vr1, \vr2, \vr3, \vr4, 2 +.endm +.macro VGFMAG vr1, vr2, vr3, vr4 + VGFMA \vr1, \vr2, \vr3, \vr4, 3 +.endm + +/* VECTOR SHIFT RIGHT LOGICAL BY BYTE */ +.macro VSRLB vr1, vr2, vr3 + VX_NUM v1, \vr1 + VX_NUM v2, \vr2 + VX_NUM v3, \vr3 + .word 0xE700 | (VX_R(v1) << 4) | VX_R(v2) + .word (VX_R(v3) << 12) + MRXBOPC 0, 0x7D, v1, v2, v3 +.endm + +#endif /* __ASM_S390_VX_INSN_H */ diff --git a/src/third_party/wiredtiger/src/config/config.c b/src/third_party/wiredtiger/src/config/config.c index 96ef7a4e62a..3416153d160 100644 --- a/src/third_party/wiredtiger/src/config/config.c +++ b/src/third_party/wiredtiger/src/config/config.c @@ -26,7 +26,7 @@ __config_err(WT_CONFIG *conf, const char *msg, int err) * Initialize a config handle, used to iterate through a config string of * specified length. */ -int +void __wt_config_initn( WT_SESSION_IMPL *session, WT_CONFIG *conf, const char *str, size_t len) { @@ -36,8 +36,6 @@ __wt_config_initn( conf->depth = 0; conf->top = -1; conf->go = NULL; - - return (0); } /* @@ -45,14 +43,14 @@ __wt_config_initn( * Initialize a config handle, used to iterate through a NUL-terminated * config string. */ -int +void __wt_config_init(WT_SESSION_IMPL *session, WT_CONFIG *conf, const char *str) { size_t len; len = (str == NULL) ? 0 : strlen(str); - return (__wt_config_initn(session, conf, str, len)); + __wt_config_initn(session, conf, str, len); } /* @@ -61,11 +59,11 @@ __wt_config_init(WT_SESSION_IMPL *session, WT_CONFIG *conf, const char *str) * extracted from another config string (used for parsing nested * structures). */ -int +void __wt_config_subinit( WT_SESSION_IMPL *session, WT_CONFIG *conf, WT_CONFIG_ITEM *item) { - return (__wt_config_initn(session, conf, item->str, item->len)); + __wt_config_initn(session, conf, item->str, item->len); } #define PUSH(i, t) do { \ @@ -601,8 +599,8 @@ __config_getraw( strncmp(key->str, k.str, k.len) == 0) { subk.str = key->str + k.len + 1; subk.len = (key->len - k.len) - 1; - WT_RET(__wt_config_initn( - cparser->session, &sparser, v.str, v.len)); + __wt_config_initn( + cparser->session, &sparser, v.str, v.len); if ((ret = __config_getraw( &sparser, &subk, value, false)) == 0) found = true; @@ -641,7 +639,7 @@ __wt_config_get(WT_SESSION_IMPL *session, do { --cfg; - WT_RET(__wt_config_init(session, &cparser, *cfg)); + __wt_config_init(session, &cparser, *cfg); if ((ret = __config_getraw(&cparser, key, value, true)) == 0) return (0); WT_RET_NOTFOUND_OK(ret); @@ -690,7 +688,7 @@ __wt_config_getone(WT_SESSION_IMPL *session, { WT_CONFIG cparser; - WT_RET(__wt_config_init(session, &cparser, config)); + __wt_config_init(session, &cparser, config); return (__config_getraw(&cparser, key, value, true)); } @@ -706,7 +704,7 @@ __wt_config_getones(WT_SESSION_IMPL *session, WT_CONFIG_ITEM key_item = { key, strlen(key), 0, WT_CONFIG_ITEM_STRING }; - WT_RET(__wt_config_init(session, &cparser, config)); + __wt_config_init(session, &cparser, config); return (__config_getraw(&cparser, &key_item, value, true)); } @@ -771,7 +769,7 @@ __wt_config_subgetraw(WT_SESSION_IMPL *session, { WT_CONFIG cparser; - WT_RET(__wt_config_initn(session, &cparser, cfg->str, cfg->len)); + __wt_config_initn(session, &cparser, cfg->str, cfg->len); return (__config_getraw(&cparser, key, value, true)); } diff --git a/src/third_party/wiredtiger/src/config/config_api.c b/src/third_party/wiredtiger/src/config/config_api.c index b5228c4329c..8655057e94d 100644 --- a/src/third_party/wiredtiger/src/config/config_api.c +++ b/src/third_party/wiredtiger/src/config/config_api.c @@ -79,7 +79,6 @@ wiredtiger_config_parser_open(WT_SESSION *wt_session, WT_CONFIG_ITEM config_item = { config, len, 0, WT_CONFIG_ITEM_STRING }; WT_CONFIG_PARSER_IMPL *config_parser; - WT_DECL_RET; WT_SESSION_IMPL *session; *config_parserp = NULL; @@ -94,14 +93,10 @@ wiredtiger_config_parser_open(WT_SESSION *wt_session, * structure for iterations through the configuration string. */ memcpy(&config_parser->config_item, &config_item, sizeof(config_item)); - WT_ERR(__wt_config_initn(session, &config_parser->config, config, len)); - - if (ret == 0) - *config_parserp = (WT_CONFIG_PARSER *)config_parser; - else -err: __wt_free(session, config_parser); + __wt_config_initn(session, &config_parser->config, config, len); - return (ret); + *config_parserp = (WT_CONFIG_PARSER *)config_parser; + return (0); } /* diff --git a/src/third_party/wiredtiger/src/config/config_check.c b/src/third_party/wiredtiger/src/config/config_check.c index c29013483f6..d0aa09a96c1 100644 --- a/src/third_party/wiredtiger/src/config/config_check.c +++ b/src/third_party/wiredtiger/src/config/config_check.c @@ -91,9 +91,9 @@ config_check(WT_SESSION_IMPL *session, * that are not nul-terminated. */ if (config_len == 0) - WT_RET(__wt_config_init(session, &parser, config)); + __wt_config_init(session, &parser, config); else - WT_RET(__wt_config_initn(session, &parser, config, config_len)); + __wt_config_initn(session, &parser, config, config_len); while ((ret = __wt_config_next(&parser, &k, &v)) == 0) { if (k.type != WT_CONFIG_ITEM_STRING && k.type != WT_CONFIG_ITEM_ID) @@ -143,7 +143,7 @@ config_check(WT_SESSION_IMPL *session, continue; /* Setup an iterator for the check string. */ - WT_RET(__wt_config_init(session, &cparser, checks[i].checks)); + __wt_config_init(session, &cparser, checks[i].checks); while ((ret = __wt_config_next(&cparser, &ck, &cv)) == 0) { if (WT_STRING_MATCH("min", ck.str, ck.len)) { if (v.val < cv.val) @@ -169,8 +169,8 @@ config_check(WT_SESSION_IMPL *session, * Handle the 'verbose' case of a list * containing restricted choices. */ - WT_RET(__wt_config_subinit(session, - &sparser, &v)); + __wt_config_subinit( + session, &sparser, &v); found = true; while (found && (ret = __wt_config_next(&sparser, diff --git a/src/third_party/wiredtiger/src/config/config_collapse.c b/src/third_party/wiredtiger/src/config/config_collapse.c index 591d22284f5..ea956ebfff9 100644 --- a/src/third_party/wiredtiger/src/config/config_collapse.c +++ b/src/third_party/wiredtiger/src/config/config_collapse.c @@ -42,7 +42,7 @@ __wt_config_collapse( WT_RET(__wt_scr_alloc(session, 0, &tmp)); - WT_ERR(__wt_config_init(session, &cparser, cfg[0])); + __wt_config_init(session, &cparser, cfg[0]); while ((ret = __wt_config_next(&cparser, &k, &v)) == 0) { if (k.type != WT_CONFIG_ITEM_STRING && k.type != WT_CONFIG_ITEM_ID) @@ -127,7 +127,7 @@ __config_merge_scan(WT_SESSION_IMPL *session, WT_ERR(__wt_scr_alloc(session, 0, &kb)); WT_ERR(__wt_scr_alloc(session, 0, &vb)); - WT_ERR(__wt_config_init(session, &cparser, value)); + __wt_config_init(session, &cparser, value); while ((ret = __wt_config_next(&cparser, &k, &v)) == 0) { if (k.type != WT_CONFIG_ITEM_STRING && k.type != WT_CONFIG_ITEM_ID) diff --git a/src/third_party/wiredtiger/src/config/config_def.c b/src/third_party/wiredtiger/src/config/config_def.c index 352464ee92a..f231d7fc5d9 100644 --- a/src/third_party/wiredtiger/src/config/config_def.c +++ b/src/third_party/wiredtiger/src/config/config_def.c @@ -42,7 +42,6 @@ static const WT_CONFIG_CHECK static const WT_CONFIG_CHECK confchk_wiredtiger_open_checkpoint_subconfigs[] = { { "log_size", "int", NULL, "min=0,max=2GB", NULL, 0 }, - { "name", "string", NULL, NULL, NULL, 0 }, { "wait", "int", NULL, "min=0,max=100000", NULL, 0 }, { NULL, NULL, NULL, NULL, NULL, 0 } }; @@ -109,16 +108,19 @@ static const WT_CONFIG_CHECK confchk_WT_CONNECTION_reconfigure[] = { { "cache_size", "int", NULL, "min=1MB,max=10TB", NULL, 0 }, { "checkpoint", "category", NULL, NULL, - confchk_wiredtiger_open_checkpoint_subconfigs, 3 }, + confchk_wiredtiger_open_checkpoint_subconfigs, 2 }, { "error_prefix", "string", NULL, NULL, NULL, 0 }, { "eviction", "category", NULL, NULL, confchk_wiredtiger_open_eviction_subconfigs, 2 }, + { "eviction_checkpoint_target", "int", + NULL, "min=0,max=99", + NULL, 0 }, { "eviction_dirty_target", "int", - NULL, "min=5,max=99", + NULL, "min=1,max=99", NULL, 0 }, { "eviction_dirty_trigger", "int", - NULL, "min=5,max=99", + NULL, "min=1,max=99", NULL, 0 }, { "eviction_target", "int", NULL, "min=10,max=99", NULL, 0 }, { "eviction_trigger", "int", NULL, "min=10,max=99", NULL, 0 }, @@ -146,8 +148,8 @@ static const WT_CONFIG_CHECK confchk_WT_CONNECTION_reconfigure[] = { "\"evict\",\"evictserver\",\"fileops\",\"handleops\",\"log\"," "\"lsm\",\"lsm_manager\",\"metadata\",\"mutex\",\"overflow\"," "\"read\",\"rebalance\",\"reconcile\",\"recovery\",\"salvage\"," - "\"shared_cache\",\"split\",\"temporary\",\"transaction\"," - "\"verify\",\"version\",\"write\"]", + "\"shared_cache\",\"split\",\"temporary\",\"thread_group\"," + "\"transaction\",\"verify\",\"version\",\"write\"]", NULL, 0 }, { NULL, NULL, NULL, NULL, NULL, 0 } }; @@ -318,6 +320,7 @@ static const WT_CONFIG_CHECK confchk_WT_SESSION_open_cursor[] = { { "append", "boolean", NULL, NULL, NULL, 0 }, { "bulk", "string", NULL, NULL, NULL, 0 }, { "checkpoint", "string", NULL, NULL, NULL, 0 }, + { "checkpoint_wait", "boolean", NULL, NULL, NULL, 0 }, { "dump", "string", NULL, "choices=[\"hex\",\"json\",\"print\"]", NULL, 0 }, @@ -643,7 +646,7 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open[] = { { "cache_size", "int", NULL, "min=1MB,max=10TB", NULL, 0 }, { "checkpoint", "category", NULL, NULL, - confchk_wiredtiger_open_checkpoint_subconfigs, 3 }, + confchk_wiredtiger_open_checkpoint_subconfigs, 2 }, { "checkpoint_sync", "boolean", NULL, NULL, NULL, 0 }, { "config_base", "boolean", NULL, NULL, NULL, 0 }, { "create", "boolean", NULL, NULL, NULL, 0 }, @@ -657,11 +660,14 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open[] = { { "eviction", "category", NULL, NULL, confchk_wiredtiger_open_eviction_subconfigs, 2 }, + { "eviction_checkpoint_target", "int", + NULL, "min=0,max=99", + NULL, 0 }, { "eviction_dirty_target", "int", - NULL, "min=5,max=99", + NULL, "min=1,max=99", NULL, 0 }, { "eviction_dirty_trigger", "int", - NULL, "min=5,max=99", + NULL, "min=1,max=99", NULL, 0 }, { "eviction_target", "int", NULL, "min=10,max=99", NULL, 0 }, { "eviction_trigger", "int", NULL, "min=10,max=99", NULL, 0 }, @@ -706,8 +712,8 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open[] = { "\"evict\",\"evictserver\",\"fileops\",\"handleops\",\"log\"," "\"lsm\",\"lsm_manager\",\"metadata\",\"mutex\",\"overflow\"," "\"read\",\"rebalance\",\"reconcile\",\"recovery\",\"salvage\"," - "\"shared_cache\",\"split\",\"temporary\",\"transaction\"," - "\"verify\",\"version\",\"write\"]", + "\"shared_cache\",\"split\",\"temporary\",\"thread_group\"," + "\"transaction\",\"verify\",\"version\",\"write\"]", NULL, 0 }, { "write_through", "list", NULL, "choices=[\"data\",\"log\"]", @@ -724,7 +730,7 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_all[] = { { "cache_size", "int", NULL, "min=1MB,max=10TB", NULL, 0 }, { "checkpoint", "category", NULL, NULL, - confchk_wiredtiger_open_checkpoint_subconfigs, 3 }, + confchk_wiredtiger_open_checkpoint_subconfigs, 2 }, { "checkpoint_sync", "boolean", NULL, NULL, NULL, 0 }, { "config_base", "boolean", NULL, NULL, NULL, 0 }, { "create", "boolean", NULL, NULL, NULL, 0 }, @@ -738,11 +744,14 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_all[] = { { "eviction", "category", NULL, NULL, confchk_wiredtiger_open_eviction_subconfigs, 2 }, + { "eviction_checkpoint_target", "int", + NULL, "min=0,max=99", + NULL, 0 }, { "eviction_dirty_target", "int", - NULL, "min=5,max=99", + NULL, "min=1,max=99", NULL, 0 }, { "eviction_dirty_trigger", "int", - NULL, "min=5,max=99", + NULL, "min=1,max=99", NULL, 0 }, { "eviction_target", "int", NULL, "min=10,max=99", NULL, 0 }, { "eviction_trigger", "int", NULL, "min=10,max=99", NULL, 0 }, @@ -787,8 +796,8 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_all[] = { "\"evict\",\"evictserver\",\"fileops\",\"handleops\",\"log\"," "\"lsm\",\"lsm_manager\",\"metadata\",\"mutex\",\"overflow\"," "\"read\",\"rebalance\",\"reconcile\",\"recovery\",\"salvage\"," - "\"shared_cache\",\"split\",\"temporary\",\"transaction\"," - "\"verify\",\"version\",\"write\"]", + "\"shared_cache\",\"split\",\"temporary\",\"thread_group\"," + "\"transaction\",\"verify\",\"version\",\"write\"]", NULL, 0 }, { "version", "string", NULL, NULL, NULL, 0 }, { "write_through", "list", @@ -806,7 +815,7 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_basecfg[] = { { "cache_size", "int", NULL, "min=1MB,max=10TB", NULL, 0 }, { "checkpoint", "category", NULL, NULL, - confchk_wiredtiger_open_checkpoint_subconfigs, 3 }, + confchk_wiredtiger_open_checkpoint_subconfigs, 2 }, { "checkpoint_sync", "boolean", NULL, NULL, NULL, 0 }, { "direct_io", "list", NULL, "choices=[\"checkpoint\",\"data\",\"log\"]", @@ -818,11 +827,14 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_basecfg[] = { { "eviction", "category", NULL, NULL, confchk_wiredtiger_open_eviction_subconfigs, 2 }, + { "eviction_checkpoint_target", "int", + NULL, "min=0,max=99", + NULL, 0 }, { "eviction_dirty_target", "int", - NULL, "min=5,max=99", + NULL, "min=1,max=99", NULL, 0 }, { "eviction_dirty_trigger", "int", - NULL, "min=5,max=99", + NULL, "min=1,max=99", NULL, 0 }, { "eviction_target", "int", NULL, "min=10,max=99", NULL, 0 }, { "eviction_trigger", "int", NULL, "min=10,max=99", NULL, 0 }, @@ -863,8 +875,8 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_basecfg[] = { "\"evict\",\"evictserver\",\"fileops\",\"handleops\",\"log\"," "\"lsm\",\"lsm_manager\",\"metadata\",\"mutex\",\"overflow\"," "\"read\",\"rebalance\",\"reconcile\",\"recovery\",\"salvage\"," - "\"shared_cache\",\"split\",\"temporary\",\"transaction\"," - "\"verify\",\"version\",\"write\"]", + "\"shared_cache\",\"split\",\"temporary\",\"thread_group\"," + "\"transaction\",\"verify\",\"version\",\"write\"]", NULL, 0 }, { "version", "string", NULL, NULL, NULL, 0 }, { "write_through", "list", @@ -882,7 +894,7 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_usercfg[] = { { "cache_size", "int", NULL, "min=1MB,max=10TB", NULL, 0 }, { "checkpoint", "category", NULL, NULL, - confchk_wiredtiger_open_checkpoint_subconfigs, 3 }, + confchk_wiredtiger_open_checkpoint_subconfigs, 2 }, { "checkpoint_sync", "boolean", NULL, NULL, NULL, 0 }, { "direct_io", "list", NULL, "choices=[\"checkpoint\",\"data\",\"log\"]", @@ -894,11 +906,14 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_usercfg[] = { { "eviction", "category", NULL, NULL, confchk_wiredtiger_open_eviction_subconfigs, 2 }, + { "eviction_checkpoint_target", "int", + NULL, "min=0,max=99", + NULL, 0 }, { "eviction_dirty_target", "int", - NULL, "min=5,max=99", + NULL, "min=1,max=99", NULL, 0 }, { "eviction_dirty_trigger", "int", - NULL, "min=5,max=99", + NULL, "min=1,max=99", NULL, 0 }, { "eviction_target", "int", NULL, "min=10,max=99", NULL, 0 }, { "eviction_trigger", "int", NULL, "min=10,max=99", NULL, 0 }, @@ -939,8 +954,8 @@ static const WT_CONFIG_CHECK confchk_wiredtiger_open_usercfg[] = { "\"evict\",\"evictserver\",\"fileops\",\"handleops\",\"log\"," "\"lsm\",\"lsm_manager\",\"metadata\",\"mutex\",\"overflow\"," "\"read\",\"rebalance\",\"reconcile\",\"recovery\",\"salvage\"," - "\"shared_cache\",\"split\",\"temporary\",\"transaction\"," - "\"verify\",\"version\",\"write\"]", + "\"shared_cache\",\"split\",\"temporary\",\"thread_group\"," + "\"transaction\",\"verify\",\"version\",\"write\"]", NULL, 0 }, { "write_through", "list", NULL, "choices=[\"data\",\"log\"]", @@ -970,15 +985,15 @@ static const WT_CONFIG_ENTRY config_entries[] = { NULL, 0 }, { "WT_CONNECTION.async_new_op", - "append=0,overwrite=,raw=0,timeout=1200", + "append=false,overwrite=true,raw=false,timeout=1200", confchk_WT_CONNECTION_async_new_op, 4 }, { "WT_CONNECTION.close", - "leak_memory=0", + "leak_memory=false", confchk_WT_CONNECTION_close, 1 }, { "WT_CONNECTION.load_extension", - "config=,early_load=0,entry=wiredtiger_extension_init," + "config=,early_load=false,entry=wiredtiger_extension_init," "terminate=wiredtiger_extension_terminate", confchk_WT_CONNECTION_load_extension, 4 }, @@ -987,18 +1002,19 @@ static const WT_CONFIG_ENTRY config_entries[] = { confchk_WT_CONNECTION_open_session, 1 }, { "WT_CONNECTION.reconfigure", - "async=(enabled=0,ops_max=1024,threads=2),cache_overhead=8," - "cache_size=100MB,checkpoint=(log_size=0," - "name=\"WiredTigerCheckpoint\",wait=0),error_prefix=," - "eviction=(threads_max=1,threads_min=1),eviction_dirty_target=80," - "eviction_dirty_trigger=95,eviction_target=80,eviction_trigger=95" + "async=(enabled=false,ops_max=1024,threads=2),cache_overhead=8," + "cache_size=100MB,checkpoint=(log_size=0,wait=0),error_prefix=," + "eviction=(threads_max=1,threads_min=1)," + "eviction_checkpoint_target=15,eviction_dirty_target=5," + "eviction_dirty_trigger=20,eviction_target=80,eviction_trigger=95" ",file_manager=(close_handle_minimum=250,close_idle_time=30," - "close_scan_interval=10),log=(archive=,prealloc=,zero_fill=0)," - "lsm_manager=(merge=,worker_thread_max=4),lsm_merge=," - "shared_cache=(chunk=10MB,name=,quota=0,reserve=0,size=500MB)," - "statistics=none,statistics_log=(json=0,on_close=0,sources=," - "timestamp=\"%b %d %H:%M:%S\",wait=0),verbose=", - confchk_WT_CONNECTION_reconfigure, 18 + "close_scan_interval=10),log=(archive=true,prealloc=true," + "zero_fill=false),lsm_manager=(merge=true,worker_thread_max=4)," + "lsm_merge=true,shared_cache=(chunk=10MB,name=,quota=0,reserve=0," + "size=500MB),statistics=none,statistics_log=(json=false," + "on_close=false,sources=,timestamp=\"%b %d %H:%M:%S\",wait=0)," + "verbose=", + confchk_WT_CONNECTION_reconfigure, 19 }, { "WT_CONNECTION.set_file_system", "", @@ -1009,7 +1025,7 @@ static const WT_CONFIG_ENTRY config_entries[] = { NULL, 0 }, { "WT_CURSOR.reconfigure", - "append=0,overwrite=", + "append=false,overwrite=true", confchk_WT_CURSOR_reconfigure, 2 }, { "WT_SESSION.begin_transaction", @@ -1017,7 +1033,7 @@ static const WT_CONFIG_ENTRY config_entries[] = { confchk_WT_SESSION_begin_transaction, 5 }, { "WT_SESSION.checkpoint", - "drop=,force=0,name=,target=", + "drop=,force=false,name=,target=", confchk_WT_SESSION_checkpoint, 4 }, { "WT_SESSION.close", @@ -1034,24 +1050,25 @@ static const WT_CONFIG_ENTRY config_entries[] = { }, { "WT_SESSION.create", "allocation_size=4KB,app_metadata=,block_allocation=best," - "block_compressor=,cache_resident=0,checksum=uncompressed," + "block_compressor=,cache_resident=false,checksum=uncompressed," "colgroups=,collator=,columns=,dictionary=0,encryption=(keyid=," - "name=),exclusive=0,extractor=,format=btree,huffman_key=," - "huffman_value=,immutable=0,internal_item_max=0," - "internal_key_max=0,internal_key_truncate=,internal_page_max=4KB," - "key_format=u,key_gap=10,leaf_item_max=0,leaf_key_max=0," - "leaf_page_max=32KB,leaf_value_max=0,log=(enabled=)," - "lsm=(auto_throttle=,bloom=,bloom_bit_count=16,bloom_config=," - "bloom_hash_count=8,bloom_oldest=0,chunk_count_limit=0," - "chunk_max=5GB,chunk_size=10MB,merge_max=15,merge_min=0)," - "memory_page_max=5MB,os_cache_dirty_max=0,os_cache_max=0," - "prefix_compression=0,prefix_compression_min=4,source=," - "split_deepen_min_child=0,split_deepen_per_child=0,split_pct=75," - "type=file,value_format=u", + "name=),exclusive=false,extractor=,format=btree,huffman_key=," + "huffman_value=,immutable=false,internal_item_max=0," + "internal_key_max=0,internal_key_truncate=true," + "internal_page_max=4KB,key_format=u,key_gap=10,leaf_item_max=0," + "leaf_key_max=0,leaf_page_max=32KB,leaf_value_max=0," + "log=(enabled=true),lsm=(auto_throttle=true,bloom=true," + "bloom_bit_count=16,bloom_config=,bloom_hash_count=8," + "bloom_oldest=false,chunk_count_limit=0,chunk_max=5GB," + "chunk_size=10MB,merge_max=15,merge_min=0),memory_page_max=5MB," + "os_cache_dirty_max=0,os_cache_max=0,prefix_compression=false," + "prefix_compression_min=4,source=,split_deepen_min_child=0," + "split_deepen_per_child=0,split_pct=75,type=file,value_format=u", confchk_WT_SESSION_create, 40 }, { "WT_SESSION.drop", - "checkpoint_wait=,force=0,lock_wait=,remove_files=", + "checkpoint_wait=true,force=false,lock_wait=true," + "remove_files=true", confchk_WT_SESSION_drop, 4 }, { "WT_SESSION.join", @@ -1068,10 +1085,11 @@ static const WT_CONFIG_ENTRY config_entries[] = { NULL, 0 }, { "WT_SESSION.open_cursor", - "append=0,bulk=0,checkpoint=,dump=,next_random=0," - "next_random_sample_size=0,overwrite=,raw=0,readonly=0," - "skip_sort_check=0,statistics=,target=", - confchk_WT_SESSION_open_cursor, 12 + "append=false,bulk=false,checkpoint=,checkpoint_wait=true,dump=," + "next_random=false,next_random_sample_size=0,overwrite=true," + "raw=false,readonly=false,skip_sort_check=false,statistics=," + "target=", + confchk_WT_SESSION_open_cursor, 13 }, { "WT_SESSION.rebalance", "", @@ -1094,11 +1112,11 @@ static const WT_CONFIG_ENTRY config_entries[] = { NULL, 0 }, { "WT_SESSION.salvage", - "force=0", + "force=false", confchk_WT_SESSION_salvage, 1 }, { "WT_SESSION.snapshot", - "drop=(all=0,before=,names=,to=),name=", + "drop=(all=false,before=,names=,to=),name=", confchk_WT_SESSION_snapshot, 2 }, { "WT_SESSION.strerror", @@ -1118,8 +1136,8 @@ static const WT_CONFIG_ENTRY config_entries[] = { NULL, 0 }, { "WT_SESSION.verify", - "dump_address=0,dump_blocks=0,dump_layout=0,dump_offsets=," - "dump_pages=0,strict=0", + "dump_address=false,dump_blocks=false,dump_layout=false," + "dump_offsets=,dump_pages=false,strict=false", confchk_WT_SESSION_verify, 6 }, { "colgroup.meta", @@ -1128,53 +1146,54 @@ static const WT_CONFIG_ENTRY config_entries[] = { }, { "file.config", "allocation_size=4KB,app_metadata=,block_allocation=best," - "block_compressor=,cache_resident=0,checksum=uncompressed," + "block_compressor=,cache_resident=false,checksum=uncompressed," "collator=,columns=,dictionary=0,encryption=(keyid=,name=)," "format=btree,huffman_key=,huffman_value=,internal_item_max=0," - "internal_key_max=0,internal_key_truncate=,internal_page_max=4KB," - "key_format=u,key_gap=10,leaf_item_max=0,leaf_key_max=0," - "leaf_page_max=32KB,leaf_value_max=0,log=(enabled=)," - "memory_page_max=5MB,os_cache_dirty_max=0,os_cache_max=0," - "prefix_compression=0,prefix_compression_min=4," - "split_deepen_min_child=0,split_deepen_per_child=0,split_pct=75," + "internal_key_max=0,internal_key_truncate=true," + "internal_page_max=4KB,key_format=u,key_gap=10,leaf_item_max=0," + "leaf_key_max=0,leaf_page_max=32KB,leaf_value_max=0," + "log=(enabled=true),memory_page_max=5MB,os_cache_dirty_max=0," + "os_cache_max=0,prefix_compression=false,prefix_compression_min=4" + ",split_deepen_min_child=0,split_deepen_per_child=0,split_pct=75," "value_format=u", confchk_file_config, 33 }, { "file.meta", "allocation_size=4KB,app_metadata=,block_allocation=best," - "block_compressor=,cache_resident=0,checkpoint=,checkpoint_lsn=," - "checksum=uncompressed,collator=,columns=,dictionary=0," - "encryption=(keyid=,name=),format=btree,huffman_key=," - "huffman_value=,id=,internal_item_max=0,internal_key_max=0," - "internal_key_truncate=,internal_page_max=4KB,key_format=u," + "block_compressor=,cache_resident=false,checkpoint=," + "checkpoint_lsn=,checksum=uncompressed,collator=,columns=," + "dictionary=0,encryption=(keyid=,name=),format=btree,huffman_key=" + ",huffman_value=,id=,internal_item_max=0,internal_key_max=0," + "internal_key_truncate=true,internal_page_max=4KB,key_format=u," "key_gap=10,leaf_item_max=0,leaf_key_max=0,leaf_page_max=32KB," - "leaf_value_max=0,log=(enabled=),memory_page_max=5MB," - "os_cache_dirty_max=0,os_cache_max=0,prefix_compression=0," + "leaf_value_max=0,log=(enabled=true),memory_page_max=5MB," + "os_cache_dirty_max=0,os_cache_max=0,prefix_compression=false," "prefix_compression_min=4,split_deepen_min_child=0," "split_deepen_per_child=0,split_pct=75,value_format=u," "version=(major=0,minor=0)", confchk_file_meta, 37 }, { "index.meta", - "app_metadata=,collator=,columns=,extractor=,immutable=0," + "app_metadata=,collator=,columns=,extractor=,immutable=false," "index_key_columns=,key_format=u,source=,type=file,value_format=u", confchk_index_meta, 10 }, { "lsm.meta", "allocation_size=4KB,app_metadata=,block_allocation=best," - "block_compressor=,cache_resident=0,checksum=uncompressed,chunks=" - ",collator=,columns=,dictionary=0,encryption=(keyid=,name=)," - "format=btree,huffman_key=,huffman_value=,internal_item_max=0," - "internal_key_max=0,internal_key_truncate=,internal_page_max=4KB," - "key_format=u,key_gap=10,last=,leaf_item_max=0,leaf_key_max=0," - "leaf_page_max=32KB,leaf_value_max=0,log=(enabled=)," - "lsm=(auto_throttle=,bloom=,bloom_bit_count=16,bloom_config=," - "bloom_hash_count=8,bloom_oldest=0,chunk_count_limit=0," - "chunk_max=5GB,chunk_size=10MB,merge_max=15,merge_min=0)," - "memory_page_max=5MB,old_chunks=,os_cache_dirty_max=0," - "os_cache_max=0,prefix_compression=0,prefix_compression_min=4," - "split_deepen_min_child=0,split_deepen_per_child=0,split_pct=75," - "value_format=u", + "block_compressor=,cache_resident=false,checksum=uncompressed," + "chunks=,collator=,columns=,dictionary=0,encryption=(keyid=," + "name=),format=btree,huffman_key=,huffman_value=," + "internal_item_max=0,internal_key_max=0," + "internal_key_truncate=true,internal_page_max=4KB,key_format=u," + "key_gap=10,last=,leaf_item_max=0,leaf_key_max=0," + "leaf_page_max=32KB,leaf_value_max=0,log=(enabled=true)," + "lsm=(auto_throttle=true,bloom=true,bloom_bit_count=16," + "bloom_config=,bloom_hash_count=8,bloom_oldest=false," + "chunk_count_limit=0,chunk_max=5GB,chunk_size=10MB,merge_max=15," + "merge_min=0),memory_page_max=5MB,old_chunks=," + "os_cache_dirty_max=0,os_cache_max=0,prefix_compression=false," + "prefix_compression_min=4,split_deepen_min_child=0," + "split_deepen_per_child=0,split_pct=75,value_format=u", confchk_lsm_meta, 37 }, { "table.meta", @@ -1183,85 +1202,92 @@ static const WT_CONFIG_ENTRY config_entries[] = { confchk_table_meta, 6 }, { "wiredtiger_open", - "async=(enabled=0,ops_max=1024,threads=2),buffer_alignment=-1," - "cache_overhead=8,cache_size=100MB,checkpoint=(log_size=0," - "name=\"WiredTigerCheckpoint\",wait=0),checkpoint_sync=," - "config_base=,create=0,direct_io=,encryption=(keyid=,name=," - "secretkey=),error_prefix=,eviction=(threads_max=1,threads_min=1)" - ",eviction_dirty_target=80,eviction_dirty_trigger=95," - "eviction_target=80,eviction_trigger=95,exclusive=0,extensions=," - "file_extend=,file_manager=(close_handle_minimum=250," - "close_idle_time=30,close_scan_interval=10),hazard_max=1000," - "in_memory=0,log=(archive=,compressor=,enabled=0,file_max=100MB," - "path=\".\",prealloc=,recover=on,zero_fill=0),lsm_manager=(merge=" - ",worker_thread_max=4),lsm_merge=,mmap=,multiprocess=0,readonly=0" - ",session_max=100,session_scratch_max=2MB," - "shared_cache=(chunk=10MB,name=,quota=0,reserve=0,size=500MB)," - "statistics=none,statistics_log=(json=0,on_close=0,path=\".\"," - "sources=,timestamp=\"%b %d %H:%M:%S\",wait=0)," - "transaction_sync=(enabled=0,method=fsync),use_environment=," - "use_environment_priv=0,verbose=,write_through=", - confchk_wiredtiger_open, 38 + "async=(enabled=false,ops_max=1024,threads=2),buffer_alignment=-1" + ",cache_overhead=8,cache_size=100MB,checkpoint=(log_size=0," + "wait=0),checkpoint_sync=true,config_base=true,create=false," + "direct_io=,encryption=(keyid=,name=,secretkey=),error_prefix=," + "eviction=(threads_max=1,threads_min=1)," + "eviction_checkpoint_target=15,eviction_dirty_target=5," + "eviction_dirty_trigger=20,eviction_target=80,eviction_trigger=95" + ",exclusive=false,extensions=,file_extend=," + "file_manager=(close_handle_minimum=250,close_idle_time=30," + "close_scan_interval=10),hazard_max=1000,in_memory=false," + "log=(archive=true,compressor=,enabled=false,file_max=100MB," + "path=\".\",prealloc=true,recover=on,zero_fill=false)," + "lsm_manager=(merge=true,worker_thread_max=4),lsm_merge=true," + "mmap=true,multiprocess=false,readonly=false,session_max=100," + "session_scratch_max=2MB,shared_cache=(chunk=10MB,name=,quota=0," + "reserve=0,size=500MB),statistics=none,statistics_log=(json=false" + ",on_close=false,path=\".\",sources=,timestamp=\"%b %d %H:%M:%S\"" + ",wait=0),transaction_sync=(enabled=false,method=fsync)," + "use_environment=true,use_environment_priv=false,verbose=," + "write_through=", + confchk_wiredtiger_open, 39 }, { "wiredtiger_open_all", - "async=(enabled=0,ops_max=1024,threads=2),buffer_alignment=-1," - "cache_overhead=8,cache_size=100MB,checkpoint=(log_size=0," - "name=\"WiredTigerCheckpoint\",wait=0),checkpoint_sync=," - "config_base=,create=0,direct_io=,encryption=(keyid=,name=," - "secretkey=),error_prefix=,eviction=(threads_max=1,threads_min=1)" - ",eviction_dirty_target=80,eviction_dirty_trigger=95," - "eviction_target=80,eviction_trigger=95,exclusive=0,extensions=," - "file_extend=,file_manager=(close_handle_minimum=250," - "close_idle_time=30,close_scan_interval=10),hazard_max=1000," - "in_memory=0,log=(archive=,compressor=,enabled=0,file_max=100MB," - "path=\".\",prealloc=,recover=on,zero_fill=0),lsm_manager=(merge=" - ",worker_thread_max=4),lsm_merge=,mmap=,multiprocess=0,readonly=0" - ",session_max=100,session_scratch_max=2MB," - "shared_cache=(chunk=10MB,name=,quota=0,reserve=0,size=500MB)," - "statistics=none,statistics_log=(json=0,on_close=0,path=\".\"," - "sources=,timestamp=\"%b %d %H:%M:%S\",wait=0)," - "transaction_sync=(enabled=0,method=fsync),use_environment=," - "use_environment_priv=0,verbose=,version=(major=0,minor=0)," - "write_through=", - confchk_wiredtiger_open_all, 39 + "async=(enabled=false,ops_max=1024,threads=2),buffer_alignment=-1" + ",cache_overhead=8,cache_size=100MB,checkpoint=(log_size=0," + "wait=0),checkpoint_sync=true,config_base=true,create=false," + "direct_io=,encryption=(keyid=,name=,secretkey=),error_prefix=," + "eviction=(threads_max=1,threads_min=1)," + "eviction_checkpoint_target=15,eviction_dirty_target=5," + "eviction_dirty_trigger=20,eviction_target=80,eviction_trigger=95" + ",exclusive=false,extensions=,file_extend=," + "file_manager=(close_handle_minimum=250,close_idle_time=30," + "close_scan_interval=10),hazard_max=1000,in_memory=false," + "log=(archive=true,compressor=,enabled=false,file_max=100MB," + "path=\".\",prealloc=true,recover=on,zero_fill=false)," + "lsm_manager=(merge=true,worker_thread_max=4),lsm_merge=true," + "mmap=true,multiprocess=false,readonly=false,session_max=100," + "session_scratch_max=2MB,shared_cache=(chunk=10MB,name=,quota=0," + "reserve=0,size=500MB),statistics=none,statistics_log=(json=false" + ",on_close=false,path=\".\",sources=,timestamp=\"%b %d %H:%M:%S\"" + ",wait=0),transaction_sync=(enabled=false,method=fsync)," + "use_environment=true,use_environment_priv=false,verbose=," + "version=(major=0,minor=0),write_through=", + confchk_wiredtiger_open_all, 40 }, { "wiredtiger_open_basecfg", - "async=(enabled=0,ops_max=1024,threads=2),buffer_alignment=-1," - "cache_overhead=8,cache_size=100MB,checkpoint=(log_size=0," - "name=\"WiredTigerCheckpoint\",wait=0),checkpoint_sync=," - "direct_io=,encryption=(keyid=,name=,secretkey=),error_prefix=," - "eviction=(threads_max=1,threads_min=1),eviction_dirty_target=80," - "eviction_dirty_trigger=95,eviction_target=80,eviction_trigger=95" - ",extensions=,file_extend=,file_manager=(close_handle_minimum=250" - ",close_idle_time=30,close_scan_interval=10),hazard_max=1000," - "log=(archive=,compressor=,enabled=0,file_max=100MB,path=\".\"," - "prealloc=,recover=on,zero_fill=0),lsm_manager=(merge=," - "worker_thread_max=4),lsm_merge=,mmap=,multiprocess=0,readonly=0," - "session_max=100,session_scratch_max=2MB,shared_cache=(chunk=10MB" - ",name=,quota=0,reserve=0,size=500MB),statistics=none," - "statistics_log=(json=0,on_close=0,path=\".\",sources=," - "timestamp=\"%b %d %H:%M:%S\",wait=0),transaction_sync=(enabled=0" - ",method=fsync),verbose=,version=(major=0,minor=0),write_through=", - confchk_wiredtiger_open_basecfg, 33 + "async=(enabled=false,ops_max=1024,threads=2),buffer_alignment=-1" + ",cache_overhead=8,cache_size=100MB,checkpoint=(log_size=0," + "wait=0),checkpoint_sync=true,direct_io=,encryption=(keyid=,name=" + ",secretkey=),error_prefix=,eviction=(threads_max=1," + "threads_min=1),eviction_checkpoint_target=15," + "eviction_dirty_target=5,eviction_dirty_trigger=20," + "eviction_target=80,eviction_trigger=95,extensions=,file_extend=," + "file_manager=(close_handle_minimum=250,close_idle_time=30," + "close_scan_interval=10),hazard_max=1000,log=(archive=true," + "compressor=,enabled=false,file_max=100MB,path=\".\"," + "prealloc=true,recover=on,zero_fill=false)," + "lsm_manager=(merge=true,worker_thread_max=4),lsm_merge=true," + "mmap=true,multiprocess=false,readonly=false,session_max=100," + "session_scratch_max=2MB,shared_cache=(chunk=10MB,name=,quota=0," + "reserve=0,size=500MB),statistics=none,statistics_log=(json=false" + ",on_close=false,path=\".\",sources=,timestamp=\"%b %d %H:%M:%S\"" + ",wait=0),transaction_sync=(enabled=false,method=fsync),verbose=," + "version=(major=0,minor=0),write_through=", + confchk_wiredtiger_open_basecfg, 34 }, { "wiredtiger_open_usercfg", - "async=(enabled=0,ops_max=1024,threads=2),buffer_alignment=-1," - "cache_overhead=8,cache_size=100MB,checkpoint=(log_size=0," - "name=\"WiredTigerCheckpoint\",wait=0),checkpoint_sync=," - "direct_io=,encryption=(keyid=,name=,secretkey=),error_prefix=," - "eviction=(threads_max=1,threads_min=1),eviction_dirty_target=80," - "eviction_dirty_trigger=95,eviction_target=80,eviction_trigger=95" - ",extensions=,file_extend=,file_manager=(close_handle_minimum=250" - ",close_idle_time=30,close_scan_interval=10),hazard_max=1000," - "log=(archive=,compressor=,enabled=0,file_max=100MB,path=\".\"," - "prealloc=,recover=on,zero_fill=0),lsm_manager=(merge=," - "worker_thread_max=4),lsm_merge=,mmap=,multiprocess=0,readonly=0," - "session_max=100,session_scratch_max=2MB,shared_cache=(chunk=10MB" - ",name=,quota=0,reserve=0,size=500MB),statistics=none," - "statistics_log=(json=0,on_close=0,path=\".\",sources=," - "timestamp=\"%b %d %H:%M:%S\",wait=0),transaction_sync=(enabled=0" - ",method=fsync),verbose=,write_through=", - confchk_wiredtiger_open_usercfg, 32 + "async=(enabled=false,ops_max=1024,threads=2),buffer_alignment=-1" + ",cache_overhead=8,cache_size=100MB,checkpoint=(log_size=0," + "wait=0),checkpoint_sync=true,direct_io=,encryption=(keyid=,name=" + ",secretkey=),error_prefix=,eviction=(threads_max=1," + "threads_min=1),eviction_checkpoint_target=15," + "eviction_dirty_target=5,eviction_dirty_trigger=20," + "eviction_target=80,eviction_trigger=95,extensions=,file_extend=," + "file_manager=(close_handle_minimum=250,close_idle_time=30," + "close_scan_interval=10),hazard_max=1000,log=(archive=true," + "compressor=,enabled=false,file_max=100MB,path=\".\"," + "prealloc=true,recover=on,zero_fill=false)," + "lsm_manager=(merge=true,worker_thread_max=4),lsm_merge=true," + "mmap=true,multiprocess=false,readonly=false,session_max=100," + "session_scratch_max=2MB,shared_cache=(chunk=10MB,name=,quota=0," + "reserve=0,size=500MB),statistics=none,statistics_log=(json=false" + ",on_close=false,path=\".\",sources=,timestamp=\"%b %d %H:%M:%S\"" + ",wait=0),transaction_sync=(enabled=false,method=fsync),verbose=," + "write_through=", + confchk_wiredtiger_open_usercfg, 33 }, { NULL, NULL, NULL, 0 } }; diff --git a/src/third_party/wiredtiger/src/conn/conn_api.c b/src/third_party/wiredtiger/src/conn/conn_api.c index b3092eb4828..61683f3394e 100644 --- a/src/third_party/wiredtiger/src/conn/conn_api.c +++ b/src/third_party/wiredtiger/src/conn/conn_api.c @@ -919,7 +919,7 @@ __conn_load_extensions( WT_CONFIG_BASE(session, WT_CONNECTION_load_extension), NULL, NULL }; WT_ERR(__wt_config_gets(session, cfg, "extensions", &cval)); - WT_ERR(__wt_config_subinit(session, &subconfig, &cval)); + __wt_config_subinit(session, &subconfig, &cval); while ((ret = __wt_config_next(&subconfig, &skey, &sval)) == 0) { if (expath == NULL) WT_ERR(__wt_scr_alloc(session, 0, &expath)); @@ -1020,7 +1020,7 @@ err: /* } /* Release all named snapshots. */ - WT_TRET(__wt_txn_named_snapshot_destroy(session)); + __wt_txn_named_snapshot_destroy(session); /* Close open, external sessions. */ for (s = conn->sessions, i = 0; i < conn->session_cnt; ++s, ++i) @@ -1555,7 +1555,7 @@ __conn_single(WT_SESSION_IMPL *session, const char *cfg[]) */ #define WT_SINGLETHREAD_STRING "WiredTiger lock file\n" WT_ERR(__wt_filesize(session, conn->lock_fh, &size)); - if (size != strlen(WT_SINGLETHREAD_STRING)) + if ((size_t)size != strlen(WT_SINGLETHREAD_STRING)) WT_ERR(__wt_write(session, conn->lock_fh, (wt_off_t)0, strlen(WT_SINGLETHREAD_STRING), WT_SINGLETHREAD_STRING)); @@ -1727,6 +1727,7 @@ __wt_verbose_config(WT_SESSION_IMPL *session, const char *cfg[]) { "shared_cache", WT_VERB_SHARED_CACHE }, { "split", WT_VERB_SPLIT }, { "temporary", WT_VERB_TEMPORARY }, + { "thread_group", WT_VERB_THREAD_GROUP }, { "transaction", WT_VERB_TRANSACTION }, { "verify", WT_VERB_VERIFY }, { "version", WT_VERB_VERSION }, @@ -1853,7 +1854,7 @@ __conn_write_base_config(WT_SESSION_IMPL *session, const char *cfg[]) "readonly=," "use_environment_priv=," "verbose=,", &base_config)); - WT_ERR(__wt_config_init(session, &parser, base_config)); + __wt_config_init(session, &parser, base_config); while ((ret = __wt_config_next(&parser, &k, &v)) == 0) { /* Fix quoting for non-trivial settings. */ if (v.type == WT_CONFIG_ITEM_STRING) { @@ -2008,7 +2009,7 @@ wiredtiger_open(const char *home, WT_EVENT_HANDLER *event_handler, session->name = "wiredtiger_open"; /* Do standard I/O and error handling first. */ - WT_ERR(__wt_os_stdio(session)); + __wt_os_stdio(session); __wt_event_handler_set(session, event_handler); /* @@ -2270,8 +2271,7 @@ wiredtiger_open(const char *home, WT_EVENT_HANDLER *event_handler, conn->page_size = __wt_get_vm_pagesize(); /* Now that we know if verbose is configured, output the version. */ - WT_ERR(__wt_verbose( - session, WT_VERB_VERSION, "%s", WIREDTIGER_VERSION_STRING)); + __wt_verbose(session, WT_VERB_VERSION, "%s", WIREDTIGER_VERSION_STRING); /* * Open the connection, then reset the local session as the real one diff --git a/src/third_party/wiredtiger/src/conn/conn_cache.c b/src/third_party/wiredtiger/src/conn/conn_cache.c index 9f15db5382b..7e94e9e87dc 100644 --- a/src/third_party/wiredtiger/src/conn/conn_cache.c +++ b/src/third_party/wiredtiger/src/conn/conn_cache.c @@ -18,7 +18,7 @@ __cache_config_local(WT_SESSION_IMPL *session, bool shared, const char *cfg[]) WT_CACHE *cache; WT_CONFIG_ITEM cval; WT_CONNECTION_IMPL *conn; - uint32_t evict_workers_max, evict_workers_min; + uint32_t evict_threads_max, evict_threads_min; conn = S2C(session); cache = conn->cache; @@ -42,31 +42,48 @@ __cache_config_local(WT_SESSION_IMPL *session, bool shared, const char *cfg[]) WT_RET(__wt_config_gets(session, cfg, "eviction_trigger", &cval)); cache->eviction_trigger = (u_int)cval.val; - WT_RET(__wt_config_gets(session, cfg, "eviction_dirty_target", &cval)); - cache->eviction_dirty_target = (u_int)cval.val; + if (F_ISSET(conn, WT_CONN_IN_MEMORY)) + cache->eviction_checkpoint_target = + cache->eviction_dirty_target = + cache->eviction_dirty_trigger = 100U; + else { + WT_RET(__wt_config_gets( + session, cfg, "eviction_checkpoint_target", &cval)); + cache->eviction_checkpoint_target = (u_int)cval.val; - WT_RET(__wt_config_gets(session, cfg, "eviction_dirty_trigger", &cval)); - cache->eviction_dirty_trigger = (u_int)cval.val; + WT_RET(__wt_config_gets( + session, cfg, "eviction_dirty_target", &cval)); + cache->eviction_dirty_target = (u_int)cval.val; + + /* + * Sanity check the checkpoint target: don't allow a value + * lower than the dirty target. + */ + if (cache->eviction_checkpoint_target > 0 && + cache->eviction_checkpoint_target < + cache->eviction_dirty_target) + cache->eviction_checkpoint_target = + cache->eviction_dirty_target; + + WT_RET(__wt_config_gets( + session, cfg, "eviction_dirty_trigger", &cval)); + cache->eviction_dirty_trigger = (u_int)cval.val; + } - /* - * The eviction thread configuration options include the main eviction - * thread and workers. Our implementation splits them out. Adjust for - * the difference when parsing the configuration. - */ WT_RET(__wt_config_gets(session, cfg, "eviction.threads_max", &cval)); WT_ASSERT(session, cval.val > 0); - evict_workers_max = (uint32_t)cval.val - 1; + evict_threads_max = (uint32_t)cval.val; WT_RET(__wt_config_gets(session, cfg, "eviction.threads_min", &cval)); WT_ASSERT(session, cval.val > 0); - evict_workers_min = (uint32_t)cval.val - 1; + evict_threads_min = (uint32_t)cval.val; - if (evict_workers_min > evict_workers_max) + if (evict_threads_min > evict_threads_max) WT_RET_MSG(session, EINVAL, "eviction=(threads_min) cannot be greater than " "eviction=(threads_max)"); - conn->evict_workers_max = evict_workers_max; - conn->evict_workers_min = evict_workers_min; + conn->evict_threads_max = evict_threads_max; + conn->evict_threads_min = evict_threads_min; return (0); } @@ -114,6 +131,16 @@ __wt_cache_config(WT_SESSION_IMPL *session, bool reconfigure, const char *cfg[]) WT_RET(__wt_conn_cache_pool_open(session)); } + /* + * Resize the thread group if reconfiguring, otherwise the thread group + * will be initialized as part of creating the cache. + */ + if (reconfigure) + WT_RET(__wt_thread_group_resize( + session, &conn->evict_threads, + conn->evict_threads_min, conn->evict_threads_max, + WT_THREAD_CAN_WAIT | WT_THREAD_PANIC_FAIL)); + return (0); } @@ -156,8 +183,6 @@ __wt_cache_create(WT_SESSION_IMPL *session, const char *cfg[]) WT_ERR(__wt_cond_auto_alloc(session, "cache eviction server", false, 10000, WT_MILLION, &cache->evict_cond)); - WT_ERR(__wt_cond_alloc(session, - "eviction waiters", false, &cache->evict_waiter_cond)); WT_ERR(__wt_spin_init(session, &cache->evict_pass_lock, "evict pass")); WT_ERR(__wt_spin_init(session, &cache->evict_queue_lock, "cache eviction queue")); @@ -176,6 +201,12 @@ __wt_cache_create(WT_SESSION_IMPL *session, const char *cfg[]) &cache->evict_queues[i].evict_lock, "cache eviction")); } + /* Ensure there are always non-NULL queues. */ + cache->evict_current_queue = cache->evict_fill_queue = + &cache->evict_queues[0]; + cache->evict_other_queue = &cache->evict_queues[1]; + cache->evict_urgent_queue = &cache->evict_queues[WT_EVICT_URGENT_QUEUE]; + /* * We get/set some values in the cache statistics (rather than have * two copies), configure them. @@ -197,7 +228,7 @@ __wt_cache_stats_update(WT_SESSION_IMPL *session) WT_CACHE *cache; WT_CONNECTION_IMPL *conn; WT_CONNECTION_STATS **stats; - uint64_t inuse, leaf, used; + uint64_t inuse, leaf; conn = S2C(session); cache = conn->cache; @@ -208,34 +239,37 @@ __wt_cache_stats_update(WT_SESSION_IMPL *session) * There are races updating the different cache tracking values so * be paranoid calculating the leaf byte usage. */ - used = cache->bytes_overflow + cache->bytes_internal; - leaf = inuse > used ? inuse - used : 0; + leaf = inuse > cache->bytes_internal ? + inuse - cache->bytes_internal : 0; WT_STAT_SET(session, stats, cache_bytes_max, conn->cache_size); WT_STAT_SET(session, stats, cache_bytes_inuse, inuse); - WT_STAT_SET(session, stats, cache_overhead, cache->overhead_pct); - WT_STAT_SET( - session, stats, cache_pages_inuse, __wt_cache_pages_inuse(cache)); + WT_STAT_SET( session, stats, cache_bytes_dirty, __wt_cache_dirty_inuse(cache)); - WT_STAT_SET(session, stats, - cache_eviction_maximum_page_size, cache->evict_max_page_size); - WT_STAT_SET(session, stats, cache_pages_dirty, cache->pages_dirty); - WT_STAT_SET( - session, stats, cache_bytes_internal, cache->bytes_internal); + session, stats, cache_bytes_image, __wt_cache_bytes_image(cache)); + WT_STAT_SET( + session, stats, cache_pages_inuse, __wt_cache_pages_inuse(cache)); WT_STAT_SET( - session, stats, cache_bytes_overflow, cache->bytes_overflow); + session, stats, cache_bytes_internal, cache->bytes_internal); WT_STAT_SET(session, stats, cache_bytes_leaf, leaf); + WT_STAT_SET( + session, stats, cache_bytes_other, __wt_cache_bytes_other(cache)); + + WT_STAT_SET(session, stats, + cache_eviction_maximum_page_size, cache->evict_max_page_size); + WT_STAT_SET(session, stats, cache_pages_dirty, + cache->pages_dirty_intl + cache->pages_dirty_leaf); /* * The number of files with active walks ~= number of hazard pointers * in the walk session. Note: reading without locking. */ - if (conn->evict_session != NULL) + if (conn->evict_server_running) WT_STAT_SET(session, stats, cache_eviction_walks_active, - conn->evict_session->nhazard); + cache->walk_session->nhazard); } /* @@ -267,14 +301,15 @@ __wt_cache_destroy(WT_SESSION_IMPL *session) __wt_errx(session, "cache server: exiting with %" PRIu64 " bytes in memory", cache->bytes_inmem); - if (cache->bytes_dirty != 0 || cache->pages_dirty != 0) + if (cache->bytes_dirty_intl + cache->bytes_dirty_leaf != 0 || + cache->pages_dirty_intl + cache->pages_dirty_leaf != 0) __wt_errx(session, "cache server: exiting with %" PRIu64 " bytes dirty and %" PRIu64 " pages dirty", - cache->bytes_dirty, cache->pages_dirty); + cache->bytes_dirty_intl + cache->bytes_dirty_leaf, + cache->pages_dirty_intl + cache->pages_dirty_leaf); WT_TRET(__wt_cond_auto_destroy(session, &cache->evict_cond)); - WT_TRET(__wt_cond_destroy(session, &cache->evict_waiter_cond)); __wt_spin_destroy(session, &cache->evict_pass_lock); __wt_spin_destroy(session, &cache->evict_queue_lock); __wt_spin_destroy(session, &cache->evict_walk_lock); @@ -286,6 +321,7 @@ __wt_cache_destroy(WT_SESSION_IMPL *session) __wt_spin_destroy(session, &cache->evict_queues[i].evict_lock); __wt_free(session, cache->evict_queues[i].evict_queue); } + __wt_free(session, conn->cache); return (ret); } diff --git a/src/third_party/wiredtiger/src/conn/conn_cache_pool.c b/src/third_party/wiredtiger/src/conn/conn_cache_pool.c index 75ecb6b3b4a..79c2fc23da5 100644 --- a/src/third_party/wiredtiger/src/conn/conn_cache_pool.c +++ b/src/third_party/wiredtiger/src/conn/conn_cache_pool.c @@ -34,10 +34,10 @@ #define WT_CACHE_POOL_APP_WAIT_MULTIPLIER 6 #define WT_CACHE_POOL_READ_MULTIPLIER 1 -static int __cache_pool_adjust( +static void __cache_pool_adjust( WT_SESSION_IMPL *, uint64_t, uint64_t, bool, bool *); -static int __cache_pool_assess(WT_SESSION_IMPL *, uint64_t *); -static int __cache_pool_balance(WT_SESSION_IMPL *, bool); +static void __cache_pool_assess(WT_SESSION_IMPL *, uint64_t *); +static void __cache_pool_balance(WT_SESSION_IMPL *, bool); /* * __wt_cache_pool_config -- @@ -108,8 +108,8 @@ __wt_cache_pool_config(WT_SESSION_IMPL *session, const char **cfg) "cache pool server", false, &cp->cache_pool_cond)); __wt_process.cache_pool = cp; - WT_ERR(__wt_verbose(session, - WT_VERB_SHARED_CACHE, "Created cache pool %s", cp->name)); + __wt_verbose(session, + WT_VERB_SHARED_CACHE, "Created cache pool %s", cp->name); } else if (!updating && strcmp(__wt_process.cache_pool->name, pool_name) != 0) /* Only a single cache pool is supported. */ @@ -212,12 +212,12 @@ __wt_cache_pool_config(WT_SESSION_IMPL *session, const char **cfg) /* Wake up the cache pool server so any changes are noticed. */ if (updating) - WT_ERR(__wt_cond_signal( - session, __wt_process.cache_pool->cache_pool_cond)); + __wt_cond_signal( + session, __wt_process.cache_pool->cache_pool_cond); - WT_ERR(__wt_verbose(session, WT_VERB_SHARED_CACHE, + __wt_verbose(session, WT_VERB_SHARED_CACHE, "Configured cache pool %s. Size: %" PRIu64 - ", chunk size: %" PRIu64, cp->name, cp->size, cp->chunk)); + ", chunk size: %" PRIu64, cp->name, cp->size, cp->chunk); F_SET(conn, WT_CONN_CACHE_POOL); err: __wt_spin_unlock(session, &__wt_process.spinlock); @@ -267,8 +267,8 @@ __wt_conn_cache_pool_open(WT_SESSION_IMPL *session) TAILQ_INSERT_TAIL(&cp->cache_pool_qh, conn, cpq); __wt_spin_unlock(session, &cp->cache_pool_lock); - WT_RET(__wt_verbose(session, WT_VERB_SHARED_CACHE, - "Added %s to cache pool %s", conn->home, cp->name)); + __wt_verbose(session, WT_VERB_SHARED_CACHE, + "Added %s to cache pool %s", conn->home, cp->name); /* * Each connection participating in the cache pool starts a manager @@ -282,7 +282,7 @@ __wt_conn_cache_pool_open(WT_SESSION_IMPL *session) __wt_cache_pool_server, cache->cp_session)); /* Wake up the cache pool server to get our initial chunk. */ - WT_RET(__wt_cond_signal(session, cp->cache_pool_cond)); + __wt_cond_signal(session, cp->cache_pool_cond); return (0); } @@ -324,8 +324,8 @@ __wt_conn_cache_pool_destroy(WT_SESSION_IMPL *session) * queue. We did increment the reference count, so proceed regardless. */ if (found) { - WT_TRET(__wt_verbose(session, WT_VERB_SHARED_CACHE, - "Removing %s from cache pool", entry->home)); + __wt_verbose(session, WT_VERB_SHARED_CACHE, + "Removing %s from cache pool", entry->home); TAILQ_REMOVE(&cp->cache_pool_qh, entry, cpq); /* Give the connection's resources back to the pool. */ @@ -341,7 +341,7 @@ __wt_conn_cache_pool_destroy(WT_SESSION_IMPL *session) cp_locked = false; F_CLR(cache, WT_CACHE_POOL_RUN); - WT_TRET(__wt_cond_signal(session, cp->cache_pool_cond)); + __wt_cond_signal(session, cp->cache_pool_cond); WT_TRET(__wt_thread_join(session, cache->cp_tid)); wt_session = &cache->cp_session->iface; @@ -372,8 +372,8 @@ __wt_conn_cache_pool_destroy(WT_SESSION_IMPL *session) } if (!F_ISSET(cp, WT_CACHE_POOL_ACTIVE)) { - WT_TRET(__wt_verbose( - session, WT_VERB_SHARED_CACHE, "Destroying cache pool")); + __wt_verbose( + session, WT_VERB_SHARED_CACHE, "Destroying cache pool"); __wt_spin_lock(session, &__wt_process.spinlock); /* * We have been holding the pool lock - no connections could @@ -401,8 +401,8 @@ __wt_conn_cache_pool_destroy(WT_SESSION_IMPL *session) /* Notify other participants if we were managing */ if (F_ISSET(cache, WT_CACHE_POOL_MANAGER)) { cp->pool_managed = 0; - WT_TRET(__wt_verbose(session, WT_VERB_SHARED_CACHE, - "Shutting down shared cache manager connection")); + __wt_verbose(session, WT_VERB_SHARED_CACHE, + "Shutting down shared cache manager connection"); } } @@ -414,11 +414,10 @@ __wt_conn_cache_pool_destroy(WT_SESSION_IMPL *session) * Do a pass over the cache pool members and ensure the pool is being * effectively used. */ -static int +static void __cache_pool_balance(WT_SESSION_IMPL *session, bool forward) { WT_CACHE_POOL *cp; - WT_DECL_RET; bool adjusted; uint64_t bump_threshold, highest; @@ -429,10 +428,12 @@ __cache_pool_balance(WT_SESSION_IMPL *session, bool forward) __wt_spin_lock(NULL, &cp->cache_pool_lock); /* If the queue is empty there is nothing to do. */ - if (TAILQ_FIRST(&cp->cache_pool_qh) == NULL) - goto err; + if (TAILQ_FIRST(&cp->cache_pool_qh) == NULL) { + __wt_spin_unlock(NULL, &cp->cache_pool_lock); + return; + } - WT_ERR(__cache_pool_assess(session, &highest)); + __cache_pool_assess(session, &highest); bump_threshold = WT_CACHE_POOL_BUMP_THRESHOLD; /* @@ -442,8 +443,8 @@ __cache_pool_balance(WT_SESSION_IMPL *session, bool forward) */ while (F_ISSET(cp, WT_CACHE_POOL_ACTIVE) && F_ISSET(S2C(session)->cache, WT_CACHE_POOL_RUN)) { - WT_ERR(__cache_pool_adjust( - session, highest, bump_threshold, forward, &adjusted)); + __cache_pool_adjust( + session, highest, bump_threshold, forward, &adjusted); /* * Stop if the amount of cache being used is stable, and we * aren't over capacity. @@ -454,15 +455,14 @@ __cache_pool_balance(WT_SESSION_IMPL *session, bool forward) --bump_threshold; } -err: __wt_spin_unlock(NULL, &cp->cache_pool_lock); - return (ret); + __wt_spin_unlock(NULL, &cp->cache_pool_lock); } /* * __cache_pool_assess -- * Assess the usage of the cache pool. */ -static int +static void __cache_pool_assess(WT_SESSION_IMPL *session, uint64_t *phighest) { WT_CACHE_POOL *cp; @@ -538,17 +538,16 @@ __cache_pool_assess(WT_SESSION_IMPL *session, uint64_t *phighest) if (cache->cp_pass_pressure > highest) highest = cache->cp_pass_pressure; - WT_RET(__wt_verbose(session, WT_VERB_SHARED_CACHE, + __wt_verbose(session, WT_VERB_SHARED_CACHE, "Assess entry. reads: %" PRIu64 ", app evicts: %" PRIu64 ", app waits: %" PRIu64 ", pressure: %" PRIu64, - reads, app_evicts, app_waits, cache->cp_pass_pressure)); + reads, app_evicts, app_waits, cache->cp_pass_pressure); } - WT_RET(__wt_verbose(session, WT_VERB_SHARED_CACHE, + __wt_verbose(session, WT_VERB_SHARED_CACHE, "Highest eviction count: %" PRIu64 ", entries: %" PRIu64, - highest, entries)); + highest, entries); *phighest = highest; - return (0); } /* @@ -557,7 +556,7 @@ __cache_pool_assess(WT_SESSION_IMPL *session, uint64_t *phighest) * ignore cache load information, and reduce the allocation for every * connection allocated more than their reserved size. */ -static int +static void __cache_pool_adjust(WT_SESSION_IMPL *session, uint64_t highest, uint64_t bump_threshold, bool forward, bool *adjustedp) { @@ -577,10 +576,10 @@ __cache_pool_adjust(WT_SESSION_IMPL *session, highest_percentile = (highest / 100) + 1; if (WT_VERBOSE_ISSET(session, WT_VERB_SHARED_CACHE)) { - WT_RET(__wt_verbose(session, - WT_VERB_SHARED_CACHE, "Cache pool distribution: ")); - WT_RET(__wt_verbose(session, WT_VERB_SHARED_CACHE, - "\t" "cache (MB), pressure, skips, busy, %% full:")); + __wt_verbose(session, + WT_VERB_SHARED_CACHE, "Cache pool distribution: "); + __wt_verbose(session, WT_VERB_SHARED_CACHE, + "\t" "cache (MB), pressure, skips, busy, %% full:"); } for (entry = forward ? TAILQ_FIRST(&cp->cache_pool_qh) : @@ -600,12 +599,13 @@ __cache_pool_adjust(WT_SESSION_IMPL *session, * assigned. */ pressure = cache->cp_pass_pressure / highest_percentile; - busy = __wt_eviction_needed(entry->default_session, &pct_full); + busy = __wt_eviction_needed( + entry->default_session, false, &pct_full); - WT_RET(__wt_verbose(session, WT_VERB_SHARED_CACHE, + __wt_verbose(session, WT_VERB_SHARED_CACHE, "\t%5" PRIu64 ", %3" PRIu64 ", %2" PRIu32 ", %d, %2u", entry->cache_size >> 20, pressure, cache->cp_skip_count, - busy, pct_full)); + busy, pct_full); /* Allow to stabilize after changes. */ if (cache->cp_skip_count > 0 && --cache->cp_skip_count > 0) @@ -699,9 +699,9 @@ __cache_pool_adjust(WT_SESSION_IMPL *session, entry->cache_size -= adjustment; cp->currently_used -= adjustment; } - WT_RET(__wt_verbose(session, WT_VERB_SHARED_CACHE, + __wt_verbose(session, WT_VERB_SHARED_CACHE, "Allocated %s%" PRId64 " to %s", - grow ? "" : "-", adjustment, entry->home)); + grow ? "" : "-", adjustment, entry->home); /* * TODO: Add a loop waiting for connection to give up @@ -709,7 +709,6 @@ __cache_pool_adjust(WT_SESSION_IMPL *session, */ } } - return (0); } /* @@ -721,7 +720,6 @@ __wt_cache_pool_server(void *arg) { WT_CACHE *cache; WT_CACHE_POOL *cp; - WT_DECL_RET; WT_SESSION_IMPL *session; bool forward; @@ -734,8 +732,8 @@ __wt_cache_pool_server(void *arg) while (F_ISSET(cp, WT_CACHE_POOL_ACTIVE) && F_ISSET(cache, WT_CACHE_POOL_RUN)) { if (cp->currently_used <= cp->size) - WT_ERR(__wt_cond_wait(session, - cp->cache_pool_cond, WT_MILLION)); + __wt_cond_wait( + session, cp->cache_pool_cond, WT_MILLION); /* * Re-check pool run flag - since we want to avoid getting the @@ -748,8 +746,8 @@ __wt_cache_pool_server(void *arg) /* Try to become the managing thread */ if (__wt_atomic_cas8(&cp->pool_managed, 0, 1)) { F_SET(cache, WT_CACHE_POOL_MANAGER); - WT_ERR(__wt_verbose(session, WT_VERB_SHARED_CACHE, - "Cache pool switched manager thread")); + __wt_verbose(session, WT_VERB_SHARED_CACHE, + "Cache pool switched manager thread"); } /* @@ -757,13 +755,10 @@ __wt_cache_pool_server(void *arg) * reported in the balance function. */ if (F_ISSET(cache, WT_CACHE_POOL_MANAGER)) { - (void)__cache_pool_balance(session, forward); + __cache_pool_balance(session, forward); forward = !forward; } } - if (0) { -err: WT_PANIC_MSG(session, ret, "cache pool manager server error"); - } return (WT_THREAD_RET_VALUE); } diff --git a/src/third_party/wiredtiger/src/conn/conn_ckpt.c b/src/third_party/wiredtiger/src/conn/conn_ckpt.c index b1d619dc1e8..451b0cd86f6 100644 --- a/src/third_party/wiredtiger/src/conn/conn_ckpt.c +++ b/src/third_party/wiredtiger/src/conn/conn_ckpt.c @@ -19,9 +19,8 @@ __ckpt_server_config(WT_SESSION_IMPL *session, const char **cfg, bool *startp) { WT_CONFIG_ITEM cval; WT_CONNECTION_IMPL *conn; - WT_DECL_ITEM(tmp); - WT_DECL_RET; - char *p; + + *startp = false; *startp = false; @@ -33,24 +32,6 @@ __ckpt_server_config(WT_SESSION_IMPL *session, const char **cfg, bool *startp) WT_RET(__wt_config_gets(session, cfg, "checkpoint.log_size", &cval)); conn->ckpt_logsize = (wt_off_t)cval.val; - /* - * The application can specify a checkpoint name, which we ignore if - * it's our default. - */ - WT_RET(__wt_config_gets(session, cfg, "checkpoint.name", &cval)); - if (cval.len != 0 && - !WT_STRING_MATCH(WT_CHECKPOINT, cval.str, cval.len)) { - WT_RET(__wt_checkpoint_name_ok(session, cval.str, cval.len)); - - WT_RET(__wt_scr_alloc(session, cval.len + 20, &tmp)); - WT_ERR(__wt_buf_fmt( - session, tmp, "name=%.*s", (int)cval.len, cval.str)); - WT_ERR(__wt_strdup(session, tmp->data, &p)); - - __wt_free(session, conn->ckpt_config); - conn->ckpt_config = p; - } - /* * The checkpoint configuration requires a wait time and/or a log size, * if neither is set, we're not running at all. Checkpoints based on log @@ -59,10 +40,19 @@ __ckpt_server_config(WT_SESSION_IMPL *session, const char **cfg, bool *startp) if (conn->ckpt_usecs != 0 || (conn->ckpt_logsize != 0 && FLD_ISSET(conn->log_flags, WT_CONN_LOG_ENABLED))) { + /* + * If checkpointing based on log data, use a minimum of the + * log file size. The logging subsystem has already been + * initialized. + */ + if (conn->ckpt_logsize != 0 && + FLD_ISSET(conn->log_flags, WT_CONN_LOG_ENABLED)) + conn->ckpt_logsize = WT_MAX( + conn->ckpt_logsize, conn->log_file_max); /* Checkpoints are incompatible with in-memory configuration */ - WT_ERR(__wt_config_gets(session, cfg, "in_memory", &cval)); + WT_RET(__wt_config_gets(session, cfg, "in_memory", &cval)); if (cval.val != 0) - WT_ERR_MSG(session, EINVAL, + WT_RET_MSG(session, EINVAL, "checkpoint configuration incompatible with " "in-memory configuration"); @@ -71,8 +61,7 @@ __ckpt_server_config(WT_SESSION_IMPL *session, const char **cfg, bool *startp) *startp = true; } -err: __wt_scr_free(session, &tmp); - return (ret); + return (0); } /* @@ -98,16 +87,15 @@ __ckpt_server(void *arg) * NOTE: If the user only configured logsize, then usecs * will be 0 and this wait won't return until signalled. */ - WT_ERR( - __wt_cond_wait(session, conn->ckpt_cond, conn->ckpt_usecs)); + __wt_cond_wait(session, conn->ckpt_cond, conn->ckpt_usecs); /* Checkpoint the database. */ - WT_ERR(wt_session->checkpoint(wt_session, conn->ckpt_config)); + WT_ERR(wt_session->checkpoint(wt_session, NULL)); /* Reset. */ if (conn->ckpt_logsize) { __wt_log_written_reset(session); - conn->ckpt_signalled = 0; + conn->ckpt_signalled = false; /* * In case we crossed the log limit during the @@ -115,7 +103,7 @@ __ckpt_server(void *arg) * signalled, do a tiny wait to clear it so we don't do * another checkpoint immediately. */ - WT_ERR(__wt_cond_wait(session, conn->ckpt_cond, 1)); + __wt_cond_wait(session, conn->ckpt_cond, 1); } } @@ -213,14 +201,12 @@ __wt_checkpoint_server_destroy(WT_SESSION_IMPL *session) F_CLR(conn, WT_CONN_SERVER_CHECKPOINT); if (conn->ckpt_tid_set) { - WT_TRET(__wt_cond_signal(session, conn->ckpt_cond)); + __wt_cond_signal(session, conn->ckpt_cond); WT_TRET(__wt_thread_join(session, conn->ckpt_tid)); conn->ckpt_tid_set = false; } WT_TRET(__wt_cond_destroy(session, &conn->ckpt_cond)); - __wt_free(session, conn->ckpt_config); - /* Close the server thread's session. */ if (conn->ckpt_session != NULL) { wt_session = &conn->ckpt_session->iface; @@ -234,7 +220,6 @@ __wt_checkpoint_server_destroy(WT_SESSION_IMPL *session) conn->ckpt_session = NULL; conn->ckpt_tid_set = false; conn->ckpt_cond = NULL; - conn->ckpt_config = NULL; conn->ckpt_usecs = 0; return (ret); @@ -243,9 +228,8 @@ __wt_checkpoint_server_destroy(WT_SESSION_IMPL *session) /* * __wt_checkpoint_signal -- * Signal the checkpoint thread if sufficient log has been written. - * Return 1 if this signals the checkpoint thread, 0 otherwise. */ -int +void __wt_checkpoint_signal(WT_SESSION_IMPL *session, wt_off_t logsize) { WT_CONNECTION_IMPL *conn; @@ -253,8 +237,7 @@ __wt_checkpoint_signal(WT_SESSION_IMPL *session, wt_off_t logsize) conn = S2C(session); WT_ASSERT(session, WT_CKPT_LOGSIZE(conn)); if (logsize >= conn->ckpt_logsize && !conn->ckpt_signalled) { - WT_RET(__wt_cond_signal(session, conn->ckpt_cond)); - conn->ckpt_signalled = 1; + __wt_cond_signal(session, conn->ckpt_cond); + conn->ckpt_signalled = true; } - return (0); } diff --git a/src/third_party/wiredtiger/src/conn/conn_dhandle.c b/src/third_party/wiredtiger/src/conn/conn_dhandle.c index 08fb2b24468..ec850c793cc 100644 --- a/src/third_party/wiredtiger/src/conn/conn_dhandle.c +++ b/src/third_party/wiredtiger/src/conn/conn_dhandle.c @@ -12,19 +12,15 @@ * __conn_dhandle_destroy -- * Destroy a data handle. */ -static int +static void __conn_dhandle_destroy(WT_SESSION_IMPL *session, WT_DATA_HANDLE *dhandle) { - WT_DECL_RET; - - ret = __wt_rwlock_destroy(session, &dhandle->rwlock); + __wt_rwlock_destroy(session, &dhandle->rwlock); __wt_free(session, dhandle->name); __wt_free(session, dhandle->checkpoint); __wt_free(session, dhandle->handle); __wt_spin_destroy(session, &dhandle->close_lock); __wt_overwrite_and_free(session, dhandle); - - return (ret); } /* @@ -63,6 +59,16 @@ __conn_dhandle_alloc(WT_SESSION_IMPL *session, if (strcmp(uri, WT_METAFILE_URI) == 0) F_SET(dhandle, WT_DHANDLE_IS_METADATA); + /* + * We are holding the data handle list lock, which protects most + * threads from seeing the new handle until that lock is released. + * + * However, the sweep server scans the list of handles without holding + * that lock, so we need a write barrier here to ensure the sweep + * server doesn't see a partially filled in structure. + */ + WT_WRITE_BARRIER(); + /* * Prepend the handle to the connection list, assuming we're likely to * need new files again soon, until they are cached by all sessions. @@ -73,7 +79,7 @@ __conn_dhandle_alloc(WT_SESSION_IMPL *session, *dhandlep = dhandle; return (0); -err: WT_TRET(__conn_dhandle_destroy(session, dhandle)); +err: __conn_dhandle_destroy(session, dhandle); return (ret); } @@ -482,9 +488,9 @@ __wt_conn_dhandle_close_all( * open at this point. Close the handle, if necessary. */ if (F_ISSET(dhandle, WT_DHANDLE_OPEN)) { - if ((ret = __wt_meta_track_sub_on(session)) == 0) - ret = __wt_conn_btree_sync_and_close( - session, false, force); + __wt_meta_track_sub_on(session); + ret = __wt_conn_btree_sync_and_close( + session, false, force); /* * If the close succeeded, drop any locks it acquired. @@ -566,14 +572,14 @@ __wt_conn_dhandle_discard_single( set_pass_intr = false; if (!F_ISSET(session, WT_SESSION_LOCKED_HANDLE_LIST)) { set_pass_intr = true; - (void)__wt_atomic_add32(&S2C(session)->cache->pass_intr, 1); + (void)__wt_atomic_addv32(&S2C(session)->cache->pass_intr, 1); } /* Try to remove the handle, protected by the data handle lock. */ WT_WITH_HANDLE_LIST_LOCK(session, tret = __conn_dhandle_remove(session, final)); if (set_pass_intr) - (void)__wt_atomic_sub32(&S2C(session)->cache->pass_intr, 1); + (void)__wt_atomic_subv32(&S2C(session)->cache->pass_intr, 1); WT_TRET(tret); /* @@ -581,7 +587,7 @@ __wt_conn_dhandle_discard_single( */ if (ret == 0 || final) { __conn_btree_config_clear(session); - WT_TRET(__conn_dhandle_destroy(session, dhandle)); + __conn_dhandle_destroy(session, dhandle); session->dhandle = NULL; } diff --git a/src/third_party/wiredtiger/src/conn/conn_handle.c b/src/third_party/wiredtiger/src/conn/conn_handle.c index 509966793e5..5ff8b7f798b 100644 --- a/src/third_party/wiredtiger/src/conn/conn_handle.c +++ b/src/third_party/wiredtiger/src/conn/conn_handle.c @@ -138,7 +138,7 @@ __wt_connection_destroy(WT_CONNECTION_IMPL *conn) __wt_spin_destroy(session, &conn->dhandle_lock); __wt_spin_destroy(session, &conn->encryptor_lock); __wt_spin_destroy(session, &conn->fh_lock); - WT_TRET(__wt_rwlock_destroy(session, &conn->hot_backup_lock)); + __wt_rwlock_destroy(session, &conn->hot_backup_lock); __wt_spin_destroy(session, &conn->las_lock); __wt_spin_destroy(session, &conn->metadata_lock); __wt_spin_destroy(session, &conn->reconfig_lock); diff --git a/src/third_party/wiredtiger/src/conn/conn_log.c b/src/third_party/wiredtiger/src/conn/conn_log.c index 18ed71e4688..a8f0fe4810b 100644 --- a/src/third_party/wiredtiger/src/conn/conn_log.c +++ b/src/third_party/wiredtiger/src/conn/conn_log.c @@ -173,7 +173,7 @@ __logmgr_config( WT_RET(__logmgr_sync_cfg(session, cfg)); if (conn->log_cond != NULL) - WT_RET(__wt_cond_auto_signal(session, conn->log_cond)); + __wt_cond_auto_signal(session, conn->log_cond); return (0); } @@ -222,8 +222,8 @@ __log_archive_once(WT_SESSION_IMPL *session, uint32_t backup_file) else min_lognum = WT_MIN( log->ckpt_lsn.l.file, log->sync_lsn.l.file); - WT_RET(__wt_verbose(session, WT_VERB_LOG, - "log_archive: archive to log number %" PRIu32, min_lognum)); + __wt_verbose(session, WT_VERB_LOG, + "log_archive: archive to log number %" PRIu32, min_lognum); /* * Main archive code. Get the list of all log files and @@ -236,7 +236,7 @@ __log_archive_once(WT_SESSION_IMPL *session, uint32_t backup_file) * We can only archive files if a hot backup is not in progress or * if we are the backup. */ - WT_ERR(__wt_readlock(session, conn->hot_backup_lock)); + __wt_readlock(session, conn->hot_backup_lock); locked = true; if (!conn->hot_backup || backup_file != 0) { for (i = 0; i < logcount; i++) { @@ -247,7 +247,7 @@ __log_archive_once(WT_SESSION_IMPL *session, uint32_t backup_file) session, WT_LOG_FILENAME, lognum)); } } - WT_ERR(__wt_readunlock(session, conn->hot_backup_lock)); + __wt_readunlock(session, conn->hot_backup_lock); locked = false; /* @@ -259,7 +259,7 @@ __log_archive_once(WT_SESSION_IMPL *session, uint32_t backup_file) if (0) err: __wt_err(session, ret, "log archive server error"); if (locked) - WT_TRET(__wt_readunlock(session, conn->hot_backup_lock)); + __wt_readunlock(session, conn->hot_backup_lock); WT_TRET(__wt_fs_directory_list_free(session, &logfiles, logcount)); return (ret); } @@ -295,9 +295,9 @@ __log_prealloc_once(WT_SESSION_IMPL *session) */ if (log->prep_missed > 0) { conn->log_prealloc += log->prep_missed; - WT_ERR(__wt_verbose(session, WT_VERB_LOG, + __wt_verbose(session, WT_VERB_LOG, "Missed %" PRIu32 ". Now pre-allocating up to %" PRIu32, - log->prep_missed, conn->log_prealloc)); + log->prep_missed, conn->log_prealloc); } WT_STAT_FAST_CONN_SET(session, log_prealloc_max, conn->log_prealloc); /* @@ -335,7 +335,6 @@ __wt_log_truncate_files( WT_DECL_RET; WT_LOG *log; uint32_t backup_file; - bool locked; WT_UNUSED(cfg); conn = S2C(session); @@ -352,18 +351,12 @@ __wt_log_truncate_files( if (cursor != NULL) backup_file = WT_CURSOR_BACKUP_ID(cursor); WT_ASSERT(session, backup_file <= log->alloc_lsn.l.file); - WT_RET(__wt_verbose(session, WT_VERB_LOG, - "log_truncate_files: Archive once up to %" PRIu32, - backup_file)); + __wt_verbose(session, WT_VERB_LOG, + "log_truncate_files: Archive once up to %" PRIu32, backup_file); - WT_RET(__wt_writelock(session, log->log_archive_lock)); - locked = true; - WT_ERR(__log_archive_once(session, backup_file)); - WT_ERR(__wt_writeunlock(session, log->log_archive_lock)); - locked = false; -err: - if (locked) - WT_RET(__wt_writeunlock(session, log->log_archive_lock)); + __wt_writelock(session, log->log_archive_lock); + ret = __log_archive_once(session, backup_file); + __wt_writeunlock(session, log->log_archive_lock); return (ret); } @@ -428,13 +421,27 @@ __log_file_server(void *arg) * later syncs. */ WT_ERR(__wt_fsync(session, close_fh, true)); + /* - * We want to make sure the file size reflects - * actual data and has minimal pre-allocated - * zeroed space. + * We want to have the file size reflect actual + * data with minimal pre-allocated zeroed space. + * We can't truncate the file during hot backup, + * or the underlying file system may not support + * truncate: both are OK, it's just more work + * during cursor traversal. */ - WT_ERR(__wt_ftruncate(session, - close_fh, close_end_lsn.l.offset)); + if (!conn->hot_backup) { + __wt_readlock( + session, conn->hot_backup_lock); + if (!conn->hot_backup) + WT_ERR_ERROR_OK( + __wt_ftruncate(session, + close_fh, + close_end_lsn.l.offset), + ENOTSUP); + __wt_readunlock( + session, conn->hot_backup_lock); + } WT_SET_LSN(&close_end_lsn, close_end_lsn.l.file + 1, 0); __wt_spin_lock(session, &log->log_sync_lock); @@ -443,8 +450,7 @@ __log_file_server(void *arg) WT_ASSERT(session, __wt_log_cmp( &close_end_lsn, &log->sync_lsn) >= 0); log->sync_lsn = close_end_lsn; - WT_ERR(__wt_cond_signal( - session, log->log_sync_cond)); + __wt_cond_signal(session, log->log_sync_cond); locked = false; __wt_spin_unlock(session, &log->log_sync_lock); } @@ -492,14 +498,14 @@ __log_file_server(void *arg) min_lsn.l.file == log->sync_lsn.l.file); log->sync_lsn = min_lsn; - WT_ERR(__wt_cond_signal( - session, log->log_sync_cond)); + __wt_cond_signal( + session, log->log_sync_cond); } locked = false; __wt_spin_unlock(session, &log->log_sync_lock); } else { - WT_ERR(__wt_cond_auto_signal( - session, conn->log_wrlsn_cond)); + __wt_cond_auto_signal( + session, conn->log_wrlsn_cond); /* * We do not want to wait potentially a second * to process this. Yield to give the wrlsn @@ -511,8 +517,7 @@ __log_file_server(void *arg) } } /* Wait until the next event. */ - WT_ERR(__wt_cond_wait( - session, conn->log_file_cond, WT_MILLION / 10)); + __wt_cond_wait(session, conn->log_file_cond, WT_MILLION / 10); } if (0) { @@ -546,11 +551,10 @@ typedef struct { * are contiguous. The purpose of this function is to advance the * write_lsn in LSN order after the buffer is written to the log file. */ -int +void __wt_log_wrlsn(WT_SESSION_IMPL *session, int *yield) { WT_CONNECTION_IMPL *conn; - WT_DECL_RET; WT_LOG *log; WT_LOG_WRLSN_ENTRY written[WT_SLOT_POOL]; WT_LOGSLOT *coalescing, *slot; @@ -669,21 +673,19 @@ restart: (uint32_t)slot->slot_last_offset; log->write_start_lsn = slot->slot_start_lsn; log->write_lsn = slot->slot_end_lsn; - WT_ERR(__wt_cond_signal( - session, log->log_write_cond)); + __wt_cond_signal(session, log->log_write_cond); WT_STAT_FAST_CONN_INCR(session, log_write_lsn); /* * Signal the close thread if needed. */ if (F_ISSET(slot, WT_SLOT_CLOSEFH)) - WT_ERR(__wt_cond_signal( - session, conn->log_file_cond)); + __wt_cond_signal( + session, conn->log_file_cond); } __wt_log_slot_free(session, slot); } } -err: __wt_spin_unlock(session, &log->log_writelsn_lock); - return (ret); + __wt_spin_unlock(session, &log->log_writelsn_lock); } /* @@ -716,7 +718,7 @@ __log_wrlsn_server(void *arg) */ if (__wt_log_cmp(&prev, &log->alloc_lsn) != 0 || __wt_log_cmp(&log->write_lsn, &log->alloc_lsn) != 0) - WT_ERR(__wt_log_wrlsn(session, &yield)); + __wt_log_wrlsn(session, &yield); else WT_STAT_FAST_CONN_INCR(session, log_write_lsn_skip); prev = log->alloc_lsn; @@ -732,15 +734,15 @@ __log_wrlsn_server(void *arg) * Send in false because if we did any work we would * not be on this path. */ - WT_ERR(__wt_cond_auto_wait( - session, conn->log_wrlsn_cond, did_work)); + __wt_cond_auto_wait( + session, conn->log_wrlsn_cond, did_work); } /* * On close we need to do this one more time because there could * be straggling log writes that need to be written. */ WT_ERR(__wt_log_force_write(session, 1, NULL)); - WT_ERR(__wt_log_wrlsn(session, NULL)); + __wt_log_wrlsn(session, NULL); if (0) { err: __wt_err(session, ret, "log wrlsn server error"); } @@ -760,12 +762,12 @@ __log_server(void *arg) WT_LOG *log; WT_SESSION_IMPL *session; uint64_t timediff; - bool did_work, locked, signalled; + bool did_work, signalled; session = arg; conn = S2C(session); log = conn->log; - locked = signalled = false; + signalled = false; /* * Set this to the number of milliseconds we want to run archive and @@ -812,14 +814,11 @@ __log_server(void *arg) * agreed not to rename or remove any files in * the database directory. */ - WT_ERR(__wt_readlock( - session, conn->hot_backup_lock)); - locked = true; + __wt_readlock(session, conn->hot_backup_lock); if (!conn->hot_backup) - WT_ERR(__log_prealloc_once(session)); - WT_ERR(__wt_readunlock( - session, conn->hot_backup_lock)); - locked = false; + ret = __log_prealloc_once(session); + __wt_readunlock(session, conn->hot_backup_lock); + WT_ERR(ret); } /* @@ -829,31 +828,27 @@ __log_server(void *arg) if (__wt_try_writelock( session, log->log_archive_lock) == 0) { ret = __log_archive_once(session, 0); - WT_TRET(__wt_writeunlock( - session, log->log_archive_lock)); + __wt_writeunlock( + session, log->log_archive_lock); WT_ERR(ret); } else - WT_ERR( - __wt_verbose(session, WT_VERB_LOG, + __wt_verbose(session, WT_VERB_LOG, "log_archive: Blocked due to open " - "log cursor holding archive lock")); + "log cursor holding archive lock"); } } /* Wait until the next event. */ WT_ERR(__wt_epoch(session, &start)); - WT_ERR(__wt_cond_auto_wait_signal(session, conn->log_cond, - did_work, &signalled)); + __wt_cond_auto_wait_signal(session, + conn->log_cond, did_work, &signalled); WT_ERR(__wt_epoch(session, &now)); timediff = WT_TIMEDIFF_MS(now, start); } if (0) { err: __wt_err(session, ret, "log server error"); - if (locked) - WT_TRET(__wt_readunlock( - session, conn->hot_backup_lock)); } return (WT_THREAD_RET_VALUE); } @@ -974,7 +969,7 @@ __wt_logmgr_open(WT_SESSION_IMPL *session) if (conn->log_session != NULL) { WT_ASSERT(session, conn->log_cond != NULL); WT_ASSERT(session, conn->log_tid_set == true); - WT_RET(__wt_cond_auto_signal(session, conn->log_cond)); + __wt_cond_auto_signal(session, conn->log_cond); } else { /* The log server gets its own session. */ WT_RET(__wt_open_internal_session(conn, @@ -1016,12 +1011,12 @@ __wt_logmgr_destroy(WT_SESSION_IMPL *session) return (0); } if (conn->log_tid_set) { - WT_TRET(__wt_cond_auto_signal(session, conn->log_cond)); + __wt_cond_auto_signal(session, conn->log_cond); WT_TRET(__wt_thread_join(session, conn->log_tid)); conn->log_tid_set = false; } if (conn->log_file_tid_set) { - WT_TRET(__wt_cond_signal(session, conn->log_file_cond)); + __wt_cond_signal(session, conn->log_file_cond); WT_TRET(__wt_thread_join(session, conn->log_file_tid)); conn->log_file_tid_set = false; } @@ -1031,7 +1026,7 @@ __wt_logmgr_destroy(WT_SESSION_IMPL *session) conn->log_file_session = NULL; } if (conn->log_wrlsn_tid_set) { - WT_TRET(__wt_cond_auto_signal(session, conn->log_wrlsn_cond)); + __wt_cond_auto_signal(session, conn->log_wrlsn_cond); WT_TRET(__wt_thread_join(session, conn->log_wrlsn_tid)); conn->log_wrlsn_tid_set = false; } @@ -1058,7 +1053,7 @@ __wt_logmgr_destroy(WT_SESSION_IMPL *session) WT_TRET(__wt_cond_destroy(session, &conn->log->log_sync_cond)); WT_TRET(__wt_cond_destroy(session, &conn->log->log_write_cond)); - WT_TRET(__wt_rwlock_destroy(session, &conn->log->log_archive_lock)); + __wt_rwlock_destroy(session, &conn->log->log_archive_lock); __wt_spin_destroy(session, &conn->log->log_lock); __wt_spin_destroy(session, &conn->log->log_slot_lock); __wt_spin_destroy(session, &conn->log->log_sync_lock); diff --git a/src/third_party/wiredtiger/src/conn/conn_open.c b/src/third_party/wiredtiger/src/conn/conn_open.c index 9c978fed843..69b50147bf5 100644 --- a/src/third_party/wiredtiger/src/conn/conn_open.c +++ b/src/third_party/wiredtiger/src/conn/conn_open.c @@ -157,7 +157,7 @@ __wt_connection_close(WT_CONNECTION_IMPL *conn) WT_TRET(__wt_cache_destroy(session)); /* Discard transaction state. */ - WT_TRET(__wt_txn_global_destroy(session)); + __wt_txn_global_destroy(session); /* Close extensions, first calling any unload entry point. */ while ((dlh = TAILQ_FIRST(&conn->dlhqh)) != NULL) { @@ -186,27 +186,18 @@ __wt_connection_close(WT_CONNECTION_IMPL *conn) } /* - * The session's split stash isn't discarded during normal session close - * because it may persist past the life of the session. Discard it now. + * The session split stash, hazard information and handle arrays aren't + * discarded during normal session close, they persist past the life of + * the session. Discard them now. */ - if ((s = conn->sessions) != NULL) - for (i = 0; i < conn->session_size; ++s, ++i) - __wt_split_stash_discard_all(session, s); - - /* - * The session's hazard pointer memory isn't discarded during normal - * session close because access to it isn't serialized. Discard it - * now. - */ - if ((s = conn->sessions) != NULL) - for (i = 0; i < conn->session_size; ++s, ++i) { - /* - * If hash arrays were allocated, free them now. - */ - __wt_free(session, s->dhhash); - __wt_free(session, s->tablehash); - __wt_free(session, s->hazard); - } + if (!F_ISSET(conn, WT_CONN_LEAK_MEMORY)) + if ((s = conn->sessions) != NULL) + for (i = 0; i < conn->session_size; ++s, ++i) { + __wt_free(session, s->dhhash); + __wt_free(session, s->tablehash); + __wt_split_stash_discard_all(session, s); + __wt_free(session, s->hazard); + } /* Destroy the handle. */ WT_TRET(__wt_connection_destroy(conn)); diff --git a/src/third_party/wiredtiger/src/conn/conn_stat.c b/src/third_party/wiredtiger/src/conn/conn_stat.c index 4e7cac59c4a..530bbfcd2db 100644 --- a/src/third_party/wiredtiger/src/conn/conn_stat.c +++ b/src/third_party/wiredtiger/src/conn/conn_stat.c @@ -155,13 +155,13 @@ __statlog_config(WT_SESSION_IMPL *session, const char **cfg, bool *runp) WT_ERR(__wt_filename(session, tmp->data, &conn->stat_path)); WT_ERR(__wt_config_gets(session, cfg, "statistics_log.sources", &cval)); - WT_ERR(__wt_config_subinit(session, &objectconf, &cval)); + __wt_config_subinit(session, &objectconf, &cval); for (cnt = 0; (ret = __wt_config_next(&objectconf, &k, &v)) == 0; ++cnt) ; WT_ERR_NOTFOUND_OK(ret); if (cnt != 0) { WT_ERR(__wt_calloc_def(session, cnt + 1, &sources)); - WT_ERR(__wt_config_subinit(session, &objectconf, &cval)); + __wt_config_subinit(session, &objectconf, &cval); for (cnt = 0; (ret = __wt_config_next(&objectconf, &k, &v)) == 0; ++cnt) { /* @@ -528,8 +528,7 @@ __statlog_server(void *arg) while (F_ISSET(conn, WT_CONN_SERVER_RUN) && F_ISSET(conn, WT_CONN_SERVER_STATISTICS)) { /* Wait until the next event. */ - WT_ERR( - __wt_cond_wait(session, conn->stat_cond, conn->stat_usecs)); + __wt_cond_wait(session, conn->stat_cond, conn->stat_usecs); if (!FLD_ISSET(conn->stat_flags, WT_CONN_STAT_NONE)) WT_ERR(__statlog_log_one(session, &path, &tmp)); @@ -636,7 +635,7 @@ __wt_statlog_destroy(WT_SESSION_IMPL *session, bool is_close) /* Stop the server thread. */ F_CLR(conn, WT_CONN_SERVER_STATISTICS); if (conn->stat_tid_set) { - WT_TRET(__wt_cond_signal(session, conn->stat_cond)); + __wt_cond_signal(session, conn->stat_cond); WT_TRET(__wt_thread_join(session, conn->stat_tid)); conn->stat_tid_set = false; } diff --git a/src/third_party/wiredtiger/src/conn/conn_sweep.c b/src/third_party/wiredtiger/src/conn/conn_sweep.c index 5d24ea61607..25057d73564 100644 --- a/src/third_party/wiredtiger/src/conn/conn_sweep.c +++ b/src/third_party/wiredtiger/src/conn/conn_sweep.c @@ -17,7 +17,7 @@ * Mark idle handles with a time of death, and note if we see dead * handles. */ -static int +static void __sweep_mark(WT_SESSION_IMPL *session, time_t now) { WT_CONNECTION_IMPL *conn; @@ -50,8 +50,6 @@ __sweep_mark(WT_SESSION_IMPL *session, time_t now) dhandle->timeofdeath = now; WT_STAT_FAST_CONN_INCR(session, dh_sweep_tod); } - - return (0); } /* @@ -97,7 +95,7 @@ __sweep_expire_one(WT_SESSION_IMPL *session) */ ret = __wt_conn_btree_sync_and_close(session, false, true); -err: WT_TRET(__wt_writeunlock(session, dhandle->rwlock)); +err: __wt_writeunlock(session, dhandle->rwlock); return (ret); } @@ -207,7 +205,7 @@ __sweep_remove_one(WT_SESSION_IMPL *session, WT_DATA_HANDLE *dhandle) * don't retry the discard until it times out again. */ if (ret != 0) { -err: WT_TRET(__wt_writeunlock(session, dhandle->rwlock)); +err: __wt_writeunlock(session, dhandle->rwlock); } return (ret); @@ -258,10 +256,12 @@ __sweep_server(void *arg) WT_DECL_RET; WT_SESSION_IMPL *session; time_t now; + uint64_t last_las_sweep_id, oldest_id; u_int dead_handles; session = arg; conn = S2C(session); + last_las_sweep_id = WT_TXN_NONE; /* * Sweep for dead and excess handles. @@ -269,8 +269,8 @@ __sweep_server(void *arg) while (F_ISSET(conn, WT_CONN_SERVER_RUN) && F_ISSET(conn, WT_CONN_SERVER_SWEEP)) { /* Wait until the next event. */ - WT_ERR(__wt_cond_wait(session, - conn->sweep_cond, conn->sweep_interval * WT_MILLION)); + __wt_cond_wait(session, + conn->sweep_cond, conn->sweep_interval * WT_MILLION); WT_ERR(__wt_seconds(session, &now)); WT_STAT_FAST_CONN_INCR(session, dh_sweeps); @@ -278,9 +278,22 @@ __sweep_server(void *arg) /* * Sweep the lookaside table. If the lookaside table hasn't yet * been written, there's no work to do. + * + * Don't sweep the lookaside table if the cache is stuck full. + * The sweep uses the cache and can exacerbate the problem. + * If we try to sweep when the cache is full or we aren't + * making progress in eviction, sweeping can wind up constantly + * bringing in and evicting pages from the lookaside table, + * which will stop the cache from moving into the stuck state. */ - if (__wt_las_is_written(session)) - WT_ERR(__wt_las_sweep(session)); + if (__wt_las_is_written(session) && + !__wt_cache_stuck(session)) { + oldest_id = __wt_txn_oldest_id(session); + if (WT_TXNID_LT(last_las_sweep_id, oldest_id)) { + WT_ERR(__wt_las_sweep(session)); + last_las_sweep_id = oldest_id; + } + } /* * Mark handles with a time of death, and report whether any @@ -288,7 +301,7 @@ __sweep_server(void *arg) * never become idle. */ if (conn->sweep_idle_time != 0) - WT_ERR(__sweep_mark(session, now)); + __sweep_mark(session, now); /* * Close handles if we have reached the configured limit. @@ -401,7 +414,7 @@ __wt_sweep_destroy(WT_SESSION_IMPL *session) F_CLR(conn, WT_CONN_SERVER_SWEEP); if (conn->sweep_tid_set) { - WT_TRET(__wt_cond_signal(session, conn->sweep_cond)); + __wt_cond_signal(session, conn->sweep_cond); WT_TRET(__wt_thread_join(session, conn->sweep_tid)); conn->sweep_tid_set = 0; } diff --git a/src/third_party/wiredtiger/src/cursor/cur_backup.c b/src/third_party/wiredtiger/src/cursor/cur_backup.c index f7565729cf9..3a3ff7de92b 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_backup.c +++ b/src/third_party/wiredtiger/src/cursor/cur_backup.c @@ -9,13 +9,12 @@ #include "wt_internal.h" static int __backup_all(WT_SESSION_IMPL *); -static int __backup_cleanup_handles(WT_SESSION_IMPL *, WT_CURSOR_BACKUP *); static int __backup_list_append( WT_SESSION_IMPL *, WT_CURSOR_BACKUP *, const char *); static int __backup_list_uri_append(WT_SESSION_IMPL *, const char *, bool *); static int __backup_start( WT_SESSION_IMPL *, WT_CURSOR_BACKUP *, const char *[]); -static int __backup_stop(WT_SESSION_IMPL *); +static int __backup_stop(WT_SESSION_IMPL *, WT_CURSOR_BACKUP *); static int __backup_uri(WT_SESSION_IMPL *, const char *[], bool *, bool *); /* @@ -76,20 +75,26 @@ __curbackup_close(WT_CURSOR *cursor) WT_CURSOR_BACKUP *cb; WT_DECL_RET; WT_SESSION_IMPL *session; - int tret; cb = (WT_CURSOR_BACKUP *)cursor; CURSOR_API_CALL(cursor, session, close, NULL); - WT_TRET(__backup_cleanup_handles(session, cb)); + /* + * When starting a hot backup, we serialize hot backup cursors and set + * the connection's hot-backup flag. Once that's done, we set the + * cursor's backup-locker flag, implying the cursor owns all necessary + * cleanup (including removing temporary files), regardless of error or + * success. The cursor's backup-locker flag is never cleared (it's just + * discarded when the cursor is closed), because that cursor will never + * not be responsible for cleanup. + */ + if (F_ISSET(cb, WT_CURBACKUP_LOCKER)) + WT_TRET(__backup_stop(session, cb)); + WT_TRET(__wt_cursor_close(cursor)); session->bkp_cursor = NULL; - WT_WITH_SCHEMA_LOCK(session, tret, - tret = __backup_stop(session)); /* Stop the backup. */ - WT_TRET(tret); - err: API_END_RET(session, ret); } @@ -144,11 +149,11 @@ __wt_curbackup_open(WT_SESSION_IMPL *session, ret = __backup_start(session, cb, cfg))); WT_ERR(ret); - /* __wt_cursor_init is last so we don't have to clean up on error. */ WT_ERR(__wt_cursor_init(cursor, uri, NULL, cfg, cursorp)); if (0) { -err: __wt_free(session, cb); +err: WT_TRET(__curbackup_close(cursor)); + *cursorp = NULL; } return (ret); @@ -222,9 +227,12 @@ __backup_start( * could start a hot backup that would race with an already-started * checkpoint. */ - WT_RET(__wt_writelock(session, conn->hot_backup_lock)); + __wt_writelock(session, conn->hot_backup_lock); conn->hot_backup = true; - WT_ERR(__wt_writeunlock(session, conn->hot_backup_lock)); + __wt_writeunlock(session, conn->hot_backup_lock); + + /* We're the lock holder, we own cleanup. */ + F_SET(cb, WT_CURBACKUP_LOCKER); /* * Create a temporary backup file. This must be opened before @@ -282,10 +290,7 @@ err: /* Close the hot backup file. */ WT_TRET(__wt_fclose(session, &cb->bfs)); if (srcfs != NULL) WT_TRET(__wt_fclose(session, &srcfs)); - if (ret != 0) { - WT_TRET(__backup_cleanup_handles(session, cb)); - WT_TRET(__backup_stop(session)); - } else { + if (ret == 0) { WT_ASSERT(session, dest != NULL); WT_TRET(__wt_fs_rename(session, WT_BACKUP_TMP, dest, false)); } @@ -295,9 +300,7 @@ err: /* Close the hot backup file. */ /* * __backup_cleanup_handles -- - * Release and free all btree handles held by the backup. This is kept - * separate from __backup_stop because it can be called without the - * schema lock held. + * Release and free all btree handles held by the backup. */ static int __backup_cleanup_handles(WT_SESSION_IMPL *session, WT_CURSOR_BACKUP *cb) @@ -325,20 +328,23 @@ __backup_cleanup_handles(WT_SESSION_IMPL *session, WT_CURSOR_BACKUP *cb) * Stop a backup. */ static int -__backup_stop(WT_SESSION_IMPL *session) +__backup_stop(WT_SESSION_IMPL *session, WT_CURSOR_BACKUP *cb) { WT_CONNECTION_IMPL *conn; WT_DECL_RET; conn = S2C(session); + /* Release all btree handles held by the backup. */ + WT_TRET(__backup_cleanup_handles(session, cb)); + /* Remove any backup specific file. */ - ret = __wt_backup_file_remove(session); + WT_TRET(__wt_backup_file_remove(session)); /* Checkpoint deletion can proceed, as can the next hot backup. */ - WT_TRET(__wt_writelock(session, conn->hot_backup_lock)); + __wt_writelock(session, conn->hot_backup_lock); conn->hot_backup = false; - WT_TRET(__wt_writeunlock(session, conn->hot_backup_lock)); + __wt_writeunlock(session, conn->hot_backup_lock); return (ret); } @@ -381,7 +387,7 @@ __backup_uri(WT_SESSION_IMPL *session, * otherwise it's not our problem. */ WT_RET(__wt_config_gets(session, cfg, "target", &cval)); - WT_RET(__wt_config_subinit(session, &targetconf, &cval)); + __wt_config_subinit(session, &targetconf, &cval); for (target_list = false; (ret = __wt_config_next(&targetconf, &k, &v)) == 0; target_list = true) { diff --git a/src/third_party/wiredtiger/src/cursor/cur_config.c b/src/third_party/wiredtiger/src/cursor/cur_config.c index e0d270e4245..2d3f3ffd176 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_config.c +++ b/src/third_party/wiredtiger/src/cursor/cur_config.c @@ -58,11 +58,11 @@ __wt_curconfig_open(WT_SESSION_IMPL *session, cursor->session = &session->iface; cursor->key_format = cursor->value_format = "S"; - /* __wt_cursor_init is last so we don't have to clean up on error. */ WT_ERR(__wt_cursor_init(cursor, uri, NULL, cfg, cursorp)); if (0) { -err: __wt_free(session, cconfig); +err: WT_TRET(__curconfig_close(cursor)); + *cursorp = NULL; } return (ret); } diff --git a/src/third_party/wiredtiger/src/cursor/cur_ds.c b/src/third_party/wiredtiger/src/cursor/cur_ds.c index d2b8d81ab37..8d4b7a9384b 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_ds.c +++ b/src/third_party/wiredtiger/src/cursor/cur_ds.c @@ -518,10 +518,7 @@ __wt_curds_open( source->flags = 0; if (0) { -err: if (F_ISSET(cursor, WT_CURSTD_OPEN)) - WT_TRET(cursor->close(cursor)); - else - __wt_free(session, data_source); +err: WT_TRET(__curds_close(cursor)); *cursorp = NULL; } diff --git a/src/third_party/wiredtiger/src/cursor/cur_dump.c b/src/third_party/wiredtiger/src/cursor/cur_dump.c index 595915df7b7..d7f18bb61ac 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_dump.c +++ b/src/third_party/wiredtiger/src/cursor/cur_dump.c @@ -401,13 +401,13 @@ __wt_curdump_create(WT_CURSOR *child, WT_CURSOR *owner, WT_CURSOR **cursorp) cursor->json_private = child->json_private = json; } - /* __wt_cursor_init is last so we don't have to clean up on error. */ cfg[0] = WT_CONFIG_BASE(session, WT_SESSION_open_cursor); cfg[1] = NULL; WT_ERR(__wt_cursor_init(cursor, NULL, owner, cfg, cursorp)); if (0) { -err: __wt_free(session, cursor); +err: WT_TRET(__curdump_close(cursor)); + *cursorp = NULL; } return (ret); } diff --git a/src/third_party/wiredtiger/src/cursor/cur_file.c b/src/third_party/wiredtiger/src/cursor/cur_file.c index fac903b4770..8e7bd4bbea5 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_file.c +++ b/src/third_party/wiredtiger/src/cursor/cur_file.c @@ -388,11 +388,11 @@ err: API_END_RET(session, ret); } /* - * __wt_curfile_create -- + * __curfile_create -- * Open a cursor for a given btree handle. */ -int -__wt_curfile_create(WT_SESSION_IMPL *session, +static int +__curfile_create(WT_SESSION_IMPL *session, WT_CURSOR *owner, const char *cfg[], bool bulk, bool bitmap, WT_CURSOR **cursorp) { @@ -439,6 +439,13 @@ __wt_curfile_create(WT_SESSION_IMPL *session, cursor->value_format = btree->value_format; cbt->btree = btree; + /* + * Increment the data-source's in-use counter; done now because closing + * the cursor will decrement it, and all failure paths from here close + * the cursor. + */ + __wt_cursor_dhandle_incr_use(session); + if (session->dhandle->checkpoint != NULL) F_SET(cbt, WT_CBT_NO_TXN); @@ -478,7 +485,6 @@ __wt_curfile_create(WT_SESSION_IMPL *session, /* Underlying btree initialization. */ __wt_btcur_open(cbt); - /* __wt_cursor_init is last so we don't have to clean up on error. */ WT_ERR(__wt_cursor_init( cursor, cursor->internal_uri, owner, cfg, cursorp)); @@ -486,7 +492,8 @@ __wt_curfile_create(WT_SESSION_IMPL *session, WT_STAT_FAST_DATA_INCR(session, cursor_create); if (0) { -err: __wt_free(session, cbt); +err: WT_TRET(__curfile_close(cursor)); + *cursorp = NULL; } return (ret); @@ -503,9 +510,10 @@ __wt_curfile_open(WT_SESSION_IMPL *session, const char *uri, WT_CONFIG_ITEM cval; WT_DECL_RET; uint32_t flags; - bool bitmap, bulk; + bool bitmap, bulk, checkpoint_wait; bitmap = bulk = false; + checkpoint_wait = true; flags = 0; /* @@ -531,6 +539,12 @@ __wt_curfile_open(WT_SESSION_IMPL *session, const char *uri, else if (!WT_STRING_MATCH("unordered", cval.str, cval.len)) WT_RET_MSG(session, EINVAL, "Value for 'bulk' must be a boolean or 'bitmap'"); + + if (bulk) { + WT_RET(__wt_config_gets(session, + cfg, "checkpoint_wait", &cval)); + checkpoint_wait = cval.val != 0; + } } /* Bulk handles require exclusive access. */ @@ -540,11 +554,11 @@ __wt_curfile_open(WT_SESSION_IMPL *session, const char *uri, /* Get the handle and lock it while the cursor is using it. */ if (WT_PREFIX_MATCH(uri, "file:")) { /* - * If we are opening exclusive, get the handle while holding - * the checkpoint lock. This prevents a bulk cursor open - * failing with EBUSY due to a database-wide checkpoint. + * If we are opening exclusive and don't want a bulk cursor + * open to fail with EBUSY due to a database-wide checkpoint, + * get the handle while holding the checkpoint lock. */ - if (LF_ISSET(WT_DHANDLE_EXCLUSIVE)) + if (LF_ISSET(WT_DHANDLE_EXCLUSIVE) && checkpoint_wait) WT_WITH_CHECKPOINT_LOCK(session, ret, ret = __wt_session_get_btree_ckpt( session, uri, cfg, flags)); @@ -555,10 +569,8 @@ __wt_curfile_open(WT_SESSION_IMPL *session, const char *uri, } else WT_RET(__wt_bad_object_type(session, uri)); - WT_ERR(__wt_curfile_create(session, owner, cfg, bulk, bitmap, cursorp)); + WT_ERR(__curfile_create(session, owner, cfg, bulk, bitmap, cursorp)); - /* Increment the data-source's in-use counter. */ - __wt_cursor_dhandle_incr_use(session); return (0); err: /* If the cursor could not be opened, release the handle. */ diff --git a/src/third_party/wiredtiger/src/cursor/cur_index.c b/src/third_party/wiredtiger/src/cursor/cur_index.c index 6de68d86778..ea742cac435 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_index.c +++ b/src/third_party/wiredtiger/src/cursor/cur_index.c @@ -263,19 +263,57 @@ err: F_CLR(cursor, WT_CURSTD_KEY_INT | WT_CURSTD_VALUE_INT); static int __curindex_search_near(WT_CURSOR *cursor, int *exact) { + WT_CURSOR *child; WT_CURSOR_INDEX *cindex; WT_DECL_RET; + WT_ITEM found_key; WT_SESSION_IMPL *session; + int cmp; cindex = (WT_CURSOR_INDEX *)cursor; - JOINABLE_CURSOR_API_CALL(cursor, session, search_near, NULL); - __wt_cursor_set_raw_key(cindex->child, &cursor->key); - if ((ret = cindex->child->search_near(cindex->child, exact)) == 0) - ret = __curindex_move(cindex); - else - F_CLR(cursor, WT_CURSTD_KEY_INT | WT_CURSTD_VALUE_INT); + child = cindex->child; + JOINABLE_CURSOR_API_CALL(cursor, session, search, NULL); -err: API_END_RET(session, ret); + /* + * We are searching using the application-specified key, which + * (usually) doesn't contain the primary key, so it is just a prefix of + * any matching index key. That said, if there is an exact match, we + * want to find the first matching index entry and set exact equal to + * zero. Do a search_near, step to the next entry if we land on one + * that is too small, then check that the prefix matches. + */ + __wt_cursor_set_raw_key(child, &cursor->key); + WT_ERR(child->search_near(child, &cmp)); + + if (cmp < 0) + WT_ERR(child->next(child)); + + /* + * We expect partial matches, and want the smallest record with a key + * greater than or equal to the search key. + * + * If the key we find is shorter than the search key, it can't possibly + * match. + * + * The only way for the key to be exactly equal is if there is an index + * on the primary key, because otherwise the primary key columns will + * be appended to the index key, but we don't disallow that (odd) case. + */ + found_key = child->key; + if (found_key.size < cursor->key.size) + WT_ERR(WT_NOTFOUND); + found_key.size = cursor->key.size; + + WT_ERR(__wt_compare( + session, cindex->index->collator, &cursor->key, &found_key, exact)); + + WT_ERR(__curindex_move(cindex)); + + if (0) { +err: F_CLR(cursor, WT_CURSTD_KEY_INT | WT_CURSTD_VALUE_INT); + } + + API_END_RET(session, ret); } /* @@ -475,8 +513,8 @@ __wt_curindex_open(WT_SESSION_IMPL *session, WT_ERR(__curindex_open_colgroups(session, cindex, cfg)); if (F_ISSET(cursor, WT_CURSTD_DUMP_JSON)) - WT_ERR(__wt_json_column_init(cursor, table->key_format, - &idx->colconf, &table->colconf)); + __wt_json_column_init( + cursor, table->key_format, &idx->colconf, &table->colconf); if (0) { err: WT_TRET(__curindex_close(cursor)); diff --git a/src/third_party/wiredtiger/src/cursor/cur_join.c b/src/third_party/wiredtiger/src/cursor/cur_join.c index 0760a07a3aa..087411febda 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_join.c +++ b/src/third_party/wiredtiger/src/cursor/cur_join.c @@ -612,19 +612,17 @@ __curjoin_entry_member(WT_SESSION_IMPL *session, WT_CURSOR_JOIN_ENTRY *entry, if (entry->bloom != NULL) { /* + * If the item is not in the Bloom filter, we return + * immediately, otherwise, we still need to check the long + * way, since it may be a false positive. + * * If we don't own the Bloom filter, we must be sharing one * in a previous entry. So the shared filter has already - * been checked and passed. + * been checked and passed, we don't need to check it again. + * We'll still need to check the long way. */ - if (!F_ISSET(entry, WT_CURJOIN_ENTRY_OWN_BLOOM)) - return (0); - - /* - * If the item is not in the Bloom filter, we return - * immediately, otherwise, we still need to check the - * long way. - */ - WT_ERR(__wt_bloom_inmem_get(entry->bloom, key)); + if (F_ISSET(entry, WT_CURJOIN_ENTRY_OWN_BLOOM)) + WT_ERR(__wt_bloom_inmem_get(entry->bloom, key)); bloom_found = true; } if (entry->subjoin != NULL) { @@ -875,7 +873,7 @@ insert: } else WT_ERR(c->get_key(c, &curvalue)); - WT_ERR(__wt_bloom_insert(bloom, &curvalue)); + __wt_bloom_insert(bloom, &curvalue); entry->stats.bloom_insert++; advance: if ((ret = c->next(c)) == WT_NOTFOUND) @@ -918,6 +916,9 @@ __curjoin_init_next(WT_SESSION_IMPL *session, WT_CURSOR_JOIN *cjoin, "join cursor has not yet been joined with any other " "cursors"); + /* Get a consistent view of our subordinate cursors if appropriate. */ + WT_RET(__wt_txn_cursor_op(session)); + if (F_ISSET((WT_CURSOR *)cjoin, WT_CURSTD_RAW)) config = &raw_cfg[0]; else diff --git a/src/third_party/wiredtiger/src/cursor/cur_json.c b/src/third_party/wiredtiger/src/cursor/cur_json.c index f0fa0d8aec2..bb24e88cba5 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_json.c +++ b/src/third_party/wiredtiger/src/cursor/cur_json.c @@ -186,7 +186,7 @@ __json_struct_size(WT_SESSION_IMPL *session, const void *buffer, result = 0; needcr = false; - WT_RET(__pack_name_init(session, names, iskey, &packname)); + __pack_name_init(session, names, iskey, &packname); WT_RET(__pack_init(session, &pack, fmt)); while ((ret = __pack_next(&pack, &pv)) == 0) { if (needcr) @@ -231,7 +231,7 @@ __json_struct_unpackv(WT_SESSION_IMPL *session, /* Unpacking a cursor marked as json implies a single arg. */ *va_arg(ap, const char **) = (char *)jbuf; - WT_RET(__pack_name_init(session, names, iskey, &packname)); + __pack_name_init(session, names, iskey, &packname); WT_RET(__pack_init(session, &pack, fmt)); while ((ret = __pack_next(&pack, &pv)) == 0) { if (needcr) { @@ -365,10 +365,10 @@ __wt_json_unpack_char(u_char ch, u_char *buf, size_t bufsz, bool force_unicode) /* * __wt_json_column_init -- - * set json_key_names, json_value_names to comma separated lists + * Set json_key_names, json_value_names to comma separated lists * of column names. */ -int +void __wt_json_column_init(WT_CURSOR *cursor, const char *keyformat, const WT_CONFIG_ITEM *idxconf, const WT_CONFIG_ITEM *colconf) { @@ -408,7 +408,6 @@ __wt_json_column_init(WT_CURSOR *cursor, const char *keyformat, json->key_names.str = beginkey; json->key_names.len = WT_PTRDIFF(p, beginkey); } - return (0); } #define MATCH_KEYWORD(session, in, result, keyword, matchval) do { \ @@ -774,7 +773,7 @@ __json_pack_size( bool multi; const char *tokstart; - WT_RET(__pack_name_init(session, names, iskey, &packname)); + __pack_name_init(session, names, iskey, &packname); multi = false; WT_RET(__pack_init(session, &pack, fmt)); for (total = 0; __pack_next(&pack, &pv) == 0;) { diff --git a/src/third_party/wiredtiger/src/cursor/cur_log.c b/src/third_party/wiredtiger/src/cursor/cur_log.c index 0a13803da5d..76f31b417a6 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_log.c +++ b/src/third_party/wiredtiger/src/cursor/cur_log.c @@ -315,16 +315,16 @@ __curlog_close(WT_CURSOR *cursor) WT_CONNECTION_IMPL *conn; WT_CURSOR_LOG *cl; WT_DECL_RET; - WT_LOG *log; WT_SESSION_IMPL *session; CURSOR_API_CALL(cursor, session, close, NULL); cl = (WT_CURSOR_LOG *)cursor; conn = S2C(session); + WT_ASSERT(session, FLD_ISSET(conn->log_flags, WT_CONN_LOG_ENABLED)); - log = conn->log; - WT_TRET(__wt_readunlock(session, log->log_archive_lock)); - WT_TRET(__curlog_reset(cursor)); + if (F_ISSET(cl, WT_CURLOG_ARCHIVE_LOCK)) + __wt_readunlock(session, conn->log->log_archive_lock); + __wt_free(session, cl->cur_lsn); __wt_free(session, cl->next_lsn); __wt_scr_free(session, &cl->logrec); @@ -332,6 +332,7 @@ __curlog_close(WT_CURSOR *cursor) __wt_scr_free(session, &cl->opvalue); __wt_free(session, cl->packed_key); __wt_free(session, cl->packed_value); + WT_TRET(__wt_cursor_close(cursor)); err: API_END_RET(session, ret); @@ -400,24 +401,11 @@ __wt_curlog_open(WT_SESSION_IMPL *session, WT_ERR(__wt_log_force_write(session, 1, NULL)); /* Log cursors block archiving. */ - WT_ERR(__wt_readlock(session, log->log_archive_lock)); + __wt_readlock(session, log->log_archive_lock); + F_SET(cl, WT_CURLOG_ARCHIVE_LOCK); if (0) { -err: if (F_ISSET(cursor, WT_CURSTD_OPEN)) - WT_TRET(cursor->close(cursor)); - else { - __wt_free(session, cl->cur_lsn); - __wt_free(session, cl->next_lsn); - __wt_scr_free(session, &cl->logrec); - __wt_scr_free(session, &cl->opkey); - __wt_scr_free(session, &cl->opvalue); - /* - * NOTE: We cannot get on the error path with the - * readlock held. No need to unlock it unless that - * changes above. - */ - __wt_free(session, cl); - } +err: WT_TRET(__curlog_close(cursor)); *cursorp = NULL; } diff --git a/src/third_party/wiredtiger/src/cursor/cur_metadata.c b/src/third_party/wiredtiger/src/cursor/cur_metadata.c index 3d702e2ea8c..fd00acdf0ab 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_metadata.c +++ b/src/third_party/wiredtiger/src/cursor/cur_metadata.c @@ -31,55 +31,86 @@ } while (0) /* - * __wt_schema_create_final -- - * Create a single configuration line from a set of configuration strings, - * including all of the defaults declared for a session.create, and stripping - * any configuration strings that don't belong in a session.create. Here for - * the wt dump command utility, which reads a set of configuration strings and - * needs to add in the defaults and then collapse them into single string for - * a subsequent load. + * __schema_source_config -- + * Extract the "source" configuration key, lookup its metadata. */ -int -__wt_schema_create_final( - WT_SESSION_IMPL *session, char *cfg_arg[], char **value_ret) +static int +__schema_source_config(WT_SESSION_IMPL *session, + WT_CURSOR *srch, const char *config, const char **result) { + WT_CONFIG_ITEM cval; + WT_DECL_ITEM(buf); WT_DECL_RET; - u_int i; - const char **cfg; - - /* - * Count the entries in the original, - * Allocate a copy with the defaults as the first entry, - * Collapse the whole thing into a single configuration string (which - * also strips any entries that don't appear in the first entry). - */ - for (i = 0; cfg_arg[i] != NULL; ++i) - ; - WT_RET(__wt_calloc_def(session, i + 2, &cfg)); - cfg[0] = WT_CONFIG_BASE(session, WT_SESSION_create); - for (i = 0; cfg_arg[i] != NULL; ++i) - cfg[i + 1] = cfg_arg[i]; - cfg[i + 1] = NULL; - - ret = __wt_config_collapse(session, cfg, value_ret); - - __wt_free(session, cfg); + char *v; + + WT_ERR(__wt_config_getones(session, config, "source", &cval)); + WT_ERR(__wt_scr_alloc(session, cval.len + 10, &buf)); + WT_ERR(__wt_buf_fmt(session, buf, "%.*s", (int)cval.len, cval.str)); + srch->set_key(srch, buf->data); + if ((ret = srch->search(srch)) == WT_NOTFOUND) + WT_ERR(EINVAL); + WT_ERR(ret); + WT_ERR(srch->get_value(srch, &v)); + WT_ERR(__wt_strdup(session, v, result)); + +err: __wt_scr_free(session, &buf); return (ret); } /* - * __schema_create_strip -- - * Discard any configuration information from a schema entry that is not - * applicable to an session.create call. Here for the metadata:create URI. + * __schema_create_collapse -- + * Discard any configuration information from a schema entry that is + * not applicable to an session.create call. + * + * For a table URI that contains no named column groups, fold in the + * configuration from the implicit column group and its source. For a + * named column group URI, fold in its source. */ static int -__schema_create_strip( - WT_SESSION_IMPL *session, const char *value, char **value_ret) +__schema_create_collapse(WT_SESSION_IMPL *session, WT_CURSOR_METADATA *mdc, + const char *key, const char *value, char **value_ret) { - const char *cfg[] = - { WT_CONFIG_BASE(session, WT_SESSION_create), value, NULL }; - - return (__wt_config_collapse(session, cfg, value_ret)); + WT_CURSOR *c; + WT_DECL_ITEM(buf); + WT_DECL_RET; + const char *_cfg[5] = {NULL, NULL, NULL, value, NULL}; + const char **cfg, **firstcfg, **lastcfg, *v; + + lastcfg = cfg = &_cfg[3]; /* position on value */ + c = NULL; + if (key != NULL && WT_PREFIX_SKIP(key, "table:")) { + c = mdc->create_cursor; + WT_ERR(__wt_scr_alloc(session, 0, &buf)); + /* + * When a table is created without column groups, + * we create one without a name. + */ + WT_ERR(__wt_buf_fmt(session, buf, "colgroup:%s", key)); + c->set_key(c, buf->data); + if ((ret = c->search(c)) == 0) { + WT_ERR(c->get_value(c, &v)); + WT_ERR(__wt_strdup(session, v, --cfg)); + WT_ERR(__schema_source_config(session, c, v, --cfg)); + } else + WT_ERR_NOTFOUND_OK(ret); + } else if (key != NULL && WT_PREFIX_SKIP(key, "colgroup:")) { + if (strchr(key, ':') != NULL) { + c = mdc->create_cursor; + WT_ERR(__wt_strdup(session, value, --cfg)); + WT_ERR( + __schema_source_config(session, c, value, --cfg)); + } + } + firstcfg = cfg; + *--firstcfg = WT_CONFIG_BASE(session, WT_SESSION_create); + WT_ERR(__wt_config_collapse(session, firstcfg, value_ret)); + +err: for (; cfg < lastcfg; cfg++) + __wt_free(session, *cfg); + if (c != NULL) + WT_TRET(c->reset(c)); + __wt_scr_free(session, &buf); + return (ret); } /* @@ -95,17 +126,17 @@ __curmetadata_setkv(WT_CURSOR_METADATA *mdc, WT_CURSOR *fc) WT_SESSION_IMPL *session; char *value; + value = NULL; c = &mdc->iface; session = (WT_SESSION_IMPL *)c->session; c->key.data = fc->key.data; c->key.size = fc->key.size; if (F_ISSET(mdc, WT_MDC_CREATEONLY)) { - WT_RET(__schema_create_strip(session, fc->value.data, &value)); - ret = __wt_buf_set( - session, &c->value, value, strlen(value) + 1); - __wt_free(session, value); - WT_RET(ret); + WT_ERR(__schema_create_collapse( + session, mdc, fc->key.data, fc->value.data, &value)); + WT_ERR(__wt_buf_set( + session, &c->value, value, strlen(value) + 1)); } else { c->value.data = fc->value.data; c->value.size = fc->value.size; @@ -115,7 +146,8 @@ __curmetadata_setkv(WT_CURSOR_METADATA *mdc, WT_CURSOR *fc) F_CLR(mdc, WT_MDC_ONMETADATA); F_SET(mdc, WT_MDC_POSITIONED); - return (0); +err: __wt_free(session, value); + return (ret); } /* @@ -123,8 +155,9 @@ __curmetadata_setkv(WT_CURSOR_METADATA *mdc, WT_CURSOR *fc) * but also check for the internal version of the URI. */ #define WT_KEY_IS_METADATA(key) \ + ((key)->size > 0 && \ (WT_STRING_MATCH(WT_METADATA_URI, (key)->data, (key)->size - 1) ||\ - WT_STRING_MATCH(WT_METAFILE_URI, (key)->data, (key)->size - 1)) + WT_STRING_MATCH(WT_METAFILE_URI, (key)->data, (key)->size - 1))) /* * __curmetadata_metadata_search -- @@ -143,7 +176,8 @@ __curmetadata_metadata_search(WT_SESSION_IMPL *session, WT_CURSOR *cursor) WT_RET(__wt_metadata_search(session, WT_METAFILE_URI, &value)); if (F_ISSET(mdc, WT_MDC_CREATEONLY)) { - ret = __schema_create_strip(session, value, &stripped); + ret = __schema_create_collapse(session, mdc, NULL, value, + &stripped); __wt_free(session, value); WT_RET(ret); value = stripped; @@ -467,17 +501,20 @@ err: API_END_RET(session, ret); static int __curmetadata_close(WT_CURSOR *cursor) { - WT_CURSOR *file_cursor; + WT_CURSOR *c; WT_CURSOR_METADATA *mdc; WT_DECL_RET; WT_SESSION_IMPL *session; mdc = (WT_CURSOR_METADATA *)cursor; - file_cursor = mdc->file_cursor; - CURSOR_API_CALL(cursor, session, - close, ((WT_CURSOR_BTREE *)file_cursor)->btree); - - ret = file_cursor->close(file_cursor); + c = mdc->file_cursor; + CURSOR_API_CALL(cursor, session, close, c == NULL ? + NULL : ((WT_CURSOR_BTREE *)c)->btree); + + if (c != NULL) + ret = c->close(c); + if ((c = mdc->create_cursor) != NULL) + WT_TRET(c->close(c)); WT_TRET(__wt_cursor_close(cursor)); err: API_END_RET(session, ret); @@ -534,11 +571,18 @@ __wt_curmetadata_open(WT_SESSION_IMPL *session, */ WT_ERR(__wt_metadata_cursor_open(session, cfg[1], &mdc->file_cursor)); - WT_ERR(__wt_cursor_init(cursor, uri, owner, cfg, cursorp)); - - /* If we are only returning create config, strip internal metadata. */ - if (WT_STREQ(uri, "metadata:create")) + /* + * If we are only returning create config, strip internal metadata. + * We'll need some extra cursors to pull out column group information + * and chase "source" entries. + */ + if (WT_STREQ(uri, "metadata:create")) { F_SET(mdc, WT_MDC_CREATEONLY); + WT_ERR(__wt_metadata_cursor_open(session, cfg[1], + &mdc->create_cursor)); + } + + WT_ERR(__wt_cursor_init(cursor, uri, owner, cfg, cursorp)); /* * Metadata cursors default to readonly; if not set to not-readonly, @@ -552,9 +596,8 @@ __wt_curmetadata_open(WT_SESSION_IMPL *session, } if (0) { -err: if (mdc->file_cursor != NULL) - WT_TRET(mdc->file_cursor->close(mdc->file_cursor)); - __wt_free(session, mdc); +err: WT_TRET(__curmetadata_close(cursor)); + *cursorp = NULL; } return (ret); } diff --git a/src/third_party/wiredtiger/src/cursor/cur_stat.c b/src/third_party/wiredtiger/src/cursor/cur_stat.c index f7a8f5fc866..5c9159a4c0b 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_stat.c +++ b/src/third_party/wiredtiger/src/cursor/cur_stat.c @@ -36,22 +36,6 @@ __curstat_print_value(WT_SESSION_IMPL *session, uint64_t v, WT_ITEM *buf) return (0); } -/* - * __curstat_free_config -- - * Free the saved configuration string stack - */ -static void -__curstat_free_config(WT_SESSION_IMPL *session, WT_CURSOR_STAT *cst) -{ - size_t i; - - if (cst->cfg != NULL) { - for (i = 0; cst->cfg[i] != NULL; ++i) - __wt_free(session, cst->cfg[i]); - __wt_free(session, cst->cfg); - } -} - /* * __curstat_get_key -- * WT_CURSOR->get_key for statistics cursors. @@ -334,11 +318,16 @@ __curstat_close(WT_CURSOR *cursor) WT_CURSOR_STAT *cst; WT_DECL_RET; WT_SESSION_IMPL *session; + size_t i; cst = (WT_CURSOR_STAT *)cursor; CURSOR_API_CALL(cursor, session, close, NULL); - __curstat_free_config(session, cst); + if (cst->cfg != NULL) { + for (i = 0; cst->cfg[i] != NULL; ++i) + __wt_free(session, cst->cfg[i]); + __wt_free(session, cst->cfg); + } __wt_buf_free(session, &cst->pv); __wt_free(session, cst->desc_buf); @@ -691,7 +680,6 @@ __wt_curstat_open(WT_SESSION_IMPL *session, /* The cursor isn't yet positioned. */ cst->notpositioned = true; - /* __wt_cursor_init is last so we don't have to clean up on error. */ WT_ERR(__wt_cursor_init(cursor, uri, NULL, cfg, cursorp)); if (0) { @@ -701,8 +689,8 @@ config_err: WT_ERR_MSG(session, EINVAL, } if (0) { -err: __curstat_free_config(session, cst); - __wt_free(session, cst); +err: WT_TRET(__curstat_close(cursor)); + *cursorp = NULL; } return (ret); diff --git a/src/third_party/wiredtiger/src/cursor/cur_std.c b/src/third_party/wiredtiger/src/cursor/cur_std.c index 8bb8931f36f..bf7280f796b 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_std.c +++ b/src/third_party/wiredtiger/src/cursor/cur_std.c @@ -50,7 +50,7 @@ __wt_cursor_get_value_notsup(WT_CURSOR *cursor, ...) void __wt_cursor_set_key_notsup(WT_CURSOR *cursor, ...) { - (void)__wt_cursor_notsup(cursor); + WT_IGNORE_RET(__wt_cursor_notsup(cursor)); } /* @@ -60,7 +60,7 @@ __wt_cursor_set_key_notsup(WT_CURSOR *cursor, ...) void __wt_cursor_set_value_notsup(WT_CURSOR *cursor, ...) { - (void)__wt_cursor_notsup(cursor); + WT_IGNORE_RET(__wt_cursor_notsup(cursor)); } /* @@ -539,7 +539,6 @@ err: cursor->saved_err = ret; int __wt_cursor_close(WT_CURSOR *cursor) { - WT_DECL_RET; WT_SESSION_IMPL *session; session = (WT_SESSION_IMPL *)cursor->session; @@ -557,7 +556,7 @@ __wt_cursor_close(WT_CURSOR *cursor) __wt_free(session, cursor->internal_uri); __wt_free(session, cursor->uri); __wt_overwrite_and_free(session, cursor); - return (ret); + return (0); } /* diff --git a/src/third_party/wiredtiger/src/cursor/cur_table.c b/src/third_party/wiredtiger/src/cursor/cur_table.c index 6d50523043a..0498c89fcbe 100644 --- a/src/third_party/wiredtiger/src/cursor/cur_table.c +++ b/src/third_party/wiredtiger/src/cursor/cur_table.c @@ -525,15 +525,20 @@ __curtable_insert(WT_CURSOR *cursor) } /* - * WT_CURSOR.insert doesn't leave the cursor positioned, and the - * application may want to free the memory used to configure the - * insert; don't read that memory again (matching the underlying - * file object cursor insert semantics). + * Insert is the one cursor operation that doesn't end with the cursor + * pointing to an on-page item (except for column-store appends, where + * we are returning a key). That is, the application's cursor continues + * to reference the application's memory after a successful cursor call, + * which isn't true anywhere else. We don't want to have to explain that + * scoping corner case, so we reset the application's cursor so it can + * free the referenced memory and continue on without risking subsequent + * core dumps. */ F_CLR(primary, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET); + if (F_ISSET(primary, WT_CURSTD_APPEND)) + F_SET(primary, WT_CURSTD_KEY_INT); err: CURSOR_UPDATE_API_END(session, ret); - return (ret); } @@ -933,8 +938,8 @@ __wt_curtable_open(WT_SESSION_IMPL *session, cursor, cursor->internal_uri, owner, cfg, cursorp)); if (F_ISSET(cursor, WT_CURSTD_DUMP_JSON)) - WT_ERR(__wt_json_column_init(cursor, table->key_format, - NULL, &table->colconf)); + __wt_json_column_init( + cursor, table->key_format, NULL, &table->colconf); /* * Open the colgroup cursors immediately: we're going to need them for diff --git a/src/third_party/wiredtiger/src/docs/custom-file-systems.dox b/src/third_party/wiredtiger/src/docs/custom-file-systems.dox index d496002b0fb..91bda3a23b5 100644 --- a/src/third_party/wiredtiger/src/docs/custom-file-systems.dox +++ b/src/third_party/wiredtiger/src/docs/custom-file-systems.dox @@ -9,13 +9,23 @@ in the WT_FILE_SYSTEM and WT_FILE_HANDLE structures, and documentation for those structures indicate which methods are optional. Methods which are not provided should be set to NULL. -Generally, function pointers should not be changed once a handle is -created. An exception to this are the WT_FILE_HANDLE::fallocate and -WT_FILE_HANDLE::fallocate_nolock methods, because a file system -implementation may not know what support the system provides until file -allocation is attempted. See the WiredTiger POSIX file system -implementation for an example of how the fallocate method might be -changed after initialization. +Function pointers should not be cleared once a handle is created. +(WiredTiger might check for a non-NULL method and then call it, and +clearing the function pointer could result in a core dump.) + +Function pointers are not expected to be cleared or set after a handle +is created. An exception to this are the file extension methods, because +existing file system implementations do not know the level of support +the underlying system provides until after file extension is attempted. +For this reason, these methods appear in both locking and non-locking +versions. Custom file systems needing to discover system support before +configuring non-locking methods should initialize only the locking +version of the method, then either set the non-locking version of the +method and clear the locking method (or clear both methods), after +discovery is complete. Clearing the method value is safe because calls +are serialized until a non-locking method is set. Note it is not +possible to downgrade from a non-locking version of these methods to a +locking version. WT_FILE_SYSTEM and WT_FILE_HANDLE methods are expected to return POSIX 1003.1 or ANSI C standard error codes on failure. Custom file systems @@ -23,13 +33,18 @@ on Windows systems can use the WT_EXTENSION_API::map_windows_error method to translate Windows system errors into POSIX system errors for return to WiredTiger. -WT_FILE_SYSTEM and WT_FILE_HANDLE methods which fail but not fatally -(for example, a WT_FILE_HANDLE::truncate method call which fails because -the file is currently mapped into memory), should return EBUSY. - -WT_FILE_SYSTEM and WT_FILE_HANDLE methods which fail fatally, but not -in all cases (for example, a WT_FILE_HANDLE::fadvise method call which -only supports ::WT_FILE_HANDLE_WILLNEED), should return ENOTSUP. +WT_FILE_SYSTEM and WT_FILE_HANDLE methods which fail, but where future +calls may succeed (for example, a WT_FILE_HANDLE::fh_truncate method +call which fails because the file is currently mapped into memory), +should return EBUSY. + +WT_FILE_SYSTEM and WT_FILE_HANDLE methods which fail, and no future +calls will succeed, should return ENOTSUP. This failure may describe +either the entire method being unavailable or a particular mode failure. +For example, a WT_FILE_HANDLE::fh_advise method call with an argument of +::WT_FILE_HANDLE_DONTNEED, where the file handle doesn't support the +WT_FILE_HANDLE::fh_advise method at all, or only supports the method +argument ::WT_FILE_HANDLE_WILLNEED, should return ENOTSUP. Additionally, custom file system functions may return ::WT_PANIC to shut down the system. diff --git a/src/third_party/wiredtiger/src/docs/license.dox b/src/third_party/wiredtiger/src/docs/license.dox index d7814d04fd6..b70823202ad 100644 --- a/src/third_party/wiredtiger/src/docs/license.dox +++ b/src/third_party/wiredtiger/src/docs/license.dox @@ -46,7 +46,7 @@ of the WiredTiger library should comply with these copyrights. @row{\c src/support/hash_fnv.c, Authors, Public Domain} -@section license_crc32-vpmsum 3rd party software optionally included in the WiredTiger library: PPC64 +@section license_crc32-power8 3rd party software optionally included in the WiredTiger library: PPC64 PPC64 and PPC64LE builds of the WiredTiger library binary include additional 3rd party software, distributed under separate license terms. Redistribution @@ -55,7 +55,18 @@ copyrights. @hrow{Distribution Files, Copyright Holder, License} -@row{\c src/support/power8/*, Anton Blanchard, Apache License\, Version 2.0 or the GNU General Public License\, version 2 or later} +@row{\c src/support/power8/*, Anton Blanchard\, IBM Corp., Apache License\, Version 2.0 or the GNU General Public License\, version 2 or later} +
+ +@section license_crc32-zseries 3rd party software optionally included in the WiredTiger library: s390x + +IBM z13 processor builds of the WiredTiger library binary include additional +3rd party software, distributed under separate license terms. Redistribution +of the WiredTiger library z13 builds should comply with these copyrights. + + +@hrow{Distribution Files, Copyright Holder, License} +@row{\c src/support/zseries/*, IBM Corp., Apache License\, Version 2.0 or the GNU General Public License\, version 2 or later}
@section license_leveldb 3rd party software optionally included in the WiredTiger library: LevelDB diff --git a/src/third_party/wiredtiger/src/docs/readonly.dox b/src/third_party/wiredtiger/src/docs/readonly.dox index ad4a94a73f1..35378cf9567 100644 --- a/src/third_party/wiredtiger/src/docs/readonly.dox +++ b/src/third_party/wiredtiger/src/docs/readonly.dox @@ -47,7 +47,8 @@ One unusual affect of read-only operations is the potential for multiple read-only database handles open on the same database at the same time. WiredTiger prevents multiple connection handles by writing a lock file, and this locking is done even in read-only mode. However, if the lock -file cannot be written, opening in read-only mode is still allowed to +file cannot be written, that is, if the WiredTiger home directory does not +have write permission, opening in read-only mode is still allowed to proceed. For that reason, multiple read-only connection handles could be open at the same time. Normal locking occurs if the lock file can be written in read-only mode, preventing multiple database connections. diff --git a/src/third_party/wiredtiger/src/docs/spell.ok b/src/third_party/wiredtiger/src/docs/spell.ok index e08eb7d1447..a2ef7658ec6 100644 --- a/src/third_party/wiredtiger/src/docs/spell.ok +++ b/src/third_party/wiredtiger/src/docs/spell.ok @@ -15,6 +15,7 @@ Coverity Coverity's DB's DBTs +DONTNEED Datastore DbCursor DbEnv @@ -216,6 +217,8 @@ failchk fallocate fd's fdatasync +fextend +fh fieldname fileID fileformats @@ -230,6 +233,7 @@ forw fput freelist fsync +ftruncate gcc gdbm ge @@ -502,3 +506,4 @@ wtstats xa yieldcpu zlib +zseries diff --git a/src/third_party/wiredtiger/src/docs/tune-cache.dox b/src/third_party/wiredtiger/src/docs/tune-cache.dox index 505da436277..fc42fc80046 100644 --- a/src/third_party/wiredtiger/src/docs/tune-cache.dox +++ b/src/third_party/wiredtiger/src/docs/tune-cache.dox @@ -60,24 +60,38 @@ WiredTiger eviction tuning options can be configured when first opening a database via ::wiredtiger_open, or changed after open with WT_CONNECTION::reconfigure. -The \c eviction_trigger configuration value is the occupied percentage -of the total cache size that causes eviction to start. By default, -WiredTiger begins evicting pages when the cache is 95% full. An -application concerned about a latency spike as the cache becomes full -might want to begin eviction earlier. - -The \c eviction_target configuration value is the overall target for -eviction, expressed as a percentage of total cache size; that is, once -eviction begins, it will proceed until the target percentage of bytes -in the cache is reached. Note the \c eviction_target configuration -value is ignored until eviction is triggered. - -The \c eviction_dirty_target configuration value is the overall dirty -byte target for eviction, expressed as a percentage of total cache size; -that is, once eviction begins, it will proceed until the target -percentage of dirty bytes in the cache is reached. Note the -\c eviction_dirty_target configuration value is ignored until eviction -is triggered. +The \c eviction_target configuration value (default 80%) is the level at +which WiredTiger attempts to keep the overall cache usage. Eviction worker +threads are active when the cache contains at least this much content, +expressed as a percentage of the total cache size. + +The \c eviction_trigger configuration value (default 95%) is the level at +which application threads start to perform eviction. This will throttle +application operations, increasing operation latency, usually resulting in +the cache usage staying at this level when there is more cache pressure +than eviction worker threads can handle in the background. + +Operations will stall when the cache reaches 100% of the cache size. +Application may want to change these settings from their defaults to either +increase the range in which worker threads operate before application +threads are throttled, or to use a larger proportion of RAM, if eviction +worker threads have no difficulty handling the cache pressure generated by +the application. + +The \c eviction_dirty_target (default 5%) and \c eviction_dirty_trigger +(default 20%) operate in a similar way to the overall targets, but only +apply to dirty data in cache. In particular, application threads will be +throttled if the percentage of dirty data reaches the +\c eviction_dirty_trigger. Any page that has been modified since it was +read from disk is considered dirty. + +The dirty eviction settings control how much work checkpoints have to do +in the worst case, and also limit how much memory fragmentation is likely +for memory allocations related to the cache. Most memory fragmentation is +caused by workloads that generate a mix of updates (small allocations) with +cache misses (large allocations). Limiting the percentage of cache that +can be dirty limits the worst case fragmentation to the approximately the +same level. @snippet ex_all.c Eviction configuration diff --git a/src/third_party/wiredtiger/src/docs/upgrading.dox b/src/third_party/wiredtiger/src/docs/upgrading.dox index c5fbc0a86a2..3a448818230 100644 --- a/src/third_party/wiredtiger/src/docs/upgrading.dox +++ b/src/third_party/wiredtiger/src/docs/upgrading.dox @@ -2,12 +2,45 @@ @section version_281 Upgrading to Version 2.8.1
+
Cache management defaults
+
+The default values for the \c eviction_dirty_target and \c +eviction_dirty_trigger settings to ::wiredtiger_open have changed to 5 and 20, +respectively. This means that by default, WiredTiger will start writing dirty +pages from cache when it becomes 5% dirty and will throttle activity to keep +the volume of dirty data in cache under 20%. For write-heavy workloads, the +new defaults may result in lower throughput and more threads writing to data +files concurrently. + +There is also a new \c eviction_checkpoint_target setting that determines +how much work is done at the beginning of a checkpoint to make the critical +section of checkpoints complete more quickly. +
+ +
Checkpoint server created checkpoint names
+
+The ::wiredtiger_open checkpoint configuration no longer supports the +\c name configuration, and checkpoint server created checkpoints will +always be named the default WiredTiger checkpoint name, +"WiredTigerCheckpoint". Applications depending on the ability to set the +checkpoint name for the checkpoint server will require modification. +
+
Statistics logging path
-The statistics logging path configuration has been simplified to be only a -path to a directory, and the file name component of the path may no longer -be specified. Applications depending on the ability to set statistics log -file names will require modifications. +The ::wiredtiger_open statistics logging path configuration has been +simplified to be only a path to a directory, and the file name component +of the path may no longer be specified. Applications depending on the +ability to set statistics log file names will require modification. +
+ +
Deprecated statistics field
+
+The connection statistic \c WT_STAT_CONN_CACHE_BYTES_OVERFLOW has been +removed. Overflow information is now available in the +\c WT_STAT_CONN_CACHE_BYTES_OVERFLOW and \c WT_STAT_CONN_CACHE_OVERFLOW_VALUE. +Applications specifically looking for that statistic will require +modification.

diff --git a/src/third_party/wiredtiger/src/docs/wtperf.dox b/src/third_party/wiredtiger/src/docs/wtperf.dox index e06272d117c..a49d0d9f871 100644 --- a/src/third_party/wiredtiger/src/docs/wtperf.dox +++ b/src/third_party/wiredtiger/src/docs/wtperf.dox @@ -185,6 +185,8 @@ execute a read prior to each insert in workload phase key size @par log_partial (boolean, default=false) perform partial logging on first table only. +@par log_like_table (boolean, default=false) +Append all modification operations to another shared table. @par min_throughput (unsigned int, default=0) notify if any throughput measured is less than this amount. Aborts or prints warning based on min_throughput_fatal setting. Requires @@ -210,6 +212,8 @@ if non zero choose a value from within this range as the key for insert operations @par random_value (boolean, default=false) generate random content for the value +@par range_partition (boolean, default=false) +partition data by range (vs hash) @par read_range (unsigned int, default=0) scan a range of keys after each search @par readonly (boolean, default=false) @@ -262,6 +266,8 @@ transaction configuration string, relevant when populate_opts_per_txn is nonzero @par table_name (string, default=test) table name +@par truncate_single_ops (boolean, default=false) +Implement truncate via cursor remove instead of session API @par value_sz_max (unsigned int, default=1000) maximum value size when delta updates are present. Default disabled @par value_sz_min (unsigned int, default=1) diff --git a/src/third_party/wiredtiger/src/evict/evict_lru.c b/src/third_party/wiredtiger/src/evict/evict_lru.c index 8ea487bbf83..69fff96fef5 100644 --- a/src/third_party/wiredtiger/src/evict/evict_lru.c +++ b/src/third_party/wiredtiger/src/evict/evict_lru.c @@ -9,15 +9,18 @@ #include "wt_internal.h" static int __evict_clear_all_walks(WT_SESSION_IMPL *); -static int __evict_helper(WT_SESSION_IMPL *); static int WT_CDECL __evict_lru_cmp(const void *, const void *); static int __evict_lru_pages(WT_SESSION_IMPL *, bool); static int __evict_lru_walk(WT_SESSION_IMPL *); static int __evict_page(WT_SESSION_IMPL *, bool); static int __evict_pass(WT_SESSION_IMPL *); static int __evict_server(WT_SESSION_IMPL *, bool *); -static int __evict_walk(WT_SESSION_IMPL *, uint32_t); -static int __evict_walk_file(WT_SESSION_IMPL *, uint32_t, u_int *); +static int __evict_walk(WT_SESSION_IMPL *, WT_EVICT_QUEUE *); +static int __evict_walk_file( + WT_SESSION_IMPL *, WT_EVICT_QUEUE *, u_int, u_int *, bool *); + +#define WT_EVICT_HAS_WORKERS(s) \ + (S2C(s)->evict_threads.current_threads > 1) /* * __evict_read_gen -- @@ -31,11 +34,6 @@ __evict_read_gen(const WT_EVICT_ENTRY *entry) uint64_t read_gen; btree = entry->btree; - - /* Never prioritize empty slots. */ - if (entry->ref == NULL) - return (UINT64_MAX); - page = entry->ref->page; /* Any page set to the oldest generation should be discarded. */ @@ -54,6 +52,10 @@ __evict_read_gen(const WT_EVICT_ENTRY *entry) if (__wt_page_is_empty(page)) return (WT_READGEN_OLDEST); + /* Any large page in memory is likewise a good choice. */ + if (page->memory_footprint > btree->splitmempage) + return (WT_READGEN_OLDEST); + /* * The base read-generation is skewed by the eviction priority. * Internal pages are also adjusted, we prefer to evict leaf pages. @@ -70,14 +72,15 @@ __evict_read_gen(const WT_EVICT_ENTRY *entry) * Qsort function: sort the eviction array. */ static int WT_CDECL -__evict_lru_cmp(const void *a, const void *b) +__evict_lru_cmp(const void *a_arg, const void *b_arg) { - uint64_t a_lru, b_lru; + const WT_EVICT_ENTRY *a = a_arg, *b = b_arg; + uint64_t a_score, b_score; - a_lru = __evict_read_gen(a); - b_lru = __evict_read_gen(b); + a_score = (a->ref == NULL ? UINT64_MAX : a->score); + b_score = (b->ref == NULL ? UINT64_MAX : b->score); - return ((a_lru < b_lru) ? -1 : (a_lru == b_lru) ? 0 : 1); + return ((a_score < b_score) ? -1 : (a_score == b_score) ? 0 : 1); } /* @@ -139,11 +142,34 @@ __wt_evict_list_clear_page(WT_SESSION_IMPL *session, WT_REF *ref) __wt_spin_unlock(session, &cache->evict_queue_lock); } +/* + * __evict_queue_empty -- + * Is the queue empty? + */ +static inline bool +__evict_queue_empty(WT_EVICT_QUEUE *queue) +{ + return (queue->evict_current == NULL || + queue->evict_candidates == 0); +} + +/* + * __evict_queue_full -- + * Is the queue full (i.e., it has been populated with candidates and none + * of them have been evicted yet)? + */ +static inline bool +__evict_queue_full(WT_EVICT_QUEUE *queue) +{ + return (queue->evict_current == queue->evict_queue && + queue->evict_candidates != 0); +} + /* * __wt_evict_server_wake -- * Wake the eviction server thread. */ -int +void __wt_evict_server_wake(WT_SESSION_IMPL *session) { WT_CACHE *cache; @@ -158,43 +184,45 @@ __wt_evict_server_wake(WT_SESSION_IMPL *session) bytes_inuse = __wt_cache_bytes_inuse(cache); bytes_max = conn->cache_size; - WT_RET(__wt_verbose(session, WT_VERB_EVICTSERVER, + __wt_verbose(session, WT_VERB_EVICTSERVER, "waking, bytes inuse %s max (%" PRIu64 "MB %s %" PRIu64 "MB)", bytes_inuse <= bytes_max ? "<=" : ">", bytes_inuse / WT_MEGABYTE, bytes_inuse <= bytes_max ? "<=" : ">", - bytes_max / WT_MEGABYTE)); + bytes_max / WT_MEGABYTE); } #endif - return (__wt_cond_auto_signal(session, cache->evict_cond)); + __wt_cond_auto_signal(session, cache->evict_cond); } /* - * __evict_thread_run -- - * General wrapper for any eviction thread. + * __wt_evict_thread_run -- + * Starting point for an eviction thread. */ -static WT_THREAD_RET -__evict_thread_run(void *arg) +int +__wt_evict_thread_run(WT_SESSION_IMPL *session, WT_THREAD *thread) { WT_CACHE *cache; WT_CONNECTION_IMPL *conn; WT_DECL_RET; - WT_SESSION_IMPL *session; bool did_work; - session = arg; conn = S2C(session); cache = conn->cache; #ifdef HAVE_DIAGNOSTIC - if (session == conn->evict_session) - WT_ERR(__wt_epoch( - session, &cache->stuck_ts)); /* -Wuninitialized */ + /* + * Ensure the cache stuck timer is initialized when starting eviction + */ + if (thread->id == 0) + WT_ERR(__wt_epoch(session, &cache->stuck_ts)); #endif - while (F_ISSET(conn, WT_CONN_EVICTION_RUN)) { - if (conn->evict_tid_set && + + while (F_ISSET(conn, WT_CONN_EVICTION_RUN) && + F_ISSET(thread, WT_THREAD_RUN)) { + if (conn->evict_server_running && __wt_spin_trylock(session, &cache->evict_pass_lock) == 0) { /* * Cannot use WT_WITH_PASS_LOCK because this is a try @@ -209,40 +237,40 @@ __evict_thread_run(void *arg) F_CLR(session, WT_SESSION_LOCKED_PASS); __wt_spin_unlock(session, &cache->evict_pass_lock); WT_ERR(ret); - WT_ERR(__wt_verbose( - session, WT_VERB_EVICTSERVER, "sleeping")); + __wt_verbose(session, WT_VERB_EVICTSERVER, "sleeping"); /* Don't rely on signals: check periodically. */ - WT_ERR(__wt_cond_auto_wait( - session, cache->evict_cond, did_work)); - WT_ERR(__wt_verbose( - session, WT_VERB_EVICTSERVER, "waking")); + __wt_cond_auto_wait( + session, cache->evict_cond, did_work); + __wt_verbose(session, WT_VERB_EVICTSERVER, "waking"); } else - WT_ERR(__evict_helper(session)); + WT_ERR(__evict_lru_pages(session, false)); } - if (session == conn->evict_session) { - /* - * The eviction server is shutting down: in case any trees are - * still open, clear all walks now so that they can be closed. - */ + /* + * The only time the first eviction thread is stopped is on shutdown: + * in case any trees are still open, clear all walks now so that they + * can be closed. + */ + if (thread->id == 0) { WT_WITH_PASS_LOCK(session, ret, ret = __evict_clear_all_walks(session)); WT_ERR(ret); + /* + * The only two cases when the eviction server is expected to + * stop are when recovery is finished or when the connection is + * closing. + */ + WT_ASSERT(session, + F_ISSET(conn, WT_CONN_CLOSING | WT_CONN_RECOVERING)); } - WT_ERR(__wt_verbose( - session, WT_VERB_EVICTSERVER, "cache eviction thread exiting")); - /* - * The only two cases when eviction workers are expected to stop are - * when recovery is finished or when the connection is closing. Check - * otherwise fewer eviction worker threads may be running than - * expected. - */ - WT_ASSERT(session, F_ISSET(conn, WT_CONN_CLOSING | WT_CONN_RECOVERING)); + __wt_verbose( + session, WT_VERB_EVICTSERVER, "cache eviction thread exiting"); + if (0) { err: WT_PANIC_MSG(session, ret, "cache eviction thread error"); } - return (WT_THREAD_RET_VALUE); + return (ret); } /* @@ -277,7 +305,7 @@ __evict_server(WT_SESSION_IMPL *session, bool *did_work) * Clear the walks so we don't pin pages while asleep, * otherwise we can block applications evicting large pages. */ - if (!F_ISSET(cache, WT_CACHE_STUCK)) { + if (!__wt_cache_stuck(session)) { for (spins = 0; (ret = __wt_spin_trylock( session, &conn->dhandle_lock)) == EBUSY && cache->pass_intr == 0; spins++) { @@ -310,10 +338,11 @@ __evict_server(WT_SESSION_IMPL *session, bool *did_work) /* After being stuck for 5 minutes, give up. */ WT_RET(__wt_epoch(session, &now)); if (WT_TIMEDIFF_SEC(now, cache->stuck_ts) > 300) { - __wt_err(session, ETIMEDOUT, + ret = ETIMEDOUT; + __wt_err(session, ret, "Cache stuck for too long, giving up"); - (void)__wt_cache_dump(session, NULL); - WT_RET(ETIMEDOUT); + WT_TRET(__wt_cache_dump(session, NULL)); + return (ret); } #endif } @@ -321,111 +350,32 @@ __evict_server(WT_SESSION_IMPL *session, bool *did_work) return (0); } -/* - * __evict_workers_resize -- - * Resize the array of eviction workers (as needed after a reconfigure). - * We don't do this during the reconfigure because the eviction server - * thread owns these structures. - */ -static int -__evict_workers_resize(WT_SESSION_IMPL *session) -{ - WT_CONNECTION_IMPL *conn; - WT_DECL_RET; - WT_EVICT_WORKER *workers; - size_t alloc; - uint32_t i, session_flags; - - conn = S2C(session); - workers = NULL; /* -Wconditional-uninitialized */ - - if (conn->evict_workers_alloc < conn->evict_workers_max) { - alloc = conn->evict_workers_alloc * sizeof(*workers); - WT_RET(__wt_realloc(session, &alloc, - conn->evict_workers_max * sizeof(*workers), - &conn->evict_workctx)); - workers = conn->evict_workctx; - } - - for (i = conn->evict_workers_alloc; i < conn->evict_workers_max; i++) { - /* - * Eviction worker threads get their own session. - * Eviction worker threads may be called upon to perform slow - * operations for the block manager. - * - * Eviction worker threads get their own lookaside table cursor - * if the lookaside table is open. Note that eviction is also - * started during recovery, before the lookaside table is - * created. - */ - session_flags = WT_SESSION_CAN_WAIT; - if (F_ISSET(conn, WT_CONN_LAS_OPEN)) - FLD_SET(session_flags, WT_SESSION_LOOKASIDE_CURSOR); - WT_ERR(__wt_open_internal_session(conn, "eviction-worker", - false, session_flags, &workers[i].session)); - workers[i].id = i; - - if (i < conn->evict_workers_min) { - ++conn->evict_workers; - F_SET(&workers[i], WT_EVICT_WORKER_RUN); - WT_ERR(__wt_thread_create(workers[i].session, - &workers[i].tid, __evict_thread_run, - workers[i].session)); - } - } - -err: conn->evict_workers_alloc = conn->evict_workers_max; - return (ret); -} - /* * __wt_evict_create -- - * Start the eviction server thread. + * Start the eviction server. */ int __wt_evict_create(WT_SESSION_IMPL *session) { WT_CONNECTION_IMPL *conn; - uint32_t session_flags; conn = S2C(session); + WT_ASSERT(session, conn->evict_threads_min > 0); /* Set first, the thread might run before we finish up. */ F_SET(conn, WT_CONN_EVICTION_RUN); - /* - * We need a session handle because we're reading/writing pages. - * - * The eviction server gets its own lookaside table cursor. - * - * If there's only a single eviction thread, it may be called upon to - * perform slow operations for the block manager. (The flag is not - * reset if reconfigured later, but I doubt that's a problem.) - */ - session_flags = F_ISSET(conn, WT_CONN_LAS_OPEN) ? - WT_SESSION_LOOKASIDE_CURSOR : 0; - if (conn->evict_workers_max == 0) - FLD_SET(session_flags, WT_SESSION_CAN_WAIT); - WT_RET(__wt_open_internal_session(conn, - "eviction-server", false, session_flags, &conn->evict_session)); - session = conn->evict_session; - - /* - * If eviction workers were configured, allocate sessions for them now. - * This is done to reduce the chance that we will open new eviction - * sessions after WT_CONNECTION::close is called. - */ - if (conn->evict_workers_max > 0) - WT_RET(__evict_workers_resize(session)); + /* Create the eviction thread group */ + WT_RET(__wt_thread_group_create(session, &conn->evict_threads, + "eviction-server", conn->evict_threads_min, + conn->evict_threads_max, WT_THREAD_CAN_WAIT | WT_THREAD_PANIC_FAIL, + __wt_evict_thread_run)); - /* - * Start the primary eviction server thread after the worker threads - * have started to avoid it starting additional worker threads before - * the worker's sessions are created. + /* + * Allow queues to be populated now that the eviction threads + * are running. */ - WT_RET(__wt_thread_create( - session, &conn->evict_tid, __evict_thread_run, session)); - conn->evict_tid_set = true; + conn->evict_server_running = true; return (0); } @@ -437,78 +387,33 @@ __wt_evict_create(WT_SESSION_IMPL *session) int __wt_evict_destroy(WT_SESSION_IMPL *session) { - WT_CACHE *cache; WT_CONNECTION_IMPL *conn; - WT_DECL_RET; - WT_EVICT_WORKER *workers; - WT_SESSION *wt_session; - uint32_t i; conn = S2C(session); - cache = conn->cache; - workers = conn->evict_workctx; - F_CLR(conn, WT_CONN_EVICTION_RUN); + /* We are done if the eviction server didn't start successfully. */ + if (!conn->evict_server_running) + return (0); + + /* Wait for any eviction thread group changes to stabilize. */ + __wt_writelock(session, conn->evict_threads.lock); /* - * Wait for the main eviction thread to exit before waiting on the - * helpers. The eviction server spawns helper threads, so we can't - * safely know how many helpers are running until the main thread is - * done. + * Signal the threads to finish and stop populating the queue. */ - WT_TRET(__wt_verbose( - session, WT_VERB_EVICTSERVER, "waiting for main thread")); - if (conn->evict_tid_set) { - WT_TRET(__wt_evict_server_wake(session)); - WT_TRET(__wt_thread_join(session, conn->evict_tid)); - conn->evict_tid_set = false; - } - - WT_TRET(__wt_verbose( - session, WT_VERB_EVICTSERVER, "waiting for helper threads")); - for (i = 0; i < conn->evict_workers; i++) { - WT_TRET(__wt_cond_signal(session, cache->evict_waiter_cond)); - WT_TRET(__wt_thread_join(session, workers[i].tid)); - } - conn->evict_workers = 0; - - /* Handle shutdown when cleaning up after a failed open. */ - if (conn->evict_workctx != NULL) { - for (i = 0; i < conn->evict_workers_alloc; i++) { - wt_session = &conn->evict_workctx[i].session->iface; - if (wt_session != NULL) - WT_TRET(wt_session->close(wt_session, NULL)); - } - __wt_free(session, conn->evict_workctx); - } - conn->evict_workers_alloc = 0; - - if (conn->evict_session != NULL) { - wt_session = &conn->evict_session->iface; - WT_TRET(wt_session->close(wt_session, NULL)); - - conn->evict_session = NULL; - } + F_CLR(conn, WT_CONN_EVICTION_RUN); + conn->evict_server_running = false; + __wt_evict_server_wake(session); - return (ret); -} + __wt_verbose( + session, WT_VERB_EVICTSERVER, "waiting for helper threads"); -/* - * __evict_helper -- - * Thread to help evict pages from the cache. - */ -static int -__evict_helper(WT_SESSION_IMPL *session) -{ - WT_CACHE *cache; - WT_DECL_RET; + /* + * We call the destroy function still holding the write lock. + * It assumes it is called locked. + */ + WT_RET(__wt_thread_group_destroy(session, &conn->evict_threads)); - cache = S2C(session)->cache; - if ((ret = __evict_lru_pages(session, false)) == WT_NOTFOUND) - WT_RET(__wt_cond_wait( - session, cache->evict_waiter_cond, 10000)); - else - WT_RET(ret); return (0); } @@ -521,75 +426,56 @@ __evict_update_work(WT_SESSION_IMPL *session) { WT_CACHE *cache; WT_CONNECTION_IMPL *conn; + double dirty_trigger; uint64_t bytes_inuse, bytes_max, dirty_inuse; conn = S2C(session); cache = conn->cache; - WT_STAT_FAST_CONN_SET(session, cache_eviction_aggressive_set, 0); /* Clear previous state. */ - cache->state = 0; + F_CLR(cache, WT_CACHE_EVICT_MASK); if (!F_ISSET(conn, WT_CONN_EVICTION_RUN)) return (false); - /* - * Setup the number of refs to consider in each handle, depending - * on how many handles are open. We want to consider less candidates - * from each file as more files are open. Handle the case where there - * are no files open by adding 1. - */ - cache->evict_max_refs_per_file = - WT_MAX(100, WT_MILLION / (conn->open_file_count + 1)); + if (!__evict_queue_empty(cache->evict_urgent_queue)) + F_SET(cache, WT_CACHE_EVICT_URGENT); /* - * Page eviction overrides the dirty target and other types of eviction, - * that is, we don't care where we are with respect to the dirty target - * if page eviction is configured. + * If we need space in the cache, try to find clean pages to evict. * * Avoid division by zero if the cache size has not yet been set in a * shared cache. */ bytes_max = conn->cache_size + 1; bytes_inuse = __wt_cache_bytes_inuse(cache); - if (bytes_inuse > (cache->eviction_target * bytes_max) / 100) { - FLD_SET(cache->state, WT_EVICT_PASS_ALL); - goto done; - } + if (bytes_inuse > (cache->eviction_target * bytes_max) / 100) + F_SET(cache, WT_CACHE_EVICT_CLEAN); + if (bytes_inuse > (cache->eviction_trigger * bytes_max) / 100) + F_SET(cache, WT_CACHE_EVICT_CLEAN_HARD); + + dirty_inuse = __wt_cache_dirty_leaf_inuse(cache); + if (dirty_inuse > (cache->eviction_dirty_target * bytes_max) / 100) + F_SET(cache, WT_CACHE_EVICT_DIRTY); + if ((dirty_trigger = cache->eviction_scrub_limit) < 1.0) + dirty_trigger = (double)cache->eviction_dirty_trigger; + if (dirty_inuse > (uint64_t)(dirty_trigger * bytes_max) / 100) + F_SET(cache, WT_CACHE_EVICT_DIRTY_HARD); /* - * If the cache has been stuck and is now under control, clear the - * stuck flag. + * Scrub dirty pages and keep them in cache if we are less than half + * way to the clean or dirty trigger. */ - if (bytes_inuse < bytes_max) - F_CLR(cache, WT_CACHE_STUCK); - - dirty_inuse = __wt_cache_dirty_inuse(cache); - if (dirty_inuse > (cache->eviction_dirty_target * bytes_max) / 100) { - FLD_SET(cache->state, WT_EVICT_PASS_DIRTY); - goto done; - } - - /* - * Evict pages with oldest generation (which would otherwise block - * application threads), set regardless of whether we have reached - * the eviction trigger. - */ - if (F_ISSET(cache, WT_CACHE_WOULD_BLOCK)) { - FLD_SET(cache->state, WT_EVICT_PASS_WOULD_BLOCK); - - F_CLR(cache, WT_CACHE_WOULD_BLOCK); - goto done; - } + if (bytes_inuse < ((cache->eviction_target + cache->eviction_trigger) * + bytes_max) / 200 && dirty_inuse < (uint64_t) + ((cache->eviction_dirty_target + cache->eviction_dirty_trigger) * + bytes_max) / 200) + F_SET(cache, WT_CACHE_EVICT_SCRUB); - return (false); + WT_STAT_FAST_CONN_SET(session, cache_eviction_state, + F_MASK(cache, WT_CACHE_EVICT_MASK)); -done: if (F_ISSET(cache, WT_CACHE_STUCK)) { - WT_STAT_FAST_CONN_SET(session, - cache_eviction_aggressive_set, 1); - FLD_SET(cache->state, WT_EVICT_PASS_AGGRESSIVE); - } - return (true); + return (F_ISSET(cache, WT_CACHE_EVICT_ALL | WT_CACHE_EVICT_URGENT)); } /* @@ -601,24 +487,25 @@ __evict_pass(WT_SESSION_IMPL *session) { WT_CACHE *cache; WT_CONNECTION_IMPL *conn; - WT_EVICT_WORKER *worker; - uint64_t pages_evicted; - int loop; + WT_TXN_GLOBAL *txn_global; + struct timespec now, prev; + uint64_t oldest_id, pages_evicted, prev_oldest_id; + u_int loop; conn = S2C(session); cache = conn->cache; + txn_global = &conn->txn_global; /* Track whether pages are being evicted and progress is made. */ pages_evicted = cache->pages_evict; + prev_oldest_id = txn_global->oldest_id; + WT_CLEAR(prev); /* Evict pages from the cache. */ - for (loop = 0;; loop++) { - /* - * If there is a request to clear eviction walks, do that now, - * before checking if the cache is full. - */ - if (cache->pass_intr != 0) - break; + for (loop = 0; cache->pass_intr == 0; loop++) { + WT_RET(__wt_epoch(session, &now)); + if (loop == 0) + prev = now; /* * Increment the shared read generation. Do this occasionally @@ -644,70 +531,104 @@ __evict_pass(WT_SESSION_IMPL *session) if (!__evict_update_work(session)) break; - if (loop > 10) { - WT_STAT_FAST_CONN_SET(session, - cache_eviction_aggressive_set, 1); - FLD_SET(cache->state, WT_EVICT_PASS_AGGRESSIVE); - } - /* - * Start a worker if we have capacity and we haven't reached - * the eviction targets. + * Try to start a new thread if we have capacity and haven't + * reached the eviction targets. */ - if (FLD_ISSET(cache->state, WT_EVICT_PASS_ALL | - WT_EVICT_PASS_DIRTY | WT_EVICT_PASS_WOULD_BLOCK) && - conn->evict_workers < conn->evict_workers_max) { - WT_RET(__wt_verbose(session, WT_VERB_EVICTSERVER, - "Starting evict worker: %"PRIu32"\n", - conn->evict_workers)); - if (conn->evict_workers >= conn->evict_workers_alloc) - WT_RET(__evict_workers_resize(session)); - worker = &conn->evict_workctx[conn->evict_workers++]; - F_SET(worker, WT_EVICT_WORKER_RUN); - WT_RET(__wt_thread_create(session, - &worker->tid, __evict_thread_run, worker->session)); - } + if (F_ISSET(cache, WT_CACHE_EVICT_ALL)) + WT_RET(__wt_thread_group_start_one( + session, &conn->evict_threads, false)); - WT_RET(__wt_verbose(session, WT_VERB_EVICTSERVER, + __wt_verbose(session, WT_VERB_EVICTSERVER, "Eviction pass with: Max: %" PRIu64 " In use: %" PRIu64 " Dirty: %" PRIu64, - conn->cache_size, cache->bytes_inmem, cache->bytes_dirty)); + conn->cache_size, cache->bytes_inmem, + cache->bytes_dirty_intl + cache->bytes_dirty_leaf); - WT_RET(__evict_lru_walk(session)); - WT_RET_NOTFOUND_OK(__evict_lru_pages(session, true)); + if (F_ISSET(cache, WT_CACHE_EVICT_ALL)) + WT_RET(__evict_lru_walk(session)); + + /* + * If the queue has been empty recently, keep queuing more + * pages to evict. If the rate of queuing pages is high + * enough, this score will go to zero, in which case the + * eviction server might as well help out with eviction. + * + * Also, if there is a single eviction server thread with no + * workers, it must service the urgent queue in case all + * application threads are busy. + */ + if (cache->evict_empty_score < WT_EVICT_SCORE_CUTOFF || + (!WT_EVICT_HAS_WORKERS(session) && + !__evict_queue_empty(cache->evict_urgent_queue))) + WT_RET(__evict_lru_pages(session, true)); + + if (cache->pass_intr != 0) + break; /* * If we're making progress, keep going; if we're not making * any progress at all, mark the cache "stuck" and go back to * sleep, it's not something we can fix. + * + * We check for progress every 20ms, the idea being that the + * aggressive score will reach 10 after 200ms if we aren't + * making progress and eviction will start considering more + * pages. If there is still no progress after 2s, we will + * treat the cache as stuck and start rolling back + * transactions and writing updates to the lookaside table. */ if (pages_evicted == cache->pages_evict) { - WT_STAT_FAST_CONN_INCR(session, - cache_eviction_server_slept); + if (WT_TIMEDIFF_MS(now, prev) >= 20 && + F_ISSET(cache, WT_CACHE_EVICT_CLEAN_HARD | + WT_CACHE_EVICT_DIRTY_HARD)) { + if (cache->evict_aggressive_score < 100) + ++cache->evict_aggressive_score; + oldest_id = txn_global->oldest_id; + if (prev_oldest_id == oldest_id && + txn_global->current != oldest_id && + cache->evict_aggressive_score < 100) + ++cache->evict_aggressive_score; + WT_STAT_FAST_CONN_SET(session, + cache_eviction_aggressive_set, + cache->evict_aggressive_score); + prev = now; + prev_oldest_id = oldest_id; + } + /* - * Back off if we aren't making progress: walks hold - * the handle list lock, which blocks other operations - * that can free space in cache, such as LSM discarding - * handles. + * Keep trying for long enough that we should be able + * to evict a page if the server isn't interfering. */ - __wt_sleep(0, WT_THOUSAND * (uint64_t)loop); - if (loop == 100) { + if (loop < 100 || cache->evict_aggressive_score < 100) { /* - * Mark the cache as stuck if we need space - * and aren't evicting any pages. + * Back off if we aren't making progress: walks + * hold the handle list lock, blocking other + * operations that can free space in cache, + * such as LSM discarding handles. + * + * Allow this wait to be interrupted (e.g. if a + * checkpoint completes): make sure we wait for + * a non-zero number of microseconds). */ - if (!FLD_ISSET(cache->state, - WT_EVICT_PASS_WOULD_BLOCK)) { - F_SET(cache, WT_CACHE_STUCK); - WT_STAT_FAST_CONN_INCR( - session, cache_eviction_slow); - WT_RET(__wt_verbose( - session, WT_VERB_EVICTSERVER, - "unable to reach eviction goal")); - } - break; + WT_STAT_FAST_CONN_INCR(session, + cache_eviction_server_slept); + __wt_cond_wait( + session, cache->evict_cond, WT_THOUSAND); + continue; } + + WT_STAT_FAST_CONN_INCR(session, cache_eviction_slow); + __wt_verbose(session, WT_VERB_EVICTSERVER, + "unable to reach eviction goal"); + break; } else { + if (cache->evict_aggressive_score > 0) { + --cache->evict_aggressive_score; + WT_STAT_FAST_CONN_SET(session, + cache_eviction_aggressive_set, + cache->evict_aggressive_score); + } loop = 0; pages_evicted = cache->pages_evict; } @@ -805,13 +726,12 @@ __wt_evict_file_exclusive_on(WT_SESSION_IMPL *session) * this point. */ F_SET(btree, WT_BTREE_NO_EVICTION); - (void)__wt_atomic_add32(&cache->pass_intr, 1); - WT_FULL_BARRIER(); + (void)__wt_atomic_addv32(&cache->pass_intr, 1); /* Clear any existing LRU eviction walk for the file. */ WT_WITH_PASS_LOCK(session, ret, ret = __evict_clear_walk(session)); - (void)__wt_atomic_sub32(&cache->pass_intr, 1); + (void)__wt_atomic_subv32(&cache->pass_intr, 1); WT_ERR(ret); /* @@ -879,7 +799,6 @@ __wt_evict_file_exclusive_off(WT_SESSION_IMPL *session) __wt_spin_unlock(session, &cache->evict_walk_lock); } -#define APP_EVICT_THRESHOLD 3 /* Threshold to help evict */ /* * __evict_lru_pages -- * Get pages from the LRU queue to evict. @@ -887,35 +806,25 @@ __wt_evict_file_exclusive_off(WT_SESSION_IMPL *session) static int __evict_lru_pages(WT_SESSION_IMPL *session, bool is_server) { - WT_CACHE *cache; + WT_CONNECTION_IMPL *conn; WT_DECL_RET; - uint64_t app_evict_percent, total_evict; - /* - * The server will not help evict if the workers are coping with - * eviction workload, that is, if fewer than the threshold of the - * pages are evicted by application threads. - */ - if (is_server && S2C(session)->evict_workers > 1) { - cache = S2C(session)->cache; - total_evict = cache->app_evicts + - cache->server_evicts + cache->worker_evicts; - app_evict_percent = (100 * cache->app_evicts) / - (total_evict + 1); - if (app_evict_percent < APP_EVICT_THRESHOLD) { - WT_STAT_FAST_CONN_INCR(session, - cache_eviction_server_not_evicting); - return (0); - } - } + conn = S2C(session); /* * Reconcile and discard some pages: EBUSY is returned if a page fails * eviction because it's unavailable, continue in that case. */ - while ((ret = __evict_page(session, is_server)) == 0 || ret == EBUSY) - ; - return (ret); + while (F_ISSET(S2C(session), WT_CONN_EVICTION_RUN) && ret == 0) + if ((ret = __evict_page(session, is_server)) == EBUSY) + ret = 0; + + /* If a worker thread found the queue empty, pause. */ + if (ret == WT_NOTFOUND && !is_server && + F_ISSET(S2C(session), WT_CONN_EVICTION_RUN)) + __wt_cond_wait(session, conn->evict_threads.wait_cond, 10000); + + return (ret == WT_NOTFOUND ? 0 : ret); } /* @@ -927,26 +836,88 @@ __evict_lru_walk(WT_SESSION_IMPL *session) { WT_CACHE *cache; WT_DECL_RET; - WT_EVICT_QUEUE *evict_queue; - uint64_t cutoff, read_gen_oldest; - uint32_t candidates, entries, queue_index; + WT_EVICT_QUEUE *queue, *other_queue; + uint64_t read_gen_oldest; + uint32_t candidates, entries; cache = S2C(session)->cache; - queue_index = cache->evict_queue_fill++ % WT_EVICT_QUEUE_MAX; - evict_queue = &cache->evict_queues[queue_index]; + /* Age out the score of how much the queue has been empty recently. */ + if (cache->evict_empty_score > 0) + --cache->evict_empty_score; + + /* Fill the next queue (that isn't the urgent queue). */ + queue = cache->evict_fill_queue; + other_queue = cache->evict_queues + (1 - (queue - cache->evict_queues)); + + /* If this queue is full, try the other one. */ + if (__evict_queue_full(queue) && !__evict_queue_full(other_queue)) + queue = other_queue; + cache->evict_fill_queue = + &cache->evict_queues[1 - (queue - cache->evict_queues)]; + + /* + * If both queues are full and haven't been empty on recent refills, + * we're done. + */ + if (__evict_queue_full(queue) && + cache->evict_empty_score < WT_EVICT_SCORE_CUTOFF) + return (0); + /* Get some more pages to consider for eviction. */ - if ((ret = __evict_walk(cache->walk_session, queue_index)) != 0) - return (ret == EBUSY ? 0 : ret); + switch (ret = __evict_walk(cache->walk_session, queue)) { + case 0: + break; + case EBUSY: + return (0); + case WT_NOTFOUND: + /* + * If we found no pages at all during the walk, something is + * wrong. Be more aggressive next time. + */ + if (F_ISSET(cache, + WT_CACHE_EVICT_CLEAN_HARD | WT_CACHE_EVICT_DIRTY_HARD)) + cache->evict_aggressive_score = WT_MIN( + cache->evict_aggressive_score + WT_EVICT_SCORE_BUMP, + WT_EVICT_SCORE_MAX); + WT_STAT_FAST_CONN_SET(session, + cache_eviction_aggressive_set, + cache->evict_aggressive_score); + return (0); + default: + return (ret); + } + + /* + * If the queue we are filling is empty, pages are being requested + * faster than they are being queued. + */ + if (__evict_queue_empty(queue)) { + if (F_ISSET(cache, + WT_CACHE_EVICT_CLEAN_HARD | WT_CACHE_EVICT_DIRTY_HARD)) + cache->evict_empty_score = WT_MIN( + cache->evict_empty_score + WT_EVICT_SCORE_BUMP, + WT_EVICT_SCORE_MAX); + WT_STAT_FAST_CONN_INCR(session, cache_eviction_queue_empty); + } else + WT_STAT_FAST_CONN_INCR(session, cache_eviction_queue_not_empty); /* Sort the list into LRU order and restart. */ - __wt_spin_lock(session, &evict_queue->evict_lock); + __wt_spin_lock(session, &queue->evict_lock); - entries = evict_queue->evict_entries; - qsort(evict_queue->evict_queue, + /* + * We have locked the queue: in the (unusual) case where we are filling + * the current queue, mark it empty so that subsequent requests switch + * to the other queue. + */ + if (queue == cache->evict_current_queue) + queue->evict_current = NULL; + + entries = queue->evict_entries; + qsort(queue->evict_queue, entries, sizeof(WT_EVICT_ENTRY), __evict_lru_cmp); - while (entries > 0 && evict_queue->evict_queue[entries - 1].ref == NULL) + while (entries > 0 && queue->evict_queue[entries - 1].ref == NULL) --entries; /* @@ -956,9 +927,9 @@ __evict_lru_walk(WT_SESSION_IMPL *session) */ while (entries > WT_EVICT_WALK_BASE) __evict_list_clear(session, - &evict_queue->evict_queue[--entries]); + &queue->evict_queue[--entries]); - evict_queue->evict_entries = entries; + queue->evict_entries = entries; if (entries == 0) { /* @@ -966,24 +937,16 @@ __evict_lru_walk(WT_SESSION_IMPL *session) * Make sure application threads don't read past the end of the * candidate list, or they may race with the next walk. */ - evict_queue->evict_candidates = 0; - __wt_spin_unlock(session, &evict_queue->evict_lock); - __wt_spin_lock(session, &cache->evict_queue_lock); - cache->evict_current = NULL; - cache->evict_current_queue = NULL; - __wt_spin_unlock(session, &cache->evict_queue_lock); + queue->evict_candidates = 0; + queue->evict_current = NULL; + __wt_spin_unlock(session, &queue->evict_lock); return (0); } /* Decide how many of the candidates we're going to try and evict. */ - if (FLD_ISSET(cache->state, - WT_EVICT_PASS_AGGRESSIVE | WT_EVICT_PASS_WOULD_BLOCK)) { - /* - * Take all candidates if we only gathered pages with an oldest - * read generation set. - */ - evict_queue->evict_candidates = entries; - } else { + if (__wt_cache_aggressive(session)) + queue->evict_candidates = entries; + else { /* * Find the oldest read generation we have in the queue, used * to set the initial value for pages read into the system. @@ -992,8 +955,7 @@ __evict_lru_walk(WT_SESSION_IMPL *session) read_gen_oldest = WT_READGEN_OLDEST; for (candidates = 0; candidates < entries; ++candidates) { read_gen_oldest = - __evict_read_gen( - &evict_queue->evict_queue[candidates]); + queue->evict_queue[candidates].score; if (read_gen_oldest != WT_READGEN_OLDEST) break; } @@ -1002,58 +964,40 @@ __evict_lru_walk(WT_SESSION_IMPL *session) * Take all candidates if we only gathered pages with an oldest * read generation set. * - * We normally never take more than 50% of the entries; if 50% - * of the entries were at the oldest read generation, take them. + * We normally never take more than 50% of the entries but if + * 50% of the entries were at the oldest read generation, take + * all of them. */ if (read_gen_oldest == WT_READGEN_OLDEST) - evict_queue->evict_candidates = entries; - else if (candidates >= entries / 2) - evict_queue->evict_candidates = candidates; + queue->evict_candidates = entries; + else if (candidates > entries / 2) + queue->evict_candidates = candidates; else { - /* Save the calculated oldest generation. */ - cache->read_gen_oldest = read_gen_oldest; - - /* Find the bottom 25% of read generations. */ - cutoff = - (3 * read_gen_oldest + __evict_read_gen( - &evict_queue->evict_queue[entries - 1])) / 4; - /* - * Don't take less than 10% or more than 50% of entries, - * regardless. That said, if there is only one entry, - * which is normal when populating an empty file, don't - * exclude it. + * Take all of the urgent pages plus a third of + * ordinary candidates (which could be expressed as + * WT_EVICT_WALK_INCR / WT_EVICT_WALK_BASE). In the + * steady state, we want to get as many candidates as + * the eviction walk adds to the queue. + * + * That said, if there is only one entry, which is + * normal when populating an empty file, don't exclude + * it. */ - for (candidates = 1 + entries / 10; - candidates < entries / 2; - candidates++) - if (__evict_read_gen( - &evict_queue->evict_queue[candidates]) > - cutoff) - break; - evict_queue->evict_candidates = candidates; + queue->evict_candidates = + 1 + candidates + ((entries - candidates) - 1) / 3; + cache->read_gen_oldest = read_gen_oldest; } } - __wt_spin_unlock(session, &evict_queue->evict_lock); - /* - * Now we can set the next queue. - */ - __wt_spin_lock(session, &cache->evict_queue_lock); - if (cache->evict_current == NULL) - WT_STAT_FAST_CONN_INCR(session, cache_eviction_queue_empty); - else - WT_STAT_FAST_CONN_INCR(session, cache_eviction_queue_not_empty); - - cache->evict_current = evict_queue->evict_queue; - cache->evict_current_queue = evict_queue; - __wt_spin_unlock(session, &cache->evict_queue_lock); + queue->evict_current = queue->evict_queue; + __wt_spin_unlock(session, &queue->evict_lock); /* * Signal any application or helper threads that may be waiting * to help with eviction. */ - WT_RET(__wt_cond_signal(session, cache->evict_waiter_cond)); + __wt_cond_signal(session, S2C(session)->evict_threads.wait_cond); return (0); } @@ -1063,17 +1007,15 @@ __evict_lru_walk(WT_SESSION_IMPL *session) * Fill in the array by walking the next set of pages. */ static int -__evict_walk(WT_SESSION_IMPL *session, uint32_t queue_index) +__evict_walk(WT_SESSION_IMPL *session, WT_EVICT_QUEUE *queue) { WT_BTREE *btree; WT_CACHE *cache; WT_CONNECTION_IMPL *conn; WT_DATA_HANDLE *dhandle; WT_DECL_RET; - WT_EVICT_QUEUE *evict_queue; - u_int max_entries, prev_slot, retries; - u_int slot, start_slot, spins; - bool dhandle_locked, incr; + u_int max_entries, prev_slot, retries, slot, start_slot, spins; + bool dhandle_locked, incr, progress; conn = S2C(session); cache = S2C(session)->cache; @@ -1086,17 +1028,16 @@ __evict_walk(WT_SESSION_IMPL *session, uint32_t queue_index) * Set the starting slot in the queue and the maximum pages added * per walk. */ - evict_queue = &cache->evict_queues[queue_index]; - start_slot = slot = evict_queue->evict_entries; - max_entries = slot + WT_EVICT_WALK_INCR; + start_slot = slot = queue->evict_entries; + max_entries = WT_MIN(slot + WT_EVICT_WALK_INCR, cache->evict_slots); -retry: while (slot < max_entries && ret == 0) { +retry: while (slot < max_entries) { /* * If another thread is waiting on the eviction server to clear * the walk point in a tree, give up. */ if (cache->pass_intr != 0) - break; + WT_ERR(EBUSY); /* * Lock the dhandle list to find the next handle and bump its @@ -1112,8 +1053,7 @@ retry: while (slot < max_entries && ret == 0) { else __wt_sleep(0, WT_THOUSAND); } - if (ret != 0) - break; + WT_ERR(ret); dhandle_locked = true; } @@ -1153,12 +1093,19 @@ retry: while (slot < max_entries && ret == 0) { continue; /* - * Also skip files that are checkpointing or configured to - * stick in cache until we get aggressive. + * Skip files that are checkpointing if we are only looking for + * dirty pages. */ - if ((btree->checkpointing != WT_CKPT_OFF || - btree->evict_priority != 0) && - !FLD_ISSET(cache->state, WT_EVICT_PASS_AGGRESSIVE)) + if (btree->checkpointing != WT_CKPT_OFF && + !F_ISSET(cache, WT_CACHE_EVICT_CLEAN)) + continue; + + /* + * Skip files that are configured to stick in cache until we + * become aggressive. + */ + if (btree->evict_priority != 0 && + !__wt_cache_aggressive(session)) continue; /* Skip files if we have used all available hazard pointers. */ @@ -1171,11 +1118,11 @@ retry: while (slot < max_entries && ret == 0) { * useful in the past. */ if (btree->evict_walk_period != 0 && - evict_queue->evict_entries >= WT_EVICT_WALK_INCR && btree->evict_walk_skips++ < btree->evict_walk_period) continue; btree->evict_walk_skips = 0; prev_slot = slot; + progress = false; (void)__wt_atomic_addi32(&dhandle->session_inuse, 1); incr = true; @@ -1196,19 +1143,20 @@ retry: while (slot < max_entries && ret == 0) { !__wt_spin_trylock(session, &cache->evict_walk_lock)) { if (!F_ISSET(btree, WT_BTREE_NO_EVICTION)) { cache->evict_file_next = dhandle; - WT_WITH_DHANDLE(session, dhandle, - ret = __evict_walk_file( - session, queue_index, &slot)); + WT_WITH_DHANDLE(session, dhandle, ret = + __evict_walk_file(session, queue, + max_entries, &slot, &progress)); WT_ASSERT(session, session->split_gen == 0); } __wt_spin_unlock(session, &cache->evict_walk_lock); + WT_ERR(ret); } /* * If we didn't find any candidates in the file, skip it next * time. */ - if (slot == prev_slot) + if (slot == prev_slot && !progress) btree->evict_walk_period = WT_MIN( WT_MAX(1, 2 * btree->evict_walk_period), 100); else @@ -1221,52 +1169,76 @@ retry: while (slot < max_entries && ret == 0) { incr = false; } - if (dhandle_locked) { - __wt_spin_unlock(session, &conn->dhandle_lock); - dhandle_locked = false; - } - /* * Walk the list of files a few times if we don't find enough pages. * Try two passes through all the files, give up when we have some * candidates and we aren't finding more. */ - if (cache->pass_intr == 0 && ret == 0 && - slot < max_entries && (retries < 2 || + if (slot < max_entries && (retries < 2 || (retries < 10 && - !FLD_ISSET(cache->state, WT_EVICT_PASS_WOULD_BLOCK) && - (slot == evict_queue->evict_entries || slot > start_slot)))) { + (slot == queue->evict_entries || slot > start_slot)))) { start_slot = slot; ++retries; goto retry; } - evict_queue->evict_entries = slot; +err: if (dhandle_locked) { + __wt_spin_unlock(session, &conn->dhandle_lock); + dhandle_locked = false; + } + + /* + * If we didn't find any entries on a walk when we weren't interrupted, + * let our caller know. + */ + if (queue->evict_entries == slot && cache->pass_intr == 0) + return (WT_NOTFOUND); + + queue->evict_entries = slot; return (ret); } /* - * __evict_init_candidate -- + * __evict_push_candidate -- * Initialize a WT_EVICT_ENTRY structure with a given page. */ -static void -__evict_init_candidate(WT_SESSION_IMPL *session, - WT_EVICT_QUEUE *evict_queue, WT_EVICT_ENTRY *evict, WT_REF *ref) +static bool +__evict_push_candidate(WT_SESSION_IMPL *session, + WT_EVICT_QUEUE *queue, WT_EVICT_ENTRY *evict, WT_REF *ref) { u_int slot; + uint8_t orig_flags, new_flags; + + /* + * Threads can race to queue a page (e.g., an ordinary LRU walk can + * race with a page being queued for urgent eviction). + */ + orig_flags = new_flags = ref->page->flags_atomic; + FLD_SET(new_flags, WT_PAGE_EVICT_LRU); + if (orig_flags == new_flags || + !__wt_atomic_cas8(&ref->page->flags_atomic, orig_flags, new_flags)) + return (false); /* Keep track of the maximum slot we are using. */ - slot = (u_int)(evict - evict_queue->evict_queue); - if (slot >= evict_queue->evict_max) - evict_queue->evict_max = slot + 1; + slot = (u_int)(evict - queue->evict_queue); + if (slot >= queue->evict_max) + queue->evict_max = slot + 1; if (evict->ref != NULL) __evict_list_clear(session, evict); - evict->ref = ref; + evict->btree = S2BT(session); + evict->ref = ref; + evict->score = __evict_read_gen(evict); + + /* Adjust for size when doing dirty eviction. */ + if (F_ISSET(S2C(session)->cache, WT_CACHE_EVICT_DIRTY) && + evict->score != WT_READGEN_OLDEST && evict->score != UINT64_MAX && + !__wt_page_is_modified(ref->page)) + evict->score += WT_MEGABYTE - + WT_MIN(WT_MEGABYTE, ref->page->memory_footprint); - /* Mark the page on the list; set last to flush the other updates. */ - F_SET_ATOMIC(ref->page, WT_PAGE_EVICT_LRU); + return (true); } /* @@ -1274,34 +1246,81 @@ __evict_init_candidate(WT_SESSION_IMPL *session, * Get a few page eviction candidates from a single underlying file. */ static int -__evict_walk_file(WT_SESSION_IMPL *session, uint32_t queue_index, u_int *slotp) +__evict_walk_file(WT_SESSION_IMPL *session, + WT_EVICT_QUEUE *queue, u_int max_entries, u_int *slotp, bool *progressp) { WT_BTREE *btree; WT_CACHE *cache; WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_EVICT_ENTRY *end, *evict, *start; - WT_EVICT_QUEUE *evict_queue; WT_PAGE *page; WT_PAGE_MODIFY *mod; WT_REF *ref; + WT_TXN_GLOBAL *txn_global; + uint64_t btree_inuse, bytes_per_slot, cache_inuse; uint64_t pages_seen, refs_walked; - uint32_t walk_flags; + uint32_t remaining_slots, total_slots, walk_flags; + uint32_t target_pages_clean, target_pages_dirty, target_pages; int internal_pages, restarts; - bool enough, modified; + bool modified; conn = S2C(session); btree = S2BT(session); cache = conn->cache; - evict_queue = &cache->evict_queues[queue_index]; internal_pages = restarts = 0; - enough = false; + txn_global = &conn->txn_global; + + /* + * Figure out how many slots to fill from this tree. + * Note that some care is taken in the calculation to avoid overflow. + */ + start = queue->evict_queue + *slotp; + remaining_slots = max_entries - *slotp; + total_slots = max_entries - queue->evict_entries; + + /* + * The target number of pages for this tree is proportional to the + * space it is taking up in cache. Round to the nearest number of + * slots so we assign all of the slots to a tree filling 99+% of the + * cache (and only have to walk it once). + */ + if (F_ISSET(cache, WT_CACHE_EVICT_CLEAN)) { + btree_inuse = __wt_btree_bytes_inuse(session); + cache_inuse = __wt_cache_bytes_inuse(cache); + bytes_per_slot = 1 + cache_inuse / total_slots; + target_pages_clean = (uint32_t)( + (btree_inuse + bytes_per_slot / 2) / bytes_per_slot); + } else + target_pages_clean = 0; + + if (F_ISSET(cache, WT_CACHE_EVICT_DIRTY)) { + btree_inuse = __wt_btree_dirty_leaf_inuse(session); + cache_inuse = __wt_cache_dirty_leaf_inuse(cache); + bytes_per_slot = 1 + cache_inuse / total_slots; + target_pages_dirty = (uint32_t)( + (btree_inuse + bytes_per_slot / 2) / bytes_per_slot); + } else + target_pages_dirty = 0; + + target_pages = WT_MAX(target_pages_clean, target_pages_dirty); + + if (target_pages == 0) { + /* + * Randomly walk trees with a tiny fraction of the cache in + * case there are so many trees that none of them use enough of + * the cache to be allocated slots. Walk small trees 1% of the + * time. + */ + if (__wt_random(&session->rnd) > UINT32_MAX / 100) + return (0); + target_pages = 10; + } - start = evict_queue->evict_queue + *slotp; - end = start + WT_EVICT_WALK_PER_FILE; if (F_ISSET(session->dhandle, WT_DHANDLE_DEAD) || - end > evict_queue->evict_queue + cache->evict_slots) - end = evict_queue->evict_queue + cache->evict_slots; + target_pages > remaining_slots) + target_pages = remaining_slots; + end = start + target_pages; walk_flags = WT_READ_CACHE | WT_READ_NO_EVICT | WT_READ_NO_GEN | WT_READ_NO_WAIT; @@ -1321,12 +1340,11 @@ __evict_walk_file(WT_SESSION_IMPL *session, uint32_t queue_index, u_int *slotp) * case we are appending and only the last page in the file is live. */ for (evict = start, pages_seen = refs_walked = 0; - evict < end && !enough && (ret == 0 || ret == WT_NOTFOUND); + evict < end && (ret == 0 || ret == WT_NOTFOUND); ret = __wt_tree_walk_count( session, &btree->evict_ref, &refs_walked, walk_flags)) { - enough = refs_walked > cache->evict_max_refs_per_file; if ((ref = btree->evict_ref) == NULL) { - if (++restarts == 2 || enough) + if (++restarts == 2) break; WT_STAT_FAST_CONN_INCR( session, cache_eviction_walks_started); @@ -1352,84 +1370,69 @@ __evict_walk_file(WT_SESSION_IMPL *session, uint32_t queue_index, u_int *slotp) /* * It's possible (but unlikely) to visit a page without a read * generation, if we race with the read instantiating the page. - * Ignore those pages, but set the page's read generation here - * to ensure a bug doesn't somehow leave a page without a read - * generation. + * Set the page's read generation here to ensure a bug doesn't + * somehow leave a page without a read generation. */ - if (page->read_gen == WT_READGEN_NOTSET) { + if (page->read_gen == WT_READGEN_NOTSET) __wt_cache_read_gen_new(session, page); - continue; - } /* Pages we no longer need (clean or dirty), are found money. */ - if (page->read_gen == WT_READGEN_OLDEST) { + if (page->read_gen == WT_READGEN_OLDEST || + page->memory_footprint >= btree->splitmempage) { WT_STAT_FAST_CONN_INCR( session, cache_eviction_pages_queued_oldest); - goto fast; + if (__wt_page_evict_urgent(session, ref)) + *progressp = true; + continue; } + if (__wt_page_is_empty(page) || - F_ISSET(session->dhandle, WT_DHANDLE_DEAD)) + F_ISSET(session->dhandle, WT_DHANDLE_DEAD) || + __wt_cache_aggressive(session)) goto fast; /* Skip clean pages if appropriate. */ if (!modified && (F_ISSET(conn, WT_CONN_IN_MEMORY) || - FLD_ISSET(cache->state, WT_EVICT_PASS_DIRTY))) + !F_ISSET(cache, WT_CACHE_EVICT_CLEAN))) continue; - /* - * If we are only trickling out pages marked for definite - * eviction, skip anything that isn't marked. - */ - if (FLD_ISSET(cache->state, WT_EVICT_PASS_WOULD_BLOCK) && - page->memory_footprint < btree->splitmempage) + /* Skip dirty pages if appropriate. */ + if (modified && !F_ISSET(cache, WT_CACHE_EVICT_DIRTY)) continue; - /* Limit internal pages to 50% unless we get aggressive. */ + /* Limit internal pages to 50% of the total. */ if (WT_PAGE_IS_INTERNAL(page) && - !FLD_ISSET(cache->state, WT_EVICT_PASS_AGGRESSIVE) && internal_pages >= (int)(evict - start) / 2) continue; -fast: /* If the page can't be evicted, give up. */ - if (!__wt_page_can_evict(session, ref, NULL)) - continue; - /* - * Note: take care with ordering: if we detected that - * the page is modified above, we expect mod != NULL. + * If the oldest transaction hasn't changed since the last time + * this page was written, it's unlikely we can make progress. + * Similarly, if the most recent update on the page is not yet + * globally visible, eviction will fail. These heuristics + * attempt to avoid repeated attempts to evict the same page. */ mod = page->modify; + if (modified && txn_global->current != txn_global->oldest_id && + (mod->last_eviction_id == __wt_txn_oldest_id(session) || + !__wt_txn_visible_all(session, mod->update_txn))) + continue; - /* - * Additional tests if eviction is likely to succeed. - * - * If eviction is stuck or we are helping with forced eviction, - * try anyway: maybe a transaction that was running last time - * we wrote the page has since rolled back, or we can help the - * checkpoint complete sooner. Additionally, being stuck will - * configure lookaside table writes in reconciliation, allowing - * us to evict pages we can't usually evict. - */ - if (!FLD_ISSET(cache->state, - WT_EVICT_PASS_AGGRESSIVE | WT_EVICT_PASS_WOULD_BLOCK)) { - /* - * If the page is clean but has modifications that - * appear too new to evict, skip it. - */ - if (!modified && mod != NULL && - !__wt_txn_visible_all(session, mod->rec_max_txn)) - continue; - } +fast: /* If the page can't be evicted, give up. */ + if (!__wt_page_can_evict(session, ref, NULL)) + continue; WT_ASSERT(session, evict->ref == NULL); - __evict_init_candidate(session, evict_queue, evict, ref); + if (!__evict_push_candidate(session, queue, evict, ref)) + continue; ++evict; if (WT_PAGE_IS_INTERNAL(page)) ++internal_pages; - WT_RET(__wt_verbose(session, WT_VERB_EVICTSERVER, - "select: %p, size %" PRIu64, page, page->memory_footprint)); + __wt_verbose(session, WT_VERB_EVICTSERVER, + "select: %p, size %" WT_SIZET_FMT, + (void *)page, page->memory_footprint); } WT_RET_NOTFOUND_OK(ret); @@ -1463,43 +1466,6 @@ fast: /* If the page can't be evicted, give up. */ return (0); } -/* - * __evict_check_entry_size -- - * Check if the size of an entry is too large for this thread to evict. - * We use this so that the server thread doesn't get stalled evicting - * a very large page. - */ -static bool -__evict_check_entry_size(WT_SESSION_IMPL *session, WT_EVICT_ENTRY *entry) -{ - WT_CACHE *cache; - WT_PAGE *page; - WT_REF *ref; - uint64_t max; - - cache = S2C(session)->cache; - - if (cache->pages_evict == 0) - return (true); - - max = (cache->bytes_evict / cache->pages_evict) * 4; - if ((ref = entry->ref) != NULL) { - if ((page = ref->page) == NULL) - return (true); - /* - * If this page is more than four times the average evicted page - * size then return false. Return true in all other cases. - * XXX Should we care here if the page is dirty? Probably... - */ - if (page->memory_footprint > max) { - WT_STAT_FAST_CONN_INCR( - session, cache_eviction_server_toobig); - return (false); - } - } - return (true); -} - /* * __evict_get_ref -- * Get a page for eviction. @@ -1509,72 +1475,124 @@ __evict_get_ref( WT_SESSION_IMPL *session, bool is_server, WT_BTREE **btreep, WT_REF **refp) { WT_CACHE *cache; + WT_DECL_RET; WT_EVICT_ENTRY *evict; - WT_EVICT_QUEUE *evict_queue; + WT_EVICT_QUEUE *other_queue, *queue, *urgent_queue; uint32_t candidates; + bool is_app, urgent_ok; cache = S2C(session)->cache; + is_app = !F_ISSET(session, WT_SESSION_INTERNAL); + urgent_ok = (!is_app && !is_server) || + !WT_EVICT_HAS_WORKERS(session) || + __wt_cache_aggressive(session); + urgent_queue = cache->evict_urgent_queue; *btreep = NULL; *refp = NULL; - /* - * Avoid the LRU lock if no pages are available. - */ WT_STAT_FAST_CONN_INCR(session, cache_eviction_get_ref); - if (cache->evict_current == NULL) { + + /* Avoid the LRU lock if no pages are available. */ + if (__evict_queue_empty(cache->evict_current_queue) && + __evict_queue_empty(cache->evict_other_queue) && + __evict_queue_empty(urgent_queue)) { WT_STAT_FAST_CONN_INCR(session, cache_eviction_get_ref_empty); return (WT_NOTFOUND); } - __wt_spin_lock(session, &cache->evict_queue_lock); + /* - * Verify there are still pages available. + * The server repopulates whenever the other queue is not full. + * + * Note that there are pathological cases where there are only enough + * eviction candidates in the cache to fill one queue. In that case, + * we will continually evict one page and attempt to refill the queues. + * Such cases are extremely rare in real applications. */ - if (cache->evict_current == NULL) { - __wt_spin_unlock(session, &cache->evict_queue_lock); - WT_STAT_FAST_CONN_INCR(session, cache_eviction_get_ref_empty2); - return (WT_NOTFOUND); - } + if (is_server && + (cache->evict_empty_score > WT_EVICT_SCORE_CUTOFF || + __evict_queue_empty(cache->evict_fill_queue))) { + do { + if ((!urgent_ok || + __evict_queue_empty(urgent_queue)) && + !__evict_queue_full(cache->evict_fill_queue)) + return (WT_NOTFOUND); + } while ((ret = __wt_spin_trylock( + session, &cache->evict_queue_lock)) == EBUSY); + + WT_RET(ret); + } else + __wt_spin_lock(session, &cache->evict_queue_lock); + /* - * We got the queue lock, which should be fast, and now we want to - * get the lock on the individual queue. We know that the shared - * queue fields cannot change now. + * Check if the current queue needs to change. + * The current queue could have changed while we waited for the lock. */ - evict_queue = cache->evict_current_queue; - for (;;) { - if (__wt_spin_trylock(session, &evict_queue->evict_lock) == 0) - break; - if (!F_ISSET(session, WT_SESSION_INTERNAL)) { - __wt_spin_unlock(session, &cache->evict_queue_lock); - return (WT_NOTFOUND); - } - __wt_yield(); + queue = cache->evict_current_queue; + other_queue = cache->evict_other_queue; + if (__evict_queue_empty(queue) && !__evict_queue_empty(other_queue)) { + cache->evict_current_queue = other_queue; + cache->evict_other_queue = queue; } + + /* Check the urgent queue first. */ + queue = urgent_ok && !__evict_queue_empty(urgent_queue) ? + urgent_queue : cache->evict_current_queue; + + __wt_spin_unlock(session, &cache->evict_queue_lock); + /* * Only evict half of the pages before looking for more. The remainder * are left to eviction workers (if configured), or application threads * if necessary. */ - candidates = evict_queue->evict_candidates; - if (is_server && candidates > 1) + candidates = queue->evict_candidates; + if (is_server && queue != urgent_queue && candidates > 1) candidates /= 2; + /* + * We got the queue lock, which should be fast, and chose a queue. + * Now we want to get the lock on the individual queue. + */ + for (;;) { + /* Verify there are still pages available. */ + if (__evict_queue_empty(queue) || (uint32_t) + (queue->evict_current - queue->evict_queue) >= candidates) { + WT_STAT_FAST_CONN_INCR( + session, cache_eviction_get_ref_empty2); + return (WT_NOTFOUND); + } + if (!is_server) + __wt_spin_lock(session, &queue->evict_lock); + else if (__wt_spin_trylock(session, &queue->evict_lock) != 0) + continue; + break; + } + /* Get the next page queued for eviction. */ - while ((evict = cache->evict_current) != NULL && - evict < evict_queue->evict_queue + candidates && - evict->ref != NULL) { + for (evict = queue->evict_current; + evict >= queue->evict_queue && + evict < queue->evict_queue + candidates; + ++evict) { + if (evict->ref == NULL) + continue; WT_ASSERT(session, evict->btree != NULL); + /* - * If the server is helping out and encounters an entry that - * is too large, it stops helping. Evicting a very large - * page in the server thread could stall eviction from finding - * new work. + * Evicting a dirty page in the server thread could stall + * during a write and prevent eviction from finding new work. + * + * However, we can't skip entries in the urgent queue or they + * may never be found again. + * + * Don't force application threads to evict dirty pages if they + * aren't stalled by the amount of dirty data in cache. */ - if (is_server && S2C(session)->evict_workers > 1 && - !__evict_check_entry_size(session, evict)) + if (!urgent_ok && (is_server || (is_app && + !F_ISSET(cache, WT_CACHE_EVICT_DIRTY_HARD))) && + __wt_page_is_modified(evict->ref->page)) { + --evict; break; - - /* Move to the next item. */ - ++cache->evict_current; + } /* * Lock the page while holding the eviction mutex to prevent @@ -1604,13 +1622,16 @@ __evict_get_ref( break; } - /* Clear the current pointer if there are no more candidates. */ - if (evict >= evict_queue->evict_queue + evict_queue->evict_candidates) - cache->evict_current = NULL; - __wt_spin_unlock(session, &evict_queue->evict_lock); - __wt_spin_unlock(session, &cache->evict_queue_lock); + /* Move to the next item. */ + if (evict != NULL && evict + 1 < + queue->evict_queue + queue->evict_candidates) + queue->evict_current = evict + 1; + else /* Clear the current pointer if there are no more candidates. */ + queue->evict_current = NULL; + + __wt_spin_unlock(session, &queue->evict_lock); - return ((*refp == NULL) ? WT_NOTFOUND : 0); + return (*refp == NULL ? WT_NOTFOUND : 0); } /* @@ -1633,16 +1654,14 @@ __evict_page(WT_SESSION_IMPL *session, bool is_server) * An internal session flags either the server itself or an eviction * worker thread. */ - if (F_ISSET(session, WT_SESSION_INTERNAL)) { - if (is_server) { - WT_STAT_FAST_CONN_INCR( - session, cache_eviction_server_evicting); - cache->server_evicts++; - } else { - WT_STAT_FAST_CONN_INCR( - session, cache_eviction_worker_evicting); - cache->worker_evicts++; - } + if (is_server) { + WT_STAT_FAST_CONN_INCR( + session, cache_eviction_server_evicting); + cache->server_evicts++; + } else if (F_ISSET(session, WT_SESSION_INTERNAL)) { + WT_STAT_FAST_CONN_INCR( + session, cache_eviction_worker_evicting); + cache->worker_evicts++; } else { if (__wt_page_is_modified(ref->page)) WT_STAT_FAST_CONN_INCR( @@ -1683,33 +1702,24 @@ __wt_cache_eviction_worker(WT_SESSION_IMPL *session, bool busy, u_int pct_full) WT_TXN_GLOBAL *txn_global; WT_TXN_STATE *txn_state; uint64_t init_evict_count, max_pages_evicted; - bool txn_busy; conn = S2C(session); cache = conn->cache; - - /* - * If the current transaction is keeping the oldest ID pinned, it is in - * the middle of an operation. This may prevent the oldest ID from - * moving forward, leading to deadlock, so only evict what we can. - * Otherwise, we are at a transaction boundary and we can work harder - * to make sure there is free space in the cache. - */ txn_global = &conn->txn_global; txn_state = WT_SESSION_TXN_STATE(session); - txn_busy = txn_state->id != WT_TXN_NONE || - session->nhazard > 0 || - (txn_state->snap_min != WT_TXN_NONE && - txn_global->current != txn_global->oldest_id); - if (txn_busy && pct_full < 100) + /* + * It is not safe to proceed if the eviction server threads aren't + * setup yet. + */ + if (!conn->evict_server_running) return (0); - if (busy) - txn_busy = true; + if (busy && pct_full < 100) + return (0); /* Wake the eviction server if we need to do work. */ - WT_RET(__wt_evict_server_wake(session)); + __wt_evict_server_wake(session); /* * If we're busy, either because of the transaction check we just did, @@ -1720,7 +1730,12 @@ __wt_cache_eviction_worker(WT_SESSION_IMPL *session, bool busy, u_int pct_full) init_evict_count = cache->pages_evict; for (;;) { - max_pages_evicted = txn_busy ? 5 : 20; + /* Check if we have become busy. */ + if (!busy && txn_state->snap_min != WT_TXN_NONE && + txn_global->current != txn_global->oldest_id) + busy = true; + + max_pages_evicted = busy ? 5 : 20; /* * A pathological case: if we're the oldest transaction in the @@ -1728,45 +1743,108 @@ __wt_cache_eviction_worker(WT_SESSION_IMPL *session, bool busy, u_int pct_full) * abort the transaction to give up all hazard pointers before * trying again. */ - if (F_ISSET(cache, WT_CACHE_STUCK) && - __wt_txn_am_oldest(session)) { - F_CLR(cache, WT_CACHE_STUCK); + if (__wt_cache_stuck(session) && __wt_txn_am_oldest(session)) { + --cache->evict_aggressive_score; WT_STAT_FAST_CONN_INCR(session, txn_fail_cache); return (WT_ROLLBACK); } /* See if eviction is still needed. */ - if (!__wt_eviction_needed(session, &pct_full) || + if (!__wt_eviction_needed(session, busy, &pct_full) || (pct_full < 100 && cache->pages_evict > init_evict_count + max_pages_evicted)) return (0); + /* + * Don't make application threads participate in scrubbing for + * checkpoints. Just throttle updates instead. + */ + if (busy && WT_EVICT_HAS_WORKERS(session) && + cache->eviction_scrub_limit > 0.0 && + !F_ISSET(cache, WT_CACHE_EVICT_CLEAN_HARD)) { + __wt_yield(); + continue; + } + /* Evict a page. */ switch (ret = __evict_page(session, false)) { case 0: - if (txn_busy) + if (busy) return (0); /* FALLTHROUGH */ case EBUSY: break; case WT_NOTFOUND: /* Allow the queue to re-populate before retrying. */ - WT_RET(__wt_cond_wait( - session, cache->evict_waiter_cond, 100000)); + __wt_cond_wait( + session, conn->evict_threads.wait_cond, 10000); cache->app_waits++; break; default: return (ret); } - - /* Check if we have become busy. */ - if (!txn_busy && txn_state->snap_min != WT_TXN_NONE && - txn_global->current != txn_global->oldest_id) - txn_busy = true; } /* NOTREACHED */ } +/* + * __wt_page_evict_urgent -- + * Set a page to be evicted as soon as possible. + */ +bool +__wt_page_evict_urgent(WT_SESSION_IMPL *session, WT_REF *ref) +{ + WT_CACHE *cache; + WT_EVICT_ENTRY *evict; + WT_EVICT_QUEUE *urgent_queue; + WT_PAGE *page; + bool queued; + + /* Root pages should never be evicted via LRU. */ + WT_ASSERT(session, !__wt_ref_is_root(ref)); + + page = ref->page; + if (F_ISSET_ATOMIC(page, WT_PAGE_EVICT_LRU) || + F_ISSET(S2BT(session), WT_BTREE_NO_EVICTION)) + return (false); + + /* Append to the urgent queue if we can. */ + cache = S2C(session)->cache; + urgent_queue = &cache->evict_queues[WT_EVICT_URGENT_QUEUE]; + queued = false; + + __wt_spin_lock(session, &cache->evict_queue_lock); + if (F_ISSET_ATOMIC(page, WT_PAGE_EVICT_LRU) || + F_ISSET(S2BT(session), WT_BTREE_NO_EVICTION)) + goto done; + + __wt_spin_lock(session, &urgent_queue->evict_lock); + if (__evict_queue_empty(urgent_queue)) { + urgent_queue->evict_current = urgent_queue->evict_queue; + urgent_queue->evict_candidates = 0; + } + evict = urgent_queue->evict_queue + urgent_queue->evict_candidates; + if (evict < urgent_queue->evict_queue + cache->evict_slots && + __evict_push_candidate(session, urgent_queue, evict, ref)) { + ++urgent_queue->evict_candidates; + queued = true; + } + __wt_spin_unlock(session, &urgent_queue->evict_lock); + +done: __wt_spin_unlock(session, &cache->evict_queue_lock); + if (queued) { + WT_STAT_FAST_CONN_INCR( + session, cache_eviction_pages_queued_urgent); + if (WT_EVICT_HAS_WORKERS(session)) + __wt_cond_signal(session, + S2C(session)->evict_threads.wait_cond); + else + __wt_evict_server_wake(session); + } + + return (queued); +} + /* * __wt_evict_priority_set -- * Set a tree's eviction priority. @@ -1801,13 +1879,15 @@ __wt_cache_dump(WT_SESSION_IMPL *session, const char *ofile) WT_DATA_HANDLE *dhandle, *saved_dhandle; WT_PAGE *page; WT_REF *next_walk; - uint64_t dirty_bytes, dirty_pages, intl_bytes, intl_pages; - uint64_t leaf_bytes, leaf_pages; - uint64_t max_dirty_bytes, max_intl_bytes, max_leaf_bytes, total_bytes; + uint64_t intl_bytes, intl_bytes_max, intl_dirty_bytes; + uint64_t intl_dirty_bytes_max, intl_dirty_pages, intl_pages; + uint64_t leaf_bytes, leaf_bytes_max, leaf_dirty_bytes; + uint64_t leaf_dirty_bytes_max, leaf_dirty_pages, leaf_pages; + uint64_t total_bytes, total_dirty_bytes; size_t size; conn = S2C(session); - total_bytes = 0; + total_bytes = total_dirty_bytes = 0; if (ofile == NULL) fp = stderr; @@ -1823,9 +1903,10 @@ __wt_cache_dump(WT_SESSION_IMPL *session, const char *ofile) !F_ISSET(dhandle, WT_DHANDLE_OPEN)) continue; - dirty_bytes = dirty_pages = intl_bytes = intl_pages = 0; - leaf_bytes = leaf_pages = 0; - max_dirty_bytes = max_intl_bytes = max_leaf_bytes = 0; + intl_bytes = intl_bytes_max = intl_dirty_bytes = 0; + intl_dirty_bytes_max = intl_dirty_pages = intl_pages = 0; + leaf_bytes = leaf_bytes_max = leaf_dirty_bytes = 0; + leaf_dirty_bytes_max = leaf_dirty_pages = leaf_pages = 0; next_walk = NULL; session->dhandle = dhandle; @@ -1838,17 +1919,23 @@ __wt_cache_dump(WT_SESSION_IMPL *session, const char *ofile) if (WT_PAGE_IS_INTERNAL(page)) { ++intl_pages; intl_bytes += size; - max_intl_bytes = WT_MAX(max_intl_bytes, size); + intl_bytes_max = WT_MAX(intl_bytes_max, size); + if (__wt_page_is_modified(page)) { + ++intl_dirty_pages; + intl_dirty_bytes += size; + intl_dirty_bytes_max = + WT_MAX(intl_dirty_bytes_max, size); + } } else { ++leaf_pages; leaf_bytes += size; - max_leaf_bytes = WT_MAX(max_leaf_bytes, size); - } - if (__wt_page_is_modified(page)) { - ++dirty_pages; - dirty_bytes += size; - max_dirty_bytes = - WT_MAX(max_dirty_bytes, size); + leaf_bytes_max = WT_MAX(leaf_bytes_max, size); + if (__wt_page_is_modified(page)) { + ++leaf_dirty_pages; + leaf_dirty_bytes += size; + leaf_dirty_bytes_max = + WT_MAX(leaf_dirty_bytes_max, size); + } } } session->dhandle = NULL; @@ -1860,21 +1947,41 @@ __wt_cache_dump(WT_SESSION_IMPL *session, const char *ofile) dhandle->name, dhandle->checkpoint); if (intl_pages != 0) (void)fprintf(fp, - "\t" "internal pages: %" PRIu64 " pages, %" PRIu64 - " max, %" PRIu64 "MB total\n", - intl_pages, max_intl_bytes, intl_bytes >> 20); + "\t" "internal: " + "%" PRIu64 " pages, " + "%" PRIu64 "MB, " + "%" PRIu64 "/%" PRIu64 " clean/dirty pages, " + "%" PRIu64 "/%" PRIu64 " clean/dirty MB, " + "%" PRIu64 "MB max page, " + "%" PRIu64 "MB max dirty page\n", + intl_pages, + intl_bytes >> 20, + intl_pages - intl_dirty_pages, + intl_dirty_pages, + (intl_bytes - intl_dirty_bytes) >> 20, + intl_dirty_bytes >> 20, + intl_bytes_max >> 20, + intl_dirty_bytes_max >> 20); if (leaf_pages != 0) (void)fprintf(fp, - "\t" "leaf pages: %" PRIu64 " pages, %" PRIu64 - " max, %" PRIu64 "MB total\n", - leaf_pages, max_leaf_bytes, leaf_bytes >> 20); - if (dirty_pages != 0) - (void)fprintf(fp, - "\t" "dirty pages: %" PRIu64 " pages, %" PRIu64 - " max, %" PRIu64 "MB total\n", - dirty_pages, max_dirty_bytes, dirty_bytes >> 20); + "\t" "leaf: " + "%" PRIu64 " pages, " + "%" PRIu64 "MB, " + "%" PRIu64 "/%" PRIu64 " clean/dirty pages, " + "%" PRIu64 "/%" PRIu64 " clean/dirty MB, " + "%" PRIu64 "MB max page, " + "%" PRIu64 "MB max dirty page\n", + leaf_pages, + leaf_bytes >> 20, + leaf_pages - leaf_dirty_pages, + leaf_dirty_pages, + (leaf_bytes - leaf_dirty_bytes) >> 20, + leaf_dirty_bytes >> 20, + leaf_bytes_max >> 20, + leaf_dirty_bytes_max >> 20); total_bytes += intl_bytes + leaf_bytes; + total_dirty_bytes += intl_dirty_bytes + leaf_dirty_bytes; } session->dhandle = saved_dhandle; @@ -1882,14 +1989,16 @@ __wt_cache_dump(WT_SESSION_IMPL *session, const char *ofile) * Apply the overhead percentage so our total bytes are comparable with * the tracked value. */ - if (conn->cache->overhead_pct != 0) - total_bytes += - (total_bytes * (uint64_t)conn->cache->overhead_pct) / 100; + total_bytes = __wt_cache_bytes_plus_overhead(conn->cache, total_bytes); + (void)fprintf(fp, - "cache dump: total found = %" PRIu64 - "MB vs tracked inuse %" PRIu64 "MB\n", - total_bytes >> 20, __wt_cache_bytes_inuse(conn->cache) >> 20); + "cache dump: " + "total found = %" PRIu64 "MB vs tracked inuse %" PRIu64 "MB\n" + "total dirty bytes = %" PRIu64 "MB\n", + total_bytes >> 20, __wt_cache_bytes_inuse(conn->cache) >> 20, + total_dirty_bytes >> 20); (void)fprintf(fp, "==========\n"); + if (ofile != NULL && fclose(fp) != 0) return (EIO); return (0); diff --git a/src/third_party/wiredtiger/src/evict/evict_page.c b/src/third_party/wiredtiger/src/evict/evict_page.c index 0d26c1a2a84..5ddf787c1f5 100644 --- a/src/third_party/wiredtiger/src/evict/evict_page.c +++ b/src/third_party/wiredtiger/src/evict/evict_page.c @@ -10,7 +10,7 @@ static int __evict_page_clean_update(WT_SESSION_IMPL *, WT_REF *, bool); static int __evict_page_dirty_update(WT_SESSION_IMPL *, WT_REF *, bool); -static int __evict_review(WT_SESSION_IMPL *, WT_REF *, bool *, bool); +static int __evict_review(WT_SESSION_IMPL *, WT_REF *, uint32_t *, bool); /* * __evict_exclusive_clear -- @@ -31,20 +31,78 @@ __evict_exclusive_clear(WT_SESSION_IMPL *session, WT_REF *ref) static inline int __evict_exclusive(WT_SESSION_IMPL *session, WT_REF *ref) { + int loops; + WT_ASSERT(session, ref->state == WT_REF_LOCKED); /* * Check for a hazard pointer indicating another thread is using the * page, meaning the page cannot be evicted. */ - if (__wt_page_hazard_check(session, ref->page) == NULL) - return (0); + for (loops = 0; loops < 10; loops++) { + if (__wt_page_hazard_check(session, ref->page) == NULL) + return (0); + if (ref->page->read_gen != WT_READGEN_OLDEST && + ref->page->memory_footprint < + S2BT(session)->split_deepen_min_child) + break; + __wt_sleep(0, WT_THOUSAND); + } WT_STAT_FAST_DATA_INCR(session, cache_eviction_hazard); WT_STAT_FAST_CONN_INCR(session, cache_eviction_hazard); return (EBUSY); } +/* + * __wt_page_release_evict -- + * Release a reference to a page, and attempt to immediately evict it. + */ +int +__wt_page_release_evict(WT_SESSION_IMPL *session, WT_REF *ref) +{ + WT_BTREE *btree; + WT_DECL_RET; + WT_PAGE *page; + bool locked, too_big; + + btree = S2BT(session); + page = ref->page; + + /* + * Take some care with order of operations: if we release the hazard + * reference without first locking the page, it could be evicted in + * between. + */ + locked = __wt_atomic_casv32(&ref->state, WT_REF_MEM, WT_REF_LOCKED); + if ((ret = __wt_hazard_clear(session, page)) != 0 || !locked) { + if (locked) + ref->state = WT_REF_MEM; + return (ret == 0 ? EBUSY : ret); + } + + (void)__wt_atomic_addv32(&btree->evict_busy, 1); + + too_big = page->memory_footprint >= btree->splitmempage; + if ((ret = __wt_evict(session, ref, false)) == 0) { + if (too_big) + WT_STAT_FAST_CONN_INCR(session, cache_eviction_force); + else + /* + * If the page isn't too big, we are evicting it because + * it had a chain of deleted entries that make traversal + * expensive. + */ + WT_STAT_FAST_CONN_INCR( + session, cache_eviction_force_delete); + } else + WT_STAT_FAST_CONN_INCR(session, cache_eviction_force_fail); + + (void)__wt_atomic_subv32(&btree->evict_busy, 1); + + return (ret); +} + /* * __wt_evict -- * Evict a page. @@ -56,7 +114,8 @@ __wt_evict(WT_SESSION_IMPL *session, WT_REF *ref, bool closing) WT_DECL_RET; WT_PAGE *page; WT_PAGE_MODIFY *mod; - bool clean_page, forced_eviction, inmem_split, tree_dead; + uint32_t flags; + bool clean_page, tree_dead; conn = S2C(session); @@ -64,12 +123,10 @@ __wt_evict(WT_SESSION_IMPL *session, WT_REF *ref, bool closing) WT_ASSERT(session, !WT_SESSION_IS_CHECKPOINT(session)); page = ref->page; - forced_eviction = page->read_gen == WT_READGEN_OLDEST; - inmem_split = false; tree_dead = F_ISSET(session->dhandle, WT_DHANDLE_DEAD); - WT_RET(__wt_verbose(session, WT_VERB_EVICT, - "page %p (%s)", page, __wt_page_type_string(page->type))); + __wt_verbose(session, WT_VERB_EVICT, + "page %p (%s)", (void *)page, __wt_page_type_string(page->type)); /* * Get exclusive access to the page and review it for conditions that @@ -78,20 +135,14 @@ __wt_evict(WT_SESSION_IMPL *session, WT_REF *ref, bool closing) * to make this check for clean pages, too: while unlikely eviction * would choose an internal page with children, it's not disallowed. */ - WT_ERR(__evict_review(session, ref, &inmem_split, closing)); + WT_ERR(__evict_review(session, ref, &flags, closing)); /* * If there was an in-memory split, the tree has been left in the state * we want: there is nothing more to do. */ - if (inmem_split) - goto done; - - /* - * Update the page's modification reference, reconciliation might have - * changed it. - */ - mod = page->modify; + if (LF_ISSET(WT_EVICT_INMEM_SPLIT)) + return (0); /* Count evictions of internal pages during normal operation. */ if (!closing && WT_PAGE_IS_INTERNAL(page)) { @@ -108,12 +159,13 @@ __wt_evict(WT_SESSION_IMPL *session, WT_REF *ref, bool closing) conn->cache->evict_max_page_size = page->memory_footprint; /* Figure out whether reconciliation was done on the page */ + mod = page->modify; clean_page = mod == NULL || mod->rec_result == 0; /* Update the reference and discard the page. */ if (__wt_ref_is_root(ref)) __wt_ref_out(session, ref); - else if (tree_dead || (clean_page && !F_ISSET(conn, WT_CONN_IN_MEMORY))) + else if ((clean_page && !LF_ISSET(WT_EVICT_IN_MEMORY)) || tree_dead) /* * Pages that belong to dead trees never write back to disk * and can't support page splits. @@ -139,26 +191,9 @@ err: if (!closing) WT_STAT_FAST_DATA_INCR(session, cache_eviction_fail); } -done: if (((inmem_split && ret == 0) || (forced_eviction && ret == EBUSY)) && - !F_ISSET(conn->cache, WT_CACHE_WOULD_BLOCK)) { - F_SET(conn->cache, WT_CACHE_WOULD_BLOCK); - WT_TRET(__wt_evict_server_wake(session)); - } - - /* - * When application threads perform eviction, we don't want to cache - * reconciliation structures. - */ - if (!F_ISSET(session, WT_SESSION_INTERNAL)) { - if (session->block_manager_cleanup != NULL) - WT_TRET(session->block_manager_cleanup(session)); - - if (session->reconcile_cleanup != NULL) - WT_TRET(session->reconcile_cleanup(session)); - } - return (ret); } + /* * __evict_delete_ref -- * Mark a page reference deleted and check if the parent can reverse @@ -221,13 +256,6 @@ __evict_page_clean_update(WT_SESSION_IMPL *session, WT_REF *ref, bool closing) { WT_DECL_RET; - /* - * If doing normal system eviction, but only in the service of reducing - * the number of dirty pages, leave the clean page in cache. - */ - if (!closing && __wt_eviction_dirty_target(session)) - return (EBUSY); - /* * Discard the page and update the reference structure; if the page has * an address, it's a disk page; if it has no address, it's a deleted @@ -254,6 +282,7 @@ __evict_page_dirty_update(WT_SESSION_IMPL *session, WT_REF *ref, bool closing) WT_ADDR *addr; WT_DECL_RET; WT_PAGE_MODIFY *mod; + WT_MULTI multi; mod = ref->page->modify; @@ -296,23 +325,14 @@ __evict_page_dirty_update(WT_SESSION_IMPL *session, WT_REF *ref, bool closing) * write. Take advantage of the fact we have exclusive access * to the page and rewrite it in memory. */ - if (mod->mod_multi_entries == 1) - WT_RET(__wt_split_rewrite(session, ref)); - else + if (mod->mod_multi_entries == 1) { + WT_ASSERT(session, closing == false); + WT_RET(__wt_split_rewrite( + session, ref, &mod->mod_multi[0])); + } else WT_RET(__wt_split_multi(session, ref, closing)); break; case WT_PM_REC_REPLACE: /* 1-for-1 page swap */ - /* - * If doing normal system eviction, but only in the service of - * reducing the number of dirty pages, leave the clean page in - * cache. Only do this when replacing a page with another one, - * because when a page splits into multiple pages, we want to - * push it out of cache (and read it back in, when needed), we - * would rather have more, smaller pages than fewer large pages. - */ - if (!closing && __wt_eviction_dirty_target(session)) - return (EBUSY); - /* * Update the parent to reference the replacement page. * @@ -323,10 +343,26 @@ __evict_page_dirty_update(WT_SESSION_IMPL *session, WT_REF *ref, bool closing) *addr = mod->mod_replace; mod->mod_replace.addr = NULL; mod->mod_replace.size = 0; - - __wt_ref_out(session, ref); ref->addr = addr; - WT_PUBLISH(ref->state, WT_REF_DISK); + + /* + * Eviction wants to keep this page if we have a disk image, + * re-instantiate the page in memory, else discard the page. + */ + if (mod->mod_disk_image == NULL) { + __wt_ref_out(session, ref); + WT_PUBLISH(ref->state, WT_REF_DISK); + } else { + /* + * The split code works with WT_MULTI structures, build + * one for the disk image. + */ + memset(&multi, 0, sizeof(multi)); + multi.disk_image = mod->mod_disk_image; + + WT_RET(__wt_split_rewrite(session, ref, &multi)); + } + break; WT_ILLEGAL_VALUE(session); } @@ -363,13 +399,17 @@ __evict_child_check(WT_SESSION_IMPL *session, WT_REF *parent) */ static int __evict_review( - WT_SESSION_IMPL *session, WT_REF *ref, bool *inmem_splitp, bool closing) + WT_SESSION_IMPL *session, WT_REF *ref, uint32_t *flagsp, bool closing) { + WT_CACHE *cache; WT_DECL_RET; WT_PAGE *page; uint32_t flags; bool modified; + flags = WT_EVICTING; + *flagsp = flags; + /* * Get exclusive access to the page if our caller doesn't have the tree * locked down. @@ -435,8 +475,9 @@ __evict_review( WT_RET(__wt_txn_update_oldest( session, WT_TXN_OLDEST_STRICT)); - if (!__wt_page_can_evict(session, ref, inmem_splitp)) + if (!__wt_page_can_evict(session, ref, flagsp)) return (EBUSY); + flags = *flagsp; /* * Check for an append-only workload needing an in-memory @@ -445,8 +486,12 @@ __evict_review( * the page stays in memory and the tree is left in the desired * state: avoid the usual cleanup. */ - if (*inmem_splitp) + if (LF_ISSET(WT_EVICT_INMEM_SPLIT)) return (__wt_split_insert(session, ref)); + + /* We are done if reconciliation is disabled. */ + if (F_ISSET(S2BT(session), WT_BTREE_NO_RECONCILE)) + return (EBUSY); } /* If the page is clean, we're done and we can evict. */ @@ -459,10 +504,15 @@ __evict_review( * If we have an exclusive lock (we're discarding the tree), assert * there are no updates we cannot read. * - * Otherwise, if the page we're evicting is a leaf page marked for - * forced eviction, set the update-restore flag, so reconciliation will - * write blocks it can write and create a list of skipped updates for - * blocks it cannot write. This is how forced eviction of active, huge + * Don't set any other flags for internal pages: they don't have update + * lists to be saved and restored, nor can we re-create them in memory. + * + * For leaf pages: + * + * If an in-memory configuration or the page is being forcibly evicted, + * set the update-restore flag, so reconciliation will write blocks it + * can write and create a list of skipped updates for blocks it cannot + * write, along with disk images. This is how eviction of active, huge * pages works: we take a big page and reconcile it into blocks, some of * which we write and discard, the rest of which we re-create as smaller * in-memory pages, (restoring the updates that stopped us from writing @@ -473,32 +523,45 @@ __evict_review( * allowing the eviction of pages we'd otherwise have to retain in cache * to support older readers. * - * Don't set the update-restore or lookaside table flags for internal - * pages, they don't have update lists that can be saved and restored. + * Finally, if we don't need to do eviction at the moment, create disk + * images of split pages in order to re-instantiate them. */ - flags = WT_EVICTING; + cache = S2C(session)->cache; if (closing) LF_SET(WT_VISIBILITY_ERR); else if (!WT_PAGE_IS_INTERNAL(page)) { if (F_ISSET(S2C(session), WT_CONN_IN_MEMORY)) - LF_SET(WT_EVICT_IN_MEMORY | WT_EVICT_UPDATE_RESTORE); - else if (page->read_gen == WT_READGEN_OLDEST) - LF_SET(WT_EVICT_UPDATE_RESTORE); - else if (F_ISSET(S2C(session)->cache, WT_CACHE_STUCK)) + LF_SET(WT_EVICT_IN_MEMORY | + WT_EVICT_SCRUB | WT_EVICT_UPDATE_RESTORE); + else if (__wt_cache_stuck(session)) LF_SET(WT_EVICT_LOOKASIDE); + else if (!__wt_txn_visible_all( + session, page->modify->update_txn) || + page->read_gen == WT_READGEN_OLDEST || + page->memory_footprint >= S2BT(session)->splitmempage) + LF_SET(WT_EVICT_UPDATE_RESTORE); + + /* + * If we aren't trying to free space in the cache, scrub the + * page and keep it around. + */ + if (!LF_ISSET(WT_EVICT_LOOKASIDE) && + F_ISSET(cache, WT_CACHE_EVICT_SCRUB)) + LF_SET(WT_EVICT_SCRUB); } + *flagsp = flags; WT_RET(__wt_reconcile(session, ref, NULL, flags)); /* * Success: assert the page is clean or reconciliation was configured - * for an update/restore split. If the page is clean, assert that - * reconciliation was configured for a lookaside table, or it's not a - * durable object (currently the lookaside table), or all page updates - * were globally visible. + * for update/restore. If the page is clean, assert that reconciliation + * was configured for a lookaside table, or it's not a durable object + * (currently the lookaside table), or all page updates were globally + * visible. */ WT_ASSERT(session, - LF_ISSET(WT_EVICT_UPDATE_RESTORE) || !__wt_page_is_modified(page)); + !__wt_page_is_modified(page) || LF_ISSET(WT_EVICT_UPDATE_RESTORE)); WT_ASSERT(session, __wt_page_is_modified(page) || LF_ISSET(WT_EVICT_LOOKASIDE) || diff --git a/src/third_party/wiredtiger/src/include/api.h b/src/third_party/wiredtiger/src/include/api.h index 50b2eab83b8..e1b2f8edaf3 100644 --- a/src/third_party/wiredtiger/src/include/api.h +++ b/src/third_party/wiredtiger/src/include/api.h @@ -17,7 +17,7 @@ #define API_CALL_NOCONF(s, h, n, cur, dh) do { \ API_SESSION_INIT(s, h, n, cur, dh); \ WT_ERR(WT_SESSION_CHECK_PANIC(s)); \ - WT_ERR(__wt_verbose((s), WT_VERB_API, "CALL: " #h ":" #n)) + __wt_verbose((s), WT_VERB_API, "CALL: " #h ":" #n) #define API_CALL(s, h, n, cur, dh, config, cfg) do { \ const char *cfg[] = \ @@ -27,7 +27,7 @@ if ((config) != NULL) \ WT_ERR(__wt_config_check((s), \ WT_CONFIG_REF(session, h##_##n), (config), 0)); \ - WT_ERR(__wt_verbose((s), WT_VERB_API, "CALL: " #h ":" #n)) + __wt_verbose((s), WT_VERB_API, "CALL: " #h ":" #n) #define API_END(s, ret) \ if ((s) != NULL) { \ @@ -66,6 +66,8 @@ else if (ret == 0 && !F_ISSET(&(s)->txn, WT_TXN_ERROR)) \ ret = __wt_txn_commit((s), NULL); \ else { \ + if (retry) \ + WT_TRET(__wt_session_copy_values(s)); \ WT_TRET(__wt_txn_rollback((s), NULL)); \ if ((ret == 0 || ret == WT_ROLLBACK) && \ (retry)) { \ diff --git a/src/third_party/wiredtiger/src/include/block.h b/src/third_party/wiredtiger/src/include/block.h index a8080c1651c..0cf76e34367 100644 --- a/src/third_party/wiredtiger/src/include/block.h +++ b/src/third_party/wiredtiger/src/include/block.h @@ -52,7 +52,8 @@ struct __wt_extlist { uint32_t entries; /* Entry count */ wt_off_t offset; /* Written extent offset */ - uint32_t cksum, size; /* Written extent cksum, size */ + uint32_t checksum; /* Written extent checksum */ + uint32_t size; /* Written extent size */ bool track_size; /* Maintain per-size skiplist */ @@ -128,7 +129,7 @@ struct __wt_block_ckpt { uint8_t version; /* Version */ wt_off_t root_offset; /* The root */ - uint32_t root_cksum, root_size; + uint32_t root_checksum, root_size; WT_EXTLIST alloc; /* Extents allocated */ WT_EXTLIST avail; /* Extents available */ @@ -192,7 +193,7 @@ struct __wt_bm { int (*verify_start) (WT_BM *, WT_SESSION_IMPL *, WT_CKPT *, const char *[]); int (*write) (WT_BM *, - WT_SESSION_IMPL *, WT_ITEM *, uint8_t *, size_t *, bool); + WT_SESSION_IMPL *, WT_ITEM *, uint8_t *, size_t *, bool, bool); int (*write_size)(WT_BM *, WT_SESSION_IMPL *, size_t *); WT_BLOCK *block; /* Underlying file */ @@ -282,7 +283,7 @@ struct __wt_block_desc { #define WT_BLOCK_MINOR_VERSION 0 uint16_t minorv; /* 06-07: Minor version */ - uint32_t cksum; /* 08-11: Description block checksum */ + uint32_t checksum; /* 08-11: Description block checksum */ uint32_t unused; /* 12-15: Padding */ }; @@ -305,7 +306,7 @@ __wt_block_desc_byteswap(WT_BLOCK_DESC *desc) desc->magic = __wt_bswap32(desc->magic); desc->majorv = __wt_bswap16(desc->majorv); desc->minorv = __wt_bswap16(desc->minorv); - desc->cksum = __wt_bswap32(desc->cksum); + desc->checksum = __wt_bswap32(desc->checksum); #else WT_UNUSED(desc); #endif @@ -335,7 +336,7 @@ struct __wt_block_header { * stored in the disk header. This is for salvage, so salvage knows it * has found a page that may be useful. */ - uint32_t cksum; /* 04-07: checksum */ + uint32_t checksum; /* 04-07: checksum */ #define WT_BLOCK_DATA_CKSUM 0x01 /* Block data is part of the checksum */ uint8_t flags; /* 08: flags */ @@ -364,7 +365,7 @@ __wt_block_header_byteswap_copy(WT_BLOCK_HEADER *from, WT_BLOCK_HEADER *to) *to = *from; #ifdef WORDS_BIGENDIAN to->disk_size = __wt_bswap32(from->disk_size); - to->cksum = __wt_bswap32(from->cksum); + to->checksum = __wt_bswap32(from->checksum); #endif } diff --git a/src/third_party/wiredtiger/src/include/btmem.h b/src/third_party/wiredtiger/src/include/btmem.h index 9700b6f4761..b4ca937e7ed 100644 --- a/src/third_party/wiredtiger/src/include/btmem.h +++ b/src/third_party/wiredtiger/src/include/btmem.h @@ -218,6 +218,14 @@ struct __wt_page_modify { /* The first unwritten transaction ID (approximate). */ uint64_t first_dirty_txn; + /* The transaction state last time eviction was attempted. */ + uint64_t last_eviction_id; + +#ifdef HAVE_DIAGNOSTIC + /* Check that transaction time moves forward. */ + uint64_t last_oldest_id; +#endif + /* Avoid checking for obsolete updates during checkpoints. */ uint64_t obsolete_check_txn; @@ -227,9 +235,6 @@ struct __wt_page_modify { /* The largest update transaction ID (approximate). */ uint64_t update_txn; - /* Check that transaction time moves forward. */ - uint64_t last_oldest_id; - /* Dirty bytes added to the cache. */ size_t bytes_dirty; @@ -250,9 +255,19 @@ struct __wt_page_modify { * a replace address and multiple replacement blocks. */ union { - WT_ADDR replace; /* Single, written replacement block */ + struct { /* Single, written replacement block */ + WT_ADDR replace; + + /* + * A disk image that may or may not have been written, used to + * re-instantiate the page in memory. + */ + void *disk_image; + } r; #undef mod_replace -#define mod_replace u1.replace +#define mod_replace u1.r.replace +#undef mod_disk_image +#define mod_disk_image u1.r.disk_image struct { /* Multiple replacement blocks */ struct __wt_multi { @@ -266,14 +281,19 @@ struct __wt_page_modify { } key; /* - * Eviction, but the block wasn't written: either an in-memory - * configuration or unresolved updates prevented the write. - * There may be a list of unresolved updates, there's always an - * associated disk image. + * A disk image that may or may not have been written, used to + * re-instantiate the page in memory. + */ + void *disk_image; + + /* + * List of unresolved updates. Updates are either a WT_INSERT + * or a row-store leaf page entry; when creating lookaside + * records, there is an additional value, the committed item's + * transaction ID. * - * Saved updates are either a WT_INSERT, or a row-store leaf - * page entry; in the case of creating lookaside records, there - * is an additional value, the committed item's transaction ID. + * If there are unresolved updates, the block wasn't written and + * there will always be a disk image. */ struct __wt_save_upd { WT_INSERT *ins; @@ -281,10 +301,9 @@ struct __wt_page_modify { uint64_t onpage_txn; } *supd; uint32_t supd_entries; - void *disk_image; /* - * Block was written: address, size and checksum. + * Disk image was written: address, size and checksum. * On subsequent reconciliations of this page, we avoid writing * the block if it's unchanged by comparing size and checksum; * the reuse flag is set when the block is unchanged and we're @@ -292,7 +311,7 @@ struct __wt_page_modify { */ WT_ADDR addr; uint32_t size; - uint32_t cksum; + uint32_t checksum; } *multi; uint32_t multi_entries; /* Multiple blocks element count */ } m; @@ -570,9 +589,10 @@ struct __wt_page { /* * Used to protect and co-ordinate splits for internal pages and - * reconciliation for all pages. + * reconciliation for all pages. Only used to co-ordinate among the + * uncommon cases that require exclusive access to a page. */ - WT_FAIR_LOCK page_lock; + WT_RWLOCK page_lock; /* * The page's read generation acts as an LRU value for each page in the diff --git a/src/third_party/wiredtiger/src/include/btree.h b/src/third_party/wiredtiger/src/include/btree.h index fd921677751..f1365c6c933 100644 --- a/src/third_party/wiredtiger/src/include/btree.h +++ b/src/third_party/wiredtiger/src/include/btree.h @@ -126,12 +126,17 @@ struct __wt_btree { u_int block_header; /* WT_PAGE_HEADER_BYTE_SIZE */ uint64_t checkpoint_gen; /* Checkpoint generation */ + bool include_checkpoint_txn;/* ID checks include checkpoint */ uint64_t rec_max_txn; /* Maximum txn seen (clean trees) */ uint64_t write_gen; /* Write generation */ + uint64_t bytes_inmem; /* Cache bytes in memory. */ + uint64_t bytes_dirty_leaf; /* Bytes in dirty leaf pages. */ + WT_REF *evict_ref; /* Eviction thread's location */ uint64_t evict_priority; /* Relative priority of cached pages */ u_int evict_walk_period; /* Skip this many LRU walks */ + u_int evict_walk_saved; /* Saved walk skips for checkpoints */ u_int evict_walk_skips; /* Number of walks skipped */ u_int evict_disabled; /* Eviction disabled count */ volatile uint32_t evict_busy; /* Count of threads in eviction */ @@ -154,11 +159,12 @@ struct __wt_btree { #define WT_BTREE_NO_CHECKPOINT 0x00800 /* Disable checkpoints */ #define WT_BTREE_NO_EVICTION 0x01000 /* Disable eviction */ #define WT_BTREE_NO_LOGGING 0x02000 /* Disable logging */ -#define WT_BTREE_REBALANCE 0x04000 /* Handle is for rebalance */ -#define WT_BTREE_SALVAGE 0x08000 /* Handle is for salvage */ -#define WT_BTREE_SKIP_CKPT 0x10000 /* Handle skipped checkpoint */ -#define WT_BTREE_UPGRADE 0x20000 /* Handle is for upgrade */ -#define WT_BTREE_VERIFY 0x40000 /* Handle is for verify */ +#define WT_BTREE_NO_RECONCILE 0x04000 /* Allow splits, even with no evict */ +#define WT_BTREE_REBALANCE 0x08000 /* Handle is for rebalance */ +#define WT_BTREE_SALVAGE 0x10000 /* Handle is for salvage */ +#define WT_BTREE_SKIP_CKPT 0x20000 /* Handle skipped checkpoint */ +#define WT_BTREE_UPGRADE 0x40000 /* Handle is for upgrade */ +#define WT_BTREE_VERIFY 0x80000 /* Handle is for verify */ uint32_t flags; }; diff --git a/src/third_party/wiredtiger/src/include/btree.i b/src/third_party/wiredtiger/src/include/btree.i index e0102a11511..c07966a4453 100644 --- a/src/third_party/wiredtiger/src/include/btree.i +++ b/src/third_party/wiredtiger/src/include/btree.i @@ -54,6 +54,38 @@ __wt_btree_block_free( return (bm->free(bm, session, addr, addr_size)); } +/* + * __wt_btree_bytes_inuse -- + * Return the number of bytes in use. + */ +static inline uint64_t +__wt_btree_bytes_inuse(WT_SESSION_IMPL *session) +{ + WT_BTREE *btree; + WT_CACHE *cache; + + btree = S2BT(session); + cache = S2C(session)->cache; + + return (__wt_cache_bytes_plus_overhead(cache, btree->bytes_inmem)); +} + +/* + * __wt_btree_dirty_leaf_inuse -- + * Return the number of bytes in use by dirty leaf pages. + */ +static inline uint64_t +__wt_btree_dirty_leaf_inuse(WT_SESSION_IMPL *session) +{ + WT_BTREE *btree; + WT_CACHE *cache; + + btree = S2BT(session); + cache = S2C(session)->cache; + + return (__wt_cache_bytes_plus_overhead(cache, btree->bytes_dirty_leaf)); +} + /* * __wt_cache_page_inmem_incr -- * Increment a page's memory footprint in the cache. @@ -61,22 +93,28 @@ __wt_btree_block_free( static inline void __wt_cache_page_inmem_incr(WT_SESSION_IMPL *session, WT_PAGE *page, size_t size) { + WT_BTREE *btree; WT_CACHE *cache; WT_ASSERT(session, size < WT_EXABYTE); - + btree = S2BT(session); cache = S2C(session)->cache; + + (void)__wt_atomic_add64(&btree->bytes_inmem, size); (void)__wt_atomic_add64(&cache->bytes_inmem, size); (void)__wt_atomic_addsize(&page->memory_footprint, size); if (__wt_page_is_modified(page)) { - (void)__wt_atomic_add64(&cache->bytes_dirty, size); (void)__wt_atomic_addsize(&page->modify->bytes_dirty, size); + if (WT_PAGE_IS_INTERNAL(page)) + (void)__wt_atomic_add64(&cache->bytes_dirty_intl, size); + else { + (void)__wt_atomic_add64(&cache->bytes_dirty_leaf, size); + (void)__wt_atomic_add64(&btree->bytes_dirty_leaf, size); + } } - /* Track internal and overflow size in cache. */ + /* Track internal size in cache. */ if (WT_PAGE_IS_INTERNAL(page)) (void)__wt_atomic_add64(&cache->bytes_internal, size); - else if (page->type == WT_PAGE_OVFL) - (void)__wt_atomic_add64(&cache->bytes_overflow, size); } /* @@ -135,6 +173,22 @@ __wt_cache_decr_check_uint64( #endif } +/* + * __wt_cache_decr_zero_uint64 -- + * Decrement a uint64_t cache value and zero it on underflow. + */ +static inline void +__wt_cache_decr_zero_uint64( + WT_SESSION_IMPL *session, uint64_t *vp, size_t v, const char *fld) +{ + if (__wt_atomic_sub64(vp, v) < WT_EXABYTE) + return; + + __wt_errx( + session, "%s went negative: decrementing %" WT_SIZET_FMT, fld, v); + *vp = 0; +} + /* * __wt_cache_page_byte_dirty_decr -- * Decrement the page's dirty byte count, guarding from underflow. @@ -143,11 +197,14 @@ static inline void __wt_cache_page_byte_dirty_decr( WT_SESSION_IMPL *session, WT_PAGE *page, size_t size) { + WT_BTREE *btree; WT_CACHE *cache; size_t decr, orig; int i; + btree = S2BT(session); cache = S2C(session)->cache; + decr = 0; /* [-Wconditional-uninitialized] */ /* * We don't have exclusive access and there are ways of decrementing the @@ -174,11 +231,21 @@ __wt_cache_page_byte_dirty_decr( orig = page->modify->bytes_dirty; decr = WT_MIN(size, orig); if (__wt_atomic_cassize( - &page->modify->bytes_dirty, orig, orig - decr)) { - __wt_cache_decr_check_uint64(session, - &cache->bytes_dirty, decr, "WT_CACHE.bytes_dirty"); + &page->modify->bytes_dirty, orig, orig - decr)) break; - } + } + + if (i == 5) + return; + + if (WT_PAGE_IS_INTERNAL(page)) + __wt_cache_decr_check_uint64(session, &cache->bytes_dirty_intl, + decr, "WT_CACHE.bytes_dirty_intl"); + else { + __wt_cache_decr_check_uint64(session, &btree->bytes_dirty_leaf, + decr, "WT_BTREE.bytes_dirty_leaf"); + __wt_cache_decr_check_uint64(session, &cache->bytes_dirty_leaf, + decr, "WT_CACHE.bytes_dirty_leaf"); } } @@ -195,19 +262,18 @@ __wt_cache_page_inmem_decr(WT_SESSION_IMPL *session, WT_PAGE *page, size_t size) WT_ASSERT(session, size < WT_EXABYTE); + __wt_cache_decr_check_uint64( + session, &S2BT(session)->bytes_inmem, size, "WT_BTREE.bytes_inmem"); __wt_cache_decr_check_uint64( session, &cache->bytes_inmem, size, "WT_CACHE.bytes_inmem"); __wt_cache_decr_check_size( session, &page->memory_footprint, size, "WT_PAGE.memory_footprint"); if (__wt_page_is_modified(page)) __wt_cache_page_byte_dirty_decr(session, page, size); - /* Track internal and overflow size in cache. */ + /* Track internal size in cache. */ if (WT_PAGE_IS_INTERNAL(page)) __wt_cache_decr_check_uint64(session, &cache->bytes_internal, size, "WT_CACHE.bytes_internal"); - else if (page->type == WT_PAGE_OVFL) - __wt_cache_decr_check_uint64(session, - &cache->bytes_overflow, size, "WT_CACHE.bytes_overflow"); } /* @@ -218,18 +284,26 @@ __wt_cache_page_inmem_decr(WT_SESSION_IMPL *session, WT_PAGE *page, size_t size) static inline void __wt_cache_dirty_incr(WT_SESSION_IMPL *session, WT_PAGE *page) { + WT_BTREE *btree; WT_CACHE *cache; size_t size; + btree = S2BT(session); cache = S2C(session)->cache; - (void)__wt_atomic_add64(&cache->pages_dirty, 1); /* * Take care to read the memory_footprint once in case we are racing * with updates. */ size = page->memory_footprint; - (void)__wt_atomic_add64(&cache->bytes_dirty, size); + if (WT_PAGE_IS_INTERNAL(page)) { + (void)__wt_atomic_add64(&cache->bytes_dirty_intl, size); + (void)__wt_atomic_add64(&cache->pages_dirty_intl, 1); + } else { + (void)__wt_atomic_add64(&btree->bytes_dirty_leaf, size); + (void)__wt_atomic_add64(&cache->bytes_dirty_leaf, size); + (void)__wt_atomic_add64(&cache->pages_dirty_leaf, 1); + } (void)__wt_atomic_addsize(&page->modify->bytes_dirty, size); } @@ -246,13 +320,12 @@ __wt_cache_dirty_decr(WT_SESSION_IMPL *session, WT_PAGE *page) cache = S2C(session)->cache; - if (cache->pages_dirty < 1) { - __wt_errx(session, - "cache eviction dirty-page decrement failed: dirty page" - "count went negative"); - cache->pages_dirty = 0; - } else - (void)__wt_atomic_sub64(&cache->pages_dirty, 1); + if (WT_PAGE_IS_INTERNAL(page)) + __wt_cache_decr_zero_uint64(session, + &cache->pages_dirty_intl, 1, "dirty internal page count"); + else + __wt_cache_decr_zero_uint64(session, + &cache->pages_dirty_leaf, 1, "dirty leaf page count"); modify = page->modify; if (modify != NULL && modify->bytes_dirty != 0) @@ -260,6 +333,34 @@ __wt_cache_dirty_decr(WT_SESSION_IMPL *session, WT_PAGE *page) session, page, modify->bytes_dirty); } +/* + * __wt_cache_page_image_decr -- + * Decrement a page image's size to the cache. + */ +static inline void +__wt_cache_page_image_decr(WT_SESSION_IMPL *session, uint32_t size) +{ + WT_CACHE *cache; + + cache = S2C(session)->cache; + + __wt_cache_decr_check_uint64( + session, &cache->bytes_image, size, "WT_CACHE.image_inmem"); +} + +/* + * __wt_cache_page_image_incr -- + * Increment a page image's size to the cache. + */ +static inline void +__wt_cache_page_image_incr(WT_SESSION_IMPL *session, uint32_t size) +{ + WT_CACHE *cache; + + cache = S2C(session)->cache; + (void)__wt_atomic_add64(&cache->bytes_image, size); +} + /* * __wt_cache_page_evict -- * Evict pages from the cache. @@ -267,15 +368,18 @@ __wt_cache_dirty_decr(WT_SESSION_IMPL *session, WT_PAGE *page) static inline void __wt_cache_page_evict(WT_SESSION_IMPL *session, WT_PAGE *page) { + WT_BTREE *btree; WT_CACHE *cache; WT_PAGE_MODIFY *modify; + btree = S2BT(session); cache = S2C(session)->cache; modify = page->modify; /* Update the bytes in-memory to reflect the eviction. */ - __wt_cache_decr_check_uint64(session, - &cache->bytes_inmem, + __wt_cache_decr_check_uint64(session, &S2BT(session)->bytes_inmem, + page->memory_footprint, "WT_BTREE.bytes_inmem"); + __wt_cache_decr_check_uint64(session, &cache->bytes_inmem, page->memory_footprint, "WT_CACHE.bytes_inmem"); /* Update the bytes_internal value to reflect the eviction */ @@ -286,15 +390,18 @@ __wt_cache_page_evict(WT_SESSION_IMPL *session, WT_PAGE *page) /* Update the cache's dirty-byte count. */ if (modify != NULL && modify->bytes_dirty != 0) { - if (cache->bytes_dirty < modify->bytes_dirty) { - __wt_errx(session, - "cache eviction dirty-bytes decrement failed: " - "dirty byte count went negative"); - cache->bytes_dirty = 0; - } else - __wt_cache_decr_check_uint64(session, - &cache->bytes_dirty, - modify->bytes_dirty, "WT_CACHE.bytes_dirty"); + if (WT_PAGE_IS_INTERNAL(page)) + __wt_cache_decr_zero_uint64(session, + &cache->bytes_dirty_intl, + modify->bytes_dirty, "WT_CACHE.bytes_dirty_intl"); + else { + __wt_cache_decr_zero_uint64(session, + &cache->bytes_dirty_leaf, + modify->bytes_dirty, "WT_CACHE.bytes_dirty_leaf"); + __wt_cache_decr_zero_uint64(session, + &btree->bytes_dirty_leaf, + modify->bytes_dirty, "WT_BTREE.bytes_dirty_leaf"); + } } /* Update pages and bytes evicted. */ @@ -317,16 +424,6 @@ __wt_update_list_memsize(WT_UPDATE *upd) return (upd_size); } -/* - * __wt_page_evict_soon -- - * Set a page to be evicted as soon as possible. - */ -static inline void -__wt_page_evict_soon(WT_PAGE *page) -{ - page->read_gen = WT_READGEN_OLDEST; -} - /* * __wt_page_modify_init -- * A page is about to be modified, allocate the modification structure. @@ -1099,16 +1196,14 @@ __wt_leaf_page_can_split(WT_SESSION_IMPL *session, WT_PAGE *page) * Check whether a page can be evicted. */ static inline bool -__wt_page_can_evict(WT_SESSION_IMPL *session, WT_REF *ref, bool *inmem_splitp) +__wt_page_can_evict( + WT_SESSION_IMPL *session, WT_REF *ref, uint32_t *evict_flagsp) { WT_BTREE *btree; WT_PAGE *page; WT_PAGE_MODIFY *mod; bool modified; - if (inmem_splitp != NULL) - *inmem_splitp = false; - btree = S2BT(session); page = ref->page; mod = page->modify; @@ -1124,8 +1219,8 @@ __wt_page_can_evict(WT_SESSION_IMPL *session, WT_REF *ref, bool *inmem_splitp) * won't be written or discarded from the cache. */ if (__wt_leaf_page_can_split(session, page)) { - if (inmem_splitp != NULL) - *inmem_splitp = true; + if (evict_flagsp != NULL) + FLD_SET(*evict_flagsp, WT_EVICT_INMEM_SPLIT); return (true); } @@ -1137,7 +1232,7 @@ __wt_page_can_evict(WT_SESSION_IMPL *session, WT_REF *ref, bool *inmem_splitp) * previous version might be referenced by an internal page already * been written in the checkpoint, leaving the checkpoint inconsistent. */ - if (btree->checkpointing != WT_CKPT_OFF && modified) { + if (modified && btree->checkpointing != WT_CKPT_OFF) { WT_STAT_FAST_CONN_INCR(session, cache_eviction_checkpoint); WT_STAT_FAST_DATA_INCR(session, cache_eviction_checkpoint); return (false); @@ -1165,71 +1260,15 @@ __wt_page_can_evict(WT_SESSION_IMPL *session, WT_REF *ref, bool *inmem_splitp) return (false); /* - * If the oldest transaction hasn't changed since the last time - * this page was written, it's unlikely we can make progress. - * Similarly, if the most recent update on the page is not yet - * globally visible, eviction will fail. These heuristics - * attempt to avoid repeated attempts to evict the same page. + * If the page is clean but has modifications that appear too new to + * evict, skip it. */ - if (modified && - !F_ISSET(S2C(session)->cache, WT_CACHE_STUCK) && - (mod->last_oldest_id == __wt_txn_oldest_id(session) || - !__wt_txn_visible_all(session, mod->update_txn))) + if (!modified && !__wt_txn_visible_all(session, mod->rec_max_txn)) return (false); return (true); } -/* - * __wt_page_release_evict -- - * Release a reference to a page, and attempt to immediately evict it. - */ -static inline int -__wt_page_release_evict(WT_SESSION_IMPL *session, WT_REF *ref) -{ - WT_BTREE *btree; - WT_DECL_RET; - WT_PAGE *page; - bool locked, too_big; - - btree = S2BT(session); - page = ref->page; - - /* - * Take some care with order of operations: if we release the hazard - * reference without first locking the page, it could be evicted in - * between. - */ - locked = __wt_atomic_casv32( - &ref->state, WT_REF_MEM, WT_REF_LOCKED) ? true : false; - if ((ret = __wt_hazard_clear(session, page)) != 0 || !locked) { - if (locked) - ref->state = WT_REF_MEM; - return (ret == 0 ? EBUSY : ret); - } - - (void)__wt_atomic_addv32(&btree->evict_busy, 1); - - too_big = page->memory_footprint > btree->maxmempage; - if ((ret = __wt_evict(session, ref, false)) == 0) { - if (too_big) - WT_STAT_FAST_CONN_INCR(session, cache_eviction_force); - else - /* - * If the page isn't too big, we are evicting it because - * it had a chain of deleted entries that make traversal - * expensive. - */ - WT_STAT_FAST_CONN_INCR( - session, cache_eviction_force_delete); - } else - WT_STAT_FAST_CONN_INCR(session, cache_eviction_force_fail); - - (void)__wt_atomic_subv32(&btree->evict_busy, 1); - - return (ret); -} - /* * __wt_page_release -- * Release a reference to a page. diff --git a/src/third_party/wiredtiger/src/include/buf.i b/src/third_party/wiredtiger/src/include/buf.i index 95d945ec6d3..ebbee6b4633 100644 --- a/src/third_party/wiredtiger/src/include/buf.i +++ b/src/third_party/wiredtiger/src/include/buf.i @@ -76,7 +76,8 @@ __wt_buf_set( WT_RET(__wt_buf_initsize(session, buf, size)); /* Copy the data, allowing for overlapping strings. */ - memmove(buf->mem, data, size); + if (size != 0) + memmove(buf->mem, data, size); return (0); } diff --git a/src/third_party/wiredtiger/src/include/cache.h b/src/third_party/wiredtiger/src/include/cache.h index f4a35de7201..0cb61f01435 100644 --- a/src/third_party/wiredtiger/src/include/cache.h +++ b/src/third_party/wiredtiger/src/include/cache.h @@ -13,7 +13,6 @@ #define WT_EVICT_INT_SKEW (1<<20) /* Prefer leaf pages over internal pages by this many increments of the read generation. */ -#define WT_EVICT_WALK_PER_FILE 10 /* Pages to queue per file */ #define WT_EVICT_WALK_BASE 300 /* Pages tracked across file visits */ #define WT_EVICT_WALK_INCR 100 /* Pages added each walk */ @@ -24,9 +23,12 @@ struct __wt_evict_entry { WT_BTREE *btree; /* Enclosing btree object */ WT_REF *ref; /* Page to flush/evict */ + uint64_t score; /* Relative eviction priority */ }; -#define WT_EVICT_QUEUE_MAX 2 +#define WT_EVICT_QUEUE_MAX 3 /* Two ordinary queues plus urgent */ +#define WT_EVICT_URGENT_QUEUE 2 /* Urgent queue index */ + /* * WT_EVICT_QUEUE -- * Encapsulation of an eviction candidate queue. @@ -34,23 +36,12 @@ struct __wt_evict_entry { struct __wt_evict_queue { WT_SPINLOCK evict_lock; /* Eviction LRU queue */ WT_EVICT_ENTRY *evict_queue; /* LRU pages being tracked */ + WT_EVICT_ENTRY *evict_current; /* LRU current page to be evicted */ uint32_t evict_candidates; /* LRU list pages to evict */ uint32_t evict_entries; /* LRU entries in the queue */ volatile uint32_t evict_max; /* LRU maximum eviction slot used */ }; -/* - * WT_EVICT_WORKER -- - * Encapsulation of an eviction worker thread. - */ -struct __wt_evict_worker { - WT_SESSION_IMPL *session; - u_int id; - wt_thread_t tid; -#define WT_EVICT_WORKER_RUN 0x01 - uint32_t flags; -}; - /* Cache operations. */ typedef enum __wt_cache_op { WT_SYNC_CHECKPOINT, @@ -66,20 +57,23 @@ struct __wt_cache { /* * Different threads read/write pages to/from the cache and create pages * in the cache, so we cannot know precisely how much memory is in use - * at any specific time. However, even though the values don't have to + * at any specific time. However, even though the values don't have to * be exact, they can't be garbage, we track what comes in and what goes * out and calculate the difference as needed. */ - uint64_t bytes_inmem; /* Bytes/pages in memory */ - uint64_t pages_inmem; - uint64_t bytes_internal; /* Bytes of internal pages */ - uint64_t bytes_overflow; /* Bytes of overflow pages */ + uint64_t bytes_dirty_intl; /* Bytes/pages currently dirty */ + uint64_t pages_dirty_intl; + uint64_t bytes_dirty_leaf; + uint64_t pages_dirty_leaf; uint64_t bytes_evict; /* Bytes/pages discarded by eviction */ uint64_t pages_evict; uint64_t pages_evicted; /* Pages evicted during a pass */ - uint64_t bytes_dirty; /* Bytes/pages currently dirty */ - uint64_t pages_dirty; + uint64_t bytes_image; /* Bytes of disk images */ + uint64_t bytes_inmem; /* Bytes/pages in memory */ + uint64_t pages_inmem; + uint64_t bytes_internal; /* Bytes of internal pages */ uint64_t bytes_read; /* Bytes read into memory */ + uint64_t bytes_written; uint64_t app_waits; /* User threads waited for cache */ uint64_t app_evicts; /* Pages evicted by user threads */ @@ -103,30 +97,62 @@ struct __wt_cache { */ WT_CONDVAR *evict_cond; /* Eviction server condition */ WT_SPINLOCK evict_walk_lock; /* Eviction walk location */ - /* Condition signalled when the eviction server populates the queue */ - WT_CONDVAR *evict_waiter_cond; - u_int eviction_trigger; /* Percent to trigger eviction */ - u_int eviction_target; /* Percent to end eviction */ u_int eviction_dirty_target; /* Percent to allow dirty */ u_int eviction_dirty_trigger; /* Percent to trigger dirty eviction */ + u_int eviction_trigger; /* Percent to trigger eviction */ + u_int eviction_target; /* Percent to end eviction */ + + u_int eviction_checkpoint_target;/* Percent to reduce dirty + to during checkpoint scrubs */ + double eviction_scrub_limit; /* Percent of cache to trigger + dirty eviction during checkpoint + scrubs */ u_int overhead_pct; /* Cache percent adjustment */ + /* + * Pass interrupt counter. + */ + volatile uint32_t pass_intr; /* Interrupt eviction pass. */ + /* * LRU eviction list information. */ WT_SPINLOCK evict_pass_lock; /* Eviction pass lock */ WT_SESSION_IMPL *walk_session; /* Eviction pass session */ + WT_DATA_HANDLE *evict_file_next;/* LRU next file to search */ + WT_SPINLOCK evict_queue_lock; /* Eviction current queue lock */ WT_EVICT_QUEUE evict_queues[WT_EVICT_QUEUE_MAX]; - WT_EVICT_QUEUE *evict_current_queue;/* LRU current queue in use */ - WT_EVICT_ENTRY *evict_current; /* LRU current page to be evicted */ - uint32_t evict_queue_fill; /* LRU eviction queue index to fill */ + WT_EVICT_QUEUE *evict_current_queue; /* LRU current queue in use */ + WT_EVICT_QUEUE *evict_fill_queue; /* LRU next queue to fill. + This is usually the same as the + "other" queue but under heavy + load the eviction server will + start filling the current queue + before it switches. */ + WT_EVICT_QUEUE *evict_other_queue; /* LRU queue not in use */ + WT_EVICT_QUEUE *evict_urgent_queue; /* LRU urgent queue */ uint32_t evict_slots; /* LRU list eviction slots */ - WT_DATA_HANDLE - *evict_file_next; /* LRU next file to search */ - uint32_t evict_max_refs_per_file;/* LRU pages per file per pass */ + +#define WT_EVICT_SCORE_BUMP 10 +#define WT_EVICT_SCORE_CUTOFF 10 +#define WT_EVICT_SCORE_MAX 100 + uint32_t evict_aggressive_score;/* Score of how aggressive eviction + should be about selecting eviction + candidates. If eviction is + struggling to make progress, this + score rises (up to a maximum of + 100), at which point the cache is + "stuck" and transaction will be + rolled back. */ + uint32_t evict_empty_score; /* Score of how often LRU queues are + empty on refill. This score varies + between 0 (if the queue hasn't been + empty for a long time) and 100 (if + the queue has been empty the last 10 + times we filled up. */ /* * Cache pool information. @@ -142,27 +168,20 @@ struct __wt_cache { uint64_t cp_saved_app_waits; /* User wait count at last review */ uint64_t cp_saved_read; /* Read count at last review */ - /* - * Work state. - */ -#define WT_EVICT_PASS_AGGRESSIVE 0x01 -#define WT_EVICT_PASS_ALL 0x02 -#define WT_EVICT_PASS_DIRTY 0x04 -#define WT_EVICT_PASS_WOULD_BLOCK 0x08 - uint32_t state; - /* - * Pass interrupt counter. - */ - uint32_t pass_intr; /* Interrupt eviction pass. */ - /* * Flags. */ -#define WT_CACHE_POOL_MANAGER 0x01 /* The active cache pool manager */ -#define WT_CACHE_POOL_RUN 0x02 /* Cache pool thread running */ -#define WT_CACHE_STUCK 0x04 /* Eviction server is stuck */ -#define WT_CACHE_WALK_REVERSE 0x08 /* Scan backwards for candidates */ -#define WT_CACHE_WOULD_BLOCK 0x10 /* Pages that would block apps */ +#define WT_CACHE_EVICT_CLEAN 0x001 /* Evict clean pages */ +#define WT_CACHE_EVICT_CLEAN_HARD 0x002 /* Clean % blocking app threads */ +#define WT_CACHE_EVICT_DIRTY 0x004 /* Evict dirty pages */ +#define WT_CACHE_EVICT_DIRTY_HARD 0x008 /* Dirty % blocking app threads */ +#define WT_CACHE_EVICT_SCRUB 0x010 /* Scrub dirty pages pages */ +#define WT_CACHE_EVICT_URGENT 0x020 /* Pages are in the urgent queue */ +#define WT_CACHE_EVICT_ALL (WT_CACHE_EVICT_CLEAN | WT_CACHE_EVICT_DIRTY) +#define WT_CACHE_EVICT_MASK 0x0FF +#define WT_CACHE_POOL_MANAGER 0x100 /* The active cache pool manager */ +#define WT_CACHE_POOL_RUN 0x200 /* Cache pool thread running */ +#define WT_CACHE_WALK_REVERSE 0x400 /* Scan backwards for candidates */ uint32_t flags; }; diff --git a/src/third_party/wiredtiger/src/include/cache.i b/src/third_party/wiredtiger/src/include/cache.i index 72c8307756d..b5605769f1a 100644 --- a/src/third_party/wiredtiger/src/include/cache.i +++ b/src/third_party/wiredtiger/src/include/cache.i @@ -6,6 +6,17 @@ * See the file LICENSE for redistribution information. */ +/* + * __wt_cache_aggressive -- + * Indicate if the cache is operating in aggressive mode. + */ +static inline bool +__wt_cache_aggressive(WT_SESSION_IMPL *session) +{ + return (S2C(session)->cache->evict_aggressive_score >= + WT_EVICT_SCORE_CUTOFF); +} + /* * __wt_cache_read_gen -- * Get the current read generation number. @@ -67,6 +78,33 @@ __wt_cache_read_gen_new(WT_SESSION_IMPL *session, WT_PAGE *page) (__wt_cache_read_gen(session) + cache->read_gen_oldest) / 2; } +/* + * __wt_cache_stuck -- + * Indicate if the cache is stuck (i.e., not making progress). + */ +static inline bool +__wt_cache_stuck(WT_SESSION_IMPL *session) +{ + WT_CACHE *cache; + + cache = S2C(session)->cache; + return (cache->evict_aggressive_score == WT_EVICT_SCORE_MAX && + F_ISSET(cache, + WT_CACHE_EVICT_CLEAN_HARD | WT_CACHE_EVICT_DIRTY_HARD)); +} + +/* + * __wt_page_evict_soon -- + * Set a page to be evicted as soon as possible. + */ +static inline void +__wt_page_evict_soon(WT_SESSION_IMPL *session, WT_REF *ref) +{ + WT_UNUSED(session); + + ref->page->read_gen = WT_READGEN_OLDEST; +} + /* * __wt_cache_pages_inuse -- * Return the number of pages in use. @@ -77,6 +115,19 @@ __wt_cache_pages_inuse(WT_CACHE *cache) return (cache->pages_inmem - cache->pages_evict); } +/* + * __wt_cache_bytes_plus_overhead -- + * Apply the cache overhead to a size in bytes. + */ +static inline uint64_t +__wt_cache_bytes_plus_overhead(WT_CACHE *cache, uint64_t sz) +{ + if (cache->overhead_pct != 0) + sz += (sz * (uint64_t)cache->overhead_pct) / 100; + + return (sz); +} + /* * __wt_cache_bytes_inuse -- * Return the number of bytes in use. @@ -84,15 +135,7 @@ __wt_cache_pages_inuse(WT_CACHE *cache) static inline uint64_t __wt_cache_bytes_inuse(WT_CACHE *cache) { - uint64_t bytes_inuse; - - /* Adjust the cache size to take allocation overhead into account. */ - bytes_inuse = cache->bytes_inmem; - if (cache->overhead_pct != 0) - bytes_inuse += - (bytes_inuse * (uint64_t)cache->overhead_pct) / 100; - - return (bytes_inuse); + return (__wt_cache_bytes_plus_overhead(cache, cache->bytes_inmem)); } /* @@ -102,14 +145,48 @@ __wt_cache_bytes_inuse(WT_CACHE *cache) static inline uint64_t __wt_cache_dirty_inuse(WT_CACHE *cache) { - uint64_t dirty_inuse; + return (__wt_cache_bytes_plus_overhead(cache, + cache->bytes_dirty_intl + cache->bytes_dirty_leaf)); +} - dirty_inuse = cache->bytes_dirty; - if (cache->overhead_pct != 0) - dirty_inuse += - (dirty_inuse * (uint64_t)cache->overhead_pct) / 100; +/* + * __wt_cache_dirty_leaf_inuse -- + * Return the number of dirty bytes in use by leaf pages. + */ +static inline uint64_t +__wt_cache_dirty_leaf_inuse(WT_CACHE *cache) +{ + return (__wt_cache_bytes_plus_overhead(cache, cache->bytes_dirty_leaf)); +} - return (dirty_inuse); +/* + * __wt_cache_bytes_image -- + * Return the number of page image bytes in use. + */ +static inline uint64_t +__wt_cache_bytes_image(WT_CACHE *cache) +{ + return (__wt_cache_bytes_plus_overhead(cache, cache->bytes_image)); +} + +/* + * __wt_cache_bytes_other -- + * Return the number of bytes in use not for page images. + */ +static inline uint64_t +__wt_cache_bytes_other(WT_CACHE *cache) +{ + uint64_t bytes_image, bytes_inmem; + + bytes_image = cache->bytes_image; + bytes_inmem = cache->bytes_inmem; + + /* + * The reads above could race with changes to the values, so protect + * against underflow. + */ + return ((bytes_image > bytes_inmem) ? 0 : + __wt_cache_bytes_plus_overhead(cache, bytes_inmem - bytes_image)); } /* @@ -138,29 +215,19 @@ __wt_session_can_wait(WT_SESSION_IMPL *session) return (1); } -/* - * __wt_eviction_dirty_target -- - * Return if the eviction server is running to reduce the number of dirty - * pages (versus running to discard pages from the cache). - */ -static inline bool -__wt_eviction_dirty_target(WT_SESSION_IMPL *session) -{ - return (FLD_ISSET(S2C(session)->cache->state, WT_EVICT_PASS_DIRTY)); -} - /* * __wt_eviction_needed -- * Return if an application thread should do eviction, and the cache full - * percentage as a side-effect. + * percentage as a side-effect. */ static inline bool -__wt_eviction_needed(WT_SESSION_IMPL *session, u_int *pct_fullp) +__wt_eviction_needed(WT_SESSION_IMPL *session, bool busy, u_int *pct_fullp) { WT_CONNECTION_IMPL *conn; WT_CACHE *cache; - uint64_t bytes_inuse, bytes_max; - u_int pct_full; + double dirty_trigger; + uint64_t bytes_inuse, bytes_max, dirty_inuse; + u_int pct_dirty, pct_full; conn = S2C(session); cache = conn->cache; @@ -176,33 +243,36 @@ __wt_eviction_needed(WT_SESSION_IMPL *session, u_int *pct_fullp) * Avoid division by zero if the cache size has not yet been set in a * shared cache. */ - bytes_inuse = __wt_cache_bytes_inuse(cache); bytes_max = conn->cache_size + 1; + bytes_inuse = __wt_cache_bytes_inuse(cache); + dirty_inuse = __wt_cache_dirty_leaf_inuse(cache); /* * Calculate the cache full percentage; anything over the trigger means * we involve the application thread. */ - pct_full = (u_int)((100 * bytes_inuse) / bytes_max); - if (pct_fullp != NULL) - *pct_fullp = pct_full; - /* - * If the connection is closing we do not need eviction from an - * application thread. The eviction subsystem is already closed. - * We return here because some callers depend on the percent full - * having been filled in. - */ - if (F_ISSET(conn, WT_CONN_CLOSING)) - return (false); + if (pct_fullp != NULL) { + pct_full = (u_int)((100 * bytes_inuse) / bytes_max); + pct_dirty = (u_int)((100 * dirty_inuse) / bytes_max); - if (pct_full > cache->eviction_trigger) - return (true); + *pct_fullp = (u_int)WT_MAX(0, 100 - WT_MIN( + (int)cache->eviction_trigger - (int)pct_full, + (int)cache->eviction_dirty_trigger - (int)pct_dirty)); + } - /* Return if there are too many dirty bytes in cache. */ - if (__wt_cache_dirty_inuse(cache) > - (cache->eviction_dirty_trigger * bytes_max) / 100) - return (true); - return (false); + /* + * Only check the dirty trigger when the session is not busy. + * + * In other words, once we are pinning resources, try to finish the + * operation as quickly as possible without exceeding the cache size. + * The next transaction in this session will not be able to start until + * the cache is under the limit. + */ + if ((dirty_trigger = cache->eviction_scrub_limit) < 1.0) + dirty_trigger = (double)cache->eviction_dirty_trigger; + return (bytes_inuse > (cache->eviction_trigger * bytes_max) / 100 || + (!busy && + dirty_inuse > (uint64_t)(dirty_trigger * bytes_max) / 100)); } /* @@ -229,11 +299,27 @@ static inline int __wt_cache_eviction_check(WT_SESSION_IMPL *session, bool busy, bool *didworkp) { WT_BTREE *btree; + WT_TXN_GLOBAL *txn_global; + WT_TXN_STATE *txn_state; u_int pct_full; if (didworkp != NULL) *didworkp = false; + /* + * If the current transaction is keeping the oldest ID pinned, it is in + * the middle of an operation. This may prevent the oldest ID from + * moving forward, leading to deadlock, so only evict what we can. + * Otherwise, we are at a transaction boundary and we can work harder + * to make sure there is free space in the cache. + */ + txn_global = &S2C(session)->txn_global; + txn_state = WT_SESSION_TXN_STATE(session); + busy = busy || txn_state->id != WT_TXN_NONE || + session->nhazard > 0 || + (txn_state->snap_min != WT_TXN_NONE && + txn_global->current != txn_global->oldest_id); + /* * LSM sets the no-cache-check flag when holding the LSM tree lock, in * that case, or when holding the schema or handle list locks (which @@ -256,7 +342,7 @@ __wt_cache_eviction_check(WT_SESSION_IMPL *session, bool busy, bool *didworkp) return (0); /* Check if eviction is needed. */ - if (!__wt_eviction_needed(session, &pct_full)) + if (!__wt_eviction_needed(session, busy, &pct_full)) return (0); /* diff --git a/src/third_party/wiredtiger/src/include/connection.h b/src/third_party/wiredtiger/src/include/connection.h index 804498f6869..77dbc87b114 100644 --- a/src/third_party/wiredtiger/src/include/connection.h +++ b/src/third_party/wiredtiger/src/include/connection.h @@ -25,6 +25,10 @@ struct __wt_process { /* Locked: connection queue */ TAILQ_HEAD(__wt_connection_impl_qh, __wt_connection_impl) connqh; WT_CACHE_POOL *cache_pool; + + /* Checksum function */ +#define __wt_checksum(chunk, len) __wt_process.checksum(chunk, len) + uint32_t (*checksum)(const void *, size_t); }; extern WT_PROCESS __wt_process; @@ -271,10 +275,9 @@ struct __wt_connection_impl { wt_thread_t ckpt_tid; /* Checkpoint thread */ bool ckpt_tid_set; /* Checkpoint thread set */ WT_CONDVAR *ckpt_cond; /* Checkpoint wait mutex */ - const char *ckpt_config; /* Checkpoint configuration */ #define WT_CKPT_LOGSIZE(conn) ((conn)->ckpt_logsize != 0) wt_off_t ckpt_logsize; /* Checkpoint log size period */ - uint32_t ckpt_signalled;/* Checkpoint signalled */ + bool ckpt_signalled;/* Checkpoint signalled */ uint64_t ckpt_usecs; /* Checkpoint timer */ uint64_t ckpt_time_max; /* Checkpoint time min/max */ @@ -304,15 +307,11 @@ struct __wt_connection_impl { WT_KEYED_ENCRYPTOR *kencryptor; /* Encryptor for metadata and log */ - WT_SESSION_IMPL *evict_session; /* Eviction server sessions */ - wt_thread_t evict_tid; /* Eviction server thread ID */ - bool evict_tid_set; /* Eviction server thread ID set */ + bool evict_server_running;/* Eviction server operating */ - uint32_t evict_workers_alloc;/* Allocated eviction workers */ - uint32_t evict_workers_max;/* Max eviction workers */ - uint32_t evict_workers_min;/* Min eviction workers */ - uint32_t evict_workers; /* Number of eviction workers */ - WT_EVICT_WORKER *evict_workctx; /* Eviction worker context */ + WT_THREAD_GROUP evict_threads; + uint32_t evict_threads_max;/* Max eviction threads */ + uint32_t evict_threads_min;/* Min eviction threads */ #define WT_STATLOG_FILENAME "WiredTigerStat.%d.%H" WT_SESSION_IMPL *stat_session; /* Statistics log session */ diff --git a/src/third_party/wiredtiger/src/include/cursor.h b/src/third_party/wiredtiger/src/include/cursor.h index 6357523a03f..f1fa4d193ac 100644 --- a/src/third_party/wiredtiger/src/include/cursor.h +++ b/src/third_party/wiredtiger/src/include/cursor.h @@ -73,6 +73,9 @@ struct __wt_cursor_backup { WT_CURSOR_BACKUP_ENTRY *list; /* List of files to be copied. */ size_t list_allocated; size_t list_next; + +#define WT_CURBACKUP_LOCKER 0x01 /* Hot-backup started */ + uint8_t flags; }; #define WT_CURSOR_BACKUP_ID(cursor) (((WT_CURSOR_BACKUP *)cursor)->maxid) @@ -413,18 +416,21 @@ struct __wt_cursor_log { uint32_t step_count; /* Intra-record count */ uint32_t rectype; /* Record type */ uint64_t txnid; /* Record txnid */ - uint32_t flags; + +#define WT_CURLOG_ARCHIVE_LOCK 0x01 /* Archive lock held */ + uint8_t flags; }; struct __wt_cursor_metadata { WT_CURSOR iface; WT_CURSOR *file_cursor; /* Queries of regular metadata */ + WT_CURSOR *create_cursor; /* Extra cursor for create option */ #define WT_MDC_CREATEONLY 0x01 #define WT_MDC_ONMETADATA 0x02 #define WT_MDC_POSITIONED 0x04 - uint32_t flags; + uint8_t flags; }; struct __wt_join_stats_group { diff --git a/src/third_party/wiredtiger/src/include/cursor.i b/src/third_party/wiredtiger/src/include/cursor.i index c1fb7bfcb9f..e142441e0a6 100644 --- a/src/third_party/wiredtiger/src/include/cursor.i +++ b/src/third_party/wiredtiger/src/include/cursor.i @@ -117,7 +117,7 @@ __curfile_leave(WT_CURSOR_BTREE *cbt) */ if (cbt->ref != NULL && cbt->page_deleted_count > WT_BTREE_DELETE_THRESHOLD) - __wt_page_evict_soon(cbt->ref->page); + __wt_page_evict_soon(session, cbt->ref); cbt->page_deleted_count = 0; /* diff --git a/src/third_party/wiredtiger/src/include/error.h b/src/third_party/wiredtiger/src/include/error.h index 5f24d205af9..bbb7f989332 100644 --- a/src/third_party/wiredtiger/src/include/error.h +++ b/src/third_party/wiredtiger/src/include/error.h @@ -77,7 +77,6 @@ ret == 0 || ret == WT_DUPLICATE_KEY || ret == WT_NOTFOUND)) \ ret = __ret; \ } while (0) -#define WT_TRET_BUSY_OK(a) WT_TRET_ERROR_OK(a, EBUSY) #define WT_TRET_NOTFOUND_OK(a) WT_TRET_ERROR_OK(a, WT_NOTFOUND) /* Return and branch-to-err-label cases for switch statements. */ @@ -95,10 +94,11 @@ #define WT_PANIC_MSG(session, v, ...) do { \ __wt_err(session, v, __VA_ARGS__); \ - (void)__wt_panic(session); \ + WT_IGNORE_RET(__wt_panic(session)); \ } while (0) #define WT_PANIC_ERR(session, v, ...) do { \ WT_PANIC_MSG(session, v, __VA_ARGS__); \ + /* Return WT_PANIC regardless of earlier return codes. */ \ WT_ERR(WT_PANIC); \ } while (0) #define WT_PANIC_RET(session, v, ...) do { \ diff --git a/src/third_party/wiredtiger/src/include/extern.h b/src/third_party/wiredtiger/src/include/extern.h index 20329e9d9b7..5444b2e9f14 100644 --- a/src/third_party/wiredtiger/src/include/extern.h +++ b/src/third_party/wiredtiger/src/include/extern.h @@ -1,640 +1,643 @@ /* DO NOT EDIT: automatically built by dist/s_prototypes. */ extern void __wt_async_stats_update(WT_SESSION_IMPL *session); -extern int __wt_async_create(WT_SESSION_IMPL *session, const char *cfg[]); -extern int __wt_async_reconfig(WT_SESSION_IMPL *session, const char *cfg[]); -extern int __wt_async_destroy(WT_SESSION_IMPL *session); -extern int __wt_async_flush(WT_SESSION_IMPL *session); -extern int __wt_async_new_op(WT_SESSION_IMPL *session, const char *uri, const char *config, const char *cfg[], WT_ASYNC_CALLBACK *cb, WT_ASYNC_OP_IMPL **opp); -extern int __wt_async_op_enqueue(WT_SESSION_IMPL *session, WT_ASYNC_OP_IMPL *op); -extern int __wt_async_op_init(WT_SESSION_IMPL *session); +extern int __wt_async_create(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_async_reconfig(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_async_destroy(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_async_flush(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_async_new_op(WT_SESSION_IMPL *session, const char *uri, const char *config, const char *cfg[], WT_ASYNC_CALLBACK *cb, WT_ASYNC_OP_IMPL **opp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_async_op_enqueue(WT_SESSION_IMPL *session, WT_ASYNC_OP_IMPL *op) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_async_op_init(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern WT_THREAD_RET __wt_async_worker(void *arg); -extern int __wt_block_addr_to_buffer(WT_BLOCK *block, uint8_t **pp, wt_off_t offset, uint32_t size, uint32_t cksum); -extern int __wt_block_buffer_to_addr(WT_BLOCK *block, const uint8_t *p, wt_off_t *offsetp, uint32_t *sizep, uint32_t *cksump); -extern int __wt_block_addr_invalid(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr, size_t addr_size, bool live); -extern int __wt_block_addr_string(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, const uint8_t *addr, size_t addr_size); -extern int __wt_block_buffer_to_ckpt(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *p, WT_BLOCK_CKPT *ci); -extern int __wt_block_ckpt_decode(WT_SESSION *wt_session, size_t allocsize, const uint8_t *p, WT_BLOCK_CKPT *ci); -extern int __wt_block_ckpt_to_buffer(WT_SESSION_IMPL *session, WT_BLOCK *block, uint8_t **pp, WT_BLOCK_CKPT *ci); -extern int __wt_block_ckpt_init( WT_SESSION_IMPL *session, WT_BLOCK_CKPT *ci, const char *name); -extern int __wt_block_checkpoint_load(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr, size_t addr_size, uint8_t *root_addr, size_t *root_addr_sizep, bool checkpoint); -extern int __wt_block_checkpoint_unload( WT_SESSION_IMPL *session, WT_BLOCK *block, bool checkpoint); +extern int __wt_block_addr_to_buffer(WT_BLOCK *block, uint8_t **pp, wt_off_t offset, uint32_t size, uint32_t checksum) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_buffer_to_addr(WT_BLOCK *block, const uint8_t *p, wt_off_t *offsetp, uint32_t *sizep, uint32_t *checksump) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_addr_invalid(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr, size_t addr_size, bool live) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_addr_string(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, const uint8_t *addr, size_t addr_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_buffer_to_ckpt(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *p, WT_BLOCK_CKPT *ci) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_ckpt_decode(WT_SESSION *wt_session, size_t allocsize, const uint8_t *p, WT_BLOCK_CKPT *ci) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_ckpt_to_buffer(WT_SESSION_IMPL *session, WT_BLOCK *block, uint8_t **pp, WT_BLOCK_CKPT *ci) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_ckpt_init( WT_SESSION_IMPL *session, WT_BLOCK_CKPT *ci, const char *name) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_checkpoint_load(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr, size_t addr_size, uint8_t *root_addr, size_t *root_addr_sizep, bool checkpoint) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_checkpoint_unload( WT_SESSION_IMPL *session, WT_BLOCK *block, bool checkpoint) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_block_ckpt_destroy(WT_SESSION_IMPL *session, WT_BLOCK_CKPT *ci); -extern int __wt_block_checkpoint(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, WT_CKPT *ckptbase, bool data_cksum); -extern int __wt_block_checkpoint_resolve(WT_SESSION_IMPL *session, WT_BLOCK *block); -extern int __wt_block_compact_start(WT_SESSION_IMPL *session, WT_BLOCK *block); -extern int __wt_block_compact_end(WT_SESSION_IMPL *session, WT_BLOCK *block); -extern int __wt_block_compact_skip(WT_SESSION_IMPL *session, WT_BLOCK *block, bool *skipp); -extern int __wt_block_compact_page_skip(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr, size_t addr_size, bool *skipp); -extern int __wt_block_misplaced(WT_SESSION_IMPL *session, WT_BLOCK *block, const char *tag, wt_off_t offset, uint32_t size, bool live); -extern int __wt_block_off_remove_overlap(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_EXTLIST *el, wt_off_t off, wt_off_t size); -extern int __wt_block_alloc( WT_SESSION_IMPL *session, WT_BLOCK *block, wt_off_t *offp, wt_off_t size); -extern int __wt_block_free(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr, size_t addr_size); -extern int __wt_block_off_free( WT_SESSION_IMPL *session, WT_BLOCK *block, wt_off_t offset, wt_off_t size); -extern int __wt_block_extlist_check( WT_SESSION_IMPL *session, WT_EXTLIST *al, WT_EXTLIST *bl); -extern int __wt_block_extlist_overlap( WT_SESSION_IMPL *session, WT_BLOCK *block, WT_BLOCK_CKPT *ci); -extern int __wt_block_extlist_merge(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_EXTLIST *a, WT_EXTLIST *b); -extern int __wt_block_insert_ext(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_EXTLIST *el, wt_off_t off, wt_off_t size); -extern int __wt_block_extlist_read_avail(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_EXTLIST *el, wt_off_t ckpt_size); -extern int __wt_block_extlist_read(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_EXTLIST *el, wt_off_t ckpt_size); -extern int __wt_block_extlist_write(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_EXTLIST *el, WT_EXTLIST *additional); -extern int __wt_block_extlist_truncate( WT_SESSION_IMPL *session, WT_BLOCK *block, WT_EXTLIST *el); -extern int __wt_block_extlist_init(WT_SESSION_IMPL *session, WT_EXTLIST *el, const char *name, const char *extname, bool track_size); +extern int __wt_block_checkpoint(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, WT_CKPT *ckptbase, bool data_checksum) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_checkpoint_resolve(WT_SESSION_IMPL *session, WT_BLOCK *block) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_compact_start(WT_SESSION_IMPL *session, WT_BLOCK *block) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_compact_end(WT_SESSION_IMPL *session, WT_BLOCK *block) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_compact_skip(WT_SESSION_IMPL *session, WT_BLOCK *block, bool *skipp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_compact_page_skip(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr, size_t addr_size, bool *skipp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_misplaced(WT_SESSION_IMPL *session, WT_BLOCK *block, const char *tag, wt_off_t offset, uint32_t size, bool live) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_off_remove_overlap(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_EXTLIST *el, wt_off_t off, wt_off_t size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_alloc( WT_SESSION_IMPL *session, WT_BLOCK *block, wt_off_t *offp, wt_off_t size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_free(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr, size_t addr_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_off_free( WT_SESSION_IMPL *session, WT_BLOCK *block, wt_off_t offset, wt_off_t size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_extlist_check( WT_SESSION_IMPL *session, WT_EXTLIST *al, WT_EXTLIST *bl) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_extlist_overlap( WT_SESSION_IMPL *session, WT_BLOCK *block, WT_BLOCK_CKPT *ci) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_extlist_merge(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_EXTLIST *a, WT_EXTLIST *b) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_insert_ext(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_EXTLIST *el, wt_off_t off, wt_off_t size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_extlist_read_avail(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_EXTLIST *el, wt_off_t ckpt_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_extlist_read(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_EXTLIST *el, wt_off_t ckpt_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_extlist_write(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_EXTLIST *el, WT_EXTLIST *additional) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_extlist_truncate( WT_SESSION_IMPL *session, WT_BLOCK *block, WT_EXTLIST *el) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_extlist_init(WT_SESSION_IMPL *session, WT_EXTLIST *el, const char *name, const char *extname, bool track_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_block_extlist_free(WT_SESSION_IMPL *session, WT_EXTLIST *el); -extern int __wt_block_map(WT_SESSION_IMPL *session, WT_BLOCK *block, void *mapped_regionp, size_t *lengthp, void *mapped_cookiep); -extern int __wt_block_unmap(WT_SESSION_IMPL *session, WT_BLOCK *block, void *mapped_region, size_t length, void *mapped_cookie); -extern int __wt_block_manager_open(WT_SESSION_IMPL *session, const char *filename, const char *cfg[], bool forced_salvage, bool readonly, uint32_t allocsize, WT_BM **bmp); -extern int __wt_block_manager_drop( WT_SESSION_IMPL *session, const char *filename, bool durable); -extern int __wt_block_manager_create( WT_SESSION_IMPL *session, const char *filename, uint32_t allocsize); +extern int __wt_block_map(WT_SESSION_IMPL *session, WT_BLOCK *block, void *mapped_regionp, size_t *lengthp, void *mapped_cookiep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_unmap(WT_SESSION_IMPL *session, WT_BLOCK *block, void *mapped_region, size_t length, void *mapped_cookie) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_manager_open(WT_SESSION_IMPL *session, const char *filename, const char *cfg[], bool forced_salvage, bool readonly, uint32_t allocsize, WT_BM **bmp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_panic(WT_SESSION_IMPL *session, int error, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4))) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_manager_drop( WT_SESSION_IMPL *session, const char *filename, bool durable) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_manager_create( WT_SESSION_IMPL *session, const char *filename, uint32_t allocsize) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_block_configure_first_fit(WT_BLOCK *block, bool on); -extern int __wt_block_open(WT_SESSION_IMPL *session, const char *filename, const char *cfg[], bool forced_salvage, bool readonly, uint32_t allocsize, WT_BLOCK **blockp); -extern int __wt_block_close(WT_SESSION_IMPL *session, WT_BLOCK *block); -extern int __wt_desc_write(WT_SESSION_IMPL *session, WT_FH *fh, uint32_t allocsize); +extern int __wt_block_open(WT_SESSION_IMPL *session, const char *filename, const char *cfg[], bool forced_salvage, bool readonly, uint32_t allocsize, WT_BLOCK **blockp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_close(WT_SESSION_IMPL *session, WT_BLOCK *block) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_desc_write(WT_SESSION_IMPL *session, WT_FH *fh, uint32_t allocsize) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_block_stat(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_DSRC_STATS *stats); -extern int __wt_block_manager_size(WT_BM *bm, WT_SESSION_IMPL *session, wt_off_t *sizep); -extern int __wt_block_manager_named_size( WT_SESSION_IMPL *session, const char *name, wt_off_t *sizep); -extern int __wt_bm_preload( WT_BM *bm, WT_SESSION_IMPL *session, const uint8_t *addr, size_t addr_size); -extern int __wt_bm_read(WT_BM *bm, WT_SESSION_IMPL *session, WT_ITEM *buf, const uint8_t *addr, size_t addr_size); -extern int __wt_block_read_off_blind( WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_off_t offset); -extern int __wt_block_read_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_off_t offset, uint32_t size, uint32_t cksum); -extern int __wt_block_ext_alloc(WT_SESSION_IMPL *session, WT_EXT **extp); +extern int __wt_block_manager_size(WT_BM *bm, WT_SESSION_IMPL *session, wt_off_t *sizep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_manager_named_size( WT_SESSION_IMPL *session, const char *name, wt_off_t *sizep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_bm_preload( WT_BM *bm, WT_SESSION_IMPL *session, const uint8_t *addr, size_t addr_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_bm_read(WT_BM *bm, WT_SESSION_IMPL *session, WT_ITEM *buf, const uint8_t *addr, size_t addr_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_read_off_blind( WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_off_t offset) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_read_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_off_t offset, uint32_t size, uint32_t checksum) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_ext_alloc(WT_SESSION_IMPL *session, WT_EXT **extp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_block_ext_free(WT_SESSION_IMPL *session, WT_EXT *ext); -extern int __wt_block_size_alloc(WT_SESSION_IMPL *session, WT_SIZE **szp); +extern int __wt_block_size_alloc(WT_SESSION_IMPL *session, WT_SIZE **szp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_block_size_free(WT_SESSION_IMPL *session, WT_SIZE *sz); -extern int __wt_block_ext_prealloc(WT_SESSION_IMPL *session, u_int max); -extern int __wt_block_ext_discard(WT_SESSION_IMPL *session, u_int max); -extern int __wt_block_salvage_start(WT_SESSION_IMPL *session, WT_BLOCK *block); -extern int __wt_block_salvage_end(WT_SESSION_IMPL *session, WT_BLOCK *block); +extern int __wt_block_ext_prealloc(WT_SESSION_IMPL *session, u_int max) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_ext_discard(WT_SESSION_IMPL *session, u_int max) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_salvage_start(WT_SESSION_IMPL *session, WT_BLOCK *block) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_salvage_end(WT_SESSION_IMPL *session, WT_BLOCK *block) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern bool __wt_block_offset_invalid(WT_BLOCK *block, wt_off_t offset, uint32_t size); -extern int __wt_block_salvage_next(WT_SESSION_IMPL *session, WT_BLOCK *block, uint8_t *addr, size_t *addr_sizep, bool *eofp); -extern int __wt_block_salvage_valid(WT_SESSION_IMPL *session, WT_BLOCK *block, uint8_t *addr, size_t addr_size, bool valid); -extern int __wt_block_verify_start(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_CKPT *ckptbase, const char *cfg[]); -extern int __wt_block_verify_end(WT_SESSION_IMPL *session, WT_BLOCK *block); -extern int __wt_verify_ckpt_load( WT_SESSION_IMPL *session, WT_BLOCK *block, WT_BLOCK_CKPT *ci); -extern int __wt_verify_ckpt_unload(WT_SESSION_IMPL *session, WT_BLOCK *block); -extern int __wt_block_verify_addr(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr, size_t addr_size); -extern int __wt_block_truncate(WT_SESSION_IMPL *session, WT_BLOCK *block, wt_off_t len); -extern int __wt_block_discard(WT_SESSION_IMPL *session, WT_BLOCK *block, size_t added_size); -extern int __wt_block_write_size(WT_SESSION_IMPL *session, WT_BLOCK *block, size_t *sizep); -extern int __wt_block_write(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, uint8_t *addr, size_t *addr_sizep, bool data_cksum); -extern int __wt_block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_off_t *offsetp, uint32_t *sizep, uint32_t *cksump, bool data_cksum, bool caller_locked); -extern int __wt_bloom_create( WT_SESSION_IMPL *session, const char *uri, const char *config, uint64_t count, uint32_t factor, uint32_t k, WT_BLOOM **bloomp); -extern int __wt_bloom_open(WT_SESSION_IMPL *session, const char *uri, uint32_t factor, uint32_t k, WT_CURSOR *owner, WT_BLOOM **bloomp); -extern int __wt_bloom_insert(WT_BLOOM *bloom, WT_ITEM *key); -extern int __wt_bloom_finalize(WT_BLOOM *bloom); -extern int __wt_bloom_hash(WT_BLOOM *bloom, WT_ITEM *key, WT_BLOOM_HASH *bhash); -extern int __wt_bloom_hash_get(WT_BLOOM *bloom, WT_BLOOM_HASH *bhash); -extern int __wt_bloom_get(WT_BLOOM *bloom, WT_ITEM *key); -extern int __wt_bloom_inmem_get(WT_BLOOM *bloom, WT_ITEM *key); -extern int __wt_bloom_intersection(WT_BLOOM *bloom, WT_BLOOM *other); -extern int __wt_bloom_close(WT_BLOOM *bloom); -extern int __wt_bloom_drop(WT_BLOOM *bloom, const char *config); -extern int __wt_compact(WT_SESSION_IMPL *session, const char *cfg[]); -extern int __wt_compact_page_skip(WT_SESSION_IMPL *session, WT_REF *ref, bool *skipp); -extern int __wt_cursor_key_order_check( WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, bool next); -extern int __wt_cursor_key_order_init(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt); +extern int __wt_block_salvage_next(WT_SESSION_IMPL *session, WT_BLOCK *block, uint8_t *addr, size_t *addr_sizep, bool *eofp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_salvage_valid(WT_SESSION_IMPL *session, WT_BLOCK *block, uint8_t *addr, size_t addr_size, bool valid) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_verify_start(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_CKPT *ckptbase, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_verify_end(WT_SESSION_IMPL *session, WT_BLOCK *block) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_verify_ckpt_load( WT_SESSION_IMPL *session, WT_BLOCK *block, WT_BLOCK_CKPT *ci) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_verify_ckpt_unload(WT_SESSION_IMPL *session, WT_BLOCK *block) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_verify_addr(WT_SESSION_IMPL *session, WT_BLOCK *block, const uint8_t *addr, size_t addr_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_truncate(WT_SESSION_IMPL *session, WT_BLOCK *block, wt_off_t len) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_discard(WT_SESSION_IMPL *session, WT_BLOCK *block, size_t added_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_write_size(WT_SESSION_IMPL *session, WT_BLOCK *block, size_t *sizep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_write(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, uint8_t *addr, size_t *addr_sizep, bool data_checksum, bool checkpoint_io) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_block_write_off(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_ITEM *buf, wt_off_t *offsetp, uint32_t *sizep, uint32_t *checksump, bool data_checksum, bool checkpoint_io, bool caller_locked) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_bloom_create( WT_SESSION_IMPL *session, const char *uri, const char *config, uint64_t count, uint32_t factor, uint32_t k, WT_BLOOM **bloomp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_bloom_open(WT_SESSION_IMPL *session, const char *uri, uint32_t factor, uint32_t k, WT_CURSOR *owner, WT_BLOOM **bloomp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_bloom_insert(WT_BLOOM *bloom, WT_ITEM *key); +extern int __wt_bloom_finalize(WT_BLOOM *bloom) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_bloom_hash(WT_BLOOM *bloom, WT_ITEM *key, WT_BLOOM_HASH *bhash); +extern int __wt_bloom_hash_get(WT_BLOOM *bloom, WT_BLOOM_HASH *bhash) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_bloom_get(WT_BLOOM *bloom, WT_ITEM *key) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_bloom_inmem_get(WT_BLOOM *bloom, WT_ITEM *key) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_bloom_intersection(WT_BLOOM *bloom, WT_BLOOM *other) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_bloom_close(WT_BLOOM *bloom) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_bloom_drop(WT_BLOOM *bloom, const char *config) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_compact(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_compact_page_skip(WT_SESSION_IMPL *session, WT_REF *ref, bool *skipp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_cursor_key_order_check( WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, bool next) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_cursor_key_order_init(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_cursor_key_order_reset(WT_CURSOR_BTREE *cbt); extern void __wt_btcur_iterate_setup(WT_CURSOR_BTREE *cbt); -extern int __wt_btcur_next(WT_CURSOR_BTREE *cbt, bool truncating); -extern int __wt_btcur_prev(WT_CURSOR_BTREE *cbt, bool truncating); -extern int __wt_btcur_reset(WT_CURSOR_BTREE *cbt); -extern int __wt_btcur_search(WT_CURSOR_BTREE *cbt); -extern int __wt_btcur_search_near(WT_CURSOR_BTREE *cbt, int *exactp); -extern int __wt_btcur_insert(WT_CURSOR_BTREE *cbt); -extern int __wt_btcur_update_check(WT_CURSOR_BTREE *cbt); -extern int __wt_btcur_remove(WT_CURSOR_BTREE *cbt); -extern int __wt_btcur_update(WT_CURSOR_BTREE *cbt); -extern int __wt_btcur_next_random(WT_CURSOR_BTREE *cbt); -extern int __wt_btcur_compare(WT_CURSOR_BTREE *a_arg, WT_CURSOR_BTREE *b_arg, int *cmpp); -extern int __wt_btcur_equals(WT_CURSOR_BTREE *a_arg, WT_CURSOR_BTREE *b_arg, int *equalp); -extern int __wt_btcur_range_truncate(WT_CURSOR_BTREE *start, WT_CURSOR_BTREE *stop); +extern int __wt_btcur_next(WT_CURSOR_BTREE *cbt, bool truncating) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_btcur_prev(WT_CURSOR_BTREE *cbt, bool truncating) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_btcur_reset(WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_btcur_search(WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_btcur_search_near(WT_CURSOR_BTREE *cbt, int *exactp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_btcur_insert(WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_btcur_update_check(WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_btcur_remove(WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_btcur_update(WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_btcur_next_random(WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_btcur_compare(WT_CURSOR_BTREE *a_arg, WT_CURSOR_BTREE *b_arg, int *cmpp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_btcur_equals(WT_CURSOR_BTREE *a_arg, WT_CURSOR_BTREE *b_arg, int *equalp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_btcur_range_truncate(WT_CURSOR_BTREE *start, WT_CURSOR_BTREE *stop) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_btcur_init(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt); extern void __wt_btcur_open(WT_CURSOR_BTREE *cbt); -extern int __wt_btcur_close(WT_CURSOR_BTREE *cbt, bool lowlevel); -extern int __wt_debug_set_verbose(WT_SESSION_IMPL *session, const char *v); -extern int __wt_debug_addr_print( WT_SESSION_IMPL *session, const uint8_t *addr, size_t addr_size); -extern int __wt_debug_addr(WT_SESSION_IMPL *session, const uint8_t *addr, size_t addr_size, const char *ofile); -extern int __wt_debug_offset_blind( WT_SESSION_IMPL *session, wt_off_t offset, const char *ofile); -extern int __wt_debug_offset(WT_SESSION_IMPL *session, wt_off_t offset, uint32_t size, uint32_t cksum, const char *ofile); -extern int __wt_debug_disk( WT_SESSION_IMPL *session, const WT_PAGE_HEADER *dsk, const char *ofile); -extern int __wt_debug_tree_shape( WT_SESSION_IMPL *session, WT_PAGE *page, const char *ofile); -extern int __wt_debug_tree_all( WT_SESSION_IMPL *session, WT_BTREE *btree, WT_REF *ref, const char *ofile); -extern int __wt_debug_tree( WT_SESSION_IMPL *session, WT_BTREE *btree, WT_REF *ref, const char *ofile); -extern int __wt_debug_page(WT_SESSION_IMPL *session, WT_REF *ref, const char *ofile); -extern int __wt_delete_page(WT_SESSION_IMPL *session, WT_REF *ref, bool *skipp); +extern int __wt_btcur_close(WT_CURSOR_BTREE *cbt, bool lowlevel) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_debug_set_verbose(WT_SESSION_IMPL *session, const char *v) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_debug_addr_print( WT_SESSION_IMPL *session, const uint8_t *addr, size_t addr_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_debug_addr(WT_SESSION_IMPL *session, const uint8_t *addr, size_t addr_size, const char *ofile) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_debug_offset_blind( WT_SESSION_IMPL *session, wt_off_t offset, const char *ofile) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_debug_offset(WT_SESSION_IMPL *session, wt_off_t offset, uint32_t size, uint32_t checksum, const char *ofile) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_debug_disk( WT_SESSION_IMPL *session, const WT_PAGE_HEADER *dsk, const char *ofile) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_debug_tree_shape( WT_SESSION_IMPL *session, WT_PAGE *page, const char *ofile) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_debug_tree_all( WT_SESSION_IMPL *session, WT_BTREE *btree, WT_REF *ref, const char *ofile) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_debug_tree( WT_SESSION_IMPL *session, WT_BTREE *btree, WT_REF *ref, const char *ofile) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_debug_page(WT_SESSION_IMPL *session, WT_REF *ref, const char *ofile) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_delete_page(WT_SESSION_IMPL *session, WT_REF *ref, bool *skipp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_delete_page_rollback(WT_SESSION_IMPL *session, WT_REF *ref); extern bool __wt_delete_page_skip(WT_SESSION_IMPL *session, WT_REF *ref, bool visible_all); -extern int __wt_delete_page_instantiate(WT_SESSION_IMPL *session, WT_REF *ref); +extern int __wt_delete_page_instantiate(WT_SESSION_IMPL *session, WT_REF *ref) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_ref_out(WT_SESSION_IMPL *session, WT_REF *ref); extern void __wt_page_out(WT_SESSION_IMPL *session, WT_PAGE **pagep); extern void __wt_free_ref( WT_SESSION_IMPL *session, WT_REF *ref, int page_type, bool free_pages); extern void __wt_free_ref_index(WT_SESSION_IMPL *session, WT_PAGE *page, WT_PAGE_INDEX *pindex, bool free_pages); extern void __wt_free_update_list(WT_SESSION_IMPL *session, WT_UPDATE *upd); -extern int __wt_btree_open(WT_SESSION_IMPL *session, const char *op_cfg[]); -extern int __wt_btree_close(WT_SESSION_IMPL *session); +extern int __wt_btree_open(WT_SESSION_IMPL *session, const char *op_cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_btree_close(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_root_ref_init(WT_REF *root_ref, WT_PAGE *root, bool is_recno); -extern int __wt_btree_tree_open( WT_SESSION_IMPL *session, const uint8_t *addr, size_t addr_size); -extern int __wt_btree_new_leaf_page(WT_SESSION_IMPL *session, WT_PAGE **pagep); +extern int __wt_btree_tree_open( WT_SESSION_IMPL *session, const uint8_t *addr, size_t addr_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_btree_new_leaf_page(WT_SESSION_IMPL *session, WT_PAGE **pagep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_btree_evictable(WT_SESSION_IMPL *session, bool on); -extern int __wt_btree_huffman_open(WT_SESSION_IMPL *session); +extern int __wt_btree_huffman_open(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_btree_huffman_close(WT_SESSION_IMPL *session); -extern int __wt_bt_read(WT_SESSION_IMPL *session, WT_ITEM *buf, const uint8_t *addr, size_t addr_size); -extern int __wt_bt_write(WT_SESSION_IMPL *session, WT_ITEM *buf, uint8_t *addr, size_t *addr_sizep, bool checkpoint, bool compressed); +extern int __wt_bt_read(WT_SESSION_IMPL *session, WT_ITEM *buf, const uint8_t *addr, size_t addr_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_bt_write(WT_SESSION_IMPL *session, WT_ITEM *buf, uint8_t *addr, size_t *addr_sizep, bool checkpoint, bool checkpoint_io, bool compressed) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern const char *__wt_page_type_string(u_int type); extern const char *__wt_cell_type_string(uint8_t type); extern const char *__wt_page_addr_string(WT_SESSION_IMPL *session, WT_REF *ref, WT_ITEM *buf); extern const char *__wt_addr_string(WT_SESSION_IMPL *session, const uint8_t *addr, size_t addr_size, WT_ITEM *buf); -extern int __wt_ovfl_read(WT_SESSION_IMPL *session, WT_PAGE *page, WT_CELL_UNPACK *unpack, WT_ITEM *store); -extern int __wt_ovfl_cache(WT_SESSION_IMPL *session, WT_PAGE *page, void *cookie, WT_CELL_UNPACK *vpack); -extern int __wt_ovfl_discard(WT_SESSION_IMPL *session, WT_CELL *cell); -extern int __wt_page_alloc(WT_SESSION_IMPL *session, uint8_t type, uint32_t alloc_entries, bool alloc_refs, WT_PAGE **pagep); -extern int __wt_page_inmem(WT_SESSION_IMPL *session, WT_REF *ref, const void *image, size_t memsize, uint32_t flags, WT_PAGE **pagep); -extern int __wt_las_remove_block(WT_SESSION_IMPL *session, WT_CURSOR *cursor, uint32_t btree_id, const uint8_t *addr, size_t addr_size); +extern int __wt_ovfl_read(WT_SESSION_IMPL *session, WT_PAGE *page, WT_CELL_UNPACK *unpack, WT_ITEM *store) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ovfl_cache(WT_SESSION_IMPL *session, WT_PAGE *page, void *cookie, WT_CELL_UNPACK *vpack) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ovfl_discard(WT_SESSION_IMPL *session, WT_CELL *cell) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_page_alloc(WT_SESSION_IMPL *session, uint8_t type, uint32_t alloc_entries, bool alloc_refs, WT_PAGE **pagep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_page_inmem(WT_SESSION_IMPL *session, WT_REF *ref, const void *image, size_t memsize, uint32_t flags, WT_PAGE **pagep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_las_remove_block(WT_SESSION_IMPL *session, WT_CURSOR *cursor, uint32_t btree_id, const uint8_t *addr, size_t addr_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern int __wt_page_in_func(WT_SESSION_IMPL *session, WT_REF *ref, uint32_t flags #ifdef HAVE_DIAGNOSTIC , const char *file, int line #endif ); -extern int __wt_bt_rebalance(WT_SESSION_IMPL *session, const char *cfg[]); -extern int __wt_kv_return(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_UPDATE *upd); -extern int __wt_bt_salvage(WT_SESSION_IMPL *session, WT_CKPT *ckptbase, const char *cfg[]); +extern int __wt_bt_rebalance(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_kv_return(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_UPDATE *upd) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_bt_salvage(WT_SESSION_IMPL *session, WT_CKPT *ckptbase, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_split_stash_discard(WT_SESSION_IMPL *session); extern void __wt_split_stash_discard_all( WT_SESSION_IMPL *session_safe, WT_SESSION_IMPL *session); -extern int __wt_multi_to_ref(WT_SESSION_IMPL *session, WT_PAGE *page, WT_MULTI *multi, WT_REF **refp, size_t *incrp); -extern int __wt_split_insert(WT_SESSION_IMPL *session, WT_REF *ref); -extern int __wt_split_multi(WT_SESSION_IMPL *session, WT_REF *ref, int closing); -extern int __wt_split_reverse(WT_SESSION_IMPL *session, WT_REF *ref); -extern int __wt_split_rewrite(WT_SESSION_IMPL *session, WT_REF *ref); -extern int __wt_btree_stat_init(WT_SESSION_IMPL *session, WT_CURSOR_STAT *cst); -extern int __wt_cache_op(WT_SESSION_IMPL *session, WT_CACHE_OP op); -extern int __wt_upgrade(WT_SESSION_IMPL *session, const char *cfg[]); -extern int __wt_verify(WT_SESSION_IMPL *session, const char *cfg[]); -extern int __wt_verify_dsk_image(WT_SESSION_IMPL *session, const char *tag, const WT_PAGE_HEADER *dsk, size_t size, bool empty_page_ok); -extern int __wt_verify_dsk(WT_SESSION_IMPL *session, const char *tag, WT_ITEM *buf); -extern int __wt_tree_walk(WT_SESSION_IMPL *session, WT_REF **refp, uint32_t flags); -extern int __wt_tree_walk_count(WT_SESSION_IMPL *session, WT_REF **refp, uint64_t *walkcntp, uint32_t flags); -extern int __wt_tree_walk_skip(WT_SESSION_IMPL *session, WT_REF **refp, uint64_t *skipleafcntp, uint32_t flags); -extern int __wt_col_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, uint64_t recno, WT_ITEM *value, WT_UPDATE *upd_arg, bool is_remove); -extern int __wt_col_search(WT_SESSION_IMPL *session, uint64_t search_recno, WT_REF *leaf, WT_CURSOR_BTREE *cbt); -extern int __wt_row_leaf_keys(WT_SESSION_IMPL *session, WT_PAGE *page); -extern int __wt_row_leaf_key_copy( WT_SESSION_IMPL *session, WT_PAGE *page, WT_ROW *rip, WT_ITEM *key); -extern int __wt_row_leaf_key_work(WT_SESSION_IMPL *session, WT_PAGE *page, WT_ROW *rip_arg, WT_ITEM *keyb, bool instantiate); -extern int __wt_row_ikey_alloc(WT_SESSION_IMPL *session, uint32_t cell_offset, const void *key, size_t size, WT_IKEY **ikeyp); -extern int __wt_row_ikey_incr(WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t cell_offset, const void *key, size_t size, WT_REF *ref); -extern int __wt_row_ikey(WT_SESSION_IMPL *session, uint32_t cell_offset, const void *key, size_t size, WT_REF *ref); -extern int __wt_page_modify_alloc(WT_SESSION_IMPL *session, WT_PAGE *page); -extern int __wt_row_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_ITEM *key, WT_ITEM *value, WT_UPDATE *upd_arg, bool is_remove); -extern int __wt_row_insert_alloc(WT_SESSION_IMPL *session, WT_ITEM *key, u_int skipdepth, WT_INSERT **insp, size_t *ins_sizep); -extern int __wt_update_alloc( WT_SESSION_IMPL *session, WT_ITEM *value, WT_UPDATE **updp, size_t *sizep); +extern int __wt_multi_to_ref(WT_SESSION_IMPL *session, WT_PAGE *page, WT_MULTI *multi, WT_REF **refp, size_t *incrp, bool closing) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_split_insert(WT_SESSION_IMPL *session, WT_REF *ref) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_split_multi(WT_SESSION_IMPL *session, WT_REF *ref, int closing) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_split_reverse(WT_SESSION_IMPL *session, WT_REF *ref) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_split_rewrite(WT_SESSION_IMPL *session, WT_REF *ref, WT_MULTI *multi) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_btree_stat_init(WT_SESSION_IMPL *session, WT_CURSOR_STAT *cst) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_cache_op(WT_SESSION_IMPL *session, WT_CACHE_OP op) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_upgrade(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_verify(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_verify_dsk_image(WT_SESSION_IMPL *session, const char *tag, const WT_PAGE_HEADER *dsk, size_t size, bool empty_page_ok) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_verify_dsk(WT_SESSION_IMPL *session, const char *tag, WT_ITEM *buf) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_tree_walk(WT_SESSION_IMPL *session, WT_REF **refp, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_tree_walk_count(WT_SESSION_IMPL *session, WT_REF **refp, uint64_t *walkcntp, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_tree_walk_skip(WT_SESSION_IMPL *session, WT_REF **refp, uint64_t *skipleafcntp, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_col_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, uint64_t recno, WT_ITEM *value, WT_UPDATE *upd_arg, bool is_remove) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_col_search(WT_SESSION_IMPL *session, uint64_t search_recno, WT_REF *leaf, WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_row_leaf_keys(WT_SESSION_IMPL *session, WT_PAGE *page) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_row_leaf_key_copy( WT_SESSION_IMPL *session, WT_PAGE *page, WT_ROW *rip, WT_ITEM *key) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_row_leaf_key_work(WT_SESSION_IMPL *session, WT_PAGE *page, WT_ROW *rip_arg, WT_ITEM *keyb, bool instantiate) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_row_ikey_alloc(WT_SESSION_IMPL *session, uint32_t cell_offset, const void *key, size_t size, WT_IKEY **ikeyp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_row_ikey_incr(WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t cell_offset, const void *key, size_t size, WT_REF *ref) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_row_ikey(WT_SESSION_IMPL *session, uint32_t cell_offset, const void *key, size_t size, WT_REF *ref) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_page_modify_alloc(WT_SESSION_IMPL *session, WT_PAGE *page) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_row_modify(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_ITEM *key, WT_ITEM *value, WT_UPDATE *upd_arg, bool is_remove) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_row_insert_alloc(WT_SESSION_IMPL *session, WT_ITEM *key, u_int skipdepth, WT_INSERT **insp, size_t *ins_sizep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_update_alloc( WT_SESSION_IMPL *session, WT_ITEM *value, WT_UPDATE **updp, size_t *sizep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern WT_UPDATE *__wt_update_obsolete_check( WT_SESSION_IMPL *session, WT_PAGE *page, WT_UPDATE *upd); extern void __wt_update_obsolete_free( WT_SESSION_IMPL *session, WT_PAGE *page, WT_UPDATE *upd); -extern int __wt_search_insert(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_INSERT_HEAD *ins_head, WT_ITEM *srch_key); -extern int __wt_row_search(WT_SESSION_IMPL *session, WT_ITEM *srch_key, WT_REF *leaf, WT_CURSOR_BTREE *cbt, bool insert); -extern int __wt_row_random_leaf(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt); -extern int __wt_row_random_descent(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt); +extern int __wt_search_insert(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt, WT_INSERT_HEAD *ins_head, WT_ITEM *srch_key) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_row_search(WT_SESSION_IMPL *session, WT_ITEM *srch_key, WT_REF *leaf, WT_CURSOR_BTREE *cbt, bool insert) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_row_random_leaf(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_row_random_descent(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_las_stats_update(WT_SESSION_IMPL *session); -extern int __wt_las_create(WT_SESSION_IMPL *session); -extern int __wt_las_destroy(WT_SESSION_IMPL *session); +extern int __wt_las_create(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_las_destroy(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_las_set_written(WT_SESSION_IMPL *session); extern bool __wt_las_is_written(WT_SESSION_IMPL *session); -extern int __wt_las_cursor_open(WT_SESSION_IMPL *session, WT_CURSOR **cursorp); -extern int __wt_las_cursor( WT_SESSION_IMPL *session, WT_CURSOR **cursorp, uint32_t *session_flags); -extern int __wt_las_cursor_close( WT_SESSION_IMPL *session, WT_CURSOR **cursorp, uint32_t session_flags); -extern int __wt_las_sweep(WT_SESSION_IMPL *session); -extern uint32_t __wt_cksum(const void *chunk, size_t len); -extern void __wt_cksum_init(void); -extern int __wt_config_initn( WT_SESSION_IMPL *session, WT_CONFIG *conf, const char *str, size_t len); -extern int __wt_config_init(WT_SESSION_IMPL *session, WT_CONFIG *conf, const char *str); -extern int __wt_config_subinit( WT_SESSION_IMPL *session, WT_CONFIG *conf, WT_CONFIG_ITEM *item); -extern int __wt_config_next(WT_CONFIG *conf, WT_CONFIG_ITEM *key, WT_CONFIG_ITEM *value); -extern int __wt_config_get(WT_SESSION_IMPL *session, const char **cfg_arg, WT_CONFIG_ITEM *key, WT_CONFIG_ITEM *value); -extern int __wt_config_gets(WT_SESSION_IMPL *session, const char **cfg, const char *key, WT_CONFIG_ITEM *value); -extern int __wt_config_gets_none(WT_SESSION_IMPL *session, const char **cfg, const char *key, WT_CONFIG_ITEM *value); -extern int __wt_config_getone(WT_SESSION_IMPL *session, const char *config, WT_CONFIG_ITEM *key, WT_CONFIG_ITEM *value); -extern int __wt_config_getones(WT_SESSION_IMPL *session, const char *config, const char *key, WT_CONFIG_ITEM *value); -extern int __wt_config_getones_none(WT_SESSION_IMPL *session, const char *config, const char *key, WT_CONFIG_ITEM *value); -extern int __wt_config_gets_def(WT_SESSION_IMPL *session, const char **cfg, const char *key, int def, WT_CONFIG_ITEM *value); -extern int __wt_config_subgetraw(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *cfg, WT_CONFIG_ITEM *key, WT_CONFIG_ITEM *value); -extern int __wt_config_subgets(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *cfg, const char *key, WT_CONFIG_ITEM *value); +extern int __wt_las_cursor_open(WT_SESSION_IMPL *session, WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_las_cursor( WT_SESSION_IMPL *session, WT_CURSOR **cursorp, uint32_t *session_flags); +extern int __wt_las_cursor_close( WT_SESSION_IMPL *session, WT_CURSOR **cursorp, uint32_t session_flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_las_sweep(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern uint32_t __wt_checksum_sw(const void *chunk, size_t len); +extern void __wt_checksum_init(void); +extern void __wt_config_initn( WT_SESSION_IMPL *session, WT_CONFIG *conf, const char *str, size_t len); +extern void __wt_config_init(WT_SESSION_IMPL *session, WT_CONFIG *conf, const char *str); +extern void __wt_config_subinit( WT_SESSION_IMPL *session, WT_CONFIG *conf, WT_CONFIG_ITEM *item); +extern int __wt_config_next(WT_CONFIG *conf, WT_CONFIG_ITEM *key, WT_CONFIG_ITEM *value) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_config_get(WT_SESSION_IMPL *session, const char **cfg_arg, WT_CONFIG_ITEM *key, WT_CONFIG_ITEM *value) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_config_gets(WT_SESSION_IMPL *session, const char **cfg, const char *key, WT_CONFIG_ITEM *value) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_config_gets_none(WT_SESSION_IMPL *session, const char **cfg, const char *key, WT_CONFIG_ITEM *value) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_config_getone(WT_SESSION_IMPL *session, const char *config, WT_CONFIG_ITEM *key, WT_CONFIG_ITEM *value) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_config_getones(WT_SESSION_IMPL *session, const char *config, const char *key, WT_CONFIG_ITEM *value) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_config_getones_none(WT_SESSION_IMPL *session, const char *config, const char *key, WT_CONFIG_ITEM *value) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_config_gets_def(WT_SESSION_IMPL *session, const char **cfg, const char *key, int def, WT_CONFIG_ITEM *value) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_config_subgetraw(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *cfg, WT_CONFIG_ITEM *key, WT_CONFIG_ITEM *value) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_config_subgets(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *cfg, const char *key, WT_CONFIG_ITEM *value) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_conn_foc_discard(WT_SESSION_IMPL *session); -extern int __wt_configure_method(WT_SESSION_IMPL *session, const char *method, const char *uri, const char *config, const char *type, const char *check); -extern int __wt_config_check(WT_SESSION_IMPL *session, const WT_CONFIG_ENTRY *entry, const char *config, size_t config_len); -extern int __wt_config_collapse( WT_SESSION_IMPL *session, const char **cfg, char **config_ret); -extern int __wt_config_merge(WT_SESSION_IMPL *session, const char **cfg, const char *cfg_strip, const char **config_ret); -extern int __wt_conn_config_init(WT_SESSION_IMPL *session); +extern int __wt_configure_method(WT_SESSION_IMPL *session, const char *method, const char *uri, const char *config, const char *type, const char *check) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_config_check(WT_SESSION_IMPL *session, const WT_CONFIG_ENTRY *entry, const char *config, size_t config_len) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_config_collapse( WT_SESSION_IMPL *session, const char **cfg, char **config_ret) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_config_merge(WT_SESSION_IMPL *session, const char **cfg, const char *cfg_strip, const char **config_ret) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_conn_config_init(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_conn_config_discard(WT_SESSION_IMPL *session); extern const WT_CONFIG_ENTRY *__wt_conn_config_match(const char *method); -extern int __wt_ext_config_parser_open(WT_EXTENSION_API *wt_ext, WT_SESSION *wt_session, const char *config, size_t len, WT_CONFIG_PARSER **config_parserp); -extern int __wt_ext_config_get(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, WT_CONFIG_ARG *cfg_arg, const char *key, WT_CONFIG_ITEM *cval); -extern int __wt_config_upgrade(WT_SESSION_IMPL *session, WT_ITEM *buf); +extern int __wt_ext_config_parser_open(WT_EXTENSION_API *wt_ext, WT_SESSION *wt_session, const char *config, size_t len, WT_CONFIG_PARSER **config_parserp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ext_config_get(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, WT_CONFIG_ARG *cfg_arg, const char *key, WT_CONFIG_ITEM *cval) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_config_upgrade(WT_SESSION_IMPL *session, WT_ITEM *buf) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern const char *__wt_wiredtiger_error(int error); -extern int __wt_collator_config(WT_SESSION_IMPL *session, const char *uri, WT_CONFIG_ITEM *cname, WT_CONFIG_ITEM *metadata, WT_COLLATOR **collatorp, int *ownp); -extern int __wt_conn_remove_collator(WT_SESSION_IMPL *session); -extern int __wt_compressor_config( WT_SESSION_IMPL *session, WT_CONFIG_ITEM *cval, WT_COMPRESSOR **compressorp); -extern int __wt_conn_remove_compressor(WT_SESSION_IMPL *session); -extern int __wt_conn_remove_data_source(WT_SESSION_IMPL *session); -extern int __wt_encryptor_config(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *cval, WT_CONFIG_ITEM *keyid, WT_CONFIG_ARG *cfg_arg, WT_KEYED_ENCRYPTOR **kencryptorp); -extern int __wt_conn_remove_encryptor(WT_SESSION_IMPL *session); -extern int __wt_extractor_config(WT_SESSION_IMPL *session, const char *uri, const char *config, WT_EXTRACTOR **extractorp, int *ownp); -extern int __wt_conn_remove_extractor(WT_SESSION_IMPL *session); -extern int __wt_verbose_config(WT_SESSION_IMPL *session, const char *cfg[]); -extern int __wt_cache_config(WT_SESSION_IMPL *session, bool reconfigure, const char *cfg[]); -extern int __wt_cache_create(WT_SESSION_IMPL *session, const char *cfg[]); +extern int __wt_collator_config(WT_SESSION_IMPL *session, const char *uri, WT_CONFIG_ITEM *cname, WT_CONFIG_ITEM *metadata, WT_COLLATOR **collatorp, int *ownp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_conn_remove_collator(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_compressor_config( WT_SESSION_IMPL *session, WT_CONFIG_ITEM *cval, WT_COMPRESSOR **compressorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_conn_remove_compressor(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_conn_remove_data_source(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_encryptor_config(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *cval, WT_CONFIG_ITEM *keyid, WT_CONFIG_ARG *cfg_arg, WT_KEYED_ENCRYPTOR **kencryptorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_conn_remove_encryptor(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_extractor_config(WT_SESSION_IMPL *session, const char *uri, const char *config, WT_EXTRACTOR **extractorp, int *ownp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_conn_remove_extractor(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_verbose_config(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_cache_config(WT_SESSION_IMPL *session, bool reconfigure, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_cache_create(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_cache_stats_update(WT_SESSION_IMPL *session); -extern int __wt_cache_destroy(WT_SESSION_IMPL *session); -extern int __wt_cache_pool_config(WT_SESSION_IMPL *session, const char **cfg); -extern int __wt_conn_cache_pool_open(WT_SESSION_IMPL *session); -extern int __wt_conn_cache_pool_destroy(WT_SESSION_IMPL *session); +extern int __wt_cache_destroy(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_cache_pool_config(WT_SESSION_IMPL *session, const char **cfg) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_conn_cache_pool_open(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_conn_cache_pool_destroy(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern WT_THREAD_RET __wt_cache_pool_server(void *arg); -extern int __wt_checkpoint_server_create(WT_SESSION_IMPL *session, const char *cfg[]); -extern int __wt_checkpoint_server_destroy(WT_SESSION_IMPL *session); -extern int __wt_checkpoint_signal(WT_SESSION_IMPL *session, wt_off_t logsize); -extern int __wt_conn_dhandle_find( WT_SESSION_IMPL *session, const char *uri, const char *checkpoint); -extern int __wt_conn_btree_sync_and_close(WT_SESSION_IMPL *session, bool final, bool force); -extern int __wt_conn_btree_open( WT_SESSION_IMPL *session, const char *cfg[], uint32_t flags); -extern int __wt_conn_btree_apply(WT_SESSION_IMPL *session, const char *uri, int (*file_func)(WT_SESSION_IMPL *, const char *[]), int (*name_func)(WT_SESSION_IMPL *, const char *, bool *), const char *cfg[]); -extern int __wt_conn_dhandle_close_all( WT_SESSION_IMPL *session, const char *uri, bool force); -extern int __wt_conn_dhandle_discard_single( WT_SESSION_IMPL *session, bool final, bool force); -extern int __wt_conn_dhandle_discard(WT_SESSION_IMPL *session); -extern int __wt_connection_init(WT_CONNECTION_IMPL *conn); -extern int __wt_connection_destroy(WT_CONNECTION_IMPL *conn); -extern int __wt_logmgr_reconfig(WT_SESSION_IMPL *session, const char **cfg); -extern int __wt_log_truncate_files( WT_SESSION_IMPL *session, WT_CURSOR *cursor, const char *cfg[]); -extern int __wt_log_wrlsn(WT_SESSION_IMPL *session, int *yield); -extern int __wt_logmgr_create(WT_SESSION_IMPL *session, const char *cfg[]); -extern int __wt_logmgr_open(WT_SESSION_IMPL *session); -extern int __wt_logmgr_destroy(WT_SESSION_IMPL *session); -extern int __wt_connection_open(WT_CONNECTION_IMPL *conn, const char *cfg[]); -extern int __wt_connection_close(WT_CONNECTION_IMPL *conn); -extern int __wt_connection_workers(WT_SESSION_IMPL *session, const char *cfg[]); +extern int __wt_checkpoint_server_create(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_checkpoint_server_destroy(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_checkpoint_signal(WT_SESSION_IMPL *session, wt_off_t logsize); +extern int __wt_conn_dhandle_find( WT_SESSION_IMPL *session, const char *uri, const char *checkpoint) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_conn_btree_sync_and_close(WT_SESSION_IMPL *session, bool final, bool force) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_conn_btree_open( WT_SESSION_IMPL *session, const char *cfg[], uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_conn_btree_apply(WT_SESSION_IMPL *session, const char *uri, int (*file_func)(WT_SESSION_IMPL *, const char *[]), int (*name_func)(WT_SESSION_IMPL *, const char *, bool *), const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_conn_dhandle_close_all( WT_SESSION_IMPL *session, const char *uri, bool force) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_conn_dhandle_discard_single( WT_SESSION_IMPL *session, bool final, bool force) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_conn_dhandle_discard(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_connection_init(WT_CONNECTION_IMPL *conn) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_connection_destroy(WT_CONNECTION_IMPL *conn) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logmgr_reconfig(WT_SESSION_IMPL *session, const char **cfg) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_log_truncate_files( WT_SESSION_IMPL *session, WT_CURSOR *cursor, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_log_wrlsn(WT_SESSION_IMPL *session, int *yield); +extern int __wt_logmgr_create(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logmgr_open(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logmgr_destroy(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_connection_open(WT_CONNECTION_IMPL *conn, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_connection_close(WT_CONNECTION_IMPL *conn) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_connection_workers(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_conn_stat_init(WT_SESSION_IMPL *session); -extern int __wt_statlog_log_one(WT_SESSION_IMPL *session); -extern int __wt_statlog_create(WT_SESSION_IMPL *session, const char *cfg[]); -extern int __wt_statlog_destroy(WT_SESSION_IMPL *session, bool is_close); -extern int __wt_sweep_config(WT_SESSION_IMPL *session, const char *cfg[]); -extern int __wt_sweep_create(WT_SESSION_IMPL *session); -extern int __wt_sweep_destroy(WT_SESSION_IMPL *session); -extern int __wt_curbackup_open(WT_SESSION_IMPL *session, const char *uri, const char *cfg[], WT_CURSOR **cursorp); -extern int __wt_backup_file_remove(WT_SESSION_IMPL *session); -extern int __wt_curbulk_init(WT_SESSION_IMPL *session, WT_CURSOR_BULK *cbulk, bool bitmap, bool skip_sort_check); -extern int __wt_curconfig_open(WT_SESSION_IMPL *session, const char *uri, const char *cfg[], WT_CURSOR **cursorp); -extern int __wt_curds_open( WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_DATA_SOURCE *dsrc, WT_CURSOR **cursorp); -extern int __wt_curdump_create(WT_CURSOR *child, WT_CURSOR *owner, WT_CURSOR **cursorp); -extern int __wt_curfile_update_check(WT_CURSOR *cursor); -extern int __wt_curfile_create(WT_SESSION_IMPL *session, WT_CURSOR *owner, const char *cfg[], bool bulk, bool bitmap, WT_CURSOR **cursorp); -extern int __wt_curfile_open(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp); -extern int __wt_curindex_open(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp); -extern int __wt_curjoin_joined(WT_CURSOR *cursor); -extern int __wt_curjoin_open(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp); -extern int __wt_curjoin_join(WT_SESSION_IMPL *session, WT_CURSOR_JOIN *cjoin, WT_INDEX *idx, WT_CURSOR *ref_cursor, uint8_t flags, uint8_t range, uint64_t count, uint32_t bloom_bit_count, uint32_t bloom_hash_count); -extern int __wt_json_alloc_unpack(WT_SESSION_IMPL *session, const void *buffer, size_t size, const char *fmt, WT_CURSOR_JSON *json, bool iskey, va_list ap); +extern int __wt_statlog_log_one(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_statlog_create(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_statlog_destroy(WT_SESSION_IMPL *session, bool is_close) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_sweep_config(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_sweep_create(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_sweep_destroy(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_curbackup_open(WT_SESSION_IMPL *session, const char *uri, const char *cfg[], WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_backup_file_remove(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_curbulk_init(WT_SESSION_IMPL *session, WT_CURSOR_BULK *cbulk, bool bitmap, bool skip_sort_check) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_curconfig_open(WT_SESSION_IMPL *session, const char *uri, const char *cfg[], WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_curds_open( WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_DATA_SOURCE *dsrc, WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_curdump_create(WT_CURSOR *child, WT_CURSOR *owner, WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_curfile_update_check(WT_CURSOR *cursor) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_curfile_open(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_curindex_open(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_curjoin_joined(WT_CURSOR *cursor) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_curjoin_open(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_curjoin_join(WT_SESSION_IMPL *session, WT_CURSOR_JOIN *cjoin, WT_INDEX *idx, WT_CURSOR *ref_cursor, uint8_t flags, uint8_t range, uint64_t count, uint32_t bloom_bit_count, uint32_t bloom_hash_count) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_json_alloc_unpack(WT_SESSION_IMPL *session, const void *buffer, size_t size, const char *fmt, WT_CURSOR_JSON *json, bool iskey, va_list ap) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_json_close(WT_SESSION_IMPL *session, WT_CURSOR *cursor); extern size_t __wt_json_unpack_char(u_char ch, u_char *buf, size_t bufsz, bool force_unicode); -extern int __wt_json_column_init(WT_CURSOR *cursor, const char *keyformat, const WT_CONFIG_ITEM *idxconf, const WT_CONFIG_ITEM *colconf); -extern int __wt_json_token(WT_SESSION *wt_session, const char *src, int *toktype, const char **tokstart, size_t *toklen); +extern void __wt_json_column_init(WT_CURSOR *cursor, const char *keyformat, const WT_CONFIG_ITEM *idxconf, const WT_CONFIG_ITEM *colconf); +extern int __wt_json_token(WT_SESSION *wt_session, const char *src, int *toktype, const char **tokstart, size_t *toklen) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern const char *__wt_json_tokname(int toktype); -extern int __wt_json_to_item(WT_SESSION_IMPL *session, const char *jstr, const char *format, WT_CURSOR_JSON *json, bool iskey, WT_ITEM *item); +extern int __wt_json_to_item(WT_SESSION_IMPL *session, const char *jstr, const char *format, WT_CURSOR_JSON *json, bool iskey, WT_ITEM *item) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern ssize_t __wt_json_strlen(const char *src, size_t srclen); -extern int __wt_json_strncpy(WT_SESSION *wt_session, char **pdst, size_t dstlen, const char *src, size_t srclen); -extern int __wt_curlog_open(WT_SESSION_IMPL *session, const char *uri, const char *cfg[], WT_CURSOR **cursorp); -extern int __wt_schema_create_final( WT_SESSION_IMPL *session, char *cfg_arg[], char **value_ret); -extern int __wt_curmetadata_open(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp); +extern int __wt_json_strncpy(WT_SESSION *wt_session, char **pdst, size_t dstlen, const char *src, size_t srclen) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_curlog_open(WT_SESSION_IMPL *session, const char *uri, const char *cfg[], WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_curmetadata_open(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_curstat_dsrc_final(WT_CURSOR_STAT *cst); -extern int __wt_curstat_init(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *curjoin, const char *cfg[], WT_CURSOR_STAT *cst); -extern int __wt_curstat_open(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *other, const char *cfg[], WT_CURSOR **cursorp); -extern int __wt_cursor_noop(WT_CURSOR *cursor); -extern int __wt_cursor_notsup(WT_CURSOR *cursor); -extern int __wt_cursor_get_value_notsup(WT_CURSOR *cursor, ...); +extern int __wt_curstat_init(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *curjoin, const char *cfg[], WT_CURSOR_STAT *cst) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_curstat_open(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *other, const char *cfg[], WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_cursor_noop(WT_CURSOR *cursor) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_cursor_notsup(WT_CURSOR *cursor) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_cursor_get_value_notsup(WT_CURSOR *cursor, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_cursor_set_key_notsup(WT_CURSOR *cursor, ...); extern void __wt_cursor_set_value_notsup(WT_CURSOR *cursor, ...); -extern int __wt_cursor_compare_notsup(WT_CURSOR *a, WT_CURSOR *b, int *cmpp); -extern int __wt_cursor_equals_notsup(WT_CURSOR *cursor, WT_CURSOR *other, int *equalp); -extern int __wt_cursor_search_near_notsup(WT_CURSOR *cursor, int *exact); -extern int __wt_cursor_reconfigure_notsup(WT_CURSOR *cursor, const char *config); +extern int __wt_cursor_compare_notsup(WT_CURSOR *a, WT_CURSOR *b, int *cmpp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_cursor_equals_notsup(WT_CURSOR *cursor, WT_CURSOR *other, int *equalp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_cursor_search_near_notsup(WT_CURSOR *cursor, int *exact) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_cursor_reconfigure_notsup(WT_CURSOR *cursor, const char *config) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_cursor_set_notsup(WT_CURSOR *cursor); -extern int __wt_cursor_kv_not_set(WT_CURSOR *cursor, bool key); -extern int __wt_cursor_get_key(WT_CURSOR *cursor, ...); +extern int __wt_cursor_kv_not_set(WT_CURSOR *cursor, bool key) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_cursor_get_key(WT_CURSOR *cursor, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_cursor_set_key(WT_CURSOR *cursor, ...); -extern int __wt_cursor_get_raw_key(WT_CURSOR *cursor, WT_ITEM *key); +extern int __wt_cursor_get_raw_key(WT_CURSOR *cursor, WT_ITEM *key) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_cursor_set_raw_key(WT_CURSOR *cursor, WT_ITEM *key); -extern int __wt_cursor_get_raw_value(WT_CURSOR *cursor, WT_ITEM *value); +extern int __wt_cursor_get_raw_value(WT_CURSOR *cursor, WT_ITEM *value) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_cursor_set_raw_value(WT_CURSOR *cursor, WT_ITEM *value); -extern int __wt_cursor_get_keyv(WT_CURSOR *cursor, uint32_t flags, va_list ap); +extern int __wt_cursor_get_keyv(WT_CURSOR *cursor, uint32_t flags, va_list ap) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_cursor_set_keyv(WT_CURSOR *cursor, uint32_t flags, va_list ap); -extern int __wt_cursor_get_value(WT_CURSOR *cursor, ...); -extern int __wt_cursor_get_valuev(WT_CURSOR *cursor, va_list ap); +extern int __wt_cursor_get_value(WT_CURSOR *cursor, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_cursor_get_valuev(WT_CURSOR *cursor, va_list ap) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_cursor_set_value(WT_CURSOR *cursor, ...); extern void __wt_cursor_set_valuev(WT_CURSOR *cursor, va_list ap); -extern int __wt_cursor_close(WT_CURSOR *cursor); -extern int __wt_cursor_equals(WT_CURSOR *cursor, WT_CURSOR *other, int *equalp); -extern int __wt_cursor_reconfigure(WT_CURSOR *cursor, const char *config); -extern int __wt_cursor_dup_position(WT_CURSOR *to_dup, WT_CURSOR *cursor); -extern int __wt_cursor_init(WT_CURSOR *cursor, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp); -extern int __wt_apply_single_idx(WT_SESSION_IMPL *session, WT_INDEX *idx, WT_CURSOR *cur, WT_CURSOR_TABLE *ctable, int (*f)(WT_CURSOR *)); -extern int __wt_curtable_get_key(WT_CURSOR *cursor, ...); -extern int __wt_curtable_get_value(WT_CURSOR *cursor, ...); +extern int __wt_cursor_close(WT_CURSOR *cursor) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_cursor_equals(WT_CURSOR *cursor, WT_CURSOR *other, int *equalp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_cursor_reconfigure(WT_CURSOR *cursor, const char *config) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_cursor_dup_position(WT_CURSOR *to_dup, WT_CURSOR *cursor) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_cursor_init(WT_CURSOR *cursor, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_apply_single_idx(WT_SESSION_IMPL *session, WT_INDEX *idx, WT_CURSOR *cur, WT_CURSOR_TABLE *ctable, int (*f)(WT_CURSOR *)) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_curtable_get_key(WT_CURSOR *cursor, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_curtable_get_value(WT_CURSOR *cursor, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_curtable_set_key(WT_CURSOR *cursor, ...); extern void __wt_curtable_set_value(WT_CURSOR *cursor, ...); -extern int __wt_table_range_truncate(WT_CURSOR_TABLE *start, WT_CURSOR_TABLE *stop); -extern int __wt_curtable_open(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp); -extern int __wt_evict_file(WT_SESSION_IMPL *session, WT_CACHE_OP syncop); +extern int __wt_table_range_truncate(WT_CURSOR_TABLE *start, WT_CURSOR_TABLE *stop) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_curtable_open(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_evict_file(WT_SESSION_IMPL *session, WT_CACHE_OP syncop) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_evict_list_clear_page(WT_SESSION_IMPL *session, WT_REF *ref); -extern int __wt_evict_server_wake(WT_SESSION_IMPL *session); -extern int __wt_evict_create(WT_SESSION_IMPL *session); -extern int __wt_evict_destroy(WT_SESSION_IMPL *session); -extern int __wt_evict_file_exclusive_on(WT_SESSION_IMPL *session); +extern void __wt_evict_server_wake(WT_SESSION_IMPL *session); +extern int __wt_evict_thread_run(WT_SESSION_IMPL *session, WT_THREAD *thread) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_evict_create(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_evict_destroy(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_evict_file_exclusive_on(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_evict_file_exclusive_off(WT_SESSION_IMPL *session); -extern int __wt_cache_eviction_worker(WT_SESSION_IMPL *session, bool busy, u_int pct_full); +extern int __wt_cache_eviction_worker(WT_SESSION_IMPL *session, bool busy, u_int pct_full) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern bool __wt_page_evict_urgent(WT_SESSION_IMPL *session, WT_REF *ref); extern void __wt_evict_priority_set(WT_SESSION_IMPL *session, uint64_t v); extern void __wt_evict_priority_clear(WT_SESSION_IMPL *session); -extern int __wt_cache_dump(WT_SESSION_IMPL *session, const char *ofile); -extern int __wt_evict(WT_SESSION_IMPL *session, WT_REF *ref, bool closing); -extern int __wt_log_ckpt(WT_SESSION_IMPL *session, WT_LSN *ckp_lsn); -extern int __wt_log_flush_lsn(WT_SESSION_IMPL *session, WT_LSN *lsn, bool start); -extern int __wt_log_background(WT_SESSION_IMPL *session, WT_LSN *lsn); -extern int __wt_log_force_sync(WT_SESSION_IMPL *session, WT_LSN *min_lsn); -extern int __wt_log_needs_recovery(WT_SESSION_IMPL *session, WT_LSN *ckp_lsn, bool *recp); +extern int __wt_cache_dump(WT_SESSION_IMPL *session, const char *ofile) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_page_release_evict(WT_SESSION_IMPL *session, WT_REF *ref) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_evict(WT_SESSION_IMPL *session, WT_REF *ref, bool closing) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_log_ckpt(WT_SESSION_IMPL *session, WT_LSN *ckp_lsn); +extern int __wt_log_flush_lsn(WT_SESSION_IMPL *session, WT_LSN *lsn, bool start) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_log_background(WT_SESSION_IMPL *session, WT_LSN *lsn); +extern int __wt_log_force_sync(WT_SESSION_IMPL *session, WT_LSN *min_lsn) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_log_needs_recovery(WT_SESSION_IMPL *session, WT_LSN *ckp_lsn, bool *recp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_log_written_reset(WT_SESSION_IMPL *session); -extern int __wt_log_get_all_files(WT_SESSION_IMPL *session, char ***filesp, u_int *countp, uint32_t *maxid, bool active_only); -extern int __wt_log_extract_lognum( WT_SESSION_IMPL *session, const char *name, uint32_t *id); -extern int __wt_log_acquire(WT_SESSION_IMPL *session, uint64_t recsize, WT_LOGSLOT *slot); -extern int __wt_log_allocfile( WT_SESSION_IMPL *session, uint32_t lognum, const char *dest); -extern int __wt_log_remove(WT_SESSION_IMPL *session, const char *file_prefix, uint32_t lognum); -extern int __wt_log_open(WT_SESSION_IMPL *session); -extern int __wt_log_close(WT_SESSION_IMPL *session); -extern int __wt_log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot, bool *freep); -extern int __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags, int (*func)(WT_SESSION_IMPL *session, WT_ITEM *record, WT_LSN *lsnp, WT_LSN *next_lsnp, void *cookie, int firstrecord), void *cookie); -extern int __wt_log_force_write(WT_SESSION_IMPL *session, bool retry, bool *did_work); -extern int __wt_log_write(WT_SESSION_IMPL *session, WT_ITEM *record, WT_LSN *lsnp, uint32_t flags); -extern int __wt_log_vprintf(WT_SESSION_IMPL *session, const char *fmt, va_list ap); -extern int __wt_log_flush(WT_SESSION_IMPL *session, uint32_t flags); -extern int __wt_logrec_alloc(WT_SESSION_IMPL *session, size_t size, WT_ITEM **logrecp); +extern int __wt_log_get_all_files(WT_SESSION_IMPL *session, char ***filesp, u_int *countp, uint32_t *maxid, bool active_only) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_log_extract_lognum( WT_SESSION_IMPL *session, const char *name, uint32_t *id) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_log_acquire(WT_SESSION_IMPL *session, uint64_t recsize, WT_LOGSLOT *slot) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_log_allocfile( WT_SESSION_IMPL *session, uint32_t lognum, const char *dest) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_log_remove(WT_SESSION_IMPL *session, const char *file_prefix, uint32_t lognum) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_log_open(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_log_close(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot, bool *freep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags, int (*func)(WT_SESSION_IMPL *session, WT_ITEM *record, WT_LSN *lsnp, WT_LSN *next_lsnp, void *cookie, int firstrecord), void *cookie) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_log_force_write(WT_SESSION_IMPL *session, bool retry, bool *did_work) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_log_write(WT_SESSION_IMPL *session, WT_ITEM *record, WT_LSN *lsnp, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_log_vprintf(WT_SESSION_IMPL *session, const char *fmt, va_list ap) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_log_flush(WT_SESSION_IMPL *session, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logrec_alloc(WT_SESSION_IMPL *session, size_t size, WT_ITEM **logrecp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_logrec_free(WT_SESSION_IMPL *session, WT_ITEM **logrecp); -extern int __wt_logrec_read(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *rectypep); -extern int __wt_logop_read(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *optypep, uint32_t *opsizep); -extern int __wt_logop_col_put_pack( WT_SESSION_IMPL *session, WT_ITEM *logrec, uint32_t fileid, uint64_t recno, WT_ITEM *value); -extern int __wt_logop_col_put_unpack( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *fileidp, uint64_t *recnop, WT_ITEM *valuep); -extern int __wt_logop_col_put_print(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t flags); -extern int __wt_logop_col_remove_pack( WT_SESSION_IMPL *session, WT_ITEM *logrec, uint32_t fileid, uint64_t recno); -extern int __wt_logop_col_remove_unpack( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *fileidp, uint64_t *recnop); -extern int __wt_logop_col_remove_print(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t flags); -extern int __wt_logop_col_truncate_pack( WT_SESSION_IMPL *session, WT_ITEM *logrec, uint32_t fileid, uint64_t start, uint64_t stop); -extern int __wt_logop_col_truncate_unpack( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *fileidp, uint64_t *startp, uint64_t *stopp); -extern int __wt_logop_col_truncate_print(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t flags); -extern int __wt_logop_row_put_pack( WT_SESSION_IMPL *session, WT_ITEM *logrec, uint32_t fileid, WT_ITEM *key, WT_ITEM *value); -extern int __wt_logop_row_put_unpack( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *fileidp, WT_ITEM *keyp, WT_ITEM *valuep); -extern int __wt_logop_row_put_print(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t flags); -extern int __wt_logop_row_remove_pack( WT_SESSION_IMPL *session, WT_ITEM *logrec, uint32_t fileid, WT_ITEM *key); -extern int __wt_logop_row_remove_unpack( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *fileidp, WT_ITEM *keyp); -extern int __wt_logop_row_remove_print(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t flags); -extern int __wt_logop_row_truncate_pack( WT_SESSION_IMPL *session, WT_ITEM *logrec, uint32_t fileid, WT_ITEM *start, WT_ITEM *stop, uint32_t mode); -extern int __wt_logop_row_truncate_unpack( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *fileidp, WT_ITEM *startp, WT_ITEM *stopp, uint32_t *modep); -extern int __wt_logop_row_truncate_print(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t flags); -extern int __wt_txn_op_printlog(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t flags); +extern int __wt_logrec_read(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *rectypep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logop_read(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *optypep, uint32_t *opsizep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logop_col_put_pack( WT_SESSION_IMPL *session, WT_ITEM *logrec, uint32_t fileid, uint64_t recno, WT_ITEM *value) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logop_col_put_unpack( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *fileidp, uint64_t *recnop, WT_ITEM *valuep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logop_col_put_print(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logop_col_remove_pack( WT_SESSION_IMPL *session, WT_ITEM *logrec, uint32_t fileid, uint64_t recno) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logop_col_remove_unpack( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *fileidp, uint64_t *recnop) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logop_col_remove_print(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logop_col_truncate_pack( WT_SESSION_IMPL *session, WT_ITEM *logrec, uint32_t fileid, uint64_t start, uint64_t stop) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logop_col_truncate_unpack( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *fileidp, uint64_t *startp, uint64_t *stopp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logop_col_truncate_print(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logop_row_put_pack( WT_SESSION_IMPL *session, WT_ITEM *logrec, uint32_t fileid, WT_ITEM *key, WT_ITEM *value) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logop_row_put_unpack( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *fileidp, WT_ITEM *keyp, WT_ITEM *valuep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logop_row_put_print(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logop_row_remove_pack( WT_SESSION_IMPL *session, WT_ITEM *logrec, uint32_t fileid, WT_ITEM *key) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logop_row_remove_unpack( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *fileidp, WT_ITEM *keyp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logop_row_remove_print(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logop_row_truncate_pack( WT_SESSION_IMPL *session, WT_ITEM *logrec, uint32_t fileid, WT_ITEM *start, WT_ITEM *stop, uint32_t mode) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logop_row_truncate_unpack( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t *fileidp, WT_ITEM *startp, WT_ITEM *stopp, uint32_t *modep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_logop_row_truncate_print(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_txn_op_printlog(WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_log_slot_activate(WT_SESSION_IMPL *session, WT_LOGSLOT *slot); -extern int __wt_log_slot_switch( WT_SESSION_IMPL *session, WT_MYSLOT *myslot, bool retry, bool forced); -extern int __wt_log_slot_new(WT_SESSION_IMPL *session); -extern int __wt_log_slot_init(WT_SESSION_IMPL *session); -extern int __wt_log_slot_destroy(WT_SESSION_IMPL *session); +extern int __wt_log_slot_switch( WT_SESSION_IMPL *session, WT_MYSLOT *myslot, bool retry, bool forced) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_log_slot_new(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_log_slot_init(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_log_slot_destroy(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_log_slot_join(WT_SESSION_IMPL *session, uint64_t mysize, uint32_t flags, WT_MYSLOT *myslot); extern int64_t __wt_log_slot_release(WT_SESSION_IMPL *session, WT_MYSLOT *myslot, int64_t size); extern void __wt_log_slot_free(WT_SESSION_IMPL *session, WT_LOGSLOT *slot); -extern int __wt_clsm_request_switch(WT_CURSOR_LSM *clsm); -extern int __wt_clsm_await_switch(WT_CURSOR_LSM *clsm); -extern int __wt_clsm_init_merge( WT_CURSOR *cursor, u_int start_chunk, uint32_t start_id, u_int nchunks); -extern int __wt_clsm_close(WT_CURSOR *cursor); -extern int __wt_clsm_open(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp); -extern int __wt_clsm_open_bulk(WT_CURSOR_LSM *clsm, const char *cfg[]); -extern int __wt_lsm_manager_config(WT_SESSION_IMPL *session, const char **cfg); -extern int __wt_lsm_manager_reconfig(WT_SESSION_IMPL *session, const char **cfg); -extern int __wt_lsm_manager_start(WT_SESSION_IMPL *session); +extern int __wt_clsm_request_switch(WT_CURSOR_LSM *clsm) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_clsm_await_switch(WT_CURSOR_LSM *clsm) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_clsm_init_merge( WT_CURSOR *cursor, u_int start_chunk, uint32_t start_id, u_int nchunks) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_clsm_close(WT_CURSOR *cursor) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_clsm_open(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_clsm_open_bulk(WT_CURSOR_LSM *clsm, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_manager_config(WT_SESSION_IMPL *session, const char **cfg) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_manager_reconfig(WT_SESSION_IMPL *session, const char **cfg) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_manager_start(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_lsm_manager_free_work_unit( WT_SESSION_IMPL *session, WT_LSM_WORK_UNIT *entry); -extern int __wt_lsm_manager_destroy(WT_SESSION_IMPL *session); -extern int __wt_lsm_manager_clear_tree( WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree); -extern int __wt_lsm_manager_pop_entry( WT_SESSION_IMPL *session, uint32_t type, WT_LSM_WORK_UNIT **entryp); -extern int __wt_lsm_manager_push_entry(WT_SESSION_IMPL *session, uint32_t type, uint32_t flags, WT_LSM_TREE *lsm_tree); -extern int __wt_lsm_merge_update_tree(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, u_int start_chunk, u_int nchunks, WT_LSM_CHUNK *chunk); -extern int __wt_lsm_merge(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, u_int id); -extern int __wt_lsm_meta_read(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree); -extern int __wt_lsm_meta_write(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree); -extern int __wt_curstat_lsm_init( WT_SESSION_IMPL *session, const char *uri, WT_CURSOR_STAT *cst); -extern int __wt_lsm_tree_close_all(WT_SESSION_IMPL *session); -extern int __wt_lsm_tree_bloom_name(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, uint32_t id, const char **retp); -extern int __wt_lsm_tree_chunk_name(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, uint32_t id, const char **retp); -extern int __wt_lsm_tree_set_chunk_size( WT_SESSION_IMPL *session, WT_LSM_CHUNK *chunk); -extern int __wt_lsm_tree_setup_chunk( WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, WT_LSM_CHUNK *chunk); -extern int __wt_lsm_tree_setup_bloom( WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, WT_LSM_CHUNK *chunk); -extern int __wt_lsm_tree_create(WT_SESSION_IMPL *session, const char *uri, bool exclusive, const char *config); -extern int __wt_lsm_tree_get(WT_SESSION_IMPL *session, const char *uri, bool exclusive, WT_LSM_TREE **treep); +extern int __wt_lsm_manager_destroy(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_lsm_manager_clear_tree(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree); +extern int __wt_lsm_manager_pop_entry( WT_SESSION_IMPL *session, uint32_t type, WT_LSM_WORK_UNIT **entryp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_manager_push_entry(WT_SESSION_IMPL *session, uint32_t type, uint32_t flags, WT_LSM_TREE *lsm_tree) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_merge_update_tree(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, u_int start_chunk, u_int nchunks, WT_LSM_CHUNK *chunk) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_merge(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, u_int id) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_meta_read(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_meta_write(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_curstat_lsm_init( WT_SESSION_IMPL *session, const char *uri, WT_CURSOR_STAT *cst) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_tree_close_all(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_tree_bloom_name(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, uint32_t id, const char **retp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_tree_chunk_name(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, uint32_t id, const char **retp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_tree_set_chunk_size( WT_SESSION_IMPL *session, WT_LSM_CHUNK *chunk) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_tree_setup_chunk( WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, WT_LSM_CHUNK *chunk) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_tree_setup_bloom( WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, WT_LSM_CHUNK *chunk) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_tree_create(WT_SESSION_IMPL *session, const char *uri, bool exclusive, const char *config) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_tree_get(WT_SESSION_IMPL *session, const char *uri, bool exclusive, WT_LSM_TREE **treep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_lsm_tree_release(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree); extern void __wt_lsm_tree_throttle( WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, bool decrease_only); -extern int __wt_lsm_tree_switch(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree); -extern int __wt_lsm_tree_retire_chunks(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, u_int start_chunk, u_int nchunks); -extern int __wt_lsm_tree_drop( WT_SESSION_IMPL *session, const char *name, const char *cfg[]); -extern int __wt_lsm_tree_rename(WT_SESSION_IMPL *session, const char *olduri, const char *newuri, const char *cfg[]); -extern int __wt_lsm_tree_truncate( WT_SESSION_IMPL *session, const char *name, const char *cfg[]); -extern int __wt_lsm_tree_readlock(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree); -extern int __wt_lsm_tree_readunlock(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree); -extern int __wt_lsm_tree_writelock(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree); -extern int __wt_lsm_tree_writeunlock(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree); -extern int __wt_lsm_compact(WT_SESSION_IMPL *session, const char *name, bool *skipp); -extern int __wt_lsm_tree_worker(WT_SESSION_IMPL *session, const char *uri, int (*file_func)(WT_SESSION_IMPL *, const char *[]), int (*name_func)(WT_SESSION_IMPL *, const char *, bool *), const char *cfg[], uint32_t open_flags); -extern int __wt_lsm_get_chunk_to_flush(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, bool force, WT_LSM_CHUNK **chunkp); -extern int __wt_lsm_work_switch( WT_SESSION_IMPL *session, WT_LSM_WORK_UNIT **entryp, bool *ran); -extern int __wt_lsm_work_bloom(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree); -extern int __wt_lsm_checkpoint_chunk(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, WT_LSM_CHUNK *chunk); -extern int __wt_lsm_free_chunks(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree); -extern int __wt_lsm_worker_start(WT_SESSION_IMPL *session, WT_LSM_WORKER_ARGS *args); -extern int __wt_meta_apply_all(WT_SESSION_IMPL *session, int (*file_func)(WT_SESSION_IMPL *, const char *[]), int (*name_func)(WT_SESSION_IMPL *, const char *, bool *), const char *cfg[]); -extern int __wt_meta_checkpoint(WT_SESSION_IMPL *session, const char *fname, const char *checkpoint, WT_CKPT *ckpt); -extern int __wt_meta_checkpoint_last_name( WT_SESSION_IMPL *session, const char *fname, const char **namep); -extern int __wt_meta_checkpoint_clear(WT_SESSION_IMPL *session, const char *fname); -extern int __wt_meta_ckptlist_get( WT_SESSION_IMPL *session, const char *fname, WT_CKPT **ckptbasep); -extern int __wt_meta_ckptlist_set(WT_SESSION_IMPL *session, const char *fname, WT_CKPT *ckptbase, WT_LSN *ckptlsn); +extern int __wt_lsm_tree_switch(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_tree_retire_chunks(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, u_int start_chunk, u_int nchunks) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_tree_drop( WT_SESSION_IMPL *session, const char *name, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_tree_rename(WT_SESSION_IMPL *session, const char *olduri, const char *newuri, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_tree_truncate( WT_SESSION_IMPL *session, const char *name, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_lsm_tree_readlock(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree); +extern void __wt_lsm_tree_readunlock(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree); +extern void __wt_lsm_tree_writelock(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree); +extern void __wt_lsm_tree_writeunlock(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree); +extern int __wt_lsm_compact(WT_SESSION_IMPL *session, const char *name, bool *skipp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_tree_worker(WT_SESSION_IMPL *session, const char *uri, int (*file_func)(WT_SESSION_IMPL *, const char *[]), int (*name_func)(WT_SESSION_IMPL *, const char *, bool *), const char *cfg[], uint32_t open_flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_get_chunk_to_flush(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, bool force, WT_LSM_CHUNK **chunkp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_work_switch( WT_SESSION_IMPL *session, WT_LSM_WORK_UNIT **entryp, bool *ran) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_work_bloom(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_checkpoint_chunk(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, WT_LSM_CHUNK *chunk) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_free_chunks(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_lsm_worker_start(WT_SESSION_IMPL *session, WT_LSM_WORKER_ARGS *args) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_meta_apply_all(WT_SESSION_IMPL *session, int (*file_func)(WT_SESSION_IMPL *, const char *[]), int (*name_func)(WT_SESSION_IMPL *, const char *, bool *), const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_meta_checkpoint(WT_SESSION_IMPL *session, const char *fname, const char *checkpoint, WT_CKPT *ckpt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_meta_checkpoint_last_name( WT_SESSION_IMPL *session, const char *fname, const char **namep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_meta_checkpoint_clear(WT_SESSION_IMPL *session, const char *fname) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_meta_ckptlist_get( WT_SESSION_IMPL *session, const char *fname, WT_CKPT **ckptbasep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_meta_ckptlist_set(WT_SESSION_IMPL *session, const char *fname, WT_CKPT *ckptbase, WT_LSN *ckptlsn) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_meta_ckptlist_free(WT_SESSION_IMPL *session, WT_CKPT *ckptbase); extern void __wt_meta_checkpoint_free(WT_SESSION_IMPL *session, WT_CKPT *ckpt); -extern int __wt_ext_metadata_insert(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *key, const char *value); -extern int __wt_ext_metadata_remove( WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *key); -extern int __wt_ext_metadata_search(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *key, char **valuep); -extern int __wt_ext_metadata_update(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *key, const char *value); -extern int __wt_metadata_get_ckptlist( WT_SESSION *session, const char *name, WT_CKPT **ckptbasep); +extern int __wt_ext_metadata_insert(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *key, const char *value) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ext_metadata_remove( WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *key) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ext_metadata_search(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *key, char **valuep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ext_metadata_update(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *key, const char *value) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_metadata_get_ckptlist( WT_SESSION *session, const char *name, WT_CKPT **ckptbasep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_metadata_free_ckptlist(WT_SESSION *session, WT_CKPT *ckptbase); -extern int __wt_metadata_cursor_open( WT_SESSION_IMPL *session, const char *config, WT_CURSOR **cursorp); -extern int __wt_metadata_cursor(WT_SESSION_IMPL *session, WT_CURSOR **cursorp); -extern int __wt_metadata_cursor_release(WT_SESSION_IMPL *session, WT_CURSOR **cursorp); -extern int __wt_metadata_insert( WT_SESSION_IMPL *session, const char *key, const char *value); -extern int __wt_metadata_update( WT_SESSION_IMPL *session, const char *key, const char *value); -extern int __wt_metadata_remove(WT_SESSION_IMPL *session, const char *key); -extern int __wt_metadata_search(WT_SESSION_IMPL *session, const char *key, char **valuep); +extern int __wt_metadata_cursor_open( WT_SESSION_IMPL *session, const char *config, WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_metadata_cursor(WT_SESSION_IMPL *session, WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_metadata_cursor_release(WT_SESSION_IMPL *session, WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_metadata_insert( WT_SESSION_IMPL *session, const char *key, const char *value) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_metadata_update( WT_SESSION_IMPL *session, const char *key, const char *value) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_metadata_remove(WT_SESSION_IMPL *session, const char *key) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_metadata_search(WT_SESSION_IMPL *session, const char *key, char **valuep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_meta_track_discard(WT_SESSION_IMPL *session); -extern int __wt_meta_track_on(WT_SESSION_IMPL *session); -extern int __wt_meta_track_off(WT_SESSION_IMPL *session, bool need_sync, bool unroll); -extern int __wt_meta_track_sub_on(WT_SESSION_IMPL *session); -extern int __wt_meta_track_sub_off(WT_SESSION_IMPL *session); -extern int __wt_meta_track_checkpoint(WT_SESSION_IMPL *session); -extern int __wt_meta_track_insert(WT_SESSION_IMPL *session, const char *key); -extern int __wt_meta_track_update(WT_SESSION_IMPL *session, const char *key); -extern int __wt_meta_track_fileop( WT_SESSION_IMPL *session, const char *olduri, const char *newuri); -extern int __wt_meta_track_drop( WT_SESSION_IMPL *session, const char *filename); -extern int __wt_meta_track_handle_lock(WT_SESSION_IMPL *session, bool created); -extern int __wt_meta_track_init(WT_SESSION_IMPL *session); -extern int __wt_meta_track_destroy(WT_SESSION_IMPL *session); -extern int __wt_turtle_init(WT_SESSION_IMPL *session); -extern int __wt_turtle_read(WT_SESSION_IMPL *session, const char *key, char **valuep); -extern int __wt_turtle_update(WT_SESSION_IMPL *session, const char *key, const char *value); -extern int __wt_filename(WT_SESSION_IMPL *session, const char *name, char **path); -extern int __wt_nfilename( WT_SESSION_IMPL *session, const char *name, size_t namelen, char **path); -extern int __wt_remove_if_exists(WT_SESSION_IMPL *session, const char *name, bool durable); -extern int __wt_copy_and_sync(WT_SESSION *wt_session, const char *from, const char *to); +extern int __wt_meta_track_on(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_meta_track_off(WT_SESSION_IMPL *session, bool need_sync, bool unroll) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_meta_track_sub_on(WT_SESSION_IMPL *session); +extern int __wt_meta_track_sub_off(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_meta_track_checkpoint(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_meta_track_insert(WT_SESSION_IMPL *session, const char *key) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_meta_track_update(WT_SESSION_IMPL *session, const char *key) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_meta_track_fileop( WT_SESSION_IMPL *session, const char *olduri, const char *newuri) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_meta_track_drop( WT_SESSION_IMPL *session, const char *filename) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_meta_track_handle_lock(WT_SESSION_IMPL *session, bool created) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_meta_track_init(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_meta_track_destroy(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_turtle_init(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_turtle_read(WT_SESSION_IMPL *session, const char *key, char **valuep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_turtle_update(WT_SESSION_IMPL *session, const char *key, const char *value) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_filename(WT_SESSION_IMPL *session, const char *name, char **path) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_nfilename( WT_SESSION_IMPL *session, const char *name, size_t namelen, char **path) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_remove_if_exists(WT_SESSION_IMPL *session, const char *name, bool durable) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_copy_and_sync(WT_SESSION *wt_session, const char *from, const char *to) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_abort(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); -extern int __wt_calloc(WT_SESSION_IMPL *session, size_t number, size_t size, void *retp); -extern int __wt_malloc(WT_SESSION_IMPL *session, size_t bytes_to_allocate, void *retp); -extern int __wt_realloc(WT_SESSION_IMPL *session, size_t *bytes_allocated_ret, size_t bytes_to_allocate, void *retp); -extern int __wt_realloc_noclear(WT_SESSION_IMPL *session, size_t *bytes_allocated_ret, size_t bytes_to_allocate, void *retp); -extern int __wt_realloc_aligned(WT_SESSION_IMPL *session, size_t *bytes_allocated_ret, size_t bytes_to_allocate, void *retp); -extern int __wt_strndup(WT_SESSION_IMPL *session, const void *str, size_t len, void *retp); +extern int __wt_calloc(WT_SESSION_IMPL *session, size_t number, size_t size, void *retp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_malloc(WT_SESSION_IMPL *session, size_t bytes_to_allocate, void *retp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_realloc(WT_SESSION_IMPL *session, size_t *bytes_allocated_ret, size_t bytes_to_allocate, void *retp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_realloc_noclear(WT_SESSION_IMPL *session, size_t *bytes_allocated_ret, size_t bytes_to_allocate, void *retp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_realloc_aligned(WT_SESSION_IMPL *session, size_t *bytes_allocated_ret, size_t bytes_to_allocate, void *retp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_strndup(WT_SESSION_IMPL *session, const void *str, size_t len, void *retp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_free_int(WT_SESSION_IMPL *session, const void *p_arg); -extern int __wt_errno(void); +extern int __wt_errno(void) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern const char *__wt_strerror(WT_SESSION_IMPL *session, int error, char *errbuf, size_t errlen); -extern int __wt_ext_map_windows_error( WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, uint32_t windows_error); +extern int __wt_ext_map_windows_error( WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, uint32_t windows_error) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern bool __wt_handle_is_open(WT_SESSION_IMPL *session, const char *name); -extern int __wt_open(WT_SESSION_IMPL *session, const char *name, WT_FS_OPEN_FILE_TYPE file_type, u_int flags, WT_FH **fhp); -extern int __wt_close(WT_SESSION_IMPL *session, WT_FH **fhp); -extern int __wt_close_connection_close(WT_SESSION_IMPL *session); -extern int __wt_os_inmemory(WT_SESSION_IMPL *session); -extern int __wt_fopen(WT_SESSION_IMPL *session, const char *name, uint32_t open_flags, uint32_t flags, WT_FSTREAM **fstrp); -extern int __wt_os_stdio(WT_SESSION_IMPL *session); -extern int __wt_getopt( const char *progname, int nargc, char *const *nargv, const char *ostr); +extern int __wt_open(WT_SESSION_IMPL *session, const char *name, WT_FS_OPEN_FILE_TYPE file_type, u_int flags, WT_FH **fhp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_close(WT_SESSION_IMPL *session, WT_FH **fhp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_close_connection_close(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_os_inmemory(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_fopen(WT_SESSION_IMPL *session, const char *name, uint32_t open_flags, uint32_t flags, WT_FSTREAM **fstrp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_os_stdio(WT_SESSION_IMPL *session); +extern int __wt_getopt( const char *progname, int nargc, char *const *nargv, const char *ostr) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern uint64_t __wt_strtouq(const char *nptr, char **endptr, int base); -extern int __wt_ext_struct_pack(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, void *buffer, size_t size, const char *fmt, ...); -extern int __wt_ext_struct_size(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, size_t *sizep, const char *fmt, ...); -extern int __wt_ext_struct_unpack(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const void *buffer, size_t size, const char *fmt, ...); -extern int __wt_struct_check(WT_SESSION_IMPL *session, const char *fmt, size_t len, bool *fixedp, uint32_t *fixed_lenp); -extern int __wt_struct_confchk(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *v); -extern int __wt_struct_size(WT_SESSION_IMPL *session, size_t *sizep, const char *fmt, ...); -extern int __wt_struct_pack(WT_SESSION_IMPL *session, void *buffer, size_t size, const char *fmt, ...); -extern int __wt_struct_unpack(WT_SESSION_IMPL *session, const void *buffer, size_t size, const char *fmt, ...); -extern int __wt_struct_repack(WT_SESSION_IMPL *session, const char *infmt, const char *outfmt, const WT_ITEM *inbuf, WT_ITEM *outbuf); -extern int __wt_ext_pack_start(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *format, void *buffer, size_t size, WT_PACK_STREAM **psp); -extern int __wt_ext_unpack_start(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *format, const void *buffer, size_t size, WT_PACK_STREAM **psp); -extern int __wt_ext_pack_close(WT_EXTENSION_API *wt_api, WT_PACK_STREAM *ps, size_t *usedp); -extern int __wt_ext_pack_item(WT_EXTENSION_API *wt_api, WT_PACK_STREAM *ps, WT_ITEM *item); -extern int __wt_ext_pack_int(WT_EXTENSION_API *wt_api, WT_PACK_STREAM *ps, int64_t i); -extern int __wt_ext_pack_str(WT_EXTENSION_API *wt_api, WT_PACK_STREAM *ps, const char *s); -extern int __wt_ext_pack_uint(WT_EXTENSION_API *wt_api, WT_PACK_STREAM *ps, uint64_t u); -extern int __wt_ext_unpack_item(WT_EXTENSION_API *wt_api, WT_PACK_STREAM *ps, WT_ITEM *item); -extern int __wt_ext_unpack_int(WT_EXTENSION_API *wt_api, WT_PACK_STREAM *ps, int64_t *ip); -extern int __wt_ext_unpack_str(WT_EXTENSION_API *wt_api, WT_PACK_STREAM *ps, const char **sp); -extern int __wt_ext_unpack_uint(WT_EXTENSION_API *wt_api, WT_PACK_STREAM *ps, uint64_t *up); -extern int __wt_ovfl_discard_add(WT_SESSION_IMPL *session, WT_PAGE *page, WT_CELL *cell); +extern int __wt_ext_struct_pack(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, void *buffer, size_t size, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ext_struct_size(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, size_t *sizep, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ext_struct_unpack(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const void *buffer, size_t size, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_struct_check(WT_SESSION_IMPL *session, const char *fmt, size_t len, bool *fixedp, uint32_t *fixed_lenp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_struct_confchk(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *v) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_struct_size(WT_SESSION_IMPL *session, size_t *sizep, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_struct_pack(WT_SESSION_IMPL *session, void *buffer, size_t size, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_struct_unpack(WT_SESSION_IMPL *session, const void *buffer, size_t size, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_struct_repack(WT_SESSION_IMPL *session, const char *infmt, const char *outfmt, const WT_ITEM *inbuf, WT_ITEM *outbuf) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ext_pack_start(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *format, void *buffer, size_t size, WT_PACK_STREAM **psp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ext_unpack_start(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *format, const void *buffer, size_t size, WT_PACK_STREAM **psp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ext_pack_close(WT_EXTENSION_API *wt_api, WT_PACK_STREAM *ps, size_t *usedp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ext_pack_item(WT_EXTENSION_API *wt_api, WT_PACK_STREAM *ps, WT_ITEM *item) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ext_pack_int(WT_EXTENSION_API *wt_api, WT_PACK_STREAM *ps, int64_t i) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ext_pack_str(WT_EXTENSION_API *wt_api, WT_PACK_STREAM *ps, const char *s) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ext_pack_uint(WT_EXTENSION_API *wt_api, WT_PACK_STREAM *ps, uint64_t u) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ext_unpack_item(WT_EXTENSION_API *wt_api, WT_PACK_STREAM *ps, WT_ITEM *item) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ext_unpack_int(WT_EXTENSION_API *wt_api, WT_PACK_STREAM *ps, int64_t *ip) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ext_unpack_str(WT_EXTENSION_API *wt_api, WT_PACK_STREAM *ps, const char **sp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ext_unpack_uint(WT_EXTENSION_API *wt_api, WT_PACK_STREAM *ps, uint64_t *up) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ovfl_discard_add(WT_SESSION_IMPL *session, WT_PAGE *page, WT_CELL *cell) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_ovfl_discard_free(WT_SESSION_IMPL *session, WT_PAGE *page); -extern int __wt_ovfl_reuse_search(WT_SESSION_IMPL *session, WT_PAGE *page, uint8_t **addrp, size_t *addr_sizep, const void *value, size_t value_size); -extern int __wt_ovfl_reuse_add(WT_SESSION_IMPL *session, WT_PAGE *page, const uint8_t *addr, size_t addr_size, const void *value, size_t value_size); +extern int __wt_ovfl_reuse_search(WT_SESSION_IMPL *session, WT_PAGE *page, uint8_t **addrp, size_t *addr_sizep, const void *value, size_t value_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ovfl_reuse_add(WT_SESSION_IMPL *session, WT_PAGE *page, const uint8_t *addr, size_t addr_size, const void *value, size_t value_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_ovfl_reuse_free(WT_SESSION_IMPL *session, WT_PAGE *page); -extern int __wt_ovfl_txnc_search( WT_PAGE *page, const uint8_t *addr, size_t addr_size, WT_ITEM *store); -extern int __wt_ovfl_txnc_add(WT_SESSION_IMPL *session, WT_PAGE *page, const uint8_t *addr, size_t addr_size, const void *value, size_t value_size); +extern int __wt_ovfl_txnc_search( WT_PAGE *page, const uint8_t *addr, size_t addr_size, WT_ITEM *store) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ovfl_txnc_add(WT_SESSION_IMPL *session, WT_PAGE *page, const uint8_t *addr, size_t addr_size, const void *value, size_t value_size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_ovfl_txnc_free(WT_SESSION_IMPL *session, WT_PAGE *page); -extern int __wt_ovfl_track_wrapup(WT_SESSION_IMPL *session, WT_PAGE *page); -extern int __wt_ovfl_track_wrapup_err(WT_SESSION_IMPL *session, WT_PAGE *page); -extern int __wt_reconcile(WT_SESSION_IMPL *session, WT_REF *ref, WT_SALVAGE_COOKIE *salvage, uint32_t flags); +extern int __wt_ovfl_track_wrapup(WT_SESSION_IMPL *session, WT_PAGE *page) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ovfl_track_wrapup_err(WT_SESSION_IMPL *session, WT_PAGE *page) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_reconcile(WT_SESSION_IMPL *session, WT_REF *ref, WT_SALVAGE_COOKIE *salvage, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern uint32_t __wt_split_page_size(WT_BTREE *btree, uint32_t maxpagesize); -extern int __wt_bulk_init(WT_SESSION_IMPL *session, WT_CURSOR_BULK *cbulk); -extern int __wt_bulk_wrapup(WT_SESSION_IMPL *session, WT_CURSOR_BULK *cbulk); -extern int __wt_bulk_insert_row(WT_SESSION_IMPL *session, WT_CURSOR_BULK *cbulk); -extern int __wt_bulk_insert_fix( WT_SESSION_IMPL *session, WT_CURSOR_BULK *cbulk, bool deleted); -extern int __wt_bulk_insert_fix_bitmap(WT_SESSION_IMPL *session, WT_CURSOR_BULK *cbulk); -extern int __wt_bulk_insert_var( WT_SESSION_IMPL *session, WT_CURSOR_BULK *cbulk, bool deleted); -extern int __wt_direct_io_size_check(WT_SESSION_IMPL *session, const char **cfg, const char *config_name, uint32_t *allocsizep); -extern int __wt_schema_colgroup_source(WT_SESSION_IMPL *session, WT_TABLE *table, const char *cgname, const char *config, WT_ITEM *buf); -extern int __wt_schema_index_source(WT_SESSION_IMPL *session, WT_TABLE *table, const char *idxname, const char *config, WT_ITEM *buf); -extern int __wt_schema_create( WT_SESSION_IMPL *session, const char *uri, const char *config); -extern int __wt_schema_drop(WT_SESSION_IMPL *session, const char *uri, const char *cfg[]); -extern int __wt_schema_get_table(WT_SESSION_IMPL *session, const char *name, size_t namelen, bool ok_incomplete, WT_TABLE **tablep); +extern int __wt_bulk_init(WT_SESSION_IMPL *session, WT_CURSOR_BULK *cbulk) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_bulk_wrapup(WT_SESSION_IMPL *session, WT_CURSOR_BULK *cbulk) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_bulk_insert_row(WT_SESSION_IMPL *session, WT_CURSOR_BULK *cbulk) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_bulk_insert_fix( WT_SESSION_IMPL *session, WT_CURSOR_BULK *cbulk, bool deleted) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_bulk_insert_fix_bitmap(WT_SESSION_IMPL *session, WT_CURSOR_BULK *cbulk) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_bulk_insert_var( WT_SESSION_IMPL *session, WT_CURSOR_BULK *cbulk, bool deleted) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_direct_io_size_check(WT_SESSION_IMPL *session, const char **cfg, const char *config_name, uint32_t *allocsizep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_colgroup_source(WT_SESSION_IMPL *session, WT_TABLE *table, const char *cgname, const char *config, WT_ITEM *buf) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_index_source(WT_SESSION_IMPL *session, WT_TABLE *table, const char *idxname, const char *config, WT_ITEM *buf) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_create( WT_SESSION_IMPL *session, const char *uri, const char *config) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_drop(WT_SESSION_IMPL *session, const char *uri, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_get_table(WT_SESSION_IMPL *session, const char *name, size_t namelen, bool ok_incomplete, WT_TABLE **tablep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_schema_release_table(WT_SESSION_IMPL *session, WT_TABLE *table); extern void __wt_schema_destroy_colgroup(WT_SESSION_IMPL *session, WT_COLGROUP **colgroupp); -extern int __wt_schema_destroy_index(WT_SESSION_IMPL *session, WT_INDEX **idxp); -extern int __wt_schema_destroy_table(WT_SESSION_IMPL *session, WT_TABLE **tablep); -extern int __wt_schema_remove_table(WT_SESSION_IMPL *session, WT_TABLE *table); -extern int __wt_schema_close_tables(WT_SESSION_IMPL *session); -extern int __wt_schema_colgroup_name(WT_SESSION_IMPL *session, WT_TABLE *table, const char *cgname, size_t len, WT_ITEM *buf); -extern int __wt_schema_open_colgroups(WT_SESSION_IMPL *session, WT_TABLE *table); -extern int __wt_schema_open_index(WT_SESSION_IMPL *session, WT_TABLE *table, const char *idxname, size_t len, WT_INDEX **indexp); -extern int __wt_schema_open_indices(WT_SESSION_IMPL *session, WT_TABLE *table); -extern int __wt_schema_get_colgroup(WT_SESSION_IMPL *session, const char *uri, bool quiet, WT_TABLE **tablep, WT_COLGROUP **colgroupp); -extern int __wt_schema_get_index(WT_SESSION_IMPL *session, const char *uri, bool quiet, WT_TABLE **tablep, WT_INDEX **indexp); -extern int __wt_schema_open_table(WT_SESSION_IMPL *session, const char *name, size_t namelen, bool ok_incomplete, WT_TABLE **tablep); -extern int __wt_schema_colcheck(WT_SESSION_IMPL *session, const char *key_format, const char *value_format, WT_CONFIG_ITEM *colconf, u_int *kcolsp, u_int *vcolsp); -extern int __wt_table_check(WT_SESSION_IMPL *session, WT_TABLE *table); -extern int __wt_struct_plan(WT_SESSION_IMPL *session, WT_TABLE *table, const char *columns, size_t len, bool value_only, WT_ITEM *plan); -extern int __wt_struct_reformat(WT_SESSION_IMPL *session, WT_TABLE *table, const char *columns, size_t len, const char *extra_cols, bool value_only, WT_ITEM *format); -extern int __wt_struct_truncate(WT_SESSION_IMPL *session, const char *input_fmt, u_int ncols, WT_ITEM *format); -extern int __wt_schema_project_in(WT_SESSION_IMPL *session, WT_CURSOR **cp, const char *proj_arg, va_list ap); -extern int __wt_schema_project_out(WT_SESSION_IMPL *session, WT_CURSOR **cp, const char *proj_arg, va_list ap); -extern int __wt_schema_project_slice(WT_SESSION_IMPL *session, WT_CURSOR **cp, const char *proj_arg, bool key_only, const char *vformat, WT_ITEM *value); -extern int __wt_schema_project_merge(WT_SESSION_IMPL *session, WT_CURSOR **cp, const char *proj_arg, const char *vformat, WT_ITEM *value); -extern int __wt_schema_rename(WT_SESSION_IMPL *session, const char *uri, const char *newuri, const char *cfg[]); -extern int __wt_curstat_colgroup_init(WT_SESSION_IMPL *session, const char *uri, const char *cfg[], WT_CURSOR_STAT *cst); -extern int __wt_curstat_index_init(WT_SESSION_IMPL *session, const char *uri, const char *cfg[], WT_CURSOR_STAT *cst); -extern int __wt_curstat_table_init(WT_SESSION_IMPL *session, const char *uri, const char *cfg[], WT_CURSOR_STAT *cst); -extern int __wt_schema_truncate( WT_SESSION_IMPL *session, const char *uri, const char *cfg[]); -extern int __wt_range_truncate(WT_CURSOR *start, WT_CURSOR *stop); -extern int __wt_schema_range_truncate( WT_SESSION_IMPL *session, WT_CURSOR *start, WT_CURSOR *stop); +extern int __wt_schema_destroy_index(WT_SESSION_IMPL *session, WT_INDEX **idxp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_destroy_table(WT_SESSION_IMPL *session, WT_TABLE **tablep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_remove_table(WT_SESSION_IMPL *session, WT_TABLE *table) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_close_tables(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_colgroup_name(WT_SESSION_IMPL *session, WT_TABLE *table, const char *cgname, size_t len, WT_ITEM *buf) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_open_colgroups(WT_SESSION_IMPL *session, WT_TABLE *table) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_open_index(WT_SESSION_IMPL *session, WT_TABLE *table, const char *idxname, size_t len, WT_INDEX **indexp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_open_indices(WT_SESSION_IMPL *session, WT_TABLE *table) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_get_colgroup(WT_SESSION_IMPL *session, const char *uri, bool quiet, WT_TABLE **tablep, WT_COLGROUP **colgroupp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_get_index(WT_SESSION_IMPL *session, const char *uri, bool quiet, WT_TABLE **tablep, WT_INDEX **indexp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_open_table(WT_SESSION_IMPL *session, const char *name, size_t namelen, bool ok_incomplete, WT_TABLE **tablep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_colcheck(WT_SESSION_IMPL *session, const char *key_format, const char *value_format, WT_CONFIG_ITEM *colconf, u_int *kcolsp, u_int *vcolsp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_table_check(WT_SESSION_IMPL *session, WT_TABLE *table) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_struct_plan(WT_SESSION_IMPL *session, WT_TABLE *table, const char *columns, size_t len, bool value_only, WT_ITEM *plan) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_struct_reformat(WT_SESSION_IMPL *session, WT_TABLE *table, const char *columns, size_t len, const char *extra_cols, bool value_only, WT_ITEM *format) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_struct_truncate(WT_SESSION_IMPL *session, const char *input_fmt, u_int ncols, WT_ITEM *format) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_project_in(WT_SESSION_IMPL *session, WT_CURSOR **cp, const char *proj_arg, va_list ap) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_project_out(WT_SESSION_IMPL *session, WT_CURSOR **cp, const char *proj_arg, va_list ap) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_project_slice(WT_SESSION_IMPL *session, WT_CURSOR **cp, const char *proj_arg, bool key_only, const char *vformat, WT_ITEM *value) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_project_merge(WT_SESSION_IMPL *session, WT_CURSOR **cp, const char *proj_arg, const char *vformat, WT_ITEM *value) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_rename(WT_SESSION_IMPL *session, const char *uri, const char *newuri, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_curstat_colgroup_init(WT_SESSION_IMPL *session, const char *uri, const char *cfg[], WT_CURSOR_STAT *cst) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_curstat_index_init(WT_SESSION_IMPL *session, const char *uri, const char *cfg[], WT_CURSOR_STAT *cst) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_curstat_table_init(WT_SESSION_IMPL *session, const char *uri, const char *cfg[], WT_CURSOR_STAT *cst) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_truncate( WT_SESSION_IMPL *session, const char *uri, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_range_truncate(WT_CURSOR *start, WT_CURSOR *stop) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_range_truncate( WT_SESSION_IMPL *session, WT_CURSOR *start, WT_CURSOR *stop) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern WT_DATA_SOURCE *__wt_schema_get_source(WT_SESSION_IMPL *session, const char *name); -extern int __wt_str_name_check(WT_SESSION_IMPL *session, const char *str); -extern int __wt_name_check(WT_SESSION_IMPL *session, const char *str, size_t len); -extern int __wt_schema_worker(WT_SESSION_IMPL *session, const char *uri, int (*file_func)(WT_SESSION_IMPL *, const char *[]), int (*name_func)(WT_SESSION_IMPL *, const char *, bool *), const char *cfg[], uint32_t open_flags); -extern int __wt_session_notsup(WT_SESSION *wt_session); -extern int __wt_session_reset_cursors(WT_SESSION_IMPL *session, bool free_buffers); -extern int __wt_session_copy_values(WT_SESSION_IMPL *session); -extern int __wt_session_release_resources(WT_SESSION_IMPL *session); -extern int __wt_open_cursor(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp); -extern int __wt_session_create( WT_SESSION_IMPL *session, const char *uri, const char *config); -extern int __wt_session_drop(WT_SESSION_IMPL *session, const char *uri, const char *cfg[]); -extern int __wt_session_range_truncate(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *start, WT_CURSOR *stop); +extern int __wt_str_name_check(WT_SESSION_IMPL *session, const char *str) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_name_check(WT_SESSION_IMPL *session, const char *str, size_t len) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_schema_worker(WT_SESSION_IMPL *session, const char *uri, int (*file_func)(WT_SESSION_IMPL *, const char *[]), int (*name_func)(WT_SESSION_IMPL *, const char *, bool *), const char *cfg[], uint32_t open_flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_session_notsup(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_session_reset_cursors(WT_SESSION_IMPL *session, bool free_buffers) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_session_copy_values(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_session_release_resources(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_open_cursor(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *owner, const char *cfg[], WT_CURSOR **cursorp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_session_create( WT_SESSION_IMPL *session, const char *uri, const char *config) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_session_drop(WT_SESSION_IMPL *session, const char *uri, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_session_range_truncate(WT_SESSION_IMPL *session, const char *uri, WT_CURSOR *start, WT_CURSOR *stop) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern const char *__wt_session_strerror(WT_SESSION *wt_session, int error); -extern int __wt_open_session(WT_CONNECTION_IMPL *conn, WT_EVENT_HANDLER *event_handler, const char *config, bool open_metadata, WT_SESSION_IMPL **sessionp); -extern int __wt_open_internal_session(WT_CONNECTION_IMPL *conn, const char *name, bool open_metadata, uint32_t session_flags, WT_SESSION_IMPL **sessionp); -extern int __wt_session_compact( WT_SESSION *wt_session, const char *uri, const char *config); -extern int __wt_session_compact_readonly( WT_SESSION *wt_session, const char *uri, const char *config); -extern int __wt_session_lock_dhandle( WT_SESSION_IMPL *session, uint32_t flags, bool *is_deadp); -extern int __wt_session_release_btree(WT_SESSION_IMPL *session); -extern int __wt_session_get_btree_ckpt(WT_SESSION_IMPL *session, const char *uri, const char *cfg[], uint32_t flags); +extern int __wt_open_session(WT_CONNECTION_IMPL *conn, WT_EVENT_HANDLER *event_handler, const char *config, bool open_metadata, WT_SESSION_IMPL **sessionp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_open_internal_session(WT_CONNECTION_IMPL *conn, const char *name, bool open_metadata, uint32_t session_flags, WT_SESSION_IMPL **sessionp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_session_compact( WT_SESSION *wt_session, const char *uri, const char *config) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_session_compact_readonly( WT_SESSION *wt_session, const char *uri, const char *config) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_session_lock_dhandle( WT_SESSION_IMPL *session, uint32_t flags, bool *is_deadp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_session_release_btree(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_session_get_btree_ckpt(WT_SESSION_IMPL *session, const char *uri, const char *cfg[], uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_session_close_cache(WT_SESSION_IMPL *session); -extern int __wt_session_get_btree(WT_SESSION_IMPL *session, const char *uri, const char *checkpoint, const char *cfg[], uint32_t flags); -extern int __wt_session_lock_checkpoint(WT_SESSION_IMPL *session, const char *checkpoint); -extern int __wt_salvage(WT_SESSION_IMPL *session, const char *cfg[]); -extern int __wt_cond_auto_alloc( WT_SESSION_IMPL *session, const char *name, bool is_signalled, uint64_t min, uint64_t max, WT_CONDVAR **condp); -extern int __wt_cond_auto_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond); -extern int __wt_cond_auto_wait_signal( WT_SESSION_IMPL *session, WT_CONDVAR *cond, bool progress, bool *signalled); -extern int __wt_cond_auto_wait( WT_SESSION_IMPL *session, WT_CONDVAR *cond, bool progress); -extern int __wt_cond_auto_destroy(WT_SESSION_IMPL *session, WT_CONDVAR **condp); -extern int __wt_decrypt(WT_SESSION_IMPL *session, WT_ENCRYPTOR *encryptor, size_t skip, WT_ITEM *in, WT_ITEM *out); -extern int __wt_encrypt(WT_SESSION_IMPL *session, WT_KEYED_ENCRYPTOR *kencryptor, size_t skip, WT_ITEM *in, WT_ITEM *out); +extern int __wt_session_get_btree(WT_SESSION_IMPL *session, const char *uri, const char *checkpoint, const char *cfg[], uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_session_lock_checkpoint(WT_SESSION_IMPL *session, const char *checkpoint) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_salvage(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_cond_auto_alloc( WT_SESSION_IMPL *session, const char *name, bool is_signalled, uint64_t min, uint64_t max, WT_CONDVAR **condp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_cond_auto_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond); +extern void __wt_cond_auto_wait_signal( WT_SESSION_IMPL *session, WT_CONDVAR *cond, bool progress, bool *signalled); +extern void __wt_cond_auto_wait( WT_SESSION_IMPL *session, WT_CONDVAR *cond, bool progress); +extern int __wt_cond_auto_destroy(WT_SESSION_IMPL *session, WT_CONDVAR **condp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_decrypt(WT_SESSION_IMPL *session, WT_ENCRYPTOR *encryptor, size_t skip, WT_ITEM *in, WT_ITEM *out) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_encrypt(WT_SESSION_IMPL *session, WT_KEYED_ENCRYPTOR *kencryptor, size_t skip, WT_ITEM *in, WT_ITEM *out) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_encrypt_size(WT_SESSION_IMPL *session, WT_KEYED_ENCRYPTOR *kencryptor, size_t incoming_size, size_t *sizep); extern void __wt_event_handler_set(WT_SESSION_IMPL *session, WT_EVENT_HANDLER *handler); -extern int __wt_eventv(WT_SESSION_IMPL *session, bool msg_event, int error, const char *file_name, int line_number, const char *fmt, va_list ap); -extern void __wt_err(WT_SESSION_IMPL *session, int error, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4))); -extern void __wt_errx(WT_SESSION_IMPL *session, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 2, 3))); -extern int __wt_ext_err_printf( WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4))); -extern int __wt_msg(WT_SESSION_IMPL *session, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 2, 3))); -extern int __wt_ext_msg_printf( WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4))); +extern int __wt_eventv(WT_SESSION_IMPL *session, bool msg_event, int error, const char *file_name, int line_number, const char *fmt, va_list ap) WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_err(WT_SESSION_IMPL *session, int error, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4))); +extern void __wt_errx(WT_SESSION_IMPL *session, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 2, 3))); +extern int __wt_ext_err_printf( WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4))) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_msg(WT_SESSION_IMPL *session, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 2, 3))) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ext_msg_printf( WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4))) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern const char *__wt_ext_strerror(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, int error); -extern int __wt_progress(WT_SESSION_IMPL *session, const char *s, uint64_t v); +extern int __wt_progress(WT_SESSION_IMPL *session, const char *s, uint64_t v) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_assert(WT_SESSION_IMPL *session, int error, const char *file_name, int line_number, const char *fmt, ...) + WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 5, 6))) #ifdef HAVE_DIAGNOSTIC WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)) #endif ; -extern int __wt_panic(WT_SESSION_IMPL *session); -extern int __wt_illegal_value(WT_SESSION_IMPL *session, const char *name); -extern int __wt_object_unsupported(WT_SESSION_IMPL *session, const char *uri); -extern int __wt_bad_object_type(WT_SESSION_IMPL *session, const char *uri); -extern int __wt_library_init(void); -extern int __wt_breakpoint(void); +extern int __wt_panic(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_illegal_value(WT_SESSION_IMPL *session, const char *name) WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_object_unsupported(WT_SESSION_IMPL *session, const char *uri) WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_bad_object_type(WT_SESSION_IMPL *session, const char *uri) WT_GCC_FUNC_DECL_ATTRIBUTE((cold)) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_library_init(void) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_breakpoint(void); extern void __wt_attach(WT_SESSION_IMPL *session); extern uint64_t __wt_hash_city64(const void *s, size_t len); extern uint64_t __wt_hash_fnv64(const void *string, size_t len); @@ -644,39 +647,41 @@ __wt_hazard_set(WT_SESSION_IMPL *session, WT_REF *ref, bool *busyp , const char *file, int line #endif ); -extern int __wt_hazard_clear(WT_SESSION_IMPL *session, WT_PAGE *page); +extern int __wt_hazard_clear(WT_SESSION_IMPL *session, WT_PAGE *page) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_hazard_close(WT_SESSION_IMPL *session); +extern u_int __wt_hazard_count(WT_SESSION_IMPL *session, WT_PAGE *page); extern void __wt_fill_hex(const uint8_t *src, size_t src_max, uint8_t *dest, size_t dest_max, size_t *lenp); -extern int __wt_raw_to_hex( WT_SESSION_IMPL *session, const uint8_t *from, size_t size, WT_ITEM *to); -extern int __wt_raw_to_esc_hex( WT_SESSION_IMPL *session, const uint8_t *from, size_t size, WT_ITEM *to); -extern int __wt_hex2byte(const u_char *from, u_char *to); -extern int __wt_hex_to_raw(WT_SESSION_IMPL *session, const char *from, WT_ITEM *to); -extern int __wt_nhex_to_raw( WT_SESSION_IMPL *session, const char *from, size_t size, WT_ITEM *to); -extern int __wt_esc_hex_to_raw(WT_SESSION_IMPL *session, const char *from, WT_ITEM *to); -extern int __wt_huffman_open(WT_SESSION_IMPL *session, void *symbol_frequency_array, u_int symcnt, u_int numbytes, void *retp); +extern int __wt_raw_to_hex( WT_SESSION_IMPL *session, const uint8_t *from, size_t size, WT_ITEM *to) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_raw_to_esc_hex( WT_SESSION_IMPL *session, const uint8_t *from, size_t size, WT_ITEM *to) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_hex2byte(const u_char *from, u_char *to) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_hex_to_raw(WT_SESSION_IMPL *session, const char *from, WT_ITEM *to) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_nhex_to_raw( WT_SESSION_IMPL *session, const char *from, size_t size, WT_ITEM *to) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_esc_hex_to_raw(WT_SESSION_IMPL *session, const char *from, WT_ITEM *to) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_huffman_open(WT_SESSION_IMPL *session, void *symbol_frequency_array, u_int symcnt, u_int numbytes, void *retp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_huffman_close(WT_SESSION_IMPL *session, void *huffman_arg); -extern int __wt_print_huffman_code(void *huffman_arg, uint16_t symbol); -extern int __wt_huffman_encode(WT_SESSION_IMPL *session, void *huffman_arg, const uint8_t *from_arg, size_t from_len, WT_ITEM *to_buf); -extern int __wt_huffman_decode(WT_SESSION_IMPL *session, void *huffman_arg, const uint8_t *from_arg, size_t from_len, WT_ITEM *to_buf); -extern int __wt_rwlock_alloc( WT_SESSION_IMPL *session, WT_RWLOCK **rwlockp, const char *name); -extern int __wt_try_readlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock); -extern int __wt_readlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock); -extern int __wt_readunlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock); -extern int __wt_try_writelock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock); -extern int __wt_writelock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock); -extern int __wt_writeunlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock); -extern int __wt_rwlock_destroy(WT_SESSION_IMPL *session, WT_RWLOCK **rwlockp); +extern void __wt_print_huffman_code(void *huffman_arg, uint16_t symbol); +extern int __wt_huffman_encode(WT_SESSION_IMPL *session, void *huffman_arg, const uint8_t *from_arg, size_t from_len, WT_ITEM *to_buf) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_huffman_decode(WT_SESSION_IMPL *session, void *huffman_arg, const uint8_t *from_arg, size_t from_len, WT_ITEM *to_buf) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_rwlock_alloc( WT_SESSION_IMPL *session, WT_RWLOCK **rwlockp, const char *name) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_try_readlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_readlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock); +extern void __wt_readunlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock); +extern int __wt_try_writelock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_writelock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock); +extern void __wt_writeunlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock); +extern void __wt_rwlock_destroy(WT_SESSION_IMPL *session, WT_RWLOCK **rwlockp); +extern bool __wt_rwlock_islocked(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock); extern uint32_t __wt_nlpo2_round(uint32_t v); extern uint32_t __wt_nlpo2(uint32_t v); extern uint32_t __wt_log2_int(uint32_t n); extern bool __wt_ispo2(uint32_t v); extern uint32_t __wt_rduppo2(uint32_t n, uint32_t po2); extern void __wt_random_init(WT_RAND_STATE volatile *rnd_state); -extern int __wt_random_init_seed( WT_SESSION_IMPL *session, WT_RAND_STATE volatile *rnd_state); +extern int __wt_random_init_seed( WT_SESSION_IMPL *session, WT_RAND_STATE volatile *rnd_state) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern uint32_t __wt_random(WT_RAND_STATE volatile *rnd_state); -extern int __wt_buf_grow_worker(WT_SESSION_IMPL *session, WT_ITEM *buf, size_t size); -extern int __wt_buf_fmt(WT_SESSION_IMPL *session, WT_ITEM *buf, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4))); -extern int __wt_buf_catfmt(WT_SESSION_IMPL *session, WT_ITEM *buf, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4))); +extern int __wt_buf_grow_worker(WT_SESSION_IMPL *session, WT_ITEM *buf, size_t size) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_buf_fmt(WT_SESSION_IMPL *session, WT_ITEM *buf, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4))) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_buf_catfmt(WT_SESSION_IMPL *session, WT_ITEM *buf, const char *fmt, ...) WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4))) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern const char *__wt_buf_set_printable( WT_SESSION_IMPL *session, const void *p, size_t size, WT_ITEM *buf); extern const char *__wt_buf_set_size( WT_SESSION_IMPL *session, uint64_t size, bool exact, WT_ITEM *buf); extern int @@ -688,58 +693,62 @@ __wt_scr_alloc_func(WT_SESSION_IMPL *session, size_t size, WT_ITEM **scratchp extern void __wt_scr_discard(WT_SESSION_IMPL *session); extern void *__wt_ext_scr_alloc( WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, size_t size); extern void __wt_ext_scr_free(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, void *p); -extern int __wt_stat_dsrc_desc(WT_CURSOR_STAT *cst, int slot, const char **p); +extern int __wt_stat_dsrc_desc(WT_CURSOR_STAT *cst, int slot, const char **p) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_stat_dsrc_init_single(WT_DSRC_STATS *stats); extern void __wt_stat_dsrc_init(WT_DATA_HANDLE *handle); extern void __wt_stat_dsrc_clear_single(WT_DSRC_STATS *stats); extern void __wt_stat_dsrc_clear_all(WT_DSRC_STATS **stats); extern void __wt_stat_dsrc_aggregate_single( WT_DSRC_STATS *from, WT_DSRC_STATS *to); extern void __wt_stat_dsrc_aggregate( WT_DSRC_STATS **from, WT_DSRC_STATS *to); -extern int __wt_stat_connection_desc(WT_CURSOR_STAT *cst, int slot, const char **p); +extern int __wt_stat_connection_desc(WT_CURSOR_STAT *cst, int slot, const char **p) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_stat_connection_init_single(WT_CONNECTION_STATS *stats); extern void __wt_stat_connection_init(WT_CONNECTION_IMPL *handle); extern void __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats); extern void __wt_stat_connection_clear_all(WT_CONNECTION_STATS **stats); extern void __wt_stat_connection_aggregate( WT_CONNECTION_STATS **from, WT_CONNECTION_STATS *to); -extern int __wt_stat_join_desc(WT_CURSOR_STAT *cst, int slot, const char **p); +extern int __wt_stat_join_desc(WT_CURSOR_STAT *cst, int slot, const char **p) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_stat_join_init_single(WT_JOIN_STATS *stats); extern void __wt_stat_join_clear_single(WT_JOIN_STATS *stats); extern void __wt_stat_join_clear_all(WT_JOIN_STATS **stats); extern void __wt_stat_join_aggregate( WT_JOIN_STATS **from, WT_JOIN_STATS *to); +extern WT_THREAD_RET __wt_thread_run(void *arg); +extern int __wt_thread_group_resize( WT_SESSION_IMPL *session, WT_THREAD_GROUP *group, uint32_t new_min, uint32_t new_max, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_thread_group_create( WT_SESSION_IMPL *session, WT_THREAD_GROUP *group, const char *name, uint32_t min, uint32_t max, uint32_t flags, int (*run_func)(WT_SESSION_IMPL *session, WT_THREAD *context)) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_thread_group_destroy(WT_SESSION_IMPL *session, WT_THREAD_GROUP *group) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_thread_group_start_one( WT_SESSION_IMPL *session, WT_THREAD_GROUP *group, bool wait) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_txn_release_snapshot(WT_SESSION_IMPL *session); -extern int __wt_txn_get_snapshot(WT_SESSION_IMPL *session); -extern int __wt_txn_update_oldest(WT_SESSION_IMPL *session, uint32_t flags); -extern int __wt_txn_config(WT_SESSION_IMPL *session, const char *cfg[]); +extern int __wt_txn_get_snapshot(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_txn_update_oldest(WT_SESSION_IMPL *session, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_txn_config(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_txn_release(WT_SESSION_IMPL *session); -extern int __wt_txn_commit(WT_SESSION_IMPL *session, const char *cfg[]); -extern int __wt_txn_rollback(WT_SESSION_IMPL *session, const char *cfg[]); -extern int __wt_txn_init(WT_SESSION_IMPL *session); +extern int __wt_txn_commit(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_txn_rollback(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_txn_init(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_txn_stats_update(WT_SESSION_IMPL *session); extern void __wt_txn_destroy(WT_SESSION_IMPL *session); -extern int __wt_txn_global_init(WT_SESSION_IMPL *session, const char *cfg[]); -extern int __wt_txn_global_destroy(WT_SESSION_IMPL *session); -extern int __wt_checkpoint_name_ok(WT_SESSION_IMPL *session, const char *name, size_t len); -extern int __wt_checkpoint_get_handles(WT_SESSION_IMPL *session, const char *cfg[]); -extern int __wt_txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[]); -extern int __wt_checkpoint(WT_SESSION_IMPL *session, const char *cfg[]); -extern int __wt_checkpoint_sync(WT_SESSION_IMPL *session, const char *cfg[]); -extern int __wt_checkpoint_close(WT_SESSION_IMPL *session, bool final); +extern int __wt_txn_global_init(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_txn_global_destroy(WT_SESSION_IMPL *session); +extern int __wt_checkpoint_get_handles(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_checkpoint(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_checkpoint_sync(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_checkpoint_close(WT_SESSION_IMPL *session, bool final) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern uint64_t __wt_ext_transaction_id(WT_EXTENSION_API *wt_api, WT_SESSION *wt_session); -extern int __wt_ext_transaction_isolation_level( WT_EXTENSION_API *wt_api, WT_SESSION *wt_session); -extern int __wt_ext_transaction_notify( WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, WT_TXN_NOTIFY *notify); +extern int __wt_ext_transaction_isolation_level( WT_EXTENSION_API *wt_api, WT_SESSION *wt_session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_ext_transaction_notify( WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, WT_TXN_NOTIFY *notify) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern uint64_t __wt_ext_transaction_oldest(WT_EXTENSION_API *wt_api); -extern int __wt_ext_transaction_visible( WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, uint64_t transaction_id); +extern int __wt_ext_transaction_visible( WT_EXTENSION_API *wt_api, WT_SESSION *wt_session, uint64_t transaction_id) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_txn_op_free(WT_SESSION_IMPL *session, WT_TXN_OP *op); -extern int __wt_txn_log_op(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt); -extern int __wt_txn_log_commit(WT_SESSION_IMPL *session, const char *cfg[]); -extern int __wt_txn_checkpoint_logread( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, WT_LSN *ckpt_lsn); -extern int __wt_txn_checkpoint_log( WT_SESSION_IMPL *session, bool full, uint32_t flags, WT_LSN *lsnp); -extern int __wt_txn_truncate_log( WT_SESSION_IMPL *session, WT_CURSOR_BTREE *start, WT_CURSOR_BTREE *stop); -extern int __wt_txn_truncate_end(WT_SESSION_IMPL *session); -extern int __wt_txn_printlog(WT_SESSION *wt_session, uint32_t flags); -extern int __wt_txn_named_snapshot_begin(WT_SESSION_IMPL *session, const char *cfg[]); -extern int __wt_txn_named_snapshot_drop(WT_SESSION_IMPL *session, const char *cfg[]); -extern int __wt_txn_named_snapshot_get(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *nameval); -extern int __wt_txn_named_snapshot_config(WT_SESSION_IMPL *session, const char *cfg[], bool *has_create, bool *has_drops); -extern int __wt_txn_named_snapshot_destroy(WT_SESSION_IMPL *session); -extern int __wt_txn_recover(WT_SESSION_IMPL *session); +extern int __wt_txn_log_op(WT_SESSION_IMPL *session, WT_CURSOR_BTREE *cbt) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_txn_log_commit(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_txn_checkpoint_logread( WT_SESSION_IMPL *session, const uint8_t **pp, const uint8_t *end, WT_LSN *ckpt_lsn) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_txn_checkpoint_log( WT_SESSION_IMPL *session, bool full, uint32_t flags, WT_LSN *lsnp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_txn_truncate_log( WT_SESSION_IMPL *session, WT_CURSOR_BTREE *start, WT_CURSOR_BTREE *stop) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_txn_truncate_end(WT_SESSION_IMPL *session); +extern int __wt_txn_printlog(WT_SESSION *wt_session, uint32_t flags) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_txn_named_snapshot_begin(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_txn_named_snapshot_drop(WT_SESSION_IMPL *session, const char *cfg[]) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_txn_named_snapshot_get(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *nameval) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_txn_named_snapshot_config(WT_SESSION_IMPL *session, const char *cfg[], bool *has_create, bool *has_drops) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_txn_named_snapshot_destroy(WT_SESSION_IMPL *session); +extern int __wt_txn_recover(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); diff --git a/src/third_party/wiredtiger/src/include/extern_posix.h b/src/third_party/wiredtiger/src/include/extern_posix.h index 6fde537f36b..d2f74d2ffe4 100644 --- a/src/third_party/wiredtiger/src/include/extern_posix.h +++ b/src/third_party/wiredtiger/src/include/extern_posix.h @@ -1,31 +1,31 @@ /* DO NOT EDIT: automatically built by dist/s_prototypes. */ -extern int __wt_posix_directory_list(WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session, const char *directory, const char *prefix, char ***dirlistp, uint32_t *countp); -extern int __wt_posix_directory_list_free(WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session, char **dirlist, uint32_t count); -extern int __wt_dlopen(WT_SESSION_IMPL *session, const char *path, WT_DLH **dlhp); -extern int __wt_dlsym(WT_SESSION_IMPL *session, WT_DLH *dlh, const char *name, bool fail, void *sym_ret); -extern int __wt_dlclose(WT_SESSION_IMPL *session, WT_DLH *dlh); -extern int __wt_posix_file_fallocate(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, wt_off_t offset, wt_off_t len); -extern int __wt_os_posix(WT_SESSION_IMPL *session); -extern int __wt_getenv(WT_SESSION_IMPL *session, const char *variable, const char **envp); -extern int __wt_posix_map(WT_FILE_HANDLE *fh, WT_SESSION *wt_session, void *mapped_regionp, size_t *lenp, void *mapped_cookiep); -extern int __wt_posix_map_preload(WT_FILE_HANDLE *fh, WT_SESSION *wt_session, const void *map, size_t length, void *mapped_cookie); -extern int __wt_posix_map_discard(WT_FILE_HANDLE *fh, WT_SESSION *wt_session, void *map, size_t length, void *mapped_cookie); -extern int __wt_posix_unmap(WT_FILE_HANDLE *fh, WT_SESSION *wt_session, void *mapped_region, size_t len, void *mapped_cookie); -extern int __wt_cond_alloc(WT_SESSION_IMPL *session, const char *name, bool is_signalled, WT_CONDVAR **condp); -extern int __wt_cond_wait_signal( WT_SESSION_IMPL *session, WT_CONDVAR *cond, uint64_t usecs, bool *signalled); -extern int __wt_cond_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond); -extern int __wt_cond_destroy(WT_SESSION_IMPL *session, WT_CONDVAR **condp); -extern int __wt_once(void (*init_routine)(void)); -extern int __wt_get_vm_pagesize(void); +extern int __wt_posix_directory_list(WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session, const char *directory, const char *prefix, char ***dirlistp, uint32_t *countp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_posix_directory_list_free(WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session, char **dirlist, uint32_t count) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_dlopen(WT_SESSION_IMPL *session, const char *path, WT_DLH **dlhp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_dlsym(WT_SESSION_IMPL *session, WT_DLH *dlh, const char *name, bool fail, void *sym_ret) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_dlclose(WT_SESSION_IMPL *session, WT_DLH *dlh) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_posix_file_extend( WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, wt_off_t offset) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_os_posix(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_getenv(WT_SESSION_IMPL *session, const char *variable, const char **envp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_posix_map(WT_FILE_HANDLE *fh, WT_SESSION *wt_session, void *mapped_regionp, size_t *lenp, void *mapped_cookiep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_posix_map_preload(WT_FILE_HANDLE *fh, WT_SESSION *wt_session, const void *map, size_t length, void *mapped_cookie) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_posix_map_discard(WT_FILE_HANDLE *fh, WT_SESSION *wt_session, void *map, size_t length, void *mapped_cookie) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_posix_unmap(WT_FILE_HANDLE *fh, WT_SESSION *wt_session, void *mapped_region, size_t len, void *mapped_cookie) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_cond_alloc(WT_SESSION_IMPL *session, const char *name, bool is_signalled, WT_CONDVAR **condp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_cond_wait_signal( WT_SESSION_IMPL *session, WT_CONDVAR *cond, uint64_t usecs, bool *signalled); +extern void __wt_cond_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond); +extern int __wt_cond_destroy(WT_SESSION_IMPL *session, WT_CONDVAR **condp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_once(void (*init_routine)(void)) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_get_vm_pagesize(void) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern bool __wt_absolute_path(const char *path); extern const char *__wt_path_separator(void); extern bool __wt_has_priv(void); extern void __wt_stream_set_line_buffer(FILE *fp); extern void __wt_stream_set_no_buffer(FILE *fp); extern void __wt_sleep(uint64_t seconds, uint64_t micro_seconds); -extern int __wt_thread_create(WT_SESSION_IMPL *session, wt_thread_t *tidret, WT_THREAD_CALLBACK(*func)(void *), void *arg); -extern int __wt_thread_join(WT_SESSION_IMPL *session, wt_thread_t tid); +extern int __wt_thread_create(WT_SESSION_IMPL *session, wt_thread_t *tidret, WT_THREAD_CALLBACK(*func)(void *), void *arg) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_thread_join(WT_SESSION_IMPL *session, wt_thread_t tid) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_thread_id(char *buf, size_t buflen); -extern int __wt_epoch(WT_SESSION_IMPL *session, struct timespec *tsp); +extern int __wt_epoch(WT_SESSION_IMPL *session, struct timespec *tsp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_yield(void); diff --git a/src/third_party/wiredtiger/src/include/extern_win.h b/src/third_party/wiredtiger/src/include/extern_win.h index c5c2624db2c..8c2b19056e0 100644 --- a/src/third_party/wiredtiger/src/include/extern_win.h +++ b/src/third_party/wiredtiger/src/include/extern_win.h @@ -1,32 +1,34 @@ /* DO NOT EDIT: automatically built by dist/s_prototypes. */ -extern int __wt_win_directory_list(WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session, const char *directory, const char *prefix, char ***dirlistp, uint32_t *countp); -extern int __wt_win_directory_list_free(WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session, char **dirlist, uint32_t count); -extern int __wt_dlopen(WT_SESSION_IMPL *session, const char *path, WT_DLH **dlhp); -extern int __wt_dlsym(WT_SESSION_IMPL *session, WT_DLH *dlh, const char *name, bool fail, void *sym_ret); -extern int __wt_dlclose(WT_SESSION_IMPL *session, WT_DLH *dlh); -extern int __wt_win_fs_size(WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session, const char *name, wt_off_t *sizep); -extern int __wt_os_win(WT_SESSION_IMPL *session); -extern int __wt_getenv(WT_SESSION_IMPL *session, const char *variable, const char **envp); -extern int __wt_win_map(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, void *mapped_regionp, size_t *lenp, void *mapped_cookiep); -extern int __wt_win_unmap(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, void *mapped_region, size_t length, void *mapped_cookie); -extern int __wt_cond_alloc(WT_SESSION_IMPL *session, const char *name, bool is_signalled, WT_CONDVAR **condp); -extern int __wt_cond_wait_signal( WT_SESSION_IMPL *session, WT_CONDVAR *cond, uint64_t usecs, bool *signalled); -extern int __wt_cond_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond); -extern int __wt_cond_destroy(WT_SESSION_IMPL *session, WT_CONDVAR **condp); -extern int __wt_once(void (*init_routine)(void)); -extern int __wt_get_vm_pagesize(void); +extern int __wt_win_directory_list(WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session, const char *directory, const char *prefix, char ***dirlistp, uint32_t *countp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_win_directory_list_free(WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session, char **dirlist, uint32_t count) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_dlopen(WT_SESSION_IMPL *session, const char *path, WT_DLH **dlhp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_dlsym(WT_SESSION_IMPL *session, WT_DLH *dlh, const char *name, bool fail, void *sym_ret) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_dlclose(WT_SESSION_IMPL *session, WT_DLH *dlh) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_win_fs_size(WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session, const char *name, wt_off_t *sizep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_os_win(WT_SESSION_IMPL *session) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_getenv(WT_SESSION_IMPL *session, const char *variable, const char **envp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_win_map(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, void *mapped_regionp, size_t *lenp, void *mapped_cookiep) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_win_unmap(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, void *mapped_region, size_t length, void *mapped_cookie) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_cond_alloc(WT_SESSION_IMPL *session, const char *name, bool is_signalled, WT_CONDVAR **condp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern void __wt_cond_wait_signal( WT_SESSION_IMPL *session, WT_CONDVAR *cond, uint64_t usecs, bool *signalled); +extern void __wt_cond_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond); +extern int __wt_cond_destroy(WT_SESSION_IMPL *session, WT_CONDVAR **condp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_once(void (*init_routine)(void)) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_get_vm_pagesize(void) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern bool __wt_absolute_path(const char *path); extern const char *__wt_path_separator(void); extern bool __wt_has_priv(void); extern void __wt_stream_set_line_buffer(FILE *fp); extern void __wt_stream_set_no_buffer(FILE *fp); extern void __wt_sleep(uint64_t seconds, uint64_t micro_seconds); -extern int __wt_thread_create(WT_SESSION_IMPL *session, wt_thread_t *tidret, WT_THREAD_CALLBACK(*func)(void *), void *arg); -extern int __wt_thread_join(WT_SESSION_IMPL *session, wt_thread_t tid); +extern int __wt_thread_create(WT_SESSION_IMPL *session, wt_thread_t *tidret, WT_THREAD_CALLBACK(*func)(void *), void *arg) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_thread_join(WT_SESSION_IMPL *session, wt_thread_t tid) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern void __wt_thread_id(char *buf, size_t buflen); -extern int __wt_epoch(WT_SESSION_IMPL *session, struct timespec *tsp); +extern int __wt_epoch(WT_SESSION_IMPL *session, struct timespec *tsp) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_to_utf16_string( WT_SESSION_IMPL *session, const char*utf8, WT_ITEM **outbuf) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); +extern int __wt_to_utf8_string( WT_SESSION_IMPL *session, const wchar_t*wide, WT_ITEM **outbuf) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern DWORD __wt_getlasterror(void); -extern int __wt_map_windows_error(DWORD windows_error); +extern int __wt_map_windows_error(DWORD windows_error) WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result)); extern const char *__wt_formatmessage(WT_SESSION_IMPL *session, DWORD windows_error); extern void __wt_yield(void); diff --git a/src/third_party/wiredtiger/src/include/flags.h b/src/third_party/wiredtiger/src/include/flags.h index f134af69d29..5d718da473d 100644 --- a/src/third_party/wiredtiger/src/include/flags.h +++ b/src/third_party/wiredtiger/src/include/flags.h @@ -2,6 +2,7 @@ * DO NOT EDIT: automatically built by dist/flags.py. * flags section: BEGIN */ +#define WT_CHECKPOINTING 0x00000001 #define WT_CONN_CACHE_POOL 0x00000001 #define WT_CONN_CKPT_SYNC 0x00000002 #define WT_CONN_CLOSING 0x00000004 @@ -21,10 +22,12 @@ #define WT_CONN_SERVER_STATISTICS 0x00010000 #define WT_CONN_SERVER_SWEEP 0x00020000 #define WT_CONN_WAS_BACKUP 0x00040000 -#define WT_EVICTING 0x00000001 -#define WT_EVICT_IN_MEMORY 0x00000002 -#define WT_EVICT_LOOKASIDE 0x00000004 -#define WT_EVICT_UPDATE_RESTORE 0x00000008 +#define WT_EVICTING 0x00000002 +#define WT_EVICT_INMEM_SPLIT 0x00000004 +#define WT_EVICT_IN_MEMORY 0x00000008 +#define WT_EVICT_LOOKASIDE 0x00000010 +#define WT_EVICT_SCRUB 0x00000020 +#define WT_EVICT_UPDATE_RESTORE 0x00000040 #define WT_LOGSCAN_FIRST 0x00000001 #define WT_LOGSCAN_FROM_CKP 0x00000002 #define WT_LOGSCAN_ONE 0x00000004 @@ -96,11 +99,12 @@ #define WT_VERB_SHARED_CACHE 0x00080000 #define WT_VERB_SPLIT 0x00100000 #define WT_VERB_TEMPORARY 0x00200000 -#define WT_VERB_TRANSACTION 0x00400000 -#define WT_VERB_VERIFY 0x00800000 -#define WT_VERB_VERSION 0x01000000 -#define WT_VERB_WRITE 0x02000000 -#define WT_VISIBILITY_ERR 0x00000010 +#define WT_VERB_THREAD_GROUP 0x00400000 +#define WT_VERB_TRANSACTION 0x00800000 +#define WT_VERB_VERIFY 0x01000000 +#define WT_VERB_VERSION 0x02000000 +#define WT_VERB_WRITE 0x04000000 +#define WT_VISIBILITY_ERR 0x00000080 /* * flags section: END * DO NOT EDIT: automatically built by dist/flags.py. diff --git a/src/third_party/wiredtiger/src/include/hardware.h b/src/third_party/wiredtiger/src/include/hardware.h index 93ed8a868b6..0e52818ae05 100644 --- a/src/third_party/wiredtiger/src/include/hardware.h +++ b/src/third_party/wiredtiger/src/include/hardware.h @@ -45,7 +45,16 @@ &(p)->flags_atomic, __orig, __orig & ~(uint8_t)(mask))); \ } while (0) -#define WT_CACHE_LINE_ALIGNMENT 64 /* Cache line alignment */ +/* + * Cache line alignment. + */ +#if defined(__PPC64__) || defined(PPC64) +#define WT_CACHE_LINE_ALIGNMENT 128 +#elif defined(__s390x__) +#define WT_CACHE_LINE_ALIGNMENT 256 +#else +#define WT_CACHE_LINE_ALIGNMENT 64 +#endif #define WT_CACHE_LINE_ALIGNMENT_VERIFY(session, a) \ WT_ASSERT(session, \ WT_PTRDIFF(&(a)[1], &(a)[0]) >= WT_CACHE_LINE_ALIGNMENT && \ diff --git a/src/third_party/wiredtiger/src/include/intpack.i b/src/third_party/wiredtiger/src/include/intpack.i index b27afd24e6c..e8bea58cede 100644 --- a/src/third_party/wiredtiger/src/include/intpack.i +++ b/src/third_party/wiredtiger/src/include/intpack.i @@ -59,7 +59,7 @@ /* Count the leading zero bytes. */ #if defined(__GNUC__) #define WT_LEADING_ZEROS(x, i) \ - (i = (x == 0) ? (int)sizeof (x) : __builtin_clzll(x) >> 3) + (i = (x == 0) ? (int)sizeof(x) : __builtin_clzll(x) >> 3) #elif defined(_MSC_VER) #define WT_LEADING_ZEROS(x, i) do { \ if (x == 0) i = (int)sizeof(x); \ @@ -89,7 +89,7 @@ __wt_vpack_posint(uint8_t **pp, size_t maxlen, uint64_t x) int len, lz, shift; WT_LEADING_ZEROS(x, lz); - len = (int)sizeof (x) - lz; + len = (int)sizeof(x) - lz; WT_SIZE_CHECK_PACK(len + 1, maxlen); p = *pp; @@ -114,7 +114,7 @@ __wt_vpack_negint(uint8_t **pp, size_t maxlen, uint64_t x) int len, lz, shift; WT_LEADING_ZEROS(~x, lz); - len = (int)sizeof (x) - lz; + len = (int)sizeof(x) - lz; WT_SIZE_CHECK_PACK(len + 1, maxlen); p = *pp; @@ -170,7 +170,7 @@ __wt_vunpack_negint(const uint8_t **pp, size_t maxlen, uint64_t *retp) /* There are four length bits in the first byte. */ p = *pp; - len = (int)sizeof (x) - (*p++ & 0xf); + len = (int)sizeof(x) - (*p++ & 0xf); WT_SIZE_CHECK_UNPACK(len + 1, maxlen); for (x = UINT64_MAX; len != 0; --len) diff --git a/src/third_party/wiredtiger/src/include/log.h b/src/third_party/wiredtiger/src/include/log.h index 870c046252c..b91c7dffe60 100644 --- a/src/third_party/wiredtiger/src/include/log.h +++ b/src/third_party/wiredtiger/src/include/log.h @@ -256,7 +256,9 @@ struct __wt_log { #ifdef HAVE_DIAGNOSTIC uint64_t write_calls; /* Calls to log_write */ #endif -#define WT_LOG_OPENED 0x01 /* Log subsystem successfully open */ + +#define WT_LOG_OPENED 0x01 /* Log subsystem successfully open */ +#define WT_LOG_TRUNCATE_NOTSUP 0x02 /* File system truncate not supported */ uint32_t flags; }; diff --git a/src/third_party/wiredtiger/src/include/misc.h b/src/third_party/wiredtiger/src/include/misc.h index 1121b7dfa75..83e238b0529 100644 --- a/src/third_party/wiredtiger/src/include/misc.h +++ b/src/third_party/wiredtiger/src/include/misc.h @@ -11,6 +11,11 @@ * and unused function return values. */ #define WT_UNUSED(var) (void)(var) +#define WT_IGNORE_RET(call) do { \ + int __ignored_ret; \ + __ignored_ret = (call); \ + WT_UNUSED(__ignored_ret); \ +} while (0) #define WT_DIVIDER "=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=" diff --git a/src/third_party/wiredtiger/src/include/misc.i b/src/third_party/wiredtiger/src/include/misc.i index eaa7a328ff1..f267c7afc91 100644 --- a/src/third_party/wiredtiger/src/include/misc.i +++ b/src/third_party/wiredtiger/src/include/misc.i @@ -10,12 +10,12 @@ * __wt_cond_wait -- * Wait on a mutex, optionally timing out. */ -static inline int +static inline void __wt_cond_wait(WT_SESSION_IMPL *session, WT_CONDVAR *cond, uint64_t usecs) { bool notused; - return (__wt_cond_wait_signal(session, cond, usecs, ¬used)); + __wt_cond_wait_signal(session, cond, usecs, ¬used); } /* @@ -48,25 +48,32 @@ __wt_seconds(WT_SESSION_IMPL *session, time_t *timep) /* * __wt_verbose -- * Verbose message. + * + * Inline functions are not parsed for external prototypes, so in cases where we + * want GCC attributes attached to the functions, we have to do so explicitly. */ -static inline int +static inline void +__wt_verbose(WT_SESSION_IMPL *session, int flag, const char *fmt, ...) +WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4))); + +/* + * __wt_verbose -- + * Verbose message. + */ +static inline void __wt_verbose(WT_SESSION_IMPL *session, int flag, const char *fmt, ...) - WT_GCC_FUNC_ATTRIBUTE((format (printf, 2, 3))) { #ifdef HAVE_VERBOSE - WT_DECL_RET; va_list ap; if (WT_VERBOSE_ISSET(session, flag)) { va_start(ap, fmt); - ret = __wt_eventv(session, true, 0, NULL, 0, fmt, ap); + WT_IGNORE_RET(__wt_eventv(session, true, 0, NULL, 0, fmt, ap)); va_end(ap); } - return (ret); #else WT_UNUSED(session); WT_UNUSED(flag); WT_UNUSED(fmt); - return (0); #endif } diff --git a/src/third_party/wiredtiger/src/include/mutex.h b/src/third_party/wiredtiger/src/include/mutex.h index 04679884930..f0f8173bad4 100644 --- a/src/third_party/wiredtiger/src/include/mutex.h +++ b/src/third_party/wiredtiger/src/include/mutex.h @@ -42,7 +42,7 @@ typedef union { /* Read/write lock */ struct { uint16_t writers; /* Now serving for writers */ uint16_t readers; /* Now serving for readers */ - uint16_t users; /* Next available ticket number */ + uint16_t next; /* Next available ticket number */ uint16_t __notused; /* Padding */ } s; } wt_rwlock_t; @@ -58,24 +58,6 @@ struct __wt_rwlock { wt_rwlock_t rwlock; /* Read/write lock */ }; -/* - * A light weight lock that can be used to replace spinlocks if fairness is - * necessary. Implements a ticket-based back off spin lock. - * The fields are available as a union to allow for atomically setting - * the state of the entire lock. - */ -struct __wt_fair_lock { - union { - uint32_t lock; - struct { - uint16_t owner; /* Ticket for current owner */ - uint16_t waiter; /* Last allocated ticket */ - } s; - } u; -#define fair_lock_owner u.s.owner -#define fair_lock_waiter u.s.waiter -}; - /* * Spin locks: * diff --git a/src/third_party/wiredtiger/src/include/mutex.i b/src/third_party/wiredtiger/src/include/mutex.i index 65956c13c08..cb1847d9991 100644 --- a/src/third_party/wiredtiger/src/include/mutex.i +++ b/src/third_party/wiredtiger/src/include/mutex.i @@ -154,9 +154,10 @@ __wt_spin_trylock(WT_SESSION_IMPL *session, WT_SPINLOCK *t) static inline void __wt_spin_lock(WT_SESSION_IMPL *session, WT_SPINLOCK *t) { - WT_UNUSED(session); + WT_DECL_RET; - (void)pthread_mutex_lock(&t->lock); + if ((ret = pthread_mutex_lock(&t->lock)) != 0) + WT_PANIC_MSG(session, ret, "pthread_mutex_lock: %s", t->name); } #endif @@ -167,16 +168,14 @@ __wt_spin_lock(WT_SESSION_IMPL *session, WT_SPINLOCK *t) static inline void __wt_spin_unlock(WT_SESSION_IMPL *session, WT_SPINLOCK *t) { - WT_UNUSED(session); + WT_DECL_RET; - (void)pthread_mutex_unlock(&t->lock); + if ((ret = pthread_mutex_unlock(&t->lock)) != 0) + WT_PANIC_MSG(session, ret, "pthread_mutex_unlock: %s", t->name); } #elif SPINLOCK_TYPE == SPINLOCK_MSVC -#define WT_SPINLOCK_REGISTER -1 -#define WT_SPINLOCK_REGISTER_FAILED -2 - /* * __wt_spin_init -- * Initialize a spinlock. @@ -184,13 +183,18 @@ __wt_spin_unlock(WT_SESSION_IMPL *session, WT_SPINLOCK *t) static inline int __wt_spin_init(WT_SESSION_IMPL *session, WT_SPINLOCK *t, const char *name) { - WT_UNUSED(session); + DWORD windows_error; + + if (InitializeCriticalSectionAndSpinCount(&t->lock, 4000) == 0) { + windows_error = __wt_getlasterror(); + __wt_errx(session, + "%s: InitializeCriticalSectionAndSpinCount: %s", + name, __wt_formatmessage(session, windows_error)); + return (__wt_map_windows_error(windows_error)); + } t->name = name; t->initialized = 1; - - InitializeCriticalSectionAndSpinCount(&t->lock, 4000); - return (0); } @@ -251,103 +255,3 @@ __wt_spin_unlock(WT_SESSION_IMPL *session, WT_SPINLOCK *t) #error Unknown spinlock type #endif - -/* - * __wt_fair_trylock -- - * Try to get a lock - give up if it is not immediately available. - */ -static inline int -__wt_fair_trylock(WT_SESSION_IMPL *session, WT_FAIR_LOCK *lock) -{ - WT_FAIR_LOCK new, old; - - WT_UNUSED(session); - - old = new = *lock; - - /* Exit early if there is no chance we can get the lock. */ - if (old.fair_lock_waiter != old.fair_lock_owner) - return (EBUSY); - - /* The replacement lock value is a result of allocating a new ticket. */ - ++new.fair_lock_waiter; - return (__wt_atomic_cas32( - &lock->u.lock, old.u.lock, new.u.lock) ? 0 : EBUSY); -} - -/* - * __wt_fair_lock -- - * Get a lock. - */ -static inline int -__wt_fair_lock(WT_SESSION_IMPL *session, WT_FAIR_LOCK *lock) -{ - uint16_t ticket; - int pause_cnt; - - WT_UNUSED(session); - - /* - * Possibly wrap: if we have more than 64K lockers waiting, the ticket - * value will wrap and two lockers will simultaneously be granted the - * lock. - */ - ticket = __wt_atomic_fetch_add16(&lock->fair_lock_waiter, 1); - for (pause_cnt = 0; ticket != lock->fair_lock_owner;) { - /* - * We failed to get the lock; pause before retrying and if we've - * paused enough, sleep so we don't burn CPU to no purpose. This - * situation happens if there are more threads than cores in the - * system and we're thrashing on shared resources. - */ - if (++pause_cnt < WT_THOUSAND) - WT_PAUSE(); - else - __wt_sleep(0, 10); - } - - /* - * Applications depend on a barrier here so that operations holding the - * lock see consistent data. - */ - WT_READ_BARRIER(); - - return (0); -} - -/* - * __wt_fair_unlock -- - * Release a shared lock. - */ -static inline int -__wt_fair_unlock(WT_SESSION_IMPL *session, WT_FAIR_LOCK *lock) -{ - WT_UNUSED(session); - - /* - * Ensure that all updates made while the lock was held are visible to - * the next thread to acquire the lock. - */ - WT_WRITE_BARRIER(); - - /* - * We have exclusive access - the update does not need to be atomic. - */ - ++lock->fair_lock_owner; - - return (0); -} - -#ifdef HAVE_DIAGNOSTIC -/* - * __wt_fair_islocked -- - * Test whether the lock is currently held. - */ -static inline bool -__wt_fair_islocked(WT_SESSION_IMPL *session, WT_FAIR_LOCK *lock) -{ - WT_UNUSED(session); - - return (lock->fair_lock_waiter != lock->fair_lock_owner); -} -#endif diff --git a/src/third_party/wiredtiger/src/include/os_fhandle.i b/src/third_party/wiredtiger/src/include/os_fhandle.i index 313bf8eca3f..a9150279a85 100644 --- a/src/third_party/wiredtiger/src/include/os_fhandle.i +++ b/src/third_party/wiredtiger/src/include/os_fhandle.i @@ -18,15 +18,15 @@ __wt_fsync(WT_SESSION_IMPL *session, WT_FH *fh, bool block) WT_ASSERT(session, !F_ISSET(S2C(session), WT_CONN_READONLY)); - WT_RET(__wt_verbose( - session, WT_VERB_HANDLEOPS, "%s: handle-sync", fh->handle->name)); + __wt_verbose( + session, WT_VERB_HANDLEOPS, "%s: handle-sync", fh->handle->name); handle = fh->handle; /* * There is no way to check when the non-blocking sync-file-range is * complete, but we track the time taken in the call for completeness. */ - WT_STAT_FAST_CONN_INCR_ATOMIC(session, fsync_active); + WT_STAT_FAST_CONN_INCR_ATOMIC(session, thread_fsync_active); WT_STAT_FAST_CONN_INCR(session, fsync_io); if (block) ret = (handle->fh_sync == NULL ? 0 : @@ -34,45 +34,37 @@ __wt_fsync(WT_SESSION_IMPL *session, WT_FH *fh, bool block) else ret = (handle->fh_sync_nowait == NULL ? 0 : handle->fh_sync_nowait(handle, (WT_SESSION *)session)); - WT_STAT_FAST_CONN_DECR_ATOMIC(session, fsync_active); + WT_STAT_FAST_CONN_DECR_ATOMIC(session, thread_fsync_active); return (ret); } /* - * __wt_fallocate -- + * __wt_fextend -- * Extend a file. */ static inline int -__wt_fallocate( - WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t offset, wt_off_t len) +__wt_fextend(WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t offset) { - WT_DECL_RET; WT_FILE_HANDLE *handle; WT_ASSERT(session, !F_ISSET(S2C(session), WT_CONN_READONLY)); WT_ASSERT(session, !F_ISSET(S2C(session), WT_CONN_IN_MEMORY)); - WT_RET(__wt_verbose(session, WT_VERB_HANDLEOPS, - "%s: handle-allocate: %" PRIuMAX " at %" PRIuMAX, - fh->handle->name, (uintmax_t)len, (uintmax_t)offset)); + __wt_verbose(session, WT_VERB_HANDLEOPS, + "%s: handle-extend: to %" PRIuMAX, + fh->handle->name, (uintmax_t)offset); /* * Our caller is responsible for handling any locking issues, all we * have to do is find a function to call. - * - * Be cautious, the underlying system might have configured the nolock - * flavor, that failed, and we have to fallback to the locking flavor. */ handle = fh->handle; - if (handle->fh_allocate_nolock != NULL) { - if ((ret = handle->fh_allocate_nolock( - handle, (WT_SESSION *)session, offset, len)) == 0) - return (0); - WT_RET_ERROR_OK(ret, ENOTSUP); - } - if (handle->fh_allocate != NULL) - return (handle->fh_allocate( - handle, (WT_SESSION *)session, offset, len)); + if (handle->fh_extend_nolock != NULL) + return (handle->fh_extend_nolock( + handle, (WT_SESSION *)session, offset)); + if (handle->fh_extend != NULL) + return (handle->fh_extend( + handle, (WT_SESSION *)session, offset)); return (ENOTSUP); } @@ -85,8 +77,8 @@ __wt_file_lock(WT_SESSION_IMPL * session, WT_FH *fh, bool lock) { WT_FILE_HANDLE *handle; - WT_RET(__wt_verbose(session, WT_VERB_HANDLEOPS, - "%s: handle-lock: %s", fh->handle->name, lock ? "lock" : "unlock")); + __wt_verbose(session, WT_VERB_HANDLEOPS, + "%s: handle-lock: %s", fh->handle->name, lock ? "lock" : "unlock"); handle = fh->handle; return (handle->fh_lock == NULL ? 0 : @@ -103,17 +95,17 @@ __wt_read( { WT_DECL_RET; - WT_RET(__wt_verbose(session, WT_VERB_HANDLEOPS, + __wt_verbose(session, WT_VERB_HANDLEOPS, "%s: handle-read: %" WT_SIZET_FMT " at %" PRIuMAX, - fh->handle->name, len, (uintmax_t)offset)); + fh->handle->name, len, (uintmax_t)offset); - WT_STAT_FAST_CONN_INCR_ATOMIC(session, read_active); + WT_STAT_FAST_CONN_INCR_ATOMIC(session, thread_read_active); WT_STAT_FAST_CONN_INCR(session, read_io); ret = fh->handle->fh_read( fh->handle, (WT_SESSION *)session, offset, len, buf); - WT_STAT_FAST_CONN_DECR_ATOMIC(session, read_active); + WT_STAT_FAST_CONN_DECR_ATOMIC(session, thread_read_active); return (ret); } @@ -124,27 +116,36 @@ __wt_read( static inline int __wt_filesize(WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t *sizep) { - WT_RET(__wt_verbose( - session, WT_VERB_HANDLEOPS, "%s: handle-size", fh->handle->name)); + __wt_verbose( + session, WT_VERB_HANDLEOPS, "%s: handle-size", fh->handle->name); return (fh->handle->fh_size(fh->handle, (WT_SESSION *)session, sizep)); } /* * __wt_ftruncate -- - * POSIX ftruncate. + * Truncate a file. */ static inline int -__wt_ftruncate(WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t len) +__wt_ftruncate(WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t offset) { + WT_FILE_HANDLE *handle; + WT_ASSERT(session, !F_ISSET(S2C(session), WT_CONN_READONLY)); - WT_RET(__wt_verbose(session, WT_VERB_HANDLEOPS, - "%s: handle-truncate: %" PRIuMAX, - fh->handle->name, (uintmax_t)len)); + __wt_verbose(session, WT_VERB_HANDLEOPS, + "%s: handle-truncate: to %" PRIuMAX, + fh->handle->name, (uintmax_t)offset); - return (fh->handle->fh_truncate( - fh->handle, (WT_SESSION *)session, len)); + /* + * Our caller is responsible for handling any locking issues, all we + * have to do is find a function to call. + */ + handle = fh->handle; + if (handle->fh_truncate != NULL) + return (handle->fh_truncate( + handle, (WT_SESSION *)session, offset)); + return (ENOTSUP); } /* @@ -161,16 +162,23 @@ __wt_write(WT_SESSION_IMPL *session, WT_STRING_MATCH(fh->name, WT_SINGLETHREAD, strlen(WT_SINGLETHREAD))); - WT_RET(__wt_verbose(session, WT_VERB_HANDLEOPS, + __wt_verbose(session, WT_VERB_HANDLEOPS, "%s: handle-write: %" WT_SIZET_FMT " at %" PRIuMAX, - fh->handle->name, len, (uintmax_t)offset)); + fh->handle->name, len, (uintmax_t)offset); + + /* + * Do a final panic check before I/O, so we stop writing as quickly as + * possible if there's an unanticipated error. We aren't handling the + * error correctly by definition, and writing won't make things better. + */ + WT_RET(WT_SESSION_CHECK_PANIC(session)); - WT_STAT_FAST_CONN_INCR_ATOMIC(session, write_active); WT_STAT_FAST_CONN_INCR(session, write_io); + WT_STAT_FAST_CONN_INCR_ATOMIC(session, thread_write_active); ret = fh->handle->fh_write( fh->handle, (WT_SESSION *)session, offset, len, buf); - WT_STAT_FAST_CONN_DECR_ATOMIC(session, write_active); + WT_STAT_FAST_CONN_DECR_ATOMIC(session, thread_write_active); return (ret); } diff --git a/src/third_party/wiredtiger/src/include/os_fs.i b/src/third_party/wiredtiger/src/include/os_fs.i index a3a2fe29b65..4cf1128280e 100644 --- a/src/third_party/wiredtiger/src/include/os_fs.i +++ b/src/third_party/wiredtiger/src/include/os_fs.i @@ -22,9 +22,9 @@ __wt_fs_directory_list(WT_SESSION_IMPL *session, *dirlistp = NULL; *countp = 0; - WT_RET(__wt_verbose(session, WT_VERB_FILEOPS, - "%s: directory-list: %s prefix %s", - dir, prefix == NULL ? "all" : prefix)); + __wt_verbose(session, WT_VERB_FILEOPS, + "%s: directory-list: prefix %s", + dir, prefix == NULL ? "all" : prefix); WT_RET(__wt_filename(session, dir, &path)); @@ -72,7 +72,7 @@ __wt_fs_exist(WT_SESSION_IMPL *session, const char *name, bool *existp) WT_SESSION *wt_session; char *path; - WT_RET(__wt_verbose(session, WT_VERB_FILEOPS, "%s: file-exist", name)); + __wt_verbose(session, WT_VERB_FILEOPS, "%s: file-exist", name); WT_RET(__wt_filename(session, name, &path)); @@ -98,7 +98,7 @@ __wt_fs_remove(WT_SESSION_IMPL *session, const char *name, bool durable) WT_ASSERT(session, !F_ISSET(S2C(session), WT_CONN_READONLY)); - WT_RET(__wt_verbose(session, WT_VERB_FILEOPS, "%s: file-remove", name)); + __wt_verbose(session, WT_VERB_FILEOPS, "%s: file-remove", name); #ifdef HAVE_DIAGNOSTIC /* @@ -136,8 +136,8 @@ __wt_fs_rename( WT_ASSERT(session, !F_ISSET(S2C(session), WT_CONN_READONLY)); - WT_RET(__wt_verbose( - session, WT_VERB_FILEOPS, "%s to %s: file-rename", from, to)); + __wt_verbose( + session, WT_VERB_FILEOPS, "%s to %s: file-rename", from, to); #ifdef HAVE_DIAGNOSTIC /* @@ -178,7 +178,7 @@ __wt_fs_size(WT_SESSION_IMPL *session, const char *name, wt_off_t *sizep) WT_SESSION *wt_session; char *path; - WT_RET(__wt_verbose(session, WT_VERB_FILEOPS, "%s: file-size", name)); + __wt_verbose(session, WT_VERB_FILEOPS, "%s: file-size", name); WT_RET(__wt_filename(session, name, &path)); diff --git a/src/third_party/wiredtiger/src/include/os_fstream.i b/src/third_party/wiredtiger/src/include/os_fstream.i index 92274431011..98d0622f346 100644 --- a/src/third_party/wiredtiger/src/include/os_fstream.i +++ b/src/third_party/wiredtiger/src/include/os_fstream.i @@ -49,19 +49,26 @@ static inline int __wt_vfprintf( WT_SESSION_IMPL *session, WT_FSTREAM *fstr, const char *fmt, va_list ap) { - WT_RET(__wt_verbose( - session, WT_VERB_HANDLEOPS, "%s: handle-printf", fstr->name)); - return (fstr->fstr_printf(session, fstr, fmt, ap)); } +/* + * __wt_fprintf -- + * ANSI C fprintf. + * + * Inline functions are not parsed for external prototypes, so in cases where we + * want GCC attributes attached to the functions, we have to do so explicitly. + */ +static inline int +__wt_fprintf(WT_SESSION_IMPL *session, WT_FSTREAM *fstr, const char *fmt, ...) + WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4))); + /* * __wt_fprintf -- * ANSI C fprintf. */ static inline int __wt_fprintf(WT_SESSION_IMPL *session, WT_FSTREAM *fstr, const char *fmt, ...) - WT_GCC_FUNC_ATTRIBUTE((format (printf, 3, 4))) { WT_DECL_RET; va_list ap; diff --git a/src/third_party/wiredtiger/src/include/packing.i b/src/third_party/wiredtiger/src/include/packing.i index d662c60d221..17ca261bcfc 100644 --- a/src/third_party/wiredtiger/src/include/packing.i +++ b/src/third_party/wiredtiger/src/include/packing.i @@ -81,7 +81,7 @@ __pack_init(WT_SESSION_IMPL *session, WT_PACK *pack, const char *fmt) * __pack_name_init -- * Initialize the name of a pack iterator. */ -static inline int +static inline void __pack_name_init(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *names, bool iskey, WT_PACK_NAME *pn) { @@ -89,11 +89,9 @@ __pack_name_init(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *names, pn->iskey = iskey; if (names->str != NULL) - WT_RET(__wt_config_subinit(session, &pn->config, names)); + __wt_config_subinit(session, &pn->config, names); else pn->genname = 1; - - return (0); } /* diff --git a/src/third_party/wiredtiger/src/include/queue.h b/src/third_party/wiredtiger/src/include/queue.h index 1d494875cf6..e3d4daf0f4c 100644 --- a/src/third_party/wiredtiger/src/include/queue.h +++ b/src/third_party/wiredtiger/src/include/queue.h @@ -1,4 +1,4 @@ -/* +/*- * Copyright (c) 1991, 1993 * The Regents of the University of California. All rights reserved. * @@ -27,28 +27,18 @@ * SUCH DAMAGE. * * @(#)queue.h 8.5 (Berkeley) 8/20/94 - * $FreeBSD: src/sys/sys/queue.h,v 1.54 2002/08/05 05:18:43 alfred Exp $ + * $FreeBSD$ */ -#ifndef _DB_QUEUE_H_ -#define _DB_QUEUE_H_ - -#if defined(__cplusplus) -extern "C" { -#endif - /* + * This is a stripped-down version of the FreeBSD sys/queue.h include file. + * * WiredTiger only uses the TAILQ macros (we've gotten into trouble in the past * by trying to use simpler queues and subsequently discovering a list we didn't * think would ever get to be large could, under some workloads, become large, * and the linear performance for removal of elements from simpler macros proved * to be more trouble than the memory savings were worth. * - * Additionally, we've altered the TAILQ_INSERT_XXX functions to include a write - * barrier, in order to ensure we never insert a partially built structure onto - * a list (this is required because the spinlocks we use don't necessarily imply - * a write barrier). - * * We #undef all of the macros because there are incompatible versions of this * file and these macros on various systems. What makes the problem worse is * they are included and/or defined by system include files which we may have @@ -57,13 +47,28 @@ extern "C" { * several of the LIST_XXX macros. Visual C.NET 7.0 also defines some of these * same macros in Vc7\PlatformSDK\Include\WinNT.h. Make sure we use ours. */ - +#undef QMD_SAVELINK +#undef QMD_TAILQ_CHECK_HEAD +#undef QMD_TAILQ_CHECK_NEXT +#undef QMD_TAILQ_CHECK_PREV +#undef QMD_TAILQ_CHECK_TAIL +#undef QMD_TRACE_ELEM +#undef QMD_TRACE_HEAD +#undef QUEUE_TYPEOF +#undef TAILQ_CLASS_ENTRY +#undef TAILQ_CLASS_HEAD #undef TAILQ_CONCAT #undef TAILQ_EMPTY #undef TAILQ_ENTRY #undef TAILQ_FIRST #undef TAILQ_FOREACH +#undef TAILQ_FOREACH_FROM +#undef TAILQ_FOREACH_FROM_SAFE #undef TAILQ_FOREACH_REVERSE +#undef TAILQ_FOREACH_REVERSE_FROM +#undef TAILQ_FOREACH_REVERSE_FROM_SAFE +#undef TAILQ_FOREACH_REVERSE_SAFE +#undef TAILQ_FOREACH_SAFE #undef TAILQ_HEAD #undef TAILQ_HEAD_INITIALIZER #undef TAILQ_INIT @@ -76,41 +81,25 @@ extern "C" { #undef TAILQ_PREV #undef TAILQ_REMOVE #undef TRACEBUF +#undef TRACEBUF_INITIALIZER #undef TRASHIT +#undef TAILQ_SWAP -#define QUEUE_MACRO_DEBUG 0 -#if QUEUE_MACRO_DEBUG -/* Store the last 2 places the queue element or head was altered */ -struct qm_trace { - char * lastfile; - int lastline; - char * prevfile; - int prevline; -}; - -#define TRACEBUF struct qm_trace trace; -#define TRASHIT(x) do {(x) = (void *)-1;} while (0) - -#define QMD_TRACE_HEAD(head) do { \ - (head)->trace.prevline = (head)->trace.lastline; \ - (head)->trace.prevfile = (head)->trace.lastfile; \ - (head)->trace.lastline = __LINE__; \ - (head)->trace.lastfile = __FILE__; \ -} while (0) - -#define QMD_TRACE_ELEM(elem) do { \ - (elem)->trace.prevline = (elem)->trace.lastline; \ - (elem)->trace.prevfile = (elem)->trace.lastfile; \ - (elem)->trace.lastline = __LINE__; \ - (elem)->trace.lastfile = __FILE__; \ -} while (0) - -#else #define QMD_TRACE_ELEM(elem) #define QMD_TRACE_HEAD(head) +#define QMD_SAVELINK(name, link) #define TRACEBUF +#define TRACEBUF_INITIALIZER #define TRASHIT(x) -#endif /* QUEUE_MACRO_DEBUG */ + +#ifdef __cplusplus +/* + * In C++ there can be structure lists and class lists: + */ +#define QUEUE_TYPEOF(type) type +#else +#define QUEUE_TYPEOF(type) struct type +#endif /* * Tail queue declarations. @@ -122,8 +111,15 @@ struct name { \ TRACEBUF \ } +#define TAILQ_CLASS_HEAD(name, type) \ +struct name { \ + class type *tqh_first; /* first element */ \ + class type **tqh_last; /* addr of last next element */ \ + TRACEBUF \ +} + #define TAILQ_HEAD_INITIALIZER(head) \ - { NULL, &(head).tqh_first } + { NULL, &(head).tqh_first, TRACEBUF_INITIALIZER } #define TAILQ_ENTRY(type) \ struct { \ @@ -132,16 +128,28 @@ struct { \ TRACEBUF \ } +#define TAILQ_CLASS_ENTRY(type) \ +struct { \ + class type *tqe_next; /* next element */ \ + class type **tqe_prev; /* address of previous next element */ \ + TRACEBUF \ +} + /* * Tail queue functions. */ +#define QMD_TAILQ_CHECK_HEAD(head, field) +#define QMD_TAILQ_CHECK_TAIL(head, headname) +#define QMD_TAILQ_CHECK_NEXT(elm, field) +#define QMD_TAILQ_CHECK_PREV(elm, field) + #define TAILQ_CONCAT(head1, head2, field) do { \ if (!TAILQ_EMPTY(head2)) { \ *(head1)->tqh_last = (head2)->tqh_first; \ (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ (head1)->tqh_last = (head2)->tqh_last; \ TAILQ_INIT((head2)); \ - QMD_TRACE_HEAD(head); \ + QMD_TRACE_HEAD(head1); \ QMD_TRACE_HEAD(head2); \ } \ } while (0) @@ -155,11 +163,41 @@ struct { \ (var); \ (var) = TAILQ_NEXT((var), field)) +#define TAILQ_FOREACH_FROM(var, head, field) \ + for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \ + (var); \ + (var) = TAILQ_NEXT((var), field)) + +#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = TAILQ_FIRST((head)); \ + (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \ + for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \ + (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + #define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ for ((var) = TAILQ_LAST((head), headname); \ (var); \ (var) = TAILQ_PREV((var), headname, field)) +#define TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field) \ + for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \ + (var); \ + (var) = TAILQ_PREV((var), headname, field)) + +#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ + for ((var) = TAILQ_LAST((head), headname); \ + (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ + (var) = (tvar)) + +#define TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) \ + for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \ + (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ + (var) = (tvar)) + #define TAILQ_INIT(head) do { \ TAILQ_FIRST((head)) = NULL; \ (head)->tqh_last = &TAILQ_FIRST((head)); \ @@ -167,9 +205,9 @@ struct { \ } while (0) #define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ - WT_WRITE_BARRIER(); \ + QMD_TAILQ_CHECK_NEXT(listelm, field); \ if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ - TAILQ_NEXT((elm), field)->field.tqe_prev = \ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ &TAILQ_NEXT((elm), field); \ else { \ (head)->tqh_last = &TAILQ_NEXT((elm), field); \ @@ -178,21 +216,21 @@ struct { \ TAILQ_NEXT((listelm), field) = (elm); \ (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ QMD_TRACE_ELEM(&(elm)->field); \ - QMD_TRACE_ELEM(&listelm->field); \ + QMD_TRACE_ELEM(&(listelm)->field); \ } while (0) #define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ - WT_WRITE_BARRIER(); \ + QMD_TAILQ_CHECK_PREV(listelm, field); \ (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ TAILQ_NEXT((elm), field) = (listelm); \ *(listelm)->field.tqe_prev = (elm); \ (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ QMD_TRACE_ELEM(&(elm)->field); \ - QMD_TRACE_ELEM(&listelm->field); \ + QMD_TRACE_ELEM(&(listelm)->field); \ } while (0) #define TAILQ_INSERT_HEAD(head, elm, field) do { \ - WT_WRITE_BARRIER(); \ + QMD_TAILQ_CHECK_HEAD(head, field); \ if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ TAILQ_FIRST((head))->field.tqe_prev = \ &TAILQ_NEXT((elm), field); \ @@ -205,7 +243,7 @@ struct { \ } while (0) #define TAILQ_INSERT_TAIL(head, elm, field) do { \ - WT_WRITE_BARRIER(); \ + QMD_TAILQ_CHECK_TAIL(head, field); \ TAILQ_NEXT((elm), field) = NULL; \ (elm)->field.tqe_prev = (head)->tqh_last; \ *(head)->tqh_last = (elm); \ @@ -223,20 +261,36 @@ struct { \ (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) #define TAILQ_REMOVE(head, elm, field) do { \ + QMD_SAVELINK(oldnext, (elm)->field.tqe_next); \ + QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \ + QMD_TAILQ_CHECK_NEXT(elm, field); \ + QMD_TAILQ_CHECK_PREV(elm, field); \ if ((TAILQ_NEXT((elm), field)) != NULL) \ - TAILQ_NEXT((elm), field)->field.tqe_prev = \ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ (elm)->field.tqe_prev; \ else { \ (head)->tqh_last = (elm)->field.tqe_prev; \ QMD_TRACE_HEAD(head); \ } \ *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ - TRASHIT((elm)->field.tqe_next); \ - TRASHIT((elm)->field.tqe_prev); \ + TRASHIT(*oldnext); \ + TRASHIT(*oldprev); \ QMD_TRACE_ELEM(&(elm)->field); \ } while (0) -#if defined(__cplusplus) -} -#endif -#endif /* !_DB_QUEUE_H_ */ +#define TAILQ_SWAP(head1, head2, type, field) do { \ + QUEUE_TYPEOF(type) *swap_first = (head1)->tqh_first; \ + QUEUE_TYPEOF(type) **swap_last = (head1)->tqh_last; \ + (head1)->tqh_first = (head2)->tqh_first; \ + (head1)->tqh_last = (head2)->tqh_last; \ + (head2)->tqh_first = swap_first; \ + (head2)->tqh_last = swap_last; \ + if ((swap_first = (head1)->tqh_first) != NULL) \ + swap_first->field.tqe_prev = &(head1)->tqh_first; \ + else \ + (head1)->tqh_last = &(head1)->tqh_first; \ + if ((swap_first = (head2)->tqh_first) != NULL) \ + swap_first->field.tqe_prev = &(head2)->tqh_first; \ + else \ + (head2)->tqh_last = &(head2)->tqh_first; \ +} while (0) diff --git a/src/third_party/wiredtiger/src/include/serial.i b/src/third_party/wiredtiger/src/include/serial.i index 67edc1c9ce1..982f196b0b8 100644 --- a/src/third_party/wiredtiger/src/include/serial.i +++ b/src/third_party/wiredtiger/src/include/serial.i @@ -316,11 +316,11 @@ __wt_update_serial(WT_SESSION_IMPL *session, WT_PAGE *page, } /* If we can't lock it, don't scan, that's okay. */ - if (__wt_fair_trylock(session, &page->page_lock) != 0) + if (__wt_try_writelock(session, &page->page_lock) != 0) return (0); obsolete = __wt_update_obsolete_check(session, page, upd->next); - WT_RET(__wt_fair_unlock(session, &page->page_lock)); + __wt_writeunlock(session, &page->page_lock); if (obsolete != NULL) __wt_update_obsolete_free(session, page, obsolete); diff --git a/src/third_party/wiredtiger/src/include/stat.h b/src/third_party/wiredtiger/src/include/stat.h index 57126af8aa4..b61c568783b 100644 --- a/src/third_party/wiredtiger/src/include/stat.h +++ b/src/third_party/wiredtiger/src/include/stat.h @@ -145,14 +145,14 @@ __wt_stats_clear(void *stats_arg, int slot) #define WT_STAT_DECRV(session, stats, fld, value) \ (stats)[WT_STATS_SLOT_ID(session)]->fld -= (int64_t)(value) #define WT_STAT_DECRV_ATOMIC(session, stats, fld, value) \ - __wt_atomic_addi64( \ + __wt_atomic_subi64( \ &(stats)[WT_STATS_SLOT_ID(session)]->fld, (int64_t)(value)) #define WT_STAT_DECR(session, stats, fld) \ WT_STAT_DECRV(session, stats, fld, 1) #define WT_STAT_INCRV(session, stats, fld, value) \ (stats)[WT_STATS_SLOT_ID(session)]->fld += (int64_t)(value) #define WT_STAT_INCRV_ATOMIC(session, stats, fld, value) \ - __wt_atomic_subi64( \ + __wt_atomic_addi64( \ &(stats)[WT_STATS_SLOT_ID(session)]->fld, (int64_t)(value)) #define WT_STAT_INCR(session, stats, fld) \ WT_STAT_INCRV(session, stats, fld, 1) @@ -273,9 +273,12 @@ struct __wt_connection_stats { int64_t block_write; int64_t block_byte_read; int64_t block_byte_write; + int64_t block_byte_write_checkpoint; int64_t block_map_read; int64_t block_byte_map_read; + int64_t cache_bytes_image; int64_t cache_bytes_inuse; + int64_t cache_bytes_other; int64_t cache_bytes_read; int64_t cache_bytes_write; int64_t cache_eviction_checkpoint; @@ -286,10 +289,9 @@ struct __wt_connection_stats { int64_t cache_eviction_queue_empty; int64_t cache_eviction_queue_not_empty; int64_t cache_eviction_server_evicting; - int64_t cache_eviction_server_not_evicting; - int64_t cache_eviction_server_toobig; int64_t cache_eviction_server_slept; int64_t cache_eviction_slow; + int64_t cache_eviction_state; int64_t cache_eviction_worker_evicting; int64_t cache_eviction_force_fail; int64_t cache_eviction_walks_active; @@ -309,6 +311,8 @@ struct __wt_connection_stats { int64_t cache_eviction_maximum_page_size; int64_t cache_eviction_dirty; int64_t cache_eviction_app_dirty; + int64_t cache_read_overflow; + int64_t cache_overflow_value; int64_t cache_eviction_deepen; int64_t cache_write_lookaside; int64_t cache_pages_inuse; @@ -316,6 +320,7 @@ struct __wt_connection_stats { int64_t cache_eviction_force_delete; int64_t cache_eviction_app; int64_t cache_eviction_pages_queued; + int64_t cache_eviction_pages_queued_urgent; int64_t cache_eviction_pages_queued_oldest; int64_t cache_read; int64_t cache_read_lookaside; @@ -328,7 +333,6 @@ struct __wt_connection_stats { int64_t cache_overhead; int64_t cache_bytes_internal; int64_t cache_bytes_leaf; - int64_t cache_bytes_overflow; int64_t cache_bytes_dirty; int64_t cache_pages_dirty; int64_t cache_eviction_clean; @@ -408,9 +412,25 @@ struct __wt_connection_stats { int64_t rec_split_stashed_objects; int64_t session_cursor_open; int64_t session_open; - int64_t fsync_active; - int64_t read_active; - int64_t write_active; + int64_t session_table_compact_fail; + int64_t session_table_compact_success; + int64_t session_table_create_fail; + int64_t session_table_create_success; + int64_t session_table_drop_fail; + int64_t session_table_drop_success; + int64_t session_table_rebalance_fail; + int64_t session_table_rebalance_success; + int64_t session_table_rename_fail; + int64_t session_table_rename_success; + int64_t session_table_salvage_fail; + int64_t session_table_salvage_success; + int64_t session_table_truncate_fail; + int64_t session_table_truncate_success; + int64_t session_table_verify_fail; + int64_t session_table_verify_success; + int64_t thread_fsync_active; + int64_t thread_read_active; + int64_t thread_write_active; int64_t page_busy_blocked; int64_t page_forcible_evict_blocked; int64_t page_locked_blocked; @@ -424,13 +444,13 @@ struct __wt_connection_stats { int64_t txn_checkpoint_time_max; int64_t txn_checkpoint_time_min; int64_t txn_checkpoint_time_recent; + int64_t txn_checkpoint_scrub_target; + int64_t txn_checkpoint_scrub_time; int64_t txn_checkpoint_time_total; int64_t txn_checkpoint; int64_t txn_fail_cache; int64_t txn_checkpoint_fsync_post; - int64_t txn_checkpoint_fsync_pre; int64_t txn_checkpoint_fsync_post_duration; - int64_t txn_checkpoint_fsync_pre_duration; int64_t txn_pinned_range; int64_t txn_pinned_checkpoint_range; int64_t txn_pinned_snapshot_range; @@ -484,6 +504,7 @@ struct __wt_dsrc_stats { int64_t btree_compact_rewrite; int64_t btree_row_internal; int64_t btree_row_leaf; + int64_t cache_bytes_inuse; int64_t cache_bytes_read; int64_t cache_bytes_write; int64_t cache_eviction_checkpoint; diff --git a/src/third_party/wiredtiger/src/include/thread_group.h b/src/third_party/wiredtiger/src/include/thread_group.h new file mode 100644 index 00000000000..f946dcab144 --- /dev/null +++ b/src/third_party/wiredtiger/src/include/thread_group.h @@ -0,0 +1,61 @@ +/*- + * Copyright (c) 2014-2016 MongoDB, Inc. + * Copyright (c) 2008-2014 WiredTiger, Inc. + * All rights reserved. + * + * See the file LICENSE for redistribution information. + */ + +/* + * WT_THREAD -- + * Encapsulation of a thread that belongs to a thread group. + */ +struct __wt_thread { + WT_SESSION_IMPL *session; + u_int id; + wt_thread_t tid; +#define WT_THREAD_RUN 0x01 + uint32_t flags; + + /* The runner function used by all threads. */ + int (*run_func)(WT_SESSION_IMPL *session, WT_THREAD *context); +}; + +/* + * Flags for thread group functions. + */ +#define WT_THREAD_CAN_WAIT 0x01 +#define WT_THREAD_PANIC_FAIL 0x02 + +/* + * WT_THREAD_GROUP -- + * Encapsulation of a group of utility threads. + */ +struct __wt_thread_group { + uint32_t alloc; /* Size of allocated group */ + uint32_t max; /* Max threads in group */ + uint32_t min; /* Min threads in group */ + uint32_t current_threads;/* Number of active threads */ + + const char *name; /* Name */ + + WT_RWLOCK *lock; /* Protects group changes */ + + /* + * Condition signalled when wanting to wake up threads that are + * part of the group - for example when shutting down. This condition + * can also be used by group owners to ensure state changes are noticed. + */ + WT_CONDVAR *wait_cond; + + /* + * The threads need to be held in an array of arrays, not an array of + * structures because the array is reallocated as it grows, which + * causes threads to loose track of their context is realloc moves the + * memory. + */ + WT_THREAD **threads; + + /* The runner function used by all threads. */ + int (*run_func)(WT_SESSION_IMPL *session, WT_THREAD *context); +}; diff --git a/src/third_party/wiredtiger/src/include/txn.i b/src/third_party/wiredtiger/src/include/txn.i index 96f7426e421..ffd319fd5c1 100644 --- a/src/third_party/wiredtiger/src/include/txn.i +++ b/src/third_party/wiredtiger/src/include/txn.i @@ -105,19 +105,22 @@ __wt_txn_oldest_id(WT_SESSION_IMPL *session) { WT_BTREE *btree; WT_TXN_GLOBAL *txn_global; - uint64_t checkpoint_gen, checkpoint_pinned, oldest_id; + uint64_t checkpoint_pinned, oldest_id; + bool include_checkpoint_txn; txn_global = &S2C(session)->txn_global; btree = S2BT_SAFE(session); /* * Take a local copy of these IDs in case they are updated while we are - * checking visibility. Only the generation needs to be carefully - * ordered: if a checkpoint is starting and the generation is bumped, - * we take the minimum of the other two IDs, which is what we want. + * checking visibility. The read of the transaction ID pinned by a + * checkpoint needs to be carefully ordered: if a checkpoint is + * starting and we have to start checking the pinned ID, we take the + * minimum of it with the oldest ID, which is what we want. */ oldest_id = txn_global->oldest_id; - WT_ORDERED_READ(checkpoint_gen, txn_global->checkpoint_gen); + include_checkpoint_txn = btree == NULL || btree->include_checkpoint_txn; + WT_READ_BARRIER(); checkpoint_pinned = txn_global->checkpoint_pinned; /* @@ -126,14 +129,12 @@ __wt_txn_oldest_id(WT_SESSION_IMPL *session) * if they are only required for the checkpoint and it has already * seen them. * - * If there is no active checkpoint, this session is doing the - * checkpoint, or this handle is up to date with the active checkpoint - * then it's safe to ignore the checkpoint ID in the visibility check. + * If there is no active checkpoint or this handle is up to date with + * the active checkpoint then it's safe to ignore the checkpoint ID in + * the visibility check. */ - if (checkpoint_pinned == WT_TXN_NONE || - WT_TXNID_LT(oldest_id, checkpoint_pinned) || - WT_SESSION_IS_CHECKPOINT(session) || - (btree != NULL && btree->checkpoint_gen == checkpoint_gen)) + if (!include_checkpoint_txn || checkpoint_pinned == WT_TXN_NONE || + WT_TXNID_LT(oldest_id, checkpoint_pinned)) return (oldest_id); return (checkpoint_pinned); diff --git a/src/third_party/wiredtiger/src/include/wiredtiger.in b/src/third_party/wiredtiger/src/include/wiredtiger.in index c27fd174030..61a66bd4086 100644 --- a/src/third_party/wiredtiger/src/include/wiredtiger.in +++ b/src/third_party/wiredtiger/src/include/wiredtiger.in @@ -131,13 +131,13 @@ struct __wt_item { * The maximum packed size of a 64-bit integer. The ::wiredtiger_struct_pack * function will pack single long integers into at most this many bytes. */ -#define WT_INTPACK64_MAXSIZE ((int)sizeof (int64_t) + 1) +#define WT_INTPACK64_MAXSIZE ((int)sizeof(int64_t) + 1) /*! * The maximum packed size of a 32-bit integer. The ::wiredtiger_struct_pack * function will pack single integers into at most this many bytes. */ -#define WT_INTPACK32_MAXSIZE ((int)sizeof (int32_t) + 1) +#define WT_INTPACK32_MAXSIZE ((int)sizeof(int32_t) + 1) /*! * A WT_CURSOR handle is the interface to a cursor. @@ -405,6 +405,12 @@ struct __wt_cursor { * WT_CURSOR::next (WT_CURSOR::prev) method will iterate from the * beginning (end) of the table. * + * If the cursor does not have record number keys or was not configured + * with "append=true", the cursor ends with no key set and a subsequent + * call to the WT_CURSOR::get_key method will fail. The cursor ends with + * no value set and a subsequent call to the WT_CURSOR::get_value method + * will fail. + * * Inserting a new record after the current maximum record in a * fixed-length bit field column-store (that is, a store with an * 'r' type key and 't' type value) may implicitly create the missing @@ -1159,8 +1165,8 @@ struct __wt_session { * @config{ ),,} * @config{memory_page_max, the maximum size a page can grow to in * memory before being reconciled to disk. The specified size will be - * adjusted to a lower bound of 50 * leaf_page_max\, and an - * upper bound of cache_size / 2. This limit is soft - it + * adjusted to a lower bound of leaf_page_max\, and an + * upper bound of cache_size / 10. This limit is soft - it * is possible for pages to be temporarily larger than this value. This * setting is ignored for LSM trees\, see \c chunk_size., an integer * between 512B and 10TB; default \c 5MB.} @@ -1779,12 +1785,11 @@ struct __wt_connection { * Enabling the checkpoint server uses a session from the configured * session_max., a set of related configuration options defined below.} * @config{    log_size, wait for this amount of log - * record bytes to be written to the log between each checkpoint. A + * record bytes to be written to the log between each checkpoint. If + * non-zero\, this value will use a minimum of the log file size. A * database can configure both log_size and wait to set an upper bound * for checkpoints; setting this value above 0 configures periodic * checkpoints., an integer between 0 and 2GB; default \c 0.} - * @config{    name, the checkpoint name., a string; - * default \c "WiredTigerCheckpoint".} * @config{    wait, seconds to wait between each * checkpoint; setting this value above 0 configures periodic * checkpoints., an integer between 0 and 100000; default \c 0.} @@ -1803,21 +1808,29 @@ struct __wt_connection { * number of threads currently running will vary depending on the * current eviction load., an integer between 1 and 20; default \c 1.} * @config{ ),,} - * @config{eviction_dirty_target, continue evicting until the cache has - * less dirty memory than the value\, as a percentage of the total cache - * size. Dirty pages will only be evicted if the cache is full enough - * to trigger eviction., an integer between 5 and 99; default \c 80.} - * @config{eviction_dirty_trigger, trigger eviction when the cache is - * using this much memory for dirty content\, as a percentage of the - * total cache size. This setting only alters behavior if it is lower - * than eviction_trigger., an integer between 5 and 99; default \c 95.} - * @config{eviction_target, continue evicting until the cache has less - * total memory than the value\, as a percentage of the total cache - * size. Must be less than \c eviction_trigger., an integer between 10 - * and 99; default \c 80.} - * @config{eviction_trigger, trigger eviction when the cache is using - * this much memory\, as a percentage of the total cache size., an - * integer between 10 and 99; default \c 95.} + * @config{eviction_checkpoint_target, perform eviction at the beginning + * of checkpoints to bring the dirty content in cache to this level\, + * expressed as a percentage of the total cache size. Ignored if set to + * zero or \c in_memory is \c true., an integer between 0 and 99; + * default \c 15.} + * @config{eviction_dirty_target, perform eviction in worker threads + * when the cache contains at least this much dirty content\, expressed + * as a percentage of the total cache size. Ignored if \c in_memory is + * \c true., an integer between 1 and 99; default \c 5.} + * @config{eviction_dirty_trigger, trigger application threads to + * perform eviction when the cache contains at least this much dirty + * content\, expressed as a percentage of the total cache size. This + * setting only alters behavior if it is lower than eviction_trigger. + * Ignored if \c in_memory is \c true., an integer between 1 and 99; + * default \c 20.} + * @config{eviction_target, perform eviction in worker threads when the + * cache contains at least this much content\, expressed as a percentage + * of the total cache size. Must be less than \c eviction_trigger., an + * integer between 10 and 99; default \c 80.} + * @config{eviction_trigger, trigger application threads to perform + * eviction when the cache contains at least this much content\, + * expressed as a percentage of the total cache size., an integer + * between 10 and 99; default \c 95.} * @config{file_manager = (, control how file handles are managed., a * set of related configuration options defined below.} * @config{    close_handle_minimum, number of @@ -1920,8 +1933,8 @@ struct __wt_connection { * \c "lsm_manager"\, \c "metadata"\, \c "mutex"\, \c "overflow"\, \c * "read"\, \c "rebalance"\, \c "reconcile"\, \c "recovery"\, \c * "salvage"\, \c "shared_cache"\, \c "split"\, \c "temporary"\, \c - * "transaction"\, \c "verify"\, \c "version"\, \c "write"; default - * empty.} + * "thread_group"\, \c "transaction"\, \c "verify"\, \c "version"\, \c + * "write"; default empty.} * @configend * @errors */ @@ -2197,15 +2210,14 @@ struct __wt_connection { * checkpoint server uses a session from the configured session_max., a set of * related configuration options defined below.} * @config{    log_size, wait for this amount of log record - * bytes to be written to the log between each checkpoint. A database can - * configure both log_size and wait to set an upper bound for checkpoints; - * setting this value above 0 configures periodic checkpoints., an integer - * between 0 and 2GB; default \c 0.} - * @config{    name, the - * checkpoint name., a string; default \c "WiredTigerCheckpoint".} - * @config{    wait, seconds to wait between each - * checkpoint; setting this value above 0 configures periodic checkpoints., an - * integer between 0 and 100000; default \c 0.} + * bytes to be written to the log between each checkpoint. If non-zero\, this + * value will use a minimum of the log file size. A database can configure both + * log_size and wait to set an upper bound for checkpoints; setting this value + * above 0 configures periodic checkpoints., an integer between 0 and 2GB; + * default \c 0.} + * @config{    wait, seconds to wait between + * each checkpoint; setting this value above 0 configures periodic checkpoints., + * an integer between 0 and 100000; default \c 0.} * @config{ ),,} * @config{checkpoint_sync, flush files to stable storage when closing or * writing checkpoints., a boolean flag; default \c true.} @@ -2263,20 +2275,27 @@ struct __wt_connection { * current eviction load., an integer between 1 and 20; default \c 1.} * @config{ * ),,} - * @config{eviction_dirty_target, continue evicting until the cache has less - * dirty memory than the value\, as a percentage of the total cache size. Dirty - * pages will only be evicted if the cache is full enough to trigger eviction., - * an integer between 5 and 99; default \c 80.} - * @config{eviction_dirty_trigger, trigger eviction when the cache is using this - * much memory for dirty content\, as a percentage of the total cache size. - * This setting only alters behavior if it is lower than eviction_trigger., an - * integer between 5 and 99; default \c 95.} - * @config{eviction_target, continue evicting until the cache has less total - * memory than the value\, as a percentage of the total cache size. Must be - * less than \c eviction_trigger., an integer between 10 and 99; default \c 80.} - * @config{eviction_trigger, trigger eviction when the cache is using this much - * memory\, as a percentage of the total cache size., an integer between 10 and - * 99; default \c 95.} + * @config{eviction_checkpoint_target, perform eviction at the beginning of + * checkpoints to bring the dirty content in cache to this level\, expressed as + * a percentage of the total cache size. Ignored if set to zero or \c in_memory + * is \c true., an integer between 0 and 99; default \c 15.} + * @config{eviction_dirty_target, perform eviction in worker threads when the + * cache contains at least this much dirty content\, expressed as a percentage + * of the total cache size. Ignored if \c in_memory is \c true., an integer + * between 1 and 99; default \c 5.} + * @config{eviction_dirty_trigger, trigger application threads to perform + * eviction when the cache contains at least this much dirty content\, expressed + * as a percentage of the total cache size. This setting only alters behavior + * if it is lower than eviction_trigger. Ignored if \c in_memory is \c true., + * an integer between 1 and 99; default \c 20.} + * @config{eviction_target, perform eviction in worker threads when the cache + * contains at least this much content\, expressed as a percentage of the total + * cache size. Must be less than \c eviction_trigger., an integer between 10 + * and 99; default \c 80.} + * @config{eviction_trigger, trigger application threads to perform eviction + * when the cache contains at least this much content\, expressed as a + * percentage of the total cache size., an integer between 10 and 99; default \c + * 95.} * @config{exclusive, fail if the database already exists\, generally used with * the \c create option., a boolean flag; default \c false.} * @config{extensions, list of shared library extensions to load (using dlopen). @@ -2437,7 +2456,8 @@ struct __wt_connection { * \c "handleops"\, \c "log"\, \c "lsm"\, \c "lsm_manager"\, \c "metadata"\, \c * "mutex"\, \c "overflow"\, \c "read"\, \c "rebalance"\, \c "reconcile"\, \c * "recovery"\, \c "salvage"\, \c "shared_cache"\, \c "split"\, \c "temporary"\, - * \c "transaction"\, \c "verify"\, \c "version"\, \c "write"; default empty.} + * \c "thread_group"\, \c "transaction"\, \c "verify"\, \c "version"\, \c + * "write"; default empty.} * @config{write_through, Use \c FILE_FLAG_WRITE_THROUGH on Windows to write to * files. Ignored on non-Windows systems. Options are given as a list\, such * as "write_through=[data]". Configuring \c write_through requires @@ -3736,7 +3756,7 @@ struct __wt_file_system { * @param[out] dirlist the method returns an allocated array of * individually allocated strings, one for each entry in the * directory. - * @param[out] countp the method the number of entries returned + * @param[out] countp the number of entries returned */ int (*fs_directory_list)(WT_FILE_SYSTEM *file_system, WT_SESSION *session, const char *directory, const char *prefix, @@ -3920,52 +3940,58 @@ struct __wt_file_handle { WT_SESSION *session, wt_off_t offset, wt_off_t len, int advice); /*! - * Ensure disk space is allocated for the file, based on the POSIX - * 1003.1 standard fallocate. + * Extend the file. * * This method is not required, and should be set to NULL when not * supported by the file. * + * Any allocated disk space must read as 0 bytes, and no existing file + * data may change. Allocating all necessary underlying storage (not + * changing just the file's metadata), is likely to result in increased + * performance. + * * This method is not called by multiple threads concurrently (on the - * same file handle). If the file handle's fallocate method supports - * concurrent calls, set the WT_FILE_HANDLE::fallocate_nolock method - * instead. + * same file handle). If the file handle's extension method supports + * concurrent calls, set the WT_FILE_HANDLE::fh_extend_nolock method + * instead. See @ref custom_file_systems for more information. * * @errors * * @param file_handle the WT_FILE_HANDLE * @param session the current WiredTiger session - * @param offset the file offset - * @param len the size of the advisory + * @param offset desired file size after extension */ - int (*fh_allocate)(WT_FILE_HANDLE *file_handle, - WT_SESSION *session, wt_off_t, wt_off_t); + int (*fh_extend)( + WT_FILE_HANDLE *file_handle, WT_SESSION *session, wt_off_t offset); /*! - * Ensure disk space is allocated for the file, based on the POSIX - * 1003.1 standard fallocate. + * Extend the file. * * This method is not required, and should be set to NULL when not * supported by the file. * + * Any allocated disk space must read as 0 bytes, and no existing file + * data may change. Allocating all necessary underlying storage (not + * only changing the file's metadata), is likely to result in increased + * performance. + * * This method may be called by multiple threads concurrently (on the - * same file handle). If the file handle's fallocate method does not - * support concurrent calls, set the WT_FILE_HANDLE::fallocate method - * instead. + * same file handle). If the file handle's extension method does not + * support concurrent calls, set the WT_FILE_HANDLE::fh_extend method + * instead. See @ref custom_file_systems for more information. * * @errors * * @param file_handle the WT_FILE_HANDLE * @param session the current WiredTiger session - * @param offset the file offset - * @param len the size of the advisory + * @param offset desired file size after extension */ - int (*fh_allocate_nolock)(WT_FILE_HANDLE *file_handle, - WT_SESSION *session, wt_off_t, wt_off_t); + int (*fh_extend_nolock)( + WT_FILE_HANDLE *file_handle, WT_SESSION *session, wt_off_t offset); /*! * Lock/unlock a file from the perspective of other processes running - * in the system. + * in the system, where necessary. * * @errors * @@ -4108,20 +4134,22 @@ struct __wt_file_handle { int (*fh_sync_nowait)(WT_FILE_HANDLE *file_handle, WT_SESSION *session); /*! - * Lengthen or shorten a file to the specified length, based on the - * POSIX 1003.1 standard ftruncate. + * Truncate the file. * - * This method is not required for read-only files, and should be set - * to NULL when not supported by the file. + * This method is not required, and should be set to NULL when not + * supported by the file. + * + * This method is not called by multiple threads concurrently (on the + * same file handle). * * @errors * * @param file_handle the WT_FILE_HANDLE * @param session the current WiredTiger session - * @param length desired file size after truncate + * @param offset desired file size after truncate */ int (*fh_truncate)( - WT_FILE_HANDLE *file_handle, WT_SESSION *session, wt_off_t length); + WT_FILE_HANDLE *file_handle, WT_SESSION *session, wt_off_t offset); /*! * Write to a file, based on the POSIX 1003.1 standard pwrite. @@ -4240,340 +4268,386 @@ extern int wiredtiger_extension_terminate(WT_CONNECTION *connection); #define WT_STAT_CONN_BLOCK_BYTE_READ 1026 /*! block-manager: bytes written */ #define WT_STAT_CONN_BLOCK_BYTE_WRITE 1027 +/*! block-manager: bytes written for checkpoint */ +#define WT_STAT_CONN_BLOCK_BYTE_WRITE_CHECKPOINT 1028 /*! block-manager: mapped blocks read */ -#define WT_STAT_CONN_BLOCK_MAP_READ 1028 +#define WT_STAT_CONN_BLOCK_MAP_READ 1029 /*! block-manager: mapped bytes read */ -#define WT_STAT_CONN_BLOCK_BYTE_MAP_READ 1029 +#define WT_STAT_CONN_BLOCK_BYTE_MAP_READ 1030 +/*! cache: bytes belonging to page images in the cache */ +#define WT_STAT_CONN_CACHE_BYTES_IMAGE 1031 /*! cache: bytes currently in the cache */ -#define WT_STAT_CONN_CACHE_BYTES_INUSE 1030 +#define WT_STAT_CONN_CACHE_BYTES_INUSE 1032 +/*! cache: bytes not belonging to page images in the cache */ +#define WT_STAT_CONN_CACHE_BYTES_OTHER 1033 /*! cache: bytes read into cache */ -#define WT_STAT_CONN_CACHE_BYTES_READ 1031 +#define WT_STAT_CONN_CACHE_BYTES_READ 1034 /*! cache: bytes written from cache */ -#define WT_STAT_CONN_CACHE_BYTES_WRITE 1032 +#define WT_STAT_CONN_CACHE_BYTES_WRITE 1035 /*! cache: checkpoint blocked page eviction */ -#define WT_STAT_CONN_CACHE_EVICTION_CHECKPOINT 1033 +#define WT_STAT_CONN_CACHE_EVICTION_CHECKPOINT 1036 /*! cache: eviction calls to get a page */ -#define WT_STAT_CONN_CACHE_EVICTION_GET_REF 1034 +#define WT_STAT_CONN_CACHE_EVICTION_GET_REF 1037 /*! cache: eviction calls to get a page found queue empty */ -#define WT_STAT_CONN_CACHE_EVICTION_GET_REF_EMPTY 1035 +#define WT_STAT_CONN_CACHE_EVICTION_GET_REF_EMPTY 1038 /*! cache: eviction calls to get a page found queue empty after locking */ -#define WT_STAT_CONN_CACHE_EVICTION_GET_REF_EMPTY2 1036 +#define WT_STAT_CONN_CACHE_EVICTION_GET_REF_EMPTY2 1039 /*! cache: eviction currently operating in aggressive mode */ -#define WT_STAT_CONN_CACHE_EVICTION_AGGRESSIVE_SET 1037 +#define WT_STAT_CONN_CACHE_EVICTION_AGGRESSIVE_SET 1040 /*! cache: eviction server candidate queue empty when topping up */ -#define WT_STAT_CONN_CACHE_EVICTION_QUEUE_EMPTY 1038 +#define WT_STAT_CONN_CACHE_EVICTION_QUEUE_EMPTY 1041 /*! cache: eviction server candidate queue not empty when topping up */ -#define WT_STAT_CONN_CACHE_EVICTION_QUEUE_NOT_EMPTY 1039 +#define WT_STAT_CONN_CACHE_EVICTION_QUEUE_NOT_EMPTY 1042 /*! cache: eviction server evicting pages */ -#define WT_STAT_CONN_CACHE_EVICTION_SERVER_EVICTING 1040 -/*! cache: eviction server populating queue, but not evicting pages */ -#define WT_STAT_CONN_CACHE_EVICTION_SERVER_NOT_EVICTING 1041 -/*! cache: eviction server skipped very large page */ -#define WT_STAT_CONN_CACHE_EVICTION_SERVER_TOOBIG 1042 -/*! cache: eviction server slept, because we did not make progress with - * eviction */ -#define WT_STAT_CONN_CACHE_EVICTION_SERVER_SLEPT 1043 +#define WT_STAT_CONN_CACHE_EVICTION_SERVER_EVICTING 1043 +/*! + * cache: eviction server slept, because we did not make progress with + * eviction + */ +#define WT_STAT_CONN_CACHE_EVICTION_SERVER_SLEPT 1044 /*! cache: eviction server unable to reach eviction goal */ -#define WT_STAT_CONN_CACHE_EVICTION_SLOW 1044 +#define WT_STAT_CONN_CACHE_EVICTION_SLOW 1045 +/*! cache: eviction state */ +#define WT_STAT_CONN_CACHE_EVICTION_STATE 1046 /*! cache: eviction worker thread evicting pages */ -#define WT_STAT_CONN_CACHE_EVICTION_WORKER_EVICTING 1045 +#define WT_STAT_CONN_CACHE_EVICTION_WORKER_EVICTING 1047 /*! cache: failed eviction of pages that exceeded the in-memory maximum */ -#define WT_STAT_CONN_CACHE_EVICTION_FORCE_FAIL 1046 +#define WT_STAT_CONN_CACHE_EVICTION_FORCE_FAIL 1048 /*! cache: files with active eviction walks */ -#define WT_STAT_CONN_CACHE_EVICTION_WALKS_ACTIVE 1047 +#define WT_STAT_CONN_CACHE_EVICTION_WALKS_ACTIVE 1049 /*! cache: files with new eviction walks started */ -#define WT_STAT_CONN_CACHE_EVICTION_WALKS_STARTED 1048 +#define WT_STAT_CONN_CACHE_EVICTION_WALKS_STARTED 1050 /*! cache: hazard pointer blocked page eviction */ -#define WT_STAT_CONN_CACHE_EVICTION_HAZARD 1049 +#define WT_STAT_CONN_CACHE_EVICTION_HAZARD 1051 /*! cache: hazard pointer check calls */ -#define WT_STAT_CONN_CACHE_HAZARD_CHECKS 1050 +#define WT_STAT_CONN_CACHE_HAZARD_CHECKS 1052 /*! cache: hazard pointer check entries walked */ -#define WT_STAT_CONN_CACHE_HAZARD_WALKS 1051 +#define WT_STAT_CONN_CACHE_HAZARD_WALKS 1053 /*! cache: hazard pointer maximum array length */ -#define WT_STAT_CONN_CACHE_HAZARD_MAX 1052 +#define WT_STAT_CONN_CACHE_HAZARD_MAX 1054 /*! cache: in-memory page passed criteria to be split */ -#define WT_STAT_CONN_CACHE_INMEM_SPLITTABLE 1053 +#define WT_STAT_CONN_CACHE_INMEM_SPLITTABLE 1055 /*! cache: in-memory page splits */ -#define WT_STAT_CONN_CACHE_INMEM_SPLIT 1054 +#define WT_STAT_CONN_CACHE_INMEM_SPLIT 1056 /*! cache: internal pages evicted */ -#define WT_STAT_CONN_CACHE_EVICTION_INTERNAL 1055 +#define WT_STAT_CONN_CACHE_EVICTION_INTERNAL 1057 /*! cache: internal pages split during eviction */ -#define WT_STAT_CONN_CACHE_EVICTION_SPLIT_INTERNAL 1056 +#define WT_STAT_CONN_CACHE_EVICTION_SPLIT_INTERNAL 1058 /*! cache: leaf pages split during eviction */ -#define WT_STAT_CONN_CACHE_EVICTION_SPLIT_LEAF 1057 +#define WT_STAT_CONN_CACHE_EVICTION_SPLIT_LEAF 1059 /*! cache: lookaside table insert calls */ -#define WT_STAT_CONN_CACHE_LOOKASIDE_INSERT 1058 +#define WT_STAT_CONN_CACHE_LOOKASIDE_INSERT 1060 /*! cache: lookaside table remove calls */ -#define WT_STAT_CONN_CACHE_LOOKASIDE_REMOVE 1059 +#define WT_STAT_CONN_CACHE_LOOKASIDE_REMOVE 1061 /*! cache: maximum bytes configured */ -#define WT_STAT_CONN_CACHE_BYTES_MAX 1060 +#define WT_STAT_CONN_CACHE_BYTES_MAX 1062 /*! cache: maximum page size at eviction */ -#define WT_STAT_CONN_CACHE_EVICTION_MAXIMUM_PAGE_SIZE 1061 +#define WT_STAT_CONN_CACHE_EVICTION_MAXIMUM_PAGE_SIZE 1063 /*! cache: modified pages evicted */ -#define WT_STAT_CONN_CACHE_EVICTION_DIRTY 1062 +#define WT_STAT_CONN_CACHE_EVICTION_DIRTY 1064 /*! cache: modified pages evicted by application threads */ -#define WT_STAT_CONN_CACHE_EVICTION_APP_DIRTY 1063 +#define WT_STAT_CONN_CACHE_EVICTION_APP_DIRTY 1065 +/*! cache: overflow pages read into cache */ +#define WT_STAT_CONN_CACHE_READ_OVERFLOW 1066 +/*! cache: overflow values cached in memory */ +#define WT_STAT_CONN_CACHE_OVERFLOW_VALUE 1067 /*! cache: page split during eviction deepened the tree */ -#define WT_STAT_CONN_CACHE_EVICTION_DEEPEN 1064 +#define WT_STAT_CONN_CACHE_EVICTION_DEEPEN 1068 /*! cache: page written requiring lookaside records */ -#define WT_STAT_CONN_CACHE_WRITE_LOOKASIDE 1065 +#define WT_STAT_CONN_CACHE_WRITE_LOOKASIDE 1069 /*! cache: pages currently held in the cache */ -#define WT_STAT_CONN_CACHE_PAGES_INUSE 1066 +#define WT_STAT_CONN_CACHE_PAGES_INUSE 1070 /*! cache: pages evicted because they exceeded the in-memory maximum */ -#define WT_STAT_CONN_CACHE_EVICTION_FORCE 1067 +#define WT_STAT_CONN_CACHE_EVICTION_FORCE 1071 /*! cache: pages evicted because they had chains of deleted items */ -#define WT_STAT_CONN_CACHE_EVICTION_FORCE_DELETE 1068 +#define WT_STAT_CONN_CACHE_EVICTION_FORCE_DELETE 1072 /*! cache: pages evicted by application threads */ -#define WT_STAT_CONN_CACHE_EVICTION_APP 1069 +#define WT_STAT_CONN_CACHE_EVICTION_APP 1073 /*! cache: pages queued for eviction */ -#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED 1070 +#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED 1074 /*! cache: pages queued for urgent eviction */ -#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED_OLDEST 1071 +#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED_URGENT 1075 +/*! cache: pages queued for urgent eviction during walk */ +#define WT_STAT_CONN_CACHE_EVICTION_PAGES_QUEUED_OLDEST 1076 /*! cache: pages read into cache */ -#define WT_STAT_CONN_CACHE_READ 1072 +#define WT_STAT_CONN_CACHE_READ 1077 /*! cache: pages read into cache requiring lookaside entries */ -#define WT_STAT_CONN_CACHE_READ_LOOKASIDE 1073 +#define WT_STAT_CONN_CACHE_READ_LOOKASIDE 1078 /*! cache: pages requested from the cache */ -#define WT_STAT_CONN_CACHE_PAGES_REQUESTED 1074 +#define WT_STAT_CONN_CACHE_PAGES_REQUESTED 1079 /*! cache: pages seen by eviction walk */ -#define WT_STAT_CONN_CACHE_EVICTION_PAGES_SEEN 1075 +#define WT_STAT_CONN_CACHE_EVICTION_PAGES_SEEN 1080 /*! cache: pages selected for eviction unable to be evicted */ -#define WT_STAT_CONN_CACHE_EVICTION_FAIL 1076 +#define WT_STAT_CONN_CACHE_EVICTION_FAIL 1081 /*! cache: pages walked for eviction */ -#define WT_STAT_CONN_CACHE_EVICTION_WALK 1077 +#define WT_STAT_CONN_CACHE_EVICTION_WALK 1082 /*! cache: pages written from cache */ -#define WT_STAT_CONN_CACHE_WRITE 1078 +#define WT_STAT_CONN_CACHE_WRITE 1083 /*! cache: pages written requiring in-memory restoration */ -#define WT_STAT_CONN_CACHE_WRITE_RESTORE 1079 +#define WT_STAT_CONN_CACHE_WRITE_RESTORE 1084 /*! cache: percentage overhead */ -#define WT_STAT_CONN_CACHE_OVERHEAD 1080 +#define WT_STAT_CONN_CACHE_OVERHEAD 1085 /*! cache: tracked bytes belonging to internal pages in the cache */ -#define WT_STAT_CONN_CACHE_BYTES_INTERNAL 1081 +#define WT_STAT_CONN_CACHE_BYTES_INTERNAL 1086 /*! cache: tracked bytes belonging to leaf pages in the cache */ -#define WT_STAT_CONN_CACHE_BYTES_LEAF 1082 -/*! cache: tracked bytes belonging to overflow pages in the cache */ -#define WT_STAT_CONN_CACHE_BYTES_OVERFLOW 1083 +#define WT_STAT_CONN_CACHE_BYTES_LEAF 1087 /*! cache: tracked dirty bytes in the cache */ -#define WT_STAT_CONN_CACHE_BYTES_DIRTY 1084 +#define WT_STAT_CONN_CACHE_BYTES_DIRTY 1088 /*! cache: tracked dirty pages in the cache */ -#define WT_STAT_CONN_CACHE_PAGES_DIRTY 1085 +#define WT_STAT_CONN_CACHE_PAGES_DIRTY 1089 /*! cache: unmodified pages evicted */ -#define WT_STAT_CONN_CACHE_EVICTION_CLEAN 1086 +#define WT_STAT_CONN_CACHE_EVICTION_CLEAN 1090 /*! connection: auto adjusting condition resets */ -#define WT_STAT_CONN_COND_AUTO_WAIT_RESET 1087 +#define WT_STAT_CONN_COND_AUTO_WAIT_RESET 1091 /*! connection: auto adjusting condition wait calls */ -#define WT_STAT_CONN_COND_AUTO_WAIT 1088 +#define WT_STAT_CONN_COND_AUTO_WAIT 1092 /*! connection: files currently open */ -#define WT_STAT_CONN_FILE_OPEN 1089 +#define WT_STAT_CONN_FILE_OPEN 1093 /*! connection: memory allocations */ -#define WT_STAT_CONN_MEMORY_ALLOCATION 1090 +#define WT_STAT_CONN_MEMORY_ALLOCATION 1094 /*! connection: memory frees */ -#define WT_STAT_CONN_MEMORY_FREE 1091 +#define WT_STAT_CONN_MEMORY_FREE 1095 /*! connection: memory re-allocations */ -#define WT_STAT_CONN_MEMORY_GROW 1092 +#define WT_STAT_CONN_MEMORY_GROW 1096 /*! connection: pthread mutex condition wait calls */ -#define WT_STAT_CONN_COND_WAIT 1093 +#define WT_STAT_CONN_COND_WAIT 1097 /*! connection: pthread mutex shared lock read-lock calls */ -#define WT_STAT_CONN_RWLOCK_READ 1094 +#define WT_STAT_CONN_RWLOCK_READ 1098 /*! connection: pthread mutex shared lock write-lock calls */ -#define WT_STAT_CONN_RWLOCK_WRITE 1095 +#define WT_STAT_CONN_RWLOCK_WRITE 1099 /*! connection: total fsync I/Os */ -#define WT_STAT_CONN_FSYNC_IO 1096 +#define WT_STAT_CONN_FSYNC_IO 1100 /*! connection: total read I/Os */ -#define WT_STAT_CONN_READ_IO 1097 +#define WT_STAT_CONN_READ_IO 1101 /*! connection: total write I/Os */ -#define WT_STAT_CONN_WRITE_IO 1098 +#define WT_STAT_CONN_WRITE_IO 1102 /*! cursor: cursor create calls */ -#define WT_STAT_CONN_CURSOR_CREATE 1099 +#define WT_STAT_CONN_CURSOR_CREATE 1103 /*! cursor: cursor insert calls */ -#define WT_STAT_CONN_CURSOR_INSERT 1100 +#define WT_STAT_CONN_CURSOR_INSERT 1104 /*! cursor: cursor next calls */ -#define WT_STAT_CONN_CURSOR_NEXT 1101 +#define WT_STAT_CONN_CURSOR_NEXT 1105 /*! cursor: cursor prev calls */ -#define WT_STAT_CONN_CURSOR_PREV 1102 +#define WT_STAT_CONN_CURSOR_PREV 1106 /*! cursor: cursor remove calls */ -#define WT_STAT_CONN_CURSOR_REMOVE 1103 +#define WT_STAT_CONN_CURSOR_REMOVE 1107 /*! cursor: cursor reset calls */ -#define WT_STAT_CONN_CURSOR_RESET 1104 +#define WT_STAT_CONN_CURSOR_RESET 1108 /*! cursor: cursor restarted searches */ -#define WT_STAT_CONN_CURSOR_RESTART 1105 +#define WT_STAT_CONN_CURSOR_RESTART 1109 /*! cursor: cursor search calls */ -#define WT_STAT_CONN_CURSOR_SEARCH 1106 +#define WT_STAT_CONN_CURSOR_SEARCH 1110 /*! cursor: cursor search near calls */ -#define WT_STAT_CONN_CURSOR_SEARCH_NEAR 1107 +#define WT_STAT_CONN_CURSOR_SEARCH_NEAR 1111 /*! cursor: cursor update calls */ -#define WT_STAT_CONN_CURSOR_UPDATE 1108 +#define WT_STAT_CONN_CURSOR_UPDATE 1112 /*! cursor: truncate calls */ -#define WT_STAT_CONN_CURSOR_TRUNCATE 1109 +#define WT_STAT_CONN_CURSOR_TRUNCATE 1113 /*! data-handle: connection data handles currently active */ -#define WT_STAT_CONN_DH_CONN_HANDLE_COUNT 1110 +#define WT_STAT_CONN_DH_CONN_HANDLE_COUNT 1114 /*! data-handle: connection sweep candidate became referenced */ -#define WT_STAT_CONN_DH_SWEEP_REF 1111 +#define WT_STAT_CONN_DH_SWEEP_REF 1115 /*! data-handle: connection sweep dhandles closed */ -#define WT_STAT_CONN_DH_SWEEP_CLOSE 1112 +#define WT_STAT_CONN_DH_SWEEP_CLOSE 1116 /*! data-handle: connection sweep dhandles removed from hash list */ -#define WT_STAT_CONN_DH_SWEEP_REMOVE 1113 +#define WT_STAT_CONN_DH_SWEEP_REMOVE 1117 /*! data-handle: connection sweep time-of-death sets */ -#define WT_STAT_CONN_DH_SWEEP_TOD 1114 +#define WT_STAT_CONN_DH_SWEEP_TOD 1118 /*! data-handle: connection sweeps */ -#define WT_STAT_CONN_DH_SWEEPS 1115 +#define WT_STAT_CONN_DH_SWEEPS 1119 /*! data-handle: session dhandles swept */ -#define WT_STAT_CONN_DH_SESSION_HANDLES 1116 +#define WT_STAT_CONN_DH_SESSION_HANDLES 1120 /*! data-handle: session sweep attempts */ -#define WT_STAT_CONN_DH_SESSION_SWEEPS 1117 +#define WT_STAT_CONN_DH_SESSION_SWEEPS 1121 /*! log: busy returns attempting to switch slots */ -#define WT_STAT_CONN_LOG_SLOT_SWITCH_BUSY 1118 +#define WT_STAT_CONN_LOG_SLOT_SWITCH_BUSY 1122 /*! log: consolidated slot closures */ -#define WT_STAT_CONN_LOG_SLOT_CLOSES 1119 +#define WT_STAT_CONN_LOG_SLOT_CLOSES 1123 /*! log: consolidated slot join races */ -#define WT_STAT_CONN_LOG_SLOT_RACES 1120 +#define WT_STAT_CONN_LOG_SLOT_RACES 1124 /*! log: consolidated slot join transitions */ -#define WT_STAT_CONN_LOG_SLOT_TRANSITIONS 1121 +#define WT_STAT_CONN_LOG_SLOT_TRANSITIONS 1125 /*! log: consolidated slot joins */ -#define WT_STAT_CONN_LOG_SLOT_JOINS 1122 +#define WT_STAT_CONN_LOG_SLOT_JOINS 1126 /*! log: consolidated slot unbuffered writes */ -#define WT_STAT_CONN_LOG_SLOT_UNBUFFERED 1123 +#define WT_STAT_CONN_LOG_SLOT_UNBUFFERED 1127 /*! log: log bytes of payload data */ -#define WT_STAT_CONN_LOG_BYTES_PAYLOAD 1124 +#define WT_STAT_CONN_LOG_BYTES_PAYLOAD 1128 /*! log: log bytes written */ -#define WT_STAT_CONN_LOG_BYTES_WRITTEN 1125 +#define WT_STAT_CONN_LOG_BYTES_WRITTEN 1129 /*! log: log files manually zero-filled */ -#define WT_STAT_CONN_LOG_ZERO_FILLS 1126 +#define WT_STAT_CONN_LOG_ZERO_FILLS 1130 /*! log: log flush operations */ -#define WT_STAT_CONN_LOG_FLUSH 1127 +#define WT_STAT_CONN_LOG_FLUSH 1131 /*! log: log force write operations */ -#define WT_STAT_CONN_LOG_FORCE_WRITE 1128 +#define WT_STAT_CONN_LOG_FORCE_WRITE 1132 /*! log: log force write operations skipped */ -#define WT_STAT_CONN_LOG_FORCE_WRITE_SKIP 1129 +#define WT_STAT_CONN_LOG_FORCE_WRITE_SKIP 1133 /*! log: log records compressed */ -#define WT_STAT_CONN_LOG_COMPRESS_WRITES 1130 +#define WT_STAT_CONN_LOG_COMPRESS_WRITES 1134 /*! log: log records not compressed */ -#define WT_STAT_CONN_LOG_COMPRESS_WRITE_FAILS 1131 +#define WT_STAT_CONN_LOG_COMPRESS_WRITE_FAILS 1135 /*! log: log records too small to compress */ -#define WT_STAT_CONN_LOG_COMPRESS_SMALL 1132 +#define WT_STAT_CONN_LOG_COMPRESS_SMALL 1136 /*! log: log release advances write LSN */ -#define WT_STAT_CONN_LOG_RELEASE_WRITE_LSN 1133 +#define WT_STAT_CONN_LOG_RELEASE_WRITE_LSN 1137 /*! log: log scan operations */ -#define WT_STAT_CONN_LOG_SCANS 1134 +#define WT_STAT_CONN_LOG_SCANS 1138 /*! log: log scan records requiring two reads */ -#define WT_STAT_CONN_LOG_SCAN_REREADS 1135 +#define WT_STAT_CONN_LOG_SCAN_REREADS 1139 /*! log: log server thread advances write LSN */ -#define WT_STAT_CONN_LOG_WRITE_LSN 1136 +#define WT_STAT_CONN_LOG_WRITE_LSN 1140 /*! log: log server thread write LSN walk skipped */ -#define WT_STAT_CONN_LOG_WRITE_LSN_SKIP 1137 +#define WT_STAT_CONN_LOG_WRITE_LSN_SKIP 1141 /*! log: log sync operations */ -#define WT_STAT_CONN_LOG_SYNC 1138 +#define WT_STAT_CONN_LOG_SYNC 1142 /*! log: log sync time duration (usecs) */ -#define WT_STAT_CONN_LOG_SYNC_DURATION 1139 +#define WT_STAT_CONN_LOG_SYNC_DURATION 1143 /*! log: log sync_dir operations */ -#define WT_STAT_CONN_LOG_SYNC_DIR 1140 +#define WT_STAT_CONN_LOG_SYNC_DIR 1144 /*! log: log sync_dir time duration (usecs) */ -#define WT_STAT_CONN_LOG_SYNC_DIR_DURATION 1141 +#define WT_STAT_CONN_LOG_SYNC_DIR_DURATION 1145 /*! log: log write operations */ -#define WT_STAT_CONN_LOG_WRITES 1142 +#define WT_STAT_CONN_LOG_WRITES 1146 /*! log: logging bytes consolidated */ -#define WT_STAT_CONN_LOG_SLOT_CONSOLIDATED 1143 +#define WT_STAT_CONN_LOG_SLOT_CONSOLIDATED 1147 /*! log: maximum log file size */ -#define WT_STAT_CONN_LOG_MAX_FILESIZE 1144 +#define WT_STAT_CONN_LOG_MAX_FILESIZE 1148 /*! log: number of pre-allocated log files to create */ -#define WT_STAT_CONN_LOG_PREALLOC_MAX 1145 +#define WT_STAT_CONN_LOG_PREALLOC_MAX 1149 /*! log: pre-allocated log files not ready and missed */ -#define WT_STAT_CONN_LOG_PREALLOC_MISSED 1146 +#define WT_STAT_CONN_LOG_PREALLOC_MISSED 1150 /*! log: pre-allocated log files prepared */ -#define WT_STAT_CONN_LOG_PREALLOC_FILES 1147 +#define WT_STAT_CONN_LOG_PREALLOC_FILES 1151 /*! log: pre-allocated log files used */ -#define WT_STAT_CONN_LOG_PREALLOC_USED 1148 +#define WT_STAT_CONN_LOG_PREALLOC_USED 1152 /*! log: records processed by log scan */ -#define WT_STAT_CONN_LOG_SCAN_RECORDS 1149 +#define WT_STAT_CONN_LOG_SCAN_RECORDS 1153 /*! log: total in-memory size of compressed records */ -#define WT_STAT_CONN_LOG_COMPRESS_MEM 1150 +#define WT_STAT_CONN_LOG_COMPRESS_MEM 1154 /*! log: total log buffer size */ -#define WT_STAT_CONN_LOG_BUFFER_SIZE 1151 +#define WT_STAT_CONN_LOG_BUFFER_SIZE 1155 /*! log: total size of compressed records */ -#define WT_STAT_CONN_LOG_COMPRESS_LEN 1152 +#define WT_STAT_CONN_LOG_COMPRESS_LEN 1156 /*! log: written slots coalesced */ -#define WT_STAT_CONN_LOG_SLOT_COALESCED 1153 +#define WT_STAT_CONN_LOG_SLOT_COALESCED 1157 /*! log: yields waiting for previous log file close */ -#define WT_STAT_CONN_LOG_CLOSE_YIELDS 1154 +#define WT_STAT_CONN_LOG_CLOSE_YIELDS 1158 /*! reconciliation: fast-path pages deleted */ -#define WT_STAT_CONN_REC_PAGE_DELETE_FAST 1155 +#define WT_STAT_CONN_REC_PAGE_DELETE_FAST 1159 /*! reconciliation: page reconciliation calls */ -#define WT_STAT_CONN_REC_PAGES 1156 +#define WT_STAT_CONN_REC_PAGES 1160 /*! reconciliation: page reconciliation calls for eviction */ -#define WT_STAT_CONN_REC_PAGES_EVICTION 1157 +#define WT_STAT_CONN_REC_PAGES_EVICTION 1161 /*! reconciliation: pages deleted */ -#define WT_STAT_CONN_REC_PAGE_DELETE 1158 +#define WT_STAT_CONN_REC_PAGE_DELETE 1162 /*! reconciliation: split bytes currently awaiting free */ -#define WT_STAT_CONN_REC_SPLIT_STASHED_BYTES 1159 +#define WT_STAT_CONN_REC_SPLIT_STASHED_BYTES 1163 /*! reconciliation: split objects currently awaiting free */ -#define WT_STAT_CONN_REC_SPLIT_STASHED_OBJECTS 1160 +#define WT_STAT_CONN_REC_SPLIT_STASHED_OBJECTS 1164 /*! session: open cursor count */ -#define WT_STAT_CONN_SESSION_CURSOR_OPEN 1161 +#define WT_STAT_CONN_SESSION_CURSOR_OPEN 1165 /*! session: open session count */ -#define WT_STAT_CONN_SESSION_OPEN 1162 +#define WT_STAT_CONN_SESSION_OPEN 1166 +/*! session: table compact failed calls */ +#define WT_STAT_CONN_SESSION_TABLE_COMPACT_FAIL 1167 +/*! session: table compact successful calls */ +#define WT_STAT_CONN_SESSION_TABLE_COMPACT_SUCCESS 1168 +/*! session: table create failed calls */ +#define WT_STAT_CONN_SESSION_TABLE_CREATE_FAIL 1169 +/*! session: table create successful calls */ +#define WT_STAT_CONN_SESSION_TABLE_CREATE_SUCCESS 1170 +/*! session: table drop failed calls */ +#define WT_STAT_CONN_SESSION_TABLE_DROP_FAIL 1171 +/*! session: table drop successful calls */ +#define WT_STAT_CONN_SESSION_TABLE_DROP_SUCCESS 1172 +/*! session: table rebalance failed calls */ +#define WT_STAT_CONN_SESSION_TABLE_REBALANCE_FAIL 1173 +/*! session: table rebalance successful calls */ +#define WT_STAT_CONN_SESSION_TABLE_REBALANCE_SUCCESS 1174 +/*! session: table rename failed calls */ +#define WT_STAT_CONN_SESSION_TABLE_RENAME_FAIL 1175 +/*! session: table rename successful calls */ +#define WT_STAT_CONN_SESSION_TABLE_RENAME_SUCCESS 1176 +/*! session: table salvage failed calls */ +#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_FAIL 1177 +/*! session: table salvage successful calls */ +#define WT_STAT_CONN_SESSION_TABLE_SALVAGE_SUCCESS 1178 +/*! session: table truncate failed calls */ +#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_FAIL 1179 +/*! session: table truncate successful calls */ +#define WT_STAT_CONN_SESSION_TABLE_TRUNCATE_SUCCESS 1180 +/*! session: table verify failed calls */ +#define WT_STAT_CONN_SESSION_TABLE_VERIFY_FAIL 1181 +/*! session: table verify successful calls */ +#define WT_STAT_CONN_SESSION_TABLE_VERIFY_SUCCESS 1182 /*! thread-state: active filesystem fsync calls */ -#define WT_STAT_CONN_FSYNC_ACTIVE 1163 +#define WT_STAT_CONN_THREAD_FSYNC_ACTIVE 1183 /*! thread-state: active filesystem read calls */ -#define WT_STAT_CONN_READ_ACTIVE 1164 +#define WT_STAT_CONN_THREAD_READ_ACTIVE 1184 /*! thread-state: active filesystem write calls */ -#define WT_STAT_CONN_WRITE_ACTIVE 1165 +#define WT_STAT_CONN_THREAD_WRITE_ACTIVE 1185 /*! thread-yield: page acquire busy blocked */ -#define WT_STAT_CONN_PAGE_BUSY_BLOCKED 1166 +#define WT_STAT_CONN_PAGE_BUSY_BLOCKED 1186 /*! thread-yield: page acquire eviction blocked */ -#define WT_STAT_CONN_PAGE_FORCIBLE_EVICT_BLOCKED 1167 +#define WT_STAT_CONN_PAGE_FORCIBLE_EVICT_BLOCKED 1187 /*! thread-yield: page acquire locked blocked */ -#define WT_STAT_CONN_PAGE_LOCKED_BLOCKED 1168 +#define WT_STAT_CONN_PAGE_LOCKED_BLOCKED 1188 /*! thread-yield: page acquire read blocked */ -#define WT_STAT_CONN_PAGE_READ_BLOCKED 1169 +#define WT_STAT_CONN_PAGE_READ_BLOCKED 1189 /*! thread-yield: page acquire time sleeping (usecs) */ -#define WT_STAT_CONN_PAGE_SLEEP 1170 +#define WT_STAT_CONN_PAGE_SLEEP 1190 /*! transaction: number of named snapshots created */ -#define WT_STAT_CONN_TXN_SNAPSHOTS_CREATED 1171 +#define WT_STAT_CONN_TXN_SNAPSHOTS_CREATED 1191 /*! transaction: number of named snapshots dropped */ -#define WT_STAT_CONN_TXN_SNAPSHOTS_DROPPED 1172 +#define WT_STAT_CONN_TXN_SNAPSHOTS_DROPPED 1192 /*! transaction: transaction begins */ -#define WT_STAT_CONN_TXN_BEGIN 1173 +#define WT_STAT_CONN_TXN_BEGIN 1193 /*! transaction: transaction checkpoint currently running */ -#define WT_STAT_CONN_TXN_CHECKPOINT_RUNNING 1174 +#define WT_STAT_CONN_TXN_CHECKPOINT_RUNNING 1194 /*! transaction: transaction checkpoint generation */ -#define WT_STAT_CONN_TXN_CHECKPOINT_GENERATION 1175 +#define WT_STAT_CONN_TXN_CHECKPOINT_GENERATION 1195 /*! transaction: transaction checkpoint max time (msecs) */ -#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MAX 1176 +#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MAX 1196 /*! transaction: transaction checkpoint min time (msecs) */ -#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MIN 1177 +#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_MIN 1197 /*! transaction: transaction checkpoint most recent time (msecs) */ -#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_RECENT 1178 +#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_RECENT 1198 +/*! transaction: transaction checkpoint scrub dirty target */ +#define WT_STAT_CONN_TXN_CHECKPOINT_SCRUB_TARGET 1199 +/*! transaction: transaction checkpoint scrub time (msecs) */ +#define WT_STAT_CONN_TXN_CHECKPOINT_SCRUB_TIME 1200 /*! transaction: transaction checkpoint total time (msecs) */ -#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_TOTAL 1179 +#define WT_STAT_CONN_TXN_CHECKPOINT_TIME_TOTAL 1201 /*! transaction: transaction checkpoints */ -#define WT_STAT_CONN_TXN_CHECKPOINT 1180 +#define WT_STAT_CONN_TXN_CHECKPOINT 1202 /*! transaction: transaction failures due to cache overflow */ -#define WT_STAT_CONN_TXN_FAIL_CACHE 1181 -/*! transaction: transaction fsync calls for checkpoint after allocating - * the transaction ID */ -#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST 1182 -/*! transaction: transaction fsync calls for checkpoint before allocating - * the transaction ID */ -#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_PRE 1183 -/*! transaction: transaction fsync duration for checkpoint after - * allocating the transaction ID (usecs) */ -#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST_DURATION 1184 -/*! transaction: transaction fsync duration for checkpoint before - * allocating the transaction ID (usecs) */ -#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_PRE_DURATION 1185 +#define WT_STAT_CONN_TXN_FAIL_CACHE 1203 +/*! + * transaction: transaction fsync calls for checkpoint after allocating + * the transaction ID + */ +#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST 1204 +/*! + * transaction: transaction fsync duration for checkpoint after + * allocating the transaction ID (usecs) + */ +#define WT_STAT_CONN_TXN_CHECKPOINT_FSYNC_POST_DURATION 1205 /*! transaction: transaction range of IDs currently pinned */ -#define WT_STAT_CONN_TXN_PINNED_RANGE 1186 +#define WT_STAT_CONN_TXN_PINNED_RANGE 1206 /*! transaction: transaction range of IDs currently pinned by a checkpoint */ -#define WT_STAT_CONN_TXN_PINNED_CHECKPOINT_RANGE 1187 -/*! transaction: transaction range of IDs currently pinned by named - * snapshots */ -#define WT_STAT_CONN_TXN_PINNED_SNAPSHOT_RANGE 1188 +#define WT_STAT_CONN_TXN_PINNED_CHECKPOINT_RANGE 1207 +/*! + * transaction: transaction range of IDs currently pinned by named + * snapshots + */ +#define WT_STAT_CONN_TXN_PINNED_SNAPSHOT_RANGE 1208 /*! transaction: transaction sync calls */ -#define WT_STAT_CONN_TXN_SYNC 1189 +#define WT_STAT_CONN_TXN_SYNC 1209 /*! transaction: transactions committed */ -#define WT_STAT_CONN_TXN_COMMIT 1190 +#define WT_STAT_CONN_TXN_COMMIT 1210 /*! transaction: transactions rolled back */ -#define WT_STAT_CONN_TXN_ROLLBACK 1191 +#define WT_STAT_CONN_TXN_ROLLBACK 1211 /*! * @} @@ -4597,8 +4671,10 @@ extern int wiredtiger_extension_terminate(WT_CONNECTION *connection); #define WT_STAT_DSRC_LSM_CHUNK_COUNT 2006 /*! LSM: highest merge generation in the LSM tree */ #define WT_STAT_DSRC_LSM_GENERATION_MAX 2007 -/*! LSM: queries that could have benefited from a Bloom filter that did - * not exist */ +/*! + * LSM: queries that could have benefited from a Bloom filter that did + * not exist + */ #define WT_STAT_DSRC_LSM_LOOKUP_NO_BLOOM 2008 /*! LSM: sleep for LSM checkpoint throttle */ #define WT_STAT_DSRC_LSM_CHECKPOINT_THROTTLE 2009 @@ -4628,15 +4704,30 @@ extern int wiredtiger_extension_terminate(WT_CONNECTION *connection); #define WT_STAT_DSRC_BLOCK_MINOR 2021 /*! btree: btree checkpoint generation */ #define WT_STAT_DSRC_BTREE_CHECKPOINT_GENERATION 2022 -/*! btree: column-store fixed-size leaf pages */ +/*! + * btree: column-store fixed-size leaf pages, only reported if + * statistics=all is set + */ #define WT_STAT_DSRC_BTREE_COLUMN_FIX 2023 -/*! btree: column-store internal pages */ +/*! + * btree: column-store internal pages, only reported if statistics=all is + * set + */ #define WT_STAT_DSRC_BTREE_COLUMN_INTERNAL 2024 -/*! btree: column-store variable-size RLE encoded values */ +/*! + * btree: column-store variable-size RLE encoded values, only reported if + * statistics=all is set + */ #define WT_STAT_DSRC_BTREE_COLUMN_RLE 2025 -/*! btree: column-store variable-size deleted values */ +/*! + * btree: column-store variable-size deleted values, only reported if + * statistics=all is set + */ #define WT_STAT_DSRC_BTREE_COLUMN_DELETED 2026 -/*! btree: column-store variable-size leaf pages */ +/*! + * btree: column-store variable-size leaf pages, only reported if + * statistics=all is set + */ #define WT_STAT_DSRC_BTREE_COLUMN_VARIABLE 2027 /*! btree: fixed-record size */ #define WT_STAT_DSRC_BTREE_FIXED_LEN 2028 @@ -4652,137 +4743,147 @@ extern int wiredtiger_extension_terminate(WT_CONNECTION *connection); #define WT_STAT_DSRC_BTREE_MAXLEAFVALUE 2033 /*! btree: maximum tree depth */ #define WT_STAT_DSRC_BTREE_MAXIMUM_DEPTH 2034 -/*! btree: number of key/value pairs */ +/*! + * btree: number of key/value pairs, only reported if statistics=all is + * set + */ #define WT_STAT_DSRC_BTREE_ENTRIES 2035 -/*! btree: overflow pages */ +/*! btree: overflow pages, only reported if statistics=all is set */ #define WT_STAT_DSRC_BTREE_OVERFLOW 2036 /*! btree: pages rewritten by compaction */ #define WT_STAT_DSRC_BTREE_COMPACT_REWRITE 2037 -/*! btree: row-store internal pages */ +/*! + * btree: row-store internal pages, only reported if statistics=all is + * set + */ #define WT_STAT_DSRC_BTREE_ROW_INTERNAL 2038 -/*! btree: row-store leaf pages */ +/*! btree: row-store leaf pages, only reported if statistics=all is set */ #define WT_STAT_DSRC_BTREE_ROW_LEAF 2039 +/*! cache: bytes currently in the cache */ +#define WT_STAT_DSRC_CACHE_BYTES_INUSE 2040 /*! cache: bytes read into cache */ -#define WT_STAT_DSRC_CACHE_BYTES_READ 2040 +#define WT_STAT_DSRC_CACHE_BYTES_READ 2041 /*! cache: bytes written from cache */ -#define WT_STAT_DSRC_CACHE_BYTES_WRITE 2041 +#define WT_STAT_DSRC_CACHE_BYTES_WRITE 2042 /*! cache: checkpoint blocked page eviction */ -#define WT_STAT_DSRC_CACHE_EVICTION_CHECKPOINT 2042 +#define WT_STAT_DSRC_CACHE_EVICTION_CHECKPOINT 2043 /*! cache: data source pages selected for eviction unable to be evicted */ -#define WT_STAT_DSRC_CACHE_EVICTION_FAIL 2043 +#define WT_STAT_DSRC_CACHE_EVICTION_FAIL 2044 /*! cache: hazard pointer blocked page eviction */ -#define WT_STAT_DSRC_CACHE_EVICTION_HAZARD 2044 +#define WT_STAT_DSRC_CACHE_EVICTION_HAZARD 2045 /*! cache: in-memory page passed criteria to be split */ -#define WT_STAT_DSRC_CACHE_INMEM_SPLITTABLE 2045 +#define WT_STAT_DSRC_CACHE_INMEM_SPLITTABLE 2046 /*! cache: in-memory page splits */ -#define WT_STAT_DSRC_CACHE_INMEM_SPLIT 2046 +#define WT_STAT_DSRC_CACHE_INMEM_SPLIT 2047 /*! cache: internal pages evicted */ -#define WT_STAT_DSRC_CACHE_EVICTION_INTERNAL 2047 +#define WT_STAT_DSRC_CACHE_EVICTION_INTERNAL 2048 /*! cache: internal pages split during eviction */ -#define WT_STAT_DSRC_CACHE_EVICTION_SPLIT_INTERNAL 2048 +#define WT_STAT_DSRC_CACHE_EVICTION_SPLIT_INTERNAL 2049 /*! cache: leaf pages split during eviction */ -#define WT_STAT_DSRC_CACHE_EVICTION_SPLIT_LEAF 2049 +#define WT_STAT_DSRC_CACHE_EVICTION_SPLIT_LEAF 2050 /*! cache: modified pages evicted */ -#define WT_STAT_DSRC_CACHE_EVICTION_DIRTY 2050 +#define WT_STAT_DSRC_CACHE_EVICTION_DIRTY 2051 /*! cache: overflow pages read into cache */ -#define WT_STAT_DSRC_CACHE_READ_OVERFLOW 2051 +#define WT_STAT_DSRC_CACHE_READ_OVERFLOW 2052 /*! cache: overflow values cached in memory */ -#define WT_STAT_DSRC_CACHE_OVERFLOW_VALUE 2052 +#define WT_STAT_DSRC_CACHE_OVERFLOW_VALUE 2053 /*! cache: page split during eviction deepened the tree */ -#define WT_STAT_DSRC_CACHE_EVICTION_DEEPEN 2053 +#define WT_STAT_DSRC_CACHE_EVICTION_DEEPEN 2054 /*! cache: page written requiring lookaside records */ -#define WT_STAT_DSRC_CACHE_WRITE_LOOKASIDE 2054 +#define WT_STAT_DSRC_CACHE_WRITE_LOOKASIDE 2055 /*! cache: pages read into cache */ -#define WT_STAT_DSRC_CACHE_READ 2055 +#define WT_STAT_DSRC_CACHE_READ 2056 /*! cache: pages read into cache requiring lookaside entries */ -#define WT_STAT_DSRC_CACHE_READ_LOOKASIDE 2056 +#define WT_STAT_DSRC_CACHE_READ_LOOKASIDE 2057 /*! cache: pages requested from the cache */ -#define WT_STAT_DSRC_CACHE_PAGES_REQUESTED 2057 +#define WT_STAT_DSRC_CACHE_PAGES_REQUESTED 2058 /*! cache: pages written from cache */ -#define WT_STAT_DSRC_CACHE_WRITE 2058 +#define WT_STAT_DSRC_CACHE_WRITE 2059 /*! cache: pages written requiring in-memory restoration */ -#define WT_STAT_DSRC_CACHE_WRITE_RESTORE 2059 +#define WT_STAT_DSRC_CACHE_WRITE_RESTORE 2060 /*! cache: unmodified pages evicted */ -#define WT_STAT_DSRC_CACHE_EVICTION_CLEAN 2060 +#define WT_STAT_DSRC_CACHE_EVICTION_CLEAN 2061 /*! compression: compressed pages read */ -#define WT_STAT_DSRC_COMPRESS_READ 2061 +#define WT_STAT_DSRC_COMPRESS_READ 2062 /*! compression: compressed pages written */ -#define WT_STAT_DSRC_COMPRESS_WRITE 2062 +#define WT_STAT_DSRC_COMPRESS_WRITE 2063 /*! compression: page written failed to compress */ -#define WT_STAT_DSRC_COMPRESS_WRITE_FAIL 2063 +#define WT_STAT_DSRC_COMPRESS_WRITE_FAIL 2064 /*! compression: page written was too small to compress */ -#define WT_STAT_DSRC_COMPRESS_WRITE_TOO_SMALL 2064 +#define WT_STAT_DSRC_COMPRESS_WRITE_TOO_SMALL 2065 /*! compression: raw compression call failed, additional data available */ -#define WT_STAT_DSRC_COMPRESS_RAW_FAIL_TEMPORARY 2065 +#define WT_STAT_DSRC_COMPRESS_RAW_FAIL_TEMPORARY 2066 /*! compression: raw compression call failed, no additional data available */ -#define WT_STAT_DSRC_COMPRESS_RAW_FAIL 2066 +#define WT_STAT_DSRC_COMPRESS_RAW_FAIL 2067 /*! compression: raw compression call succeeded */ -#define WT_STAT_DSRC_COMPRESS_RAW_OK 2067 +#define WT_STAT_DSRC_COMPRESS_RAW_OK 2068 /*! cursor: bulk-loaded cursor-insert calls */ -#define WT_STAT_DSRC_CURSOR_INSERT_BULK 2068 +#define WT_STAT_DSRC_CURSOR_INSERT_BULK 2069 /*! cursor: create calls */ -#define WT_STAT_DSRC_CURSOR_CREATE 2069 +#define WT_STAT_DSRC_CURSOR_CREATE 2070 /*! cursor: cursor-insert key and value bytes inserted */ -#define WT_STAT_DSRC_CURSOR_INSERT_BYTES 2070 +#define WT_STAT_DSRC_CURSOR_INSERT_BYTES 2071 /*! cursor: cursor-remove key bytes removed */ -#define WT_STAT_DSRC_CURSOR_REMOVE_BYTES 2071 +#define WT_STAT_DSRC_CURSOR_REMOVE_BYTES 2072 /*! cursor: cursor-update value bytes updated */ -#define WT_STAT_DSRC_CURSOR_UPDATE_BYTES 2072 +#define WT_STAT_DSRC_CURSOR_UPDATE_BYTES 2073 /*! cursor: insert calls */ -#define WT_STAT_DSRC_CURSOR_INSERT 2073 +#define WT_STAT_DSRC_CURSOR_INSERT 2074 /*! cursor: next calls */ -#define WT_STAT_DSRC_CURSOR_NEXT 2074 +#define WT_STAT_DSRC_CURSOR_NEXT 2075 /*! cursor: prev calls */ -#define WT_STAT_DSRC_CURSOR_PREV 2075 +#define WT_STAT_DSRC_CURSOR_PREV 2076 /*! cursor: remove calls */ -#define WT_STAT_DSRC_CURSOR_REMOVE 2076 +#define WT_STAT_DSRC_CURSOR_REMOVE 2077 /*! cursor: reset calls */ -#define WT_STAT_DSRC_CURSOR_RESET 2077 +#define WT_STAT_DSRC_CURSOR_RESET 2078 /*! cursor: restarted searches */ -#define WT_STAT_DSRC_CURSOR_RESTART 2078 +#define WT_STAT_DSRC_CURSOR_RESTART 2079 /*! cursor: search calls */ -#define WT_STAT_DSRC_CURSOR_SEARCH 2079 +#define WT_STAT_DSRC_CURSOR_SEARCH 2080 /*! cursor: search near calls */ -#define WT_STAT_DSRC_CURSOR_SEARCH_NEAR 2080 +#define WT_STAT_DSRC_CURSOR_SEARCH_NEAR 2081 /*! cursor: truncate calls */ -#define WT_STAT_DSRC_CURSOR_TRUNCATE 2081 +#define WT_STAT_DSRC_CURSOR_TRUNCATE 2082 /*! cursor: update calls */ -#define WT_STAT_DSRC_CURSOR_UPDATE 2082 +#define WT_STAT_DSRC_CURSOR_UPDATE 2083 /*! reconciliation: dictionary matches */ -#define WT_STAT_DSRC_REC_DICTIONARY 2083 +#define WT_STAT_DSRC_REC_DICTIONARY 2084 /*! reconciliation: fast-path pages deleted */ -#define WT_STAT_DSRC_REC_PAGE_DELETE_FAST 2084 -/*! reconciliation: internal page key bytes discarded using suffix - * compression */ -#define WT_STAT_DSRC_REC_SUFFIX_COMPRESSION 2085 +#define WT_STAT_DSRC_REC_PAGE_DELETE_FAST 2085 +/*! + * reconciliation: internal page key bytes discarded using suffix + * compression + */ +#define WT_STAT_DSRC_REC_SUFFIX_COMPRESSION 2086 /*! reconciliation: internal page multi-block writes */ -#define WT_STAT_DSRC_REC_MULTIBLOCK_INTERNAL 2086 +#define WT_STAT_DSRC_REC_MULTIBLOCK_INTERNAL 2087 /*! reconciliation: internal-page overflow keys */ -#define WT_STAT_DSRC_REC_OVERFLOW_KEY_INTERNAL 2087 +#define WT_STAT_DSRC_REC_OVERFLOW_KEY_INTERNAL 2088 /*! reconciliation: leaf page key bytes discarded using prefix compression */ -#define WT_STAT_DSRC_REC_PREFIX_COMPRESSION 2088 +#define WT_STAT_DSRC_REC_PREFIX_COMPRESSION 2089 /*! reconciliation: leaf page multi-block writes */ -#define WT_STAT_DSRC_REC_MULTIBLOCK_LEAF 2089 +#define WT_STAT_DSRC_REC_MULTIBLOCK_LEAF 2090 /*! reconciliation: leaf-page overflow keys */ -#define WT_STAT_DSRC_REC_OVERFLOW_KEY_LEAF 2090 +#define WT_STAT_DSRC_REC_OVERFLOW_KEY_LEAF 2091 /*! reconciliation: maximum blocks required for a page */ -#define WT_STAT_DSRC_REC_MULTIBLOCK_MAX 2091 +#define WT_STAT_DSRC_REC_MULTIBLOCK_MAX 2092 /*! reconciliation: overflow values written */ -#define WT_STAT_DSRC_REC_OVERFLOW_VALUE 2092 +#define WT_STAT_DSRC_REC_OVERFLOW_VALUE 2093 /*! reconciliation: page checksum matches */ -#define WT_STAT_DSRC_REC_PAGE_MATCH 2093 +#define WT_STAT_DSRC_REC_PAGE_MATCH 2094 /*! reconciliation: page reconciliation calls */ -#define WT_STAT_DSRC_REC_PAGES 2094 +#define WT_STAT_DSRC_REC_PAGES 2095 /*! reconciliation: page reconciliation calls for eviction */ -#define WT_STAT_DSRC_REC_PAGES_EVICTION 2095 +#define WT_STAT_DSRC_REC_PAGES_EVICTION 2096 /*! reconciliation: pages deleted */ -#define WT_STAT_DSRC_REC_PAGE_DELETE 2096 +#define WT_STAT_DSRC_REC_PAGE_DELETE 2097 /*! session: object compaction */ -#define WT_STAT_DSRC_SESSION_COMPACT 2097 +#define WT_STAT_DSRC_SESSION_COMPACT 2098 /*! session: open cursor count */ -#define WT_STAT_DSRC_SESSION_CURSOR_OPEN 2098 +#define WT_STAT_DSRC_SESSION_CURSOR_OPEN 2099 /*! transaction: update conflicts */ -#define WT_STAT_DSRC_TXN_UPDATE_CONFLICT 2099 +#define WT_STAT_DSRC_TXN_UPDATE_CONFLICT 2100 /*! * @} diff --git a/src/third_party/wiredtiger/src/include/wt_internal.h b/src/third_party/wiredtiger/src/include/wt_internal.h index c5337967f22..4e6699ab9d1 100644 --- a/src/third_party/wiredtiger/src/include/wt_internal.h +++ b/src/third_party/wiredtiger/src/include/wt_internal.h @@ -24,7 +24,9 @@ extern "C" { *******************************************/ #ifndef _WIN32 #include +#endif #include +#ifndef _WIN32 #include #include #endif @@ -170,14 +172,10 @@ struct __wt_evict_entry; typedef struct __wt_evict_entry WT_EVICT_ENTRY; struct __wt_evict_queue; typedef struct __wt_evict_queue WT_EVICT_QUEUE; -struct __wt_evict_worker; - typedef struct __wt_evict_worker WT_EVICT_WORKER; struct __wt_ext; typedef struct __wt_ext WT_EXT; struct __wt_extlist; typedef struct __wt_extlist WT_EXTLIST; -struct __wt_fair_lock; - typedef struct __wt_fair_lock WT_FAIR_LOCK; struct __wt_fh; typedef struct __wt_fh WT_FH; struct __wt_file_handle_inmem; @@ -286,6 +284,10 @@ struct __wt_split_stash; typedef struct __wt_split_stash WT_SPLIT_STASH; struct __wt_table; typedef struct __wt_table WT_TABLE; +struct __wt_thread; + typedef struct __wt_thread WT_THREAD; +struct __wt_thread_group; + typedef struct __wt_thread_group WT_THREAD_GROUP; struct __wt_txn; typedef struct __wt_txn WT_TXN; struct __wt_txn_global; @@ -350,6 +352,7 @@ union __wt_rand_state; #include "meta.h" #include "os.h" #include "schema.h" +#include "thread_group.h" #include "txn.h" #include "session.h" /* required by connection.h */ diff --git a/src/third_party/wiredtiger/src/log/log.c b/src/third_party/wiredtiger/src/log/log.c index 75405deb512..b17f31d5d16 100644 --- a/src/third_party/wiredtiger/src/log/log.c +++ b/src/third_party/wiredtiger/src/log/log.c @@ -9,19 +9,23 @@ #include "wt_internal.h" static int __log_openfile( - WT_SESSION_IMPL *, bool, WT_FH **, const char *, uint32_t); + WT_SESSION_IMPL *, WT_FH **, const char *, uint32_t, uint32_t); static int __log_write_internal( WT_SESSION_IMPL *, WT_ITEM *, WT_LSN *, uint32_t); #define WT_LOG_COMPRESS_SKIP (offsetof(WT_LOG_RECORD, record)) #define WT_LOG_ENCRYPT_SKIP (offsetof(WT_LOG_RECORD, record)) +/* Flags to __log_openfile */ +#define WT_LOG_OPEN_CREATE_OK 0x01 +#define WT_LOG_OPEN_VERIFY 0x02 + /* * __wt_log_ckpt -- * Record the given LSN as the checkpoint LSN and signal the archive * thread as needed. */ -int +void __wt_log_ckpt(WT_SESSION_IMPL *session, WT_LSN *ckp_lsn) { WT_CONNECTION_IMPL *conn; @@ -31,8 +35,7 @@ __wt_log_ckpt(WT_SESSION_IMPL *session, WT_LSN *ckp_lsn) log = conn->log; log->ckpt_lsn = *ckp_lsn; if (conn->log_cond != NULL) - WT_RET(__wt_cond_auto_signal(session, conn->log_cond)); - return (0); + __wt_cond_auto_signal(session, conn->log_cond); } /* @@ -49,7 +52,7 @@ __wt_log_flush_lsn(WT_SESSION_IMPL *session, WT_LSN *lsn, bool start) conn = S2C(session); log = conn->log; WT_RET(__wt_log_force_write(session, 1, NULL)); - WT_RET(__wt_log_wrlsn(session, NULL)); + __wt_log_wrlsn(session, NULL); if (start) *lsn = log->write_start_lsn; else @@ -62,7 +65,7 @@ __wt_log_flush_lsn(WT_SESSION_IMPL *session, WT_LSN *lsn, bool start) * Record the given LSN as the background LSN and signal the * thread as needed. */ -int +void __wt_log_background(WT_SESSION_IMPL *session, WT_LSN *lsn) { WT_CONNECTION_IMPL *conn; @@ -74,7 +77,7 @@ __wt_log_background(WT_SESSION_IMPL *session, WT_LSN *lsn) * If a thread already set the LSN to a bigger LSN, we're done. */ if (__wt_log_cmp(&session->bg_sync_lsn, lsn) > 0) - return (0); + return; session->bg_sync_lsn = *lsn; /* @@ -85,7 +88,7 @@ __wt_log_background(WT_SESSION_IMPL *session, WT_LSN *lsn) if (__wt_log_cmp(lsn, &log->bg_sync_lsn) > 0) log->bg_sync_lsn = *lsn; __wt_spin_unlock(session, &log->log_sync_lock); - return (__wt_cond_signal(session, conn->log_file_cond)); + __wt_cond_signal(session, conn->log_file_cond); } /* @@ -111,9 +114,8 @@ __wt_log_force_sync(WT_SESSION_IMPL *session, WT_LSN *min_lsn) * log file ready to close. */ while (log->sync_lsn.l.file < min_lsn->l.file) { - WT_ERR(__wt_cond_signal(session, - S2C(session)->log_file_cond)); - WT_ERR(__wt_cond_wait(session, log->log_sync_cond, 10000)); + __wt_cond_signal(session, S2C(session)->log_file_cond); + __wt_cond_wait(session, log->log_sync_cond, 10000); } __wt_spin_lock(session, &log->log_sync_lock); WT_ASSERT(session, log->log_dir_fh != NULL); @@ -122,10 +124,10 @@ __wt_log_force_sync(WT_SESSION_IMPL *session, WT_LSN *min_lsn) * into the directory. */ if (log->sync_dir_lsn.l.file < min_lsn->l.file) { - WT_ERR(__wt_verbose(session, WT_VERB_LOG, + __wt_verbose(session, WT_VERB_LOG, "log_force_sync: sync directory %s to LSN %" PRIu32 "/%" PRIu32, - log->log_dir_fh->name, min_lsn->l.file, min_lsn->l.offset)); + log->log_dir_fh->name, min_lsn->l.file, min_lsn->l.offset); WT_ERR(__wt_epoch(session, &fsync_start)); WT_ERR(__wt_fsync(session, log->log_dir_fh, true)); WT_ERR(__wt_epoch(session, &fsync_stop)); @@ -146,10 +148,10 @@ __wt_log_force_sync(WT_SESSION_IMPL *session, WT_LSN *min_lsn) * file than we want. */ WT_ERR(__log_openfile(session, - false, &log_fh, WT_LOG_FILENAME, min_lsn->l.file)); - WT_ERR(__wt_verbose(session, WT_VERB_LOG, + &log_fh, WT_LOG_FILENAME, min_lsn->l.file, 0)); + __wt_verbose(session, WT_VERB_LOG, "log_force_sync: sync %s to LSN %" PRIu32 "/%" PRIu32, - log_fh->name, min_lsn->l.file, min_lsn->l.offset)); + log_fh->name, min_lsn->l.file, min_lsn->l.offset); WT_ERR(__wt_epoch(session, &fsync_start)); WT_ERR(__wt_fsync(session, log_fh, true)); WT_ERR(__wt_epoch(session, &fsync_stop)); @@ -159,7 +161,7 @@ __wt_log_force_sync(WT_SESSION_IMPL *session, WT_LSN *min_lsn) WT_STAT_FAST_CONN_INCRV(session, log_sync_duration, fsync_duration_usecs); WT_ERR(__wt_close(session, &log_fh)); - WT_ERR(__wt_cond_signal(session, log->log_sync_cond)); + __wt_cond_signal(session, log->log_sync_cond); } err: __wt_spin_unlock(session, &log->log_sync_lock); @@ -277,7 +279,8 @@ __log_get_files(WT_SESSION_IMPL *session, /* * __wt_log_get_all_files -- * Retrieve the list of log files, either all of them or only the active - * ones (those that are not candidates for archiving). + * ones (those that are not candidates for archiving). The caller is + * responsible for freeing the directory list returned. */ int __wt_log_get_all_files(WT_SESSION_IMPL *session, @@ -307,6 +310,10 @@ __wt_log_get_all_files(WT_SESSION_IMPL *session, for (max = 0, i = 0; i < count; ) { WT_ERR(__wt_log_extract_lognum(session, files[i], &id)); if (active_only && id < log->ckpt_lsn.l.file) { + /* + * Any files not being returned are individually freed + * and the array adjusted. + */ __wt_free(session, files[i]); files[i] = files[count - 1]; files[--count] = NULL; @@ -321,6 +328,10 @@ __wt_log_get_all_files(WT_SESSION_IMPL *session, *filesp = files; *countp = count; + /* + * Only free on error. The caller is responsible for calling free + * once it is done using the returned list. + */ if (0) { err: WT_TRET(__wt_fs_directory_list_free(session, &files, count)); } @@ -447,7 +458,7 @@ __log_prealloc(WT_SESSION_IMPL *session, WT_FH *fh) /* * If the user configured zero filling, pre-allocate the log file - * manually. Otherwise use either fallocate or ftruncate to create + * manually. Otherwise use the file extension method to create * and zero the log file based on what is available. */ if (FLD_ISSET(conn->log_flags, WT_CONN_LOG_ZERO_FILL)) @@ -458,13 +469,8 @@ __log_prealloc(WT_SESSION_IMPL *session, WT_FH *fh) * We have exclusive access to the log file and there are no other * writes happening concurrently, so there are no locking issues. */ - if ((ret = __wt_fallocate( - session, fh, WT_LOG_FIRST_RECORD, - conn->log_file_max - WT_LOG_FIRST_RECORD)) == 0) - return (0); - WT_RET_ERROR_OK(ret, ENOTSUP); - - return (__wt_ftruncate(session, fh, conn->log_file_max)); + ret = __wt_fextend(session, fh, conn->log_file_max); + return (ret == EBUSY || ret == ENOTSUP ? 0 : ret); } /* @@ -634,7 +640,7 @@ __log_file_header( logrec->len = log->allocsize; logrec->checksum = 0; __wt_log_record_byteswap(logrec); - logrec->checksum = __wt_cksum(logrec, log->allocsize); + logrec->checksum = __wt_checksum(logrec, log->allocsize); #ifdef WORDS_BIGENDIAN logrec->checksum = __wt_bswap32(logrec->checksum); #endif @@ -674,7 +680,7 @@ err: __wt_scr_free(session, &buf); */ static int __log_openfile(WT_SESSION_IMPL *session, - bool ok_create, WT_FH **fhp, const char *file_prefix, uint32_t id) + WT_FH **fhp, const char *file_prefix, uint32_t id, uint32_t flags) { WT_CONNECTION_IMPL *conn; WT_DECL_ITEM(buf); @@ -693,10 +699,10 @@ __log_openfile(WT_SESSION_IMPL *session, allocsize = log->allocsize; WT_RET(__wt_scr_alloc(session, 0, &buf)); WT_ERR(__log_filename(session, id, file_prefix, buf)); - WT_ERR(__wt_verbose(session, WT_VERB_LOG, - "opening log %s", (const char *)buf->data)); + __wt_verbose(session, WT_VERB_LOG, + "opening log %s", (const char *)buf->data); wtopen_flags = 0; - if (ok_create) + if (LF_ISSET(WT_LOG_OPEN_CREATE_OK)) FLD_SET(wtopen_flags, WT_FS_OPEN_CREATE); if (FLD_ISSET(conn->direct_io, WT_DIRECT_IO_LOG)) FLD_SET(wtopen_flags, WT_FS_OPEN_DIRECTIO); @@ -707,7 +713,7 @@ __log_openfile(WT_SESSION_IMPL *session, * If we are not creating the log file but opening it for reading, * check that the magic number and versions are correct. */ - if (!ok_create) { + if (LF_ISSET(WT_LOG_OPEN_VERIFY)) { WT_ERR(__wt_buf_grow(session, buf, allocsize)); memset(buf->mem, 0, allocsize); WT_ERR(__wt_read(session, *fhp, 0, allocsize, buf->mem)); @@ -765,9 +771,9 @@ __log_alloc_prealloc(WT_SESSION_IMPL *session, uint32_t to_num) WT_ERR(__wt_scr_alloc(session, 0, &to_path)); WT_ERR(__log_filename(session, from_num, WT_LOG_PREPNAME, from_path)); WT_ERR(__log_filename(session, to_num, WT_LOG_FILENAME, to_path)); - WT_ERR(__wt_verbose(session, WT_VERB_LOG, + __wt_verbose(session, WT_VERB_LOG, "log_alloc_prealloc: rename log %s to %s", - (char *)from_path->data, (char *)to_path->data)); + (const char *)from_path->data, (const char *)to_path->data); WT_STAT_FAST_CONN_INCR(session, log_prealloc_used); /* * All file setup, writing the header and pre-allocation was done @@ -793,14 +799,12 @@ __log_newfile(WT_SESSION_IMPL *session, bool conn_open, bool *created) WT_FH *log_fh; WT_LOG *log; WT_LSN end_lsn; - int yield_cnt; + u_int yield_cnt; bool create_log; conn = S2C(session); log = conn->log; - create_log = true; - yield_cnt = 0; /* * Set aside the log file handle to be closed later. Other threads * may still be using it to write to the log. If the log file size @@ -808,9 +812,9 @@ __log_newfile(WT_SESSION_IMPL *session, bool conn_open, bool *created) * Wait for that to close. */ WT_ASSERT(session, F_ISSET(session, WT_SESSION_LOCKED_SLOT)); - while (log->log_close_fh != NULL) { + for (yield_cnt = 0; log->log_close_fh != NULL;) { WT_STAT_FAST_CONN_INCR(session, log_close_yields); - WT_RET(__wt_log_wrlsn(session, NULL)); + __wt_log_wrlsn(session, NULL); if (++yield_cnt > 10000) return (EBUSY); __wt_yield(); @@ -828,31 +832,39 @@ __log_newfile(WT_SESSION_IMPL *session, bool conn_open, bool *created) * Make sure everything we set above is visible. */ WT_FULL_BARRIER(); + /* - * If we're pre-allocating log files, look for one. If there aren't any - * or we're not pre-allocating, or a backup cursor is open, then - * create one. + * If pre-allocating log files look for one; otherwise, or if we don't + * find one create a log file. We can't use pre-allocated log files in + * while a hot backup is in progress: applications can copy the files + * in any way they choose, and a log file rename might confuse things. */ + create_log = true; if (conn->log_prealloc > 0 && !conn->hot_backup) { - ret = __log_alloc_prealloc(session, log->fileid); - /* - * If ret is 0 it means we found a pre-allocated file. - * If ret is non-zero but not WT_NOTFOUND, we return the error. - * If ret is WT_NOTFOUND, we leave create_log set and create - * the new log file. - */ - if (ret == 0) - create_log = false; - /* - * If we get any error other than WT_NOTFOUND, return it. - */ - WT_RET_NOTFOUND_OK(ret); + __wt_readlock(session, conn->hot_backup_lock); + if (conn->hot_backup) + __wt_readunlock(session, conn->hot_backup_lock); + else { + ret = __log_alloc_prealloc(session, log->fileid); + __wt_readunlock(session, conn->hot_backup_lock); - if (create_log) { - WT_STAT_FAST_CONN_INCR(session, log_prealloc_missed); - if (conn->log_cond != NULL) - WT_RET(__wt_cond_auto_signal( - session, conn->log_cond)); + /* + * If ret is 0 it means we found a pre-allocated file. + * If ret is WT_NOTFOUND, create the new log file and + * signal the server, we missed our pre-allocation. + * If ret is non-zero but not WT_NOTFOUND, return the + * error. + */ + WT_RET_NOTFOUND_OK(ret); + if (ret == 0) + create_log = false; + else { + WT_STAT_FAST_CONN_INCR( + session, log_prealloc_missed); + if (conn->log_cond != NULL) + __wt_cond_auto_signal( + session, conn->log_cond); + } } } /* @@ -870,7 +882,7 @@ __log_newfile(WT_SESSION_IMPL *session, bool conn_open, bool *created) * window where another thread could see a NULL log file handle. */ WT_RET(__log_openfile(session, - false, &log_fh, WT_LOG_FILENAME, log->fileid)); + &log_fh, WT_LOG_FILENAME, log->fileid, 0)); WT_PUBLISH(log->log_fh, log_fh); /* * We need to setup the LSNs. Set the end LSN and alloc LSN to @@ -946,6 +958,39 @@ __wt_log_acquire(WT_SESSION_IMPL *session, uint64_t recsize, WT_LOGSLOT *slot) return (0); } +/* + * __log_truncate_file -- + * Truncate a log file to the specified offset. + * + * If the underlying file system doesn't support truncate then we need to + * zero out the rest of the file, doing an effective truncate. + */ +static int +__log_truncate_file(WT_SESSION_IMPL *session, WT_FH *log_fh, wt_off_t offset) +{ + WT_CONNECTION_IMPL *conn; + WT_DECL_RET; + WT_LOG *log; + + conn = S2C(session); + log = conn->log; + + if (!F_ISSET(log, WT_LOG_TRUNCATE_NOTSUP) && !conn->hot_backup) { + __wt_readlock(session, conn->hot_backup_lock); + if (conn->hot_backup) + __wt_readunlock(session, conn->hot_backup_lock); + else { + ret = __wt_ftruncate(session, log_fh, offset); + __wt_readunlock(session, conn->hot_backup_lock); + if (ret != ENOTSUP) + return (ret); + F_SET(log, WT_LOG_TRUNCATE_NOTSUP); + } + } + + return (__log_zero(session, log_fh, offset, conn->log_file_max)); +} + /* * __log_truncate -- * Truncate the log to the given LSN. If this_log is set, it will only @@ -976,10 +1021,15 @@ __log_truncate(WT_SESSION_IMPL *session, /* * Truncate the log file to the given LSN. - */ - WT_ERR(__log_openfile(session, - false, &log_fh, file_prefix, lsn->l.file)); - WT_ERR(__wt_ftruncate(session, log_fh, lsn->l.offset)); + * + * It's possible the underlying file system doesn't support truncate + * (there are existing examples), which is fine, but we don't want to + * repeatedly do the setup work just to find that out every time. Check + * before doing work, and if there's a not-supported error, turn off + * future truncates. + */ + WT_ERR(__log_openfile(session, &log_fh, file_prefix, lsn->l.file, 0)); + WT_ERR(__log_truncate_file(session, log_fh, lsn->l.offset)); WT_ERR(__wt_fsync(session, log_fh, true)); WT_ERR(__wt_close(session, &log_fh)); @@ -995,13 +1045,13 @@ __log_truncate(WT_SESSION_IMPL *session, if (lognum > lsn->l.file && lognum < log->trunc_lsn.l.file) { WT_ERR(__log_openfile(session, - false, &log_fh, file_prefix, lognum)); + &log_fh, file_prefix, lognum, 0)); /* * If there are intervening files pre-allocated, * truncate them to the end of the log file header. */ - WT_ERR(__wt_ftruncate(session, - log_fh, WT_LOG_FIRST_RECORD)); + WT_ERR(__log_truncate_file( + session, log_fh, WT_LOG_FIRST_RECORD)); WT_ERR(__wt_fsync(session, log_fh, true)); WT_ERR(__wt_close(session, &log_fh)); } @@ -1047,14 +1097,15 @@ __wt_log_allocfile( /* * Set up the temporary file. */ - WT_ERR(__log_openfile(session, true, &log_fh, WT_LOG_TMPNAME, tmp_id)); + WT_ERR(__log_openfile(session, + &log_fh, WT_LOG_TMPNAME, tmp_id, WT_LOG_OPEN_CREATE_OK)); WT_ERR(__log_file_header(session, log_fh, NULL, true)); WT_ERR(__log_prealloc(session, log_fh)); WT_ERR(__wt_fsync(session, log_fh, true)); WT_ERR(__wt_close(session, &log_fh)); - WT_ERR(__wt_verbose(session, WT_VERB_LOG, + __wt_verbose(session, WT_VERB_LOG, "log_prealloc: rename %s to %s", - (char *)from_path->data, (char *)to_path->data)); + (const char *)from_path->data, (const char *)to_path->data); /* * Rename it into place and make it available. */ @@ -1079,8 +1130,8 @@ __wt_log_remove(WT_SESSION_IMPL *session, WT_RET(__wt_scr_alloc(session, 0, &path)); WT_ERR(__log_filename(session, lognum, file_prefix, path)); - WT_ERR(__wt_verbose(session, WT_VERB_LOG, - "log_remove: remove log %s", (char *)path->data)); + __wt_verbose(session, WT_VERB_LOG, + "log_remove: remove log %s", (const char *)path->data); WT_ERR(__wt_fs_remove(session, path->data, false)); err: __wt_scr_free(session, &path); return (ret); @@ -1114,8 +1165,8 @@ __wt_log_open(WT_SESSION_IMPL *session) * Open up a file handle to the log directory if we haven't. */ if (log->log_dir_fh == NULL) { - WT_RET(__wt_verbose(session, WT_VERB_LOG, - "log_open: open fh to directory %s", conn->log_path)); + __wt_verbose(session, WT_VERB_LOG, + "log_open: open fh to directory %s", conn->log_path); WT_RET(__wt_open(session, conn->log_path, WT_FS_OPEN_FILE_TYPE_DIRECTORY, 0, &log->log_dir_fh)); } @@ -1158,9 +1209,9 @@ __wt_log_open(WT_SESSION_IMPL *session) firstlog = WT_MIN(firstlog, lognum); } log->fileid = lastlog; - WT_ERR(__wt_verbose(session, WT_VERB_LOG, + __wt_verbose(session, WT_VERB_LOG, "log_open: first log %" PRIu32 " last log %" PRIu32, - firstlog, lastlog)); + firstlog, lastlog); if (firstlog == UINT32_MAX) { WT_ASSERT(session, logcount == 0); WT_INIT_LSN(&log->first_lsn); @@ -1203,23 +1254,23 @@ __wt_log_close(WT_SESSION_IMPL *session) log = conn->log; if (log->log_close_fh != NULL && log->log_close_fh != log->log_fh) { - WT_RET(__wt_verbose(session, WT_VERB_LOG, - "closing old log %s", log->log_close_fh->name)); + __wt_verbose(session, WT_VERB_LOG, + "closing old log %s", log->log_close_fh->name); if (!F_ISSET(conn, WT_CONN_READONLY)) WT_RET(__wt_fsync(session, log->log_close_fh, true)); WT_RET(__wt_close(session, &log->log_close_fh)); } if (log->log_fh != NULL) { - WT_RET(__wt_verbose(session, WT_VERB_LOG, - "closing log %s", log->log_fh->name)); + __wt_verbose(session, WT_VERB_LOG, + "closing log %s", log->log_fh->name); if (!F_ISSET(conn, WT_CONN_READONLY)) WT_RET(__wt_fsync(session, log->log_fh, true)); WT_RET(__wt_close(session, &log->log_fh)); log->log_fh = NULL; } if (log->log_dir_fh != NULL) { - WT_RET(__wt_verbose(session, WT_VERB_LOG, - "closing log directory %s", log->log_dir_fh->name)); + __wt_verbose(session, WT_VERB_LOG, + "closing log directory %s", log->log_dir_fh->name); if (!F_ISSET(conn, WT_CONN_READONLY)) WT_RET(__wt_fsync(session, log->log_dir_fh, true)); WT_RET(__wt_close(session, &log->log_dir_fh)); @@ -1311,8 +1362,7 @@ __wt_log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot, bool *freep) yield_count = 0; if (freep != NULL) *freep = 1; - release_buffered = - WT_LOG_SLOT_RELEASED_BUFFERED(slot->slot_state); + release_buffered = WT_LOG_SLOT_RELEASED_BUFFERED(slot->slot_state); release_bytes = release_buffered + slot->slot_unbuffered; /* @@ -1325,7 +1375,7 @@ __wt_log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot, bool *freep) */ if (WT_CKPT_LOGSIZE(conn)) { log->log_written += (wt_off_t)release_bytes; - WT_RET(__wt_checkpoint_signal(session, log->log_written)); + __wt_checkpoint_signal(session, log->log_written); } /* Write the buffered records */ @@ -1370,28 +1420,27 @@ __wt_log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot, bool *freep) */ if (F_ISSET(session, WT_SESSION_LOCKED_SLOT)) __wt_spin_unlock(session, &log->log_slot_lock); - WT_ERR(__wt_cond_auto_signal(session, conn->log_wrlsn_cond)); + __wt_cond_auto_signal(session, conn->log_wrlsn_cond); if (++yield_count < WT_THOUSAND) __wt_yield(); else - ret = __wt_cond_wait(session, log->log_write_cond, 200); + __wt_cond_wait(session, log->log_write_cond, 200); if (F_ISSET(session, WT_SESSION_LOCKED_SLOT)) __wt_spin_lock(session, &log->log_slot_lock); - WT_ERR(ret); } log->write_start_lsn = slot->slot_start_lsn; log->write_lsn = slot->slot_end_lsn; WT_ASSERT(session, slot != log->active_slot); - WT_ERR(__wt_cond_signal(session, log->log_write_cond)); + __wt_cond_signal(session, log->log_write_cond); F_CLR(slot, WT_SLOT_FLUSH); /* * Signal the close thread if needed. */ if (F_ISSET(slot, WT_SLOT_CLOSEFH)) - WT_ERR(__wt_cond_signal(session, conn->log_file_cond)); + __wt_cond_signal(session, conn->log_file_cond); /* * Try to consolidate calls to fsync to wait less. Acquire a spin lock @@ -1406,8 +1455,7 @@ __wt_log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot, bool *freep) */ if (log->sync_lsn.l.file < slot->slot_end_lsn.l.file || __wt_spin_trylock(session, &log->log_sync_lock) != 0) { - WT_ERR(__wt_cond_wait( - session, log->log_sync_cond, 10000)); + __wt_cond_wait(session, log->log_sync_cond, 10000); continue; } locked = true; @@ -1426,11 +1474,11 @@ __wt_log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot, bool *freep) if (F_ISSET(slot, WT_SLOT_SYNC_DIR) && (log->sync_dir_lsn.l.file < sync_lsn.l.file)) { WT_ASSERT(session, log->log_dir_fh != NULL); - WT_ERR(__wt_verbose(session, WT_VERB_LOG, + __wt_verbose(session, WT_VERB_LOG, "log_release: sync directory %s to LSN %" PRIu32 "/%" PRIu32, log->log_dir_fh->name, - sync_lsn.l.file, sync_lsn.l.offset)); + sync_lsn.l.file, sync_lsn.l.offset); WT_ERR(__wt_epoch(session, &fsync_start)); WT_ERR(__wt_fsync(session, log->log_dir_fh, true)); WT_ERR(__wt_epoch(session, &fsync_stop)); @@ -1447,11 +1495,11 @@ __wt_log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot, bool *freep) */ if (F_ISSET(slot, WT_SLOT_SYNC) && __wt_log_cmp(&log->sync_lsn, &slot->slot_end_lsn) < 0) { - WT_ERR(__wt_verbose(session, WT_VERB_LOG, + __wt_verbose(session, WT_VERB_LOG, "log_release: sync log %s to LSN %" PRIu32 "/%" PRIu32, log->log_fh->name, - sync_lsn.l.file, sync_lsn.l.offset)); + sync_lsn.l.file, sync_lsn.l.offset); WT_STAT_FAST_CONN_INCR(session, log_sync); WT_ERR(__wt_epoch(session, &fsync_start)); WT_ERR(__wt_fsync(session, log->log_fh, true)); @@ -1461,7 +1509,7 @@ __wt_log_release(WT_SESSION_IMPL *session, WT_LOGSLOT *slot, bool *freep) WT_STAT_FAST_CONN_INCRV(session, log_sync_duration, fsync_duration_usecs); log->sync_lsn = sync_lsn; - WT_ERR(__wt_cond_signal(session, log->log_sync_cond)); + __wt_cond_signal(session, log->log_sync_cond); } /* * Clear the flags before leaving the loop. @@ -1499,7 +1547,7 @@ __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags, WT_LSN end_lsn, next_lsn, rd_lsn, start_lsn; wt_off_t log_size; uint32_t allocsize, firstlog, lastlog, lognum, rdup_len, reclen; - uint32_t cksum_calculate, cksum_tmp; + uint32_t checksum_calculate, checksum_tmp; u_int i, logcount; int firstrecord; bool eol, partial_record; @@ -1521,9 +1569,9 @@ __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags, return (0); if (LF_ISSET(WT_LOGSCAN_RECOVER)) - WT_RET(__wt_verbose(session, WT_VERB_LOG, + __wt_verbose(session, WT_VERB_LOG, "__wt_log_scan truncating to %" PRIu32 "/%" PRIu32, - log->trunc_lsn.l.file, log->trunc_lsn.l.offset)); + log->trunc_lsn.l.file, log->trunc_lsn.l.offset); if (log != NULL) { allocsize = log->allocsize; @@ -1587,8 +1635,8 @@ __wt_log_scan(WT_SESSION_IMPL *session, WT_LSN *lsnp, uint32_t flags, WT_ERR( __wt_fs_directory_list_free(session, &logfiles, logcount)); } - WT_ERR(__log_openfile( - session, false, &log_fh, WT_LOG_FILENAME, start_lsn.l.file)); + WT_ERR(__log_openfile(session, + &log_fh, WT_LOG_FILENAME, start_lsn.l.file, WT_LOG_OPEN_VERIFY)); WT_ERR(__wt_filesize(session, log_fh, &log_size)); rd_lsn = start_lsn; @@ -1637,7 +1685,8 @@ advance: if (rd_lsn.l.file > end_lsn.l.file) break; WT_ERR(__log_openfile(session, - false, &log_fh, WT_LOG_FILENAME, rd_lsn.l.file)); + &log_fh, WT_LOG_FILENAME, + rd_lsn.l.file, WT_LOG_OPEN_VERIFY)); WT_ERR(__wt_filesize(session, log_fh, &log_size)); eol = false; continue; @@ -1710,12 +1759,12 @@ advance: */ buf->size = reclen; logrec = (WT_LOG_RECORD *)buf->mem; - cksum_tmp = logrec->checksum; + checksum_tmp = logrec->checksum; logrec->checksum = 0; - cksum_calculate = __wt_cksum(logrec, reclen); - logrec->checksum = cksum_tmp; + checksum_calculate = __wt_checksum(logrec, reclen); + logrec->checksum = checksum_tmp; __wt_log_record_byteswap(logrec); - if (logrec->checksum != cksum_calculate) { + if (logrec->checksum != checksum_calculate) { /* * A checksum mismatch means we have reached the end of * the useful part of the log. This should be found on @@ -2029,7 +2078,7 @@ __log_write_internal(WT_SESSION_IMPL *session, WT_ITEM *record, WT_LSN *lsnp, logrec->len = (uint32_t)record->size; logrec->checksum = 0; __wt_log_record_byteswap(logrec); - logrec->checksum = __wt_cksum(logrec, record->size); + logrec->checksum = __wt_checksum(logrec, record->size); #ifdef WORDS_BIGENDIAN logrec->checksum = __wt_bswap32(logrec->checksum); #endif @@ -2070,7 +2119,7 @@ __log_write_internal(WT_SESSION_IMPL *session, WT_ITEM *record, WT_LSN *lsnp, * XXX I've seen times when conditions are NULL. */ if (conn->log_cond != NULL) { - WT_ERR(__wt_cond_auto_signal(session, conn->log_cond)); + __wt_cond_auto_signal(session, conn->log_cond); __wt_yield(); } else WT_ERR(__wt_log_force_write(session, 1, NULL)); @@ -2079,21 +2128,19 @@ __log_write_internal(WT_SESSION_IMPL *session, WT_ITEM *record, WT_LSN *lsnp, /* Wait for our writes to reach the OS */ while (__wt_log_cmp(&log->write_lsn, &lsn) <= 0 && myslot.slot->slot_error == 0) - (void)__wt_cond_wait( - session, log->log_write_cond, 10000); + __wt_cond_wait(session, log->log_write_cond, 10000); } else if (LF_ISSET(WT_LOG_FSYNC)) { /* Wait for our writes to reach disk */ while (__wt_log_cmp(&log->sync_lsn, &lsn) <= 0 && myslot.slot->slot_error == 0) - (void)__wt_cond_wait( - session, log->log_sync_cond, 10000); + __wt_cond_wait(session, log->log_sync_cond, 10000); } /* * Advance the background sync LSN if needed. */ if (LF_ISSET(WT_LOG_BACKGROUND)) - WT_ERR(__wt_log_background(session, &lsn)); + __wt_log_background(session, &lsn); err: if (ret == 0 && lsnp != NULL) @@ -2161,8 +2208,8 @@ __wt_log_vprintf(WT_SESSION_IMPL *session, const char *fmt, va_list ap) (void)vsnprintf((char *)logrec->data + logrec->size, len, fmt, ap); - WT_ERR(__wt_verbose(session, WT_VERB_LOG, - "log_printf: %s", (char *)logrec->data + logrec->size)); + __wt_verbose(session, WT_VERB_LOG, + "log_printf: %s", (char *)logrec->data + logrec->size); logrec->size += len; WT_ERR(__wt_log_write(session, logrec, NULL, 0)); @@ -2208,16 +2255,16 @@ __wt_log_flush(WT_SESSION_IMPL *session, uint32_t flags) while (__wt_log_cmp(&last_lsn, &lsn) > 0) WT_RET(__wt_log_flush_lsn(session, &lsn, false)); - WT_RET(__wt_verbose(session, WT_VERB_LOG, + __wt_verbose(session, WT_VERB_LOG, "log_flush: flags %#" PRIx32 " LSN %" PRIu32 "/%" PRIu32, - flags, lsn.l.file, lsn.l.offset)); + flags, lsn.l.file, lsn.l.offset); /* * If the user wants write-no-sync, there is nothing more to do. * If the user wants background sync, set the LSN and we're done. * If the user wants sync, force it now. */ if (LF_ISSET(WT_LOG_BACKGROUND)) - WT_RET(__wt_log_background(session, &lsn)); + __wt_log_background(session, &lsn); else if (LF_ISSET(WT_LOG_FSYNC)) WT_RET(__wt_log_force_sync(session, &lsn)); return (0); diff --git a/src/third_party/wiredtiger/src/log/log_slot.c b/src/third_party/wiredtiger/src/log/log_slot.c index 47071211450..58377aff6f5 100644 --- a/src/third_party/wiredtiger/src/log/log_slot.c +++ b/src/third_party/wiredtiger/src/log/log_slot.c @@ -262,7 +262,7 @@ __wt_log_slot_new(WT_SESSION_IMPL *session) /* * If we didn't find any free slots signal the worker thread. */ - (void)__wt_cond_auto_signal(session, conn->log_wrlsn_cond); + __wt_cond_auto_signal(session, conn->log_wrlsn_cond); __wt_yield(); } /* NOTREACHED */ diff --git a/src/third_party/wiredtiger/src/lsm/lsm_cursor.c b/src/third_party/wiredtiger/src/lsm/lsm_cursor.c index 55e311fd273..bf591d8dbe6 100644 --- a/src/third_party/wiredtiger/src/lsm/lsm_cursor.c +++ b/src/third_party/wiredtiger/src/lsm/lsm_cursor.c @@ -40,7 +40,7 @@ __wt_clsm_request_switch(WT_CURSOR_LSM *clsm) * to switching multiple times when only one switch is * required, creating very small chunks. */ - WT_RET(__wt_lsm_tree_readlock(session, lsm_tree)); + __wt_lsm_tree_readlock(session, lsm_tree); if (lsm_tree->nchunks == 0 || (clsm->dsk_gen == lsm_tree->dsk_gen && !F_ISSET(lsm_tree, WT_LSM_TREE_NEED_SWITCH))) { @@ -48,7 +48,7 @@ __wt_clsm_request_switch(WT_CURSOR_LSM *clsm) ret = __wt_lsm_manager_push_entry( session, WT_LSM_WORK_SWITCH, 0, lsm_tree); } - WT_TRET(__wt_lsm_tree_readunlock(session, lsm_tree)); + __wt_lsm_tree_readunlock(session, lsm_tree); } return (ret); @@ -205,6 +205,12 @@ __clsm_enter(WT_CURSOR_LSM *clsm, bool reset, bool update) WT_RET(__wt_txn_id_check(session)); WT_RET(__clsm_enter_update(clsm)); + /* + * Switching the tree will update the generation before + * updating the switch transaction. We test the + * transaction in clsm_enter_update. Now test the + * disk generation to avoid races. + */ if (clsm->dsk_gen != clsm->lsm_tree->dsk_gen) goto open; @@ -452,7 +458,7 @@ __clsm_open_cursors( F_CLR(clsm, WT_CLSM_ITERATE_NEXT | WT_CLSM_ITERATE_PREV); - WT_RET(__wt_lsm_tree_readlock(session, lsm_tree)); + __wt_lsm_tree_readlock(session, lsm_tree); locked = true; /* Merge cursors have already figured out how many chunks they need. */ @@ -571,10 +577,10 @@ retry: if (F_ISSET(clsm, WT_CLSM_MERGE)) { if (close_range_end > close_range_start) { saved_gen = lsm_tree->dsk_gen; locked = false; - WT_ERR(__wt_lsm_tree_readunlock(session, lsm_tree)); + __wt_lsm_tree_readunlock(session, lsm_tree); WT_ERR(__clsm_close_cursors( clsm, close_range_start, close_range_end)); - WT_ERR(__wt_lsm_tree_readlock(session, lsm_tree)); + __wt_lsm_tree_readlock(session, lsm_tree); locked = true; if (lsm_tree->dsk_gen != saved_gen) goto retry; @@ -692,7 +698,7 @@ err: } #endif if (locked) - WT_TRET(__wt_lsm_tree_readunlock(session, lsm_tree)); + __wt_lsm_tree_readunlock(session, lsm_tree); return (ret); } @@ -1068,8 +1074,7 @@ __clsm_lookup(WT_CURSOR_LSM *clsm, WT_ITEM *value) bloom = NULL; if ((bloom = clsm->blooms[i]) != NULL) { if (!have_hash) { - WT_ERR(__wt_bloom_hash( - bloom, &cursor->key, &bhash)); + __wt_bloom_hash(bloom, &cursor->key, &bhash); have_hash = true; } @@ -1528,6 +1533,8 @@ __wt_clsm_open(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree; bool bulk; + WT_STATIC_ASSERT(offsetof(WT_CURSOR_LSM, iface) == 0); + clsm = NULL; cursor = NULL; lsm_tree = NULL; @@ -1573,6 +1580,7 @@ __wt_clsm_open(WT_SESSION_IMPL *session, cursor->value_format = lsm_tree->value_format; clsm->lsm_tree = lsm_tree; + lsm_tree = NULL; /* * The tree's dsk_gen starts at one, so starting the cursor on zero @@ -1580,7 +1588,6 @@ __wt_clsm_open(WT_SESSION_IMPL *session, */ clsm->dsk_gen = 0; - WT_STATIC_ASSERT(offsetof(WT_CURSOR_LSM, iface) == 0); WT_ERR(__wt_cursor_init(cursor, cursor->uri, owner, cfg, cursorp)); if (bulk) @@ -1592,10 +1599,6 @@ err: if (clsm != NULL) else if (lsm_tree != NULL) __wt_lsm_tree_release(session, lsm_tree); - /* - * We open bulk cursors after setting the returned cursor. - * Fix that here. - */ *cursorp = NULL; } diff --git a/src/third_party/wiredtiger/src/lsm/lsm_manager.c b/src/third_party/wiredtiger/src/lsm/lsm_manager.c index 943a5894ab3..a504acc361c 100644 --- a/src/third_party/wiredtiger/src/lsm/lsm_manager.c +++ b/src/third_party/wiredtiger/src/lsm/lsm_manager.c @@ -358,7 +358,7 @@ __lsm_manager_worker_shutdown(WT_SESSION_IMPL *session) */ for (i = 1; i < manager->lsm_workers; i++) { WT_ASSERT(session, manager->lsm_worker_cookies[i].tid != 0); - WT_TRET(__wt_cond_signal(session, manager->work_cond)); + __wt_cond_signal(session, manager->work_cond); WT_TRET(__wt_thread_join( session, manager->lsm_worker_cookies[i].tid)); } @@ -431,7 +431,7 @@ __lsm_manager_run_server(WT_SESSION_IMPL *session) session, WT_LSM_WORK_FLUSH, 0, lsm_tree)); WT_ERR(__wt_lsm_manager_push_entry( session, WT_LSM_WORK_BLOOM, 0, lsm_tree)); - WT_ERR(__wt_verbose(session, + __wt_verbose(session, WT_VERB_LSM_MANAGER, "MGR %s: queue %" PRIu32 " mod %d " "nchunks %" PRIu32 @@ -442,7 +442,7 @@ __lsm_manager_run_server(WT_SESSION_IMPL *session) lsm_tree->modified, lsm_tree->nchunks, lsm_tree->flags, lsm_tree->merge_aggressiveness, - pushms, fillms)); + pushms, fillms); WT_ERR(__wt_lsm_manager_push_entry( session, WT_LSM_WORK_MERGE, 0, lsm_tree)); } @@ -491,9 +491,8 @@ err: WT_PANIC_MSG(session, ret, "LSM worker manager thread error"); * introduces an inefficiency if LSM trees are being opened and closed * regularly. */ -int -__wt_lsm_manager_clear_tree( - WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) +void +__wt_lsm_manager_clear_tree(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) { WT_LSM_MANAGER *manager; WT_LSM_WORK_UNIT *current, *next; @@ -541,7 +540,6 @@ __wt_lsm_manager_clear_tree( } __wt_spin_unlock(session, &manager->manager_lock); WT_STAT_FAST_CONN_INCRV(session, lsm_work_units_discarded, removed); - return (0); } /* @@ -617,10 +615,8 @@ int __wt_lsm_manager_push_entry(WT_SESSION_IMPL *session, uint32_t type, uint32_t flags, WT_LSM_TREE *lsm_tree) { - WT_DECL_RET; WT_LSM_MANAGER *manager; WT_LSM_WORK_UNIT *entry; - bool pushed; manager = &S2C(session)->lsm_manager; @@ -655,9 +651,8 @@ __wt_lsm_manager_push_entry(WT_SESSION_IMPL *session, return (0); } - pushed = false; - WT_ERR(__wt_epoch(session, &lsm_tree->work_push_ts)); - WT_ERR(__wt_calloc_one(session, &entry)); + WT_RET(__wt_epoch(session, &lsm_tree->work_push_ts)); + WT_RET(__wt_calloc_one(session, &entry)); entry->type = type; entry->flags = flags; entry->lsm_tree = lsm_tree; @@ -672,12 +667,7 @@ __wt_lsm_manager_push_entry(WT_SESSION_IMPL *session, else LSM_PUSH_ENTRY(&manager->appqh, &manager->app_lock, lsm_work_queue_app); - pushed = true; - WT_ERR(__wt_cond_signal(session, manager->work_cond)); + __wt_cond_signal(session, manager->work_cond); return (0); -err: - if (!pushed) - (void)__wt_atomic_sub32(&lsm_tree->queue_ref, 1); - return (ret); } diff --git a/src/third_party/wiredtiger/src/lsm/lsm_merge.c b/src/third_party/wiredtiger/src/lsm/lsm_merge.c index 1ff0a216c02..2276631af1e 100644 --- a/src/third_party/wiredtiger/src/lsm/lsm_merge.c +++ b/src/third_party/wiredtiger/src/lsm/lsm_merge.c @@ -43,12 +43,11 @@ __wt_lsm_merge_update_tree(WT_SESSION_IMPL *session, * __lsm_merge_aggressive_clear -- * We found a merge to do - clear the aggressive timer. */ -static int +static void __lsm_merge_aggressive_clear(WT_LSM_TREE *lsm_tree) { F_CLR(lsm_tree, WT_LSM_TREE_AGGRESSIVE_TIMER); lsm_tree->merge_aggressiveness = 0; - return (0); } /* @@ -80,8 +79,10 @@ __lsm_merge_aggressive_update(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) * Only get aggressive if a reasonable number of flushes have been * completed since opening the tree. */ - if (lsm_tree->chunks_flushed <= lsm_tree->merge_min) - return (__lsm_merge_aggressive_clear(lsm_tree)); + if (lsm_tree->chunks_flushed <= lsm_tree->merge_min) { + __lsm_merge_aggressive_clear(lsm_tree); + return (0); + } /* * Start the timer if it isn't running. Use a flag to define whether @@ -124,13 +125,13 @@ __lsm_merge_aggressive_update(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) ++new_aggressive; if (new_aggressive > lsm_tree->merge_aggressiveness) { - WT_RET(__wt_verbose(session, WT_VERB_LSM, + __wt_verbose(session, WT_VERB_LSM, "LSM merge %s got aggressive " "(old %" PRIu32 " new %" PRIu32 "), " "merge_min %u, %" PRIu64 " / %" PRIu64, lsm_tree->name, lsm_tree->merge_aggressiveness, new_aggressive, lsm_tree->merge_min, - msec_since_last_merge, lsm_tree->chunk_fill_ms)); + msec_since_last_merge, lsm_tree->chunk_fill_ms); lsm_tree->merge_aggressiveness = new_aggressive; } return (0); @@ -329,7 +330,7 @@ retry_find: return (WT_NOTFOUND); } - WT_RET(__lsm_merge_aggressive_clear(lsm_tree)); + __lsm_merge_aggressive_clear(lsm_tree); *records = record_count; *start = start_chunk; *end = end_chunk; @@ -372,7 +373,7 @@ __wt_lsm_merge(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, u_int id) * avoid holding it while the merge is in progress: that may take a * long time. */ - WT_RET(__wt_lsm_tree_writelock(session, lsm_tree)); + __wt_lsm_tree_writelock(session, lsm_tree); locked = true; WT_ERR(__lsm_merge_span(session, @@ -387,7 +388,7 @@ __wt_lsm_merge(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, u_int id) generation = WT_MAX(generation, lsm_tree->chunk[start_chunk + i]->generation + 1); - WT_ERR(__wt_lsm_tree_writeunlock(session, lsm_tree)); + __wt_lsm_tree_writeunlock(session, lsm_tree); locked = false; /* Allocate an ID for the merge. */ @@ -399,20 +400,20 @@ __wt_lsm_merge(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, u_int id) * in the normal path. */ if (WT_VERBOSE_ISSET(session, WT_VERB_LSM)) { - WT_ERR(__wt_verbose(session, WT_VERB_LSM, + __wt_verbose(session, WT_VERB_LSM, "Merging %s chunks %u-%u into %u (%" PRIu64 " records)" ", generation %" PRIu32, lsm_tree->name, - start_chunk, end_chunk, dest_id, record_count, generation)); - for (verb = start_chunk; verb <= end_chunk; verb++) - WT_ERR(__wt_verbose(session, WT_VERB_LSM, + start_chunk, end_chunk, dest_id, record_count, generation); + for (verb = start_chunk; verb < end_chunk + 1; verb++) + __wt_verbose(session, WT_VERB_LSM, "Merging %s: Chunk[%u] id %" PRIu32 ", gen: %" PRIu32 ", size: %" PRIu64 ", records: %" PRIu64, lsm_tree->name, verb, lsm_tree->chunk[verb]->id, lsm_tree->chunk[verb]->generation, lsm_tree->chunk[verb]->size, - lsm_tree->chunk[verb]->count)); + lsm_tree->chunk[verb]->count); } WT_ERR(__wt_calloc_one(session, &chunk)); @@ -471,16 +472,16 @@ __wt_lsm_merge(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, u_int id) dest->set_value(dest, &value); WT_ERR(dest->insert(dest)); if (create_bloom) - WT_ERR(__wt_bloom_insert(bloom, &key)); + __wt_bloom_insert(bloom, &key); } WT_ERR_NOTFOUND_OK(ret); WT_STAT_FAST_CONN_INCRV(session, lsm_rows_merged, insert_count % LSM_MERGE_CHECK_INTERVAL); ++lsm_tree->merge_progressing; - WT_ERR(__wt_verbose(session, WT_VERB_LSM, + __wt_verbose(session, WT_VERB_LSM, "Bloom size for %" PRIu64 " has %" PRIu64 " items inserted", - record_count, insert_count)); + record_count, insert_count); /* * Closing and syncing the files can take a while. Set the @@ -543,7 +544,7 @@ __wt_lsm_merge(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, u_int id) WT_ERR_NOTFOUND_OK(ret); WT_ERR(__wt_lsm_tree_set_chunk_size(session, chunk)); - WT_ERR(__wt_lsm_tree_writelock(session, lsm_tree)); + __wt_lsm_tree_writelock(session, lsm_tree); locked = true; /* @@ -592,7 +593,7 @@ __wt_lsm_merge(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, u_int id) session, WT_LSM_WORK_DROP, 0, lsm_tree)); err: if (locked) - WT_TRET(__wt_lsm_tree_writeunlock(session, lsm_tree)); + __wt_lsm_tree_writeunlock(session, lsm_tree); if (in_sync) (void)__wt_atomic_sub32(&lsm_tree->merge_syncing, 1); if (src != NULL) @@ -620,12 +621,12 @@ err: if (locked) __wt_free(session, chunk); if (ret == EINTR) - WT_TRET(__wt_verbose(session, WT_VERB_LSM, - "Merge aborted due to close")); + __wt_verbose(session, WT_VERB_LSM, + "Merge aborted due to close"); else - WT_TRET(__wt_verbose(session, WT_VERB_LSM, + __wt_verbose(session, WT_VERB_LSM, "Merge failed with %s", - __wt_strerror(session, ret, NULL, 0))); + __wt_strerror(session, ret, NULL, 0)); } F_CLR(session, WT_SESSION_NO_CACHE | WT_SESSION_NO_EVICTION); return (ret); diff --git a/src/third_party/wiredtiger/src/lsm/lsm_meta.c b/src/third_party/wiredtiger/src/lsm/lsm_meta.c index 7e100cb855c..ec52af96231 100644 --- a/src/third_party/wiredtiger/src/lsm/lsm_meta.c +++ b/src/third_party/wiredtiger/src/lsm/lsm_meta.c @@ -28,15 +28,15 @@ __lsm_meta_read_v0( if (F_ISSET(S2C(session), WT_CONN_LSM_MERGE)) F_SET(lsm_tree, WT_LSM_TREE_MERGES); - WT_ERR(__wt_config_init(session, &cparser, lsmconf)); + __wt_config_init(session, &cparser, lsmconf); while ((ret = __wt_config_next(&cparser, &ck, &cv)) == 0) { if (WT_STRING_MATCH("key_format", ck.str, ck.len)) { __wt_free(session, lsm_tree->key_format); - WT_ERR(__wt_strndup(session, + WT_RET(__wt_strndup(session, cv.str, cv.len, &lsm_tree->key_format)); } else if (WT_STRING_MATCH("value_format", ck.str, ck.len)) { __wt_free(session, lsm_tree->value_format); - WT_ERR(__wt_strndup(session, + WT_RET(__wt_strndup(session, cv.str, cv.len, &lsm_tree->value_format)); } else if (WT_STRING_MATCH("collator", ck.str, ck.len)) { if (cv.len == 0 || @@ -46,25 +46,25 @@ __lsm_meta_read_v0( * Extract the application-supplied metadata (if any) * from the file configuration. */ - WT_ERR(__wt_config_getones( + WT_RET(__wt_config_getones( session, lsmconf, "file_config", &fileconf)); WT_CLEAR(metadata); - WT_ERR_NOTFOUND_OK(__wt_config_subgets( + WT_RET_NOTFOUND_OK(__wt_config_subgets( session, &fileconf, "app_metadata", &metadata)); - WT_ERR(__wt_collator_config(session, lsm_tree->name, + WT_RET(__wt_collator_config(session, lsm_tree->name, &cv, &metadata, &lsm_tree->collator, &lsm_tree->collator_owned)); - WT_ERR(__wt_strndup(session, + WT_RET(__wt_strndup(session, cv.str, cv.len, &lsm_tree->collator_name)); } else if (WT_STRING_MATCH("bloom_config", ck.str, ck.len)) { __wt_free(session, lsm_tree->bloom_config); /* Don't include the brackets. */ - WT_ERR(__wt_strndup(session, + WT_RET(__wt_strndup(session, cv.str + 1, cv.len - 2, &lsm_tree->bloom_config)); } else if (WT_STRING_MATCH("file_config", ck.str, ck.len)) { __wt_free(session, lsm_tree->file_config); /* Don't include the brackets. */ - WT_ERR(__wt_strndup(session, + WT_RET(__wt_strndup(session, cv.str + 1, cv.len - 2, &lsm_tree->file_config)); } else if (WT_STRING_MATCH("auto_throttle", ck.str, ck.len)) { if (cv.val) @@ -92,25 +92,25 @@ __lsm_meta_read_v0( else if (WT_STRING_MATCH("last", ck.str, ck.len)) lsm_tree->last = (u_int)cv.val; else if (WT_STRING_MATCH("chunks", ck.str, ck.len)) { - WT_ERR(__wt_config_subinit(session, &lparser, &cv)); + __wt_config_subinit(session, &lparser, &cv); for (nchunks = 0; (ret = __wt_config_next(&lparser, &lk, &lv)) == 0; ) { if (WT_STRING_MATCH("id", lk.str, lk.len)) { - WT_ERR(__wt_realloc_def(session, + WT_RET(__wt_realloc_def(session, &lsm_tree->chunk_alloc, nchunks + 1, &lsm_tree->chunk)); - WT_ERR( + WT_RET( __wt_calloc_one(session, &chunk)); lsm_tree->chunk[nchunks++] = chunk; chunk->id = (uint32_t)lv.val; - WT_ERR(__wt_lsm_tree_chunk_name(session, + WT_RET(__wt_lsm_tree_chunk_name(session, lsm_tree, chunk->id, &chunk->uri)); F_SET(chunk, WT_LSM_CHUNK_ONDISK | WT_LSM_CHUNK_STABLE); } else if (WT_STRING_MATCH( "bloom", lk.str, lk.len)) { - WT_ERR(__wt_lsm_tree_bloom_name( + WT_RET(__wt_lsm_tree_bloom_name( session, lsm_tree, chunk->id, &chunk->bloom_uri)); F_SET(chunk, WT_LSM_CHUNK_BLOOM); @@ -129,28 +129,28 @@ __lsm_meta_read_v0( continue; } } - WT_ERR_NOTFOUND_OK(ret); + WT_RET_NOTFOUND_OK(ret); lsm_tree->nchunks = nchunks; } else if (WT_STRING_MATCH("old_chunks", ck.str, ck.len)) { - WT_ERR(__wt_config_subinit(session, &lparser, &cv)); + __wt_config_subinit(session, &lparser, &cv); for (nchunks = 0; (ret = __wt_config_next(&lparser, &lk, &lv)) == 0; ) { if (WT_STRING_MATCH("bloom", lk.str, lk.len)) { - WT_ERR(__wt_strndup(session, + WT_RET(__wt_strndup(session, lv.str, lv.len, &chunk->bloom_uri)); F_SET(chunk, WT_LSM_CHUNK_BLOOM); continue; } - WT_ERR(__wt_realloc_def(session, + WT_RET(__wt_realloc_def(session, &lsm_tree->old_alloc, nchunks + 1, &lsm_tree->old_chunks)); - WT_ERR(__wt_calloc_one(session, &chunk)); + WT_RET(__wt_calloc_one(session, &chunk)); lsm_tree->old_chunks[nchunks++] = chunk; - WT_ERR(__wt_strndup(session, + WT_RET(__wt_strndup(session, lk.str, lk.len, &chunk->uri)); F_SET(chunk, WT_LSM_CHUNK_ONDISK); } - WT_ERR_NOTFOUND_OK(ret); + WT_RET_NOTFOUND_OK(ret); lsm_tree->nold_chunks = nchunks; } /* @@ -158,8 +158,8 @@ __lsm_meta_read_v0( * created by a future release, with unknown options. */ } - WT_ERR_NOTFOUND_OK(ret); -err: return (ret); + WT_RET_NOTFOUND_OK(ret); + return (0); } /* @@ -264,7 +264,7 @@ __lsm_meta_read_v1( WT_ERR(__wt_config_getones(session, lsmconf, "last", &cv)); lsm_tree->last = (u_int)cv.val; WT_ERR(__wt_config_getones(session, lsmconf, "chunks", &cv)); - WT_ERR(__wt_config_subinit(session, &lparser, &cv)); + __wt_config_subinit(session, &lparser, &cv); for (nchunks = 0; (ret = __wt_config_next(&lparser, &lk, &lv)) == 0; ) { if (WT_STRING_MATCH("id", lk.str, lk.len)) { @@ -299,7 +299,7 @@ __lsm_meta_read_v1( lsm_tree->nchunks = nchunks; WT_ERR(__wt_config_getones(session, lsmconf, "old_chunks", &cv)); - WT_ERR(__wt_config_subinit(session, &lparser, &cv)); + __wt_config_subinit(session, &lparser, &cv); for (nchunks = 0; (ret = __wt_config_next(&lparser, &lk, &lv)) == 0; ) { if (WT_STRING_MATCH("bloom", lk.str, lk.len)) { @@ -404,6 +404,7 @@ __lsm_meta_upgrade_v1(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) err: __wt_scr_free(session, &buf); return (ret); } + /* * __wt_lsm_meta_read -- * Read the metadata for an LSM tree. diff --git a/src/third_party/wiredtiger/src/lsm/lsm_stat.c b/src/third_party/wiredtiger/src/lsm/lsm_stat.c index 76e2ca6185e..95909ce30e8 100644 --- a/src/third_party/wiredtiger/src/lsm/lsm_stat.c +++ b/src/third_party/wiredtiger/src/lsm/lsm_stat.c @@ -51,7 +51,7 @@ __curstat_lsm_init( } /* Hold the LSM lock so that we can safely walk through the chunks. */ - WT_ERR(__wt_lsm_tree_readlock(session, lsm_tree)); + __wt_lsm_tree_readlock(session, lsm_tree); locked = true; /* @@ -155,7 +155,7 @@ __curstat_lsm_init( __wt_curstat_dsrc_final(cst); err: if (locked) - WT_TRET(__wt_lsm_tree_readunlock(session, lsm_tree)); + __wt_lsm_tree_readunlock(session, lsm_tree); __wt_lsm_tree_release(session, lsm_tree); __wt_scr_free(session, &uribuf); diff --git a/src/third_party/wiredtiger/src/lsm/lsm_tree.c b/src/third_party/wiredtiger/src/lsm/lsm_tree.c index da106ae2089..db9fd581110 100644 --- a/src/third_party/wiredtiger/src/lsm/lsm_tree.c +++ b/src/third_party/wiredtiger/src/lsm/lsm_tree.c @@ -55,7 +55,7 @@ __lsm_tree_discard(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, bool final) __wt_free(session, lsm_tree->bloom_config); __wt_free(session, lsm_tree->file_config); - WT_TRET(__wt_rwlock_destroy(session, &lsm_tree->rwlock)); + __wt_rwlock_destroy(session, &lsm_tree->rwlock); for (i = 0; i < lsm_tree->nchunks; i++) { if ((chunk = lsm_tree->chunk[i]) == NULL) @@ -85,10 +85,9 @@ __lsm_tree_discard(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, bool final) * __lsm_tree_close -- * Close an LSM tree structure. */ -static int +static void __lsm_tree_close(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, bool final) { - WT_DECL_RET; int i; /* @@ -97,7 +96,7 @@ __lsm_tree_close(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, bool final) * the tree queue state. */ lsm_tree->active = false; - WT_READ_BARRIER(); + WT_FULL_BARRIER(); /* * Wait for all LSM operations to drain. If WiredTiger is shutting @@ -120,17 +119,11 @@ __lsm_tree_close(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree, bool final) * other schema level operations will return EBUSY, even though * we're dropping the schema lock here. */ - if (i % WT_THOUSAND == 0) { - WT_WITHOUT_LOCKS(session, ret = + if (i % WT_THOUSAND == 0) + WT_WITHOUT_LOCKS(session, __wt_lsm_manager_clear_tree(session, lsm_tree)); - WT_ERR(ret); - } __wt_yield(); } - return (0); - -err: lsm_tree->active = true; - return (ret); } /* @@ -154,7 +147,7 @@ __wt_lsm_tree_close_all(WT_SESSION_IMPL *session) * is unconditional. */ (void)__wt_atomic_add32(&lsm_tree->refcnt, 1); - WT_TRET(__lsm_tree_close(session, lsm_tree, true)); + __lsm_tree_close(session, lsm_tree, true); WT_TRET(__lsm_tree_discard(session, lsm_tree, true)); } @@ -390,9 +383,8 @@ __lsm_tree_find(WT_SESSION_IMPL *session, * spurious busy returns. */ (void)__wt_atomic_add32(&lsm_tree->refcnt, 1); - if (__lsm_tree_close( - session, lsm_tree, false) != 0 || - lsm_tree->refcnt != 1) { + __lsm_tree_close(session, lsm_tree, false); + if (lsm_tree->refcnt != 1) { __wt_lsm_tree_release( session, lsm_tree); return (EBUSY); @@ -730,7 +722,7 @@ __wt_lsm_tree_switch(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) uint32_t chunks_moved, nchunks, new_id; bool first_switch; - WT_RET(__wt_lsm_tree_writelock(session, lsm_tree)); + __wt_lsm_tree_writelock(session, lsm_tree); nchunks = lsm_tree->nchunks; @@ -755,10 +747,10 @@ __wt_lsm_tree_switch(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) WT_ERR(__wt_realloc_def(session, &lsm_tree->chunk_alloc, nchunks + 1, &lsm_tree->chunk)); - WT_ERR(__wt_verbose(session, WT_VERB_LSM, + __wt_verbose(session, WT_VERB_LSM, "Tree %s switch to: %" PRIu32 ", checkpoint throttle %" PRIu64 ", merge throttle %" PRIu64, lsm_tree->name, - new_id, lsm_tree->ckpt_throttle, lsm_tree->merge_throttle)); + new_id, lsm_tree->ckpt_throttle, lsm_tree->merge_throttle); WT_ERR(__wt_calloc_one(session, &chunk)); chunk->id = new_id; @@ -771,6 +763,11 @@ __wt_lsm_tree_switch(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) ++lsm_tree->dsk_gen; lsm_tree->modified = true; + /* + * Ensure the updated disk generation is visible to all other threads + * before updating the transaction ID. + */ + WT_FULL_BARRIER(); /* * Set the switch transaction in the previous chunk unless this is @@ -806,7 +803,7 @@ __wt_lsm_tree_switch(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) session, WT_LSM_WORK_DROP, 0, lsm_tree)); } -err: WT_TRET(__wt_lsm_tree_writeunlock(session, lsm_tree)); +err: __wt_lsm_tree_writeunlock(session, lsm_tree); /* * Errors that happen during a tree switch leave the tree in a state * where we can't make progress. Error out of WiredTiger. @@ -869,7 +866,7 @@ __wt_lsm_tree_drop( WT_ASSERT(session, !lsm_tree->active); /* Prevent any new opens. */ - WT_ERR(__wt_lsm_tree_writelock(session, lsm_tree)); + __wt_lsm_tree_writelock(session, lsm_tree); locked = true; /* Drop the chunks. */ @@ -892,12 +889,12 @@ __wt_lsm_tree_drop( } locked = false; - WT_ERR(__wt_lsm_tree_writeunlock(session, lsm_tree)); + __wt_lsm_tree_writeunlock(session, lsm_tree); ret = __wt_metadata_remove(session, name); WT_ASSERT(session, !lsm_tree->active); err: if (locked) - WT_TRET(__wt_lsm_tree_writeunlock(session, lsm_tree)); + __wt_lsm_tree_writeunlock(session, lsm_tree); WT_WITH_HANDLE_LIST_LOCK(session, tret = __lsm_tree_discard(session, lsm_tree, false)); WT_TRET(tret); @@ -929,7 +926,7 @@ __wt_lsm_tree_rename(WT_SESSION_IMPL *session, WT_RET(ret); /* Prevent any new opens. */ - WT_ERR(__wt_lsm_tree_writelock(session, lsm_tree)); + __wt_lsm_tree_writelock(session, lsm_tree); locked = true; /* Set the new name. */ @@ -960,11 +957,11 @@ __wt_lsm_tree_rename(WT_SESSION_IMPL *session, WT_ERR(__wt_lsm_meta_write(session, lsm_tree)); locked = false; - WT_ERR(__wt_lsm_tree_writeunlock(session, lsm_tree)); + __wt_lsm_tree_writeunlock(session, lsm_tree); WT_ERR(__wt_metadata_remove(session, olduri)); err: if (locked) - WT_TRET(__wt_lsm_tree_writeunlock(session, lsm_tree)); + __wt_lsm_tree_writeunlock(session, lsm_tree); __wt_free(session, old); /* @@ -1001,7 +998,7 @@ __wt_lsm_tree_truncate( WT_RET(ret); /* Prevent any new opens. */ - WT_ERR(__wt_lsm_tree_writelock(session, lsm_tree)); + __wt_lsm_tree_writelock(session, lsm_tree); locked = true; /* Create the new chunk. */ @@ -1016,14 +1013,14 @@ __wt_lsm_tree_truncate( WT_ERR(__wt_lsm_meta_write(session, lsm_tree)); locked = false; - WT_ERR(__wt_lsm_tree_writeunlock(session, lsm_tree)); + __wt_lsm_tree_writeunlock(session, lsm_tree); __wt_lsm_tree_release(session, lsm_tree); err: if (locked) - WT_TRET(__wt_lsm_tree_writeunlock(session, lsm_tree)); + __wt_lsm_tree_writeunlock(session, lsm_tree); if (ret != 0) { if (chunk != NULL) { - (void)__wt_schema_drop(session, chunk->uri, NULL); + WT_TRET(__wt_schema_drop(session, chunk->uri, NULL)); __wt_free(session, chunk); } /* @@ -1043,66 +1040,56 @@ err: if (locked) * __wt_lsm_tree_readlock -- * Acquire a shared lock on an LSM tree. */ -int +void __wt_lsm_tree_readlock(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) { - WT_RET(__wt_readlock(session, lsm_tree->rwlock)); + __wt_readlock(session, lsm_tree->rwlock); /* * Diagnostic: avoid deadlocks with the schema lock: if we need it for * an operation, we should already have it. */ F_SET(session, WT_SESSION_NO_EVICTION | WT_SESSION_NO_SCHEMA_LOCK); - return (0); } /* * __wt_lsm_tree_readunlock -- * Release a shared lock on an LSM tree. */ -int +void __wt_lsm_tree_readunlock(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) { - WT_DECL_RET; - F_CLR(session, WT_SESSION_NO_EVICTION | WT_SESSION_NO_SCHEMA_LOCK); - if ((ret = __wt_readunlock(session, lsm_tree->rwlock)) != 0) - WT_PANIC_RET(session, ret, "Unlocking an LSM tree"); - return (0); + __wt_readunlock(session, lsm_tree->rwlock); } /* * __wt_lsm_tree_writelock -- * Acquire an exclusive lock on an LSM tree. */ -int +void __wt_lsm_tree_writelock(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) { - WT_RET(__wt_writelock(session, lsm_tree->rwlock)); + __wt_writelock(session, lsm_tree->rwlock); /* * Diagnostic: avoid deadlocks with the schema lock: if we need it for * an operation, we should already have it. */ F_SET(session, WT_SESSION_NO_EVICTION | WT_SESSION_NO_SCHEMA_LOCK); - return (0); } /* * __wt_lsm_tree_writeunlock -- * Release an exclusive lock on an LSM tree. */ -int +void __wt_lsm_tree_writeunlock(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) { - WT_DECL_RET; - F_CLR(session, WT_SESSION_NO_EVICTION | WT_SESSION_NO_SCHEMA_LOCK); - if ((ret = __wt_writeunlock(session, lsm_tree->rwlock)) != 0) - WT_PANIC_RET(session, ret, "Unlocking an LSM tree"); - return (0); + __wt_writeunlock(session, lsm_tree->rwlock); } /* @@ -1168,7 +1155,7 @@ __wt_lsm_compact(WT_SESSION_IMPL *session, const char *name, bool *skipp) */ /* Lock the tree: single-thread compaction. */ - WT_ERR(__wt_lsm_tree_writelock(session, lsm_tree)); + __wt_lsm_tree_writelock(session, lsm_tree); locked = true; /* Clear any merge throttle: compact throws out that calculation. */ @@ -1187,8 +1174,15 @@ __wt_lsm_compact(WT_SESSION_IMPL *session, const char *name, bool *skipp) */ if (lsm_tree->nchunks > 0 && (chunk = lsm_tree->chunk[lsm_tree->nchunks - 1]) != NULL) { - if (chunk->switch_txn == WT_TXN_NONE) + if (chunk->switch_txn == WT_TXN_NONE) { + /* + * Make sure any cursors open on the tree see the + * new switch generation before updating. + */ + ++lsm_tree->dsk_gen; + WT_FULL_BARRIER(); chunk->switch_txn = __wt_txn_id_alloc(session, false); + } /* * If we have a chunk, we want to look for it to be on-disk. * So we need to add a reference to keep it available. @@ -1198,13 +1192,13 @@ __wt_lsm_compact(WT_SESSION_IMPL *session, const char *name, bool *skipp) } locked = false; - WT_ERR(__wt_lsm_tree_writeunlock(session, lsm_tree)); + __wt_lsm_tree_writeunlock(session, lsm_tree); if (chunk != NULL) { - WT_ERR(__wt_verbose(session, WT_VERB_LSM, + __wt_verbose(session, WT_VERB_LSM, "Compact force flush %s flags 0x%" PRIx32 " chunk %" PRIu32 " flags 0x%" PRIx32, - name, lsm_tree->flags, chunk->id, chunk->flags)); + name, lsm_tree->flags, chunk->id, chunk->flags); flushing = true; /* * Make sure the in-memory chunk gets flushed do not push a @@ -1221,8 +1215,8 @@ __wt_lsm_compact(WT_SESSION_IMPL *session, const char *name, bool *skipp) compacting = true; progress = lsm_tree->merge_progressing; F_SET(lsm_tree, WT_LSM_TREE_COMPACTING); - WT_ERR(__wt_verbose(session, WT_VERB_LSM, - "COMPACT: Start compacting %s", lsm_tree->name)); + __wt_verbose(session, WT_VERB_LSM, + "COMPACT: Start compacting %s", lsm_tree->name); } /* Wait for the work unit queues to drain. */ @@ -1235,21 +1229,21 @@ __wt_lsm_compact(WT_SESSION_IMPL *session, const char *name, bool *skipp) if (flushing) { WT_ASSERT(session, chunk != NULL); if (F_ISSET(chunk, WT_LSM_CHUNK_ONDISK)) { - WT_ERR(__wt_verbose(session, + __wt_verbose(session, WT_VERB_LSM, "Compact flush done %s chunk %" PRIu32 ". " "Start compacting progress %" PRIu64, name, chunk->id, - lsm_tree->merge_progressing)); + lsm_tree->merge_progressing); (void)__wt_atomic_sub32(&chunk->refcnt, 1); flushing = ref = false; compacting = true; F_SET(lsm_tree, WT_LSM_TREE_COMPACTING); progress = lsm_tree->merge_progressing; } else { - WT_ERR(__wt_verbose(session, WT_VERB_LSM, + __wt_verbose(session, WT_VERB_LSM, "Compact flush retry %s chunk %" PRIu32, - name, chunk->id)); + name, chunk->id); WT_ERR(__wt_lsm_manager_push_entry(session, WT_LSM_WORK_FLUSH, WT_LSM_WORK_FORCE, lsm_tree)); @@ -1301,10 +1295,10 @@ err: lsm_tree->merge_aggressiveness = 0; } if (locked) - WT_TRET(__wt_lsm_tree_writeunlock(session, lsm_tree)); + __wt_lsm_tree_writeunlock(session, lsm_tree); - WT_TRET(__wt_verbose(session, WT_VERB_LSM, - "Compact %s complete, return %d", name, ret)); + __wt_verbose(session, WT_VERB_LSM, + "Compact %s complete, return %d", name, ret); __wt_lsm_tree_release(session, lsm_tree); return (ret); @@ -1338,9 +1332,10 @@ __wt_lsm_tree_worker(WT_SESSION_IMPL *session, * with merges so that merging doesn't change the chunk * array out from underneath us. */ - WT_ERR(exclusive ? - __wt_lsm_tree_writelock(session, lsm_tree) : - __wt_lsm_tree_readlock(session, lsm_tree)); + if (exclusive) + __wt_lsm_tree_writelock(session, lsm_tree); + else + __wt_lsm_tree_readlock(session, lsm_tree); locked = true; for (i = 0; i < lsm_tree->nchunks; i++) { chunk = lsm_tree->chunk[i]; @@ -1359,10 +1354,12 @@ __wt_lsm_tree_worker(WT_SESSION_IMPL *session, WT_ERR(__wt_schema_worker(session, chunk->bloom_uri, file_func, name_func, cfg, open_flags)); } -err: if (locked) - WT_TRET(exclusive ? - __wt_lsm_tree_writeunlock(session, lsm_tree) : - __wt_lsm_tree_readunlock(session, lsm_tree)); +err: if (locked) { + if (exclusive) + __wt_lsm_tree_writeunlock(session, lsm_tree); + else + __wt_lsm_tree_readunlock(session, lsm_tree); + } __wt_lsm_tree_release(session, lsm_tree); return (ret); } diff --git a/src/third_party/wiredtiger/src/lsm/lsm_work_unit.c b/src/third_party/wiredtiger/src/lsm/lsm_work_unit.c index 0f2a407c70d..72bcf56b3c4 100644 --- a/src/third_party/wiredtiger/src/lsm/lsm_work_unit.c +++ b/src/third_party/wiredtiger/src/lsm/lsm_work_unit.c @@ -28,9 +28,11 @@ __lsm_copy_chunks(WT_SESSION_IMPL *session, /* Always return zero chunks on error. */ cookie->nchunks = 0; - WT_RET(__wt_lsm_tree_readlock(session, lsm_tree)); - if (!lsm_tree->active) - return (__wt_lsm_tree_readunlock(session, lsm_tree)); + __wt_lsm_tree_readlock(session, lsm_tree); + if (!lsm_tree->active) { + __wt_lsm_tree_readunlock(session, lsm_tree); + return (0); + } /* Take a copy of the current state of the LSM tree. */ nchunks = old_chunks ? lsm_tree->nold_chunks : lsm_tree->nchunks; @@ -55,7 +57,7 @@ __lsm_copy_chunks(WT_SESSION_IMPL *session, for (i = 0; i < nchunks; i++) (void)__wt_atomic_add32(&cookie->chunk_array[i]->refcnt, 1); -err: WT_TRET(__wt_lsm_tree_readunlock(session, lsm_tree)); +err: __wt_lsm_tree_readunlock(session, lsm_tree); if (ret == 0) cookie->nchunks = nchunks; @@ -78,9 +80,11 @@ __wt_lsm_get_chunk_to_flush(WT_SESSION_IMPL *session, chunk = evict_chunk = flush_chunk = NULL; WT_ASSERT(session, lsm_tree->queue_ref > 0); - WT_RET(__wt_lsm_tree_readlock(session, lsm_tree)); - if (!lsm_tree->active || lsm_tree->nchunks == 0) - return (__wt_lsm_tree_readunlock(session, lsm_tree)); + __wt_lsm_tree_readlock(session, lsm_tree); + if (!lsm_tree->active || lsm_tree->nchunks == 0) { + __wt_lsm_tree_readunlock(session, lsm_tree); + return (0); + } /* Search for a chunk to evict and/or a chunk to flush. */ for (i = 0; i < lsm_tree->nchunks; i++) { @@ -117,15 +121,15 @@ __wt_lsm_get_chunk_to_flush(WT_SESSION_IMPL *session, chunk = (evict_chunk != NULL) ? evict_chunk : flush_chunk; if (chunk != NULL) { - WT_ERR(__wt_verbose(session, WT_VERB_LSM, + __wt_verbose(session, WT_VERB_LSM, "Flush%s: return chunk %" PRIu32 " of %" PRIu32 ": %s", force ? " w/ force" : "", - i, lsm_tree->nchunks, chunk->uri)); + i, lsm_tree->nchunks, chunk->uri); (void)__wt_atomic_add32(&chunk->refcnt, 1); } -err: WT_RET(__wt_lsm_tree_readunlock(session, lsm_tree)); +err: __wt_lsm_tree_readunlock(session, lsm_tree); *chunkp = chunk; return (ret); @@ -282,9 +286,9 @@ __wt_lsm_checkpoint_chunk(WT_SESSION_IMPL *session, WT_RET_MSG(session, ret, "discard handle"); } if (F_ISSET(chunk, WT_LSM_CHUNK_ONDISK)) { - WT_RET(__wt_verbose(session, WT_VERB_LSM, + __wt_verbose(session, WT_VERB_LSM, "LSM worker %s already on disk", - chunk->uri)); + chunk->uri); return (0); } @@ -293,9 +297,9 @@ __wt_lsm_checkpoint_chunk(WT_SESSION_IMPL *session, session, WT_TXN_OLDEST_STRICT | WT_TXN_OLDEST_WAIT)); if (chunk->switch_txn == WT_TXN_NONE || !__wt_txn_visible_all(session, chunk->switch_txn)) { - WT_RET(__wt_verbose(session, WT_VERB_LSM, + __wt_verbose(session, WT_VERB_LSM, "LSM worker %s: running transaction, return", - chunk->uri)); + chunk->uri); return (0); } @@ -303,8 +307,8 @@ __wt_lsm_checkpoint_chunk(WT_SESSION_IMPL *session, return (0); flush_set = true; - WT_ERR(__wt_verbose(session, WT_VERB_LSM, "LSM worker flushing %s", - chunk->uri)); + __wt_verbose(session, WT_VERB_LSM, "LSM worker flushing %s", + chunk->uri); /* * Flush the file before checkpointing: this is the expensive part in @@ -329,8 +333,8 @@ __wt_lsm_checkpoint_chunk(WT_SESSION_IMPL *session, } WT_ERR(ret); - WT_ERR(__wt_verbose(session, WT_VERB_LSM, "LSM worker checkpointing %s", - chunk->uri)); + __wt_verbose(session, WT_VERB_LSM, "LSM worker checkpointing %s", + chunk->uri); /* * Turn on metadata tracking to ensure the checkpoint gets the @@ -358,14 +362,14 @@ __wt_lsm_checkpoint_chunk(WT_SESSION_IMPL *session, ++lsm_tree->chunks_flushed; /* Lock the tree, mark the chunk as on disk and update the metadata. */ - WT_ERR(__wt_lsm_tree_writelock(session, lsm_tree)); + __wt_lsm_tree_writelock(session, lsm_tree); F_SET(chunk, WT_LSM_CHUNK_ONDISK); ret = __wt_lsm_meta_write(session, lsm_tree); ++lsm_tree->dsk_gen; /* Update the throttle time. */ __wt_lsm_tree_throttle(session, lsm_tree, true); - WT_TRET(__wt_lsm_tree_writeunlock(session, lsm_tree)); + __wt_lsm_tree_writeunlock(session, lsm_tree); if (ret != 0) WT_ERR_MSG(session, ret, "LSM metadata write"); @@ -385,8 +389,8 @@ __wt_lsm_checkpoint_chunk(WT_SESSION_IMPL *session, /* Make sure we aren't pinning a transaction ID. */ __wt_txn_release_snapshot(session); - WT_ERR(__wt_verbose(session, WT_VERB_LSM, "LSM worker checkpointed %s", - chunk->uri)); + __wt_verbose(session, WT_VERB_LSM, "LSM worker checkpointed %s", + chunk->uri); /* Schedule a bloom filter create for our newly flushed chunk. */ if (!FLD_ISSET(lsm_tree->bloom, WT_LSM_BLOOM_OFF)) @@ -443,7 +447,7 @@ __lsm_bloom_create(WT_SESSION_IMPL *session, F_SET(session, WT_SESSION_NO_CACHE | WT_SESSION_NO_EVICTION); for (insert_count = 0; (ret = src->next(src)) == 0; insert_count++) { WT_ERR(src->get_key(src, &key)); - WT_ERR(__wt_bloom_insert(bloom, &key)); + __wt_bloom_insert(bloom, &key); } WT_ERR_NOTFOUND_OK(ret); WT_TRET(src->close(src)); @@ -457,17 +461,17 @@ __lsm_bloom_create(WT_SESSION_IMPL *session, WT_CLEAR(key); WT_ERR_NOTFOUND_OK(__wt_bloom_get(bloom, &key)); - WT_ERR(__wt_verbose(session, WT_VERB_LSM, + __wt_verbose(session, WT_VERB_LSM, "LSM worker created bloom filter %s. " "Expected %" PRIu64 " items, got %" PRIu64, - chunk->bloom_uri, chunk->count, insert_count)); + chunk->bloom_uri, chunk->count, insert_count); /* Ensure the bloom filter is in the metadata. */ - WT_ERR(__wt_lsm_tree_writelock(session, lsm_tree)); + __wt_lsm_tree_writelock(session, lsm_tree); F_SET(chunk, WT_LSM_CHUNK_BLOOM); ret = __wt_lsm_meta_write(session, lsm_tree); ++lsm_tree->dsk_gen; - WT_TRET(__wt_lsm_tree_writeunlock(session, lsm_tree)); + __wt_lsm_tree_writeunlock(session, lsm_tree); if (ret != 0) WT_ERR_MSG(session, ret, "LSM bloom worker metadata write"); @@ -527,11 +531,11 @@ __lsm_drop_file(WT_SESSION_IMPL *session, const char *uri) if (ret == 0) ret = __wt_fs_remove(session, uri + strlen("file:"), false); - WT_RET(__wt_verbose(session, WT_VERB_LSM, "Dropped %s", uri)); + __wt_verbose(session, WT_VERB_LSM, "Dropped %s", uri); if (ret == EBUSY || ret == ENOENT) - WT_RET(__wt_verbose(session, WT_VERB_LSM, - "LSM worker drop of %s failed with %d", uri, ret)); + __wt_verbose(session, WT_VERB_LSM, + "LSM worker drop of %s failed with %d", uri, ret); return (ret); } @@ -623,7 +627,7 @@ __wt_lsm_free_chunks(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) } /* Lock the tree to clear out the old chunk information. */ - WT_ERR(__wt_lsm_tree_writelock(session, lsm_tree)); + __wt_lsm_tree_writelock(session, lsm_tree); /* * The chunk we are looking at should be the first one in the @@ -643,7 +647,7 @@ __wt_lsm_free_chunks(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) lsm_tree->old_chunks[lsm_tree->nold_chunks] = NULL; } - WT_ERR(__wt_lsm_tree_writeunlock(session, lsm_tree)); + __wt_lsm_tree_writeunlock(session, lsm_tree); /* * Clear the chunk in the cookie so we don't attempt to @@ -654,9 +658,9 @@ __wt_lsm_free_chunks(WT_SESSION_IMPL *session, WT_LSM_TREE *lsm_tree) err: /* Flush the metadata unless the system is in panic */ if (flush_metadata && ret != WT_PANIC) { - WT_TRET(__wt_lsm_tree_writelock(session, lsm_tree)); + __wt_lsm_tree_writelock(session, lsm_tree); WT_TRET(__wt_lsm_meta_write(session, lsm_tree)); - WT_TRET(__wt_lsm_tree_writeunlock(session, lsm_tree)); + __wt_lsm_tree_writeunlock(session, lsm_tree); } __lsm_unpin_chunks(session, &cookie); __wt_free(session, cookie.chunk_array); diff --git a/src/third_party/wiredtiger/src/lsm/lsm_worker.c b/src/third_party/wiredtiger/src/lsm/lsm_worker.c index 0874da8db13..b0d0758775d 100644 --- a/src/third_party/wiredtiger/src/lsm/lsm_worker.c +++ b/src/third_party/wiredtiger/src/lsm/lsm_worker.c @@ -19,8 +19,8 @@ static WT_THREAD_RET __lsm_worker(void *); int __wt_lsm_worker_start(WT_SESSION_IMPL *session, WT_LSM_WORKER_ARGS *args) { - WT_RET(__wt_verbose(session, WT_VERB_LSM_MANAGER, - "Start LSM worker %u type %#" PRIx32, args->id, args->type)); + __wt_verbose(session, WT_VERB_LSM_MANAGER, + "Start LSM worker %u type %#" PRIx32, args->id, args->type); return (__wt_thread_create(session, &args->tid, __lsm_worker, args)); } @@ -58,9 +58,9 @@ __lsm_worker_general_op( * If we got a chunk to flush, checkpoint it. */ if (chunk != NULL) { - WT_ERR(__wt_verbose(session, WT_VERB_LSM, + __wt_verbose(session, WT_VERB_LSM, "Flush%s chunk %" PRIu32 " %s", - force ? " w/ force" : "", chunk->id, chunk->uri)); + force ? " w/ force" : "", chunk->id, chunk->uri); ret = __wt_lsm_checkpoint_chunk( session, entry->lsm_tree, chunk); WT_ASSERT(session, chunk->refcnt > 0); @@ -154,8 +154,7 @@ __lsm_worker(void *arg) /* Don't busy wait if there was any work to do. */ if (!progress) { - WT_ERR( - __wt_cond_wait(session, cookie->work_cond, 10000)); + __wt_cond_wait(session, cookie->work_cond, 10000); continue; } } diff --git a/src/third_party/wiredtiger/src/meta/meta_ckpt.c b/src/third_party/wiredtiger/src/meta/meta_ckpt.c index 0a864432daf..2b7719c3241 100644 --- a/src/third_party/wiredtiger/src/meta/meta_ckpt.c +++ b/src/third_party/wiredtiger/src/meta/meta_ckpt.c @@ -139,7 +139,7 @@ __ckpt_named(WT_SESSION_IMPL *session, WT_CONFIG_ITEM k, v; WT_RET(__wt_config_getones(session, config, "checkpoint", &v)); - WT_RET(__wt_config_subinit(session, &ckptconf, &v)); + __wt_config_subinit(session, &ckptconf, &v); /* * Take the first match: there should never be more than a single @@ -164,7 +164,7 @@ __ckpt_last(WT_SESSION_IMPL *session, const char *config, WT_CKPT *ckpt) int64_t found; WT_RET(__wt_config_getones(session, config, "checkpoint", &v)); - WT_RET(__wt_config_subinit(session, &ckptconf, &v)); + __wt_config_subinit(session, &ckptconf, &v); for (found = 0; __wt_config_next(&ckptconf, &k, &v) == 0;) { /* Ignore checkpoints before the ones we've already seen. */ WT_RET(__wt_config_subgets(session, &v, "order", &a)); @@ -196,7 +196,7 @@ __ckpt_last_name( *namep = NULL; WT_ERR(__wt_config_getones(session, config, "checkpoint", &v)); - WT_ERR(__wt_config_subinit(session, &ckptconf, &v)); + __wt_config_subinit(session, &ckptconf, &v); for (found = 0; __wt_config_next(&ckptconf, &k, &v) == 0;) { /* * We only care about unnamed checkpoints; applications may not @@ -267,8 +267,8 @@ __wt_meta_ckptlist_get( /* Load any existing checkpoints into the array. */ WT_ERR(__wt_scr_alloc(session, 0, &buf)); - if (__wt_config_getones(session, config, "checkpoint", &v) == 0 && - __wt_config_subinit(session, &ckptconf, &v) == 0) + if (__wt_config_getones(session, config, "checkpoint", &v) == 0) { + __wt_config_subinit(session, &ckptconf, &v); for (; __wt_config_next(&ckptconf, &k, &v) == 0; ++slot) { WT_ERR(__wt_realloc_def( session, &allocated, slot + 1, &ckptbase)); @@ -276,6 +276,7 @@ __wt_meta_ckptlist_get( WT_ERR(__ckpt_load(session, &k, &v, ckpt)); } + } /* * Allocate an extra slot for a new value, plus a slot to mark the end. diff --git a/src/third_party/wiredtiger/src/meta/meta_table.c b/src/third_party/wiredtiger/src/meta/meta_table.c index 38a2edd7219..58842c756d1 100644 --- a/src/third_party/wiredtiger/src/meta/meta_table.c +++ b/src/third_party/wiredtiger/src/meta/meta_table.c @@ -68,6 +68,9 @@ __wt_metadata_cursor_open( if (F_ISSET(btree, WT_BTREE_NO_LOGGING)) F_CLR(btree, WT_BTREE_NO_LOGGING); + /* The metadata file always uses checkpoint IDs in visibility checks. */ + btree->include_checkpoint_txn = true; + return (0); } @@ -156,10 +159,10 @@ __wt_metadata_insert( WT_CURSOR *cursor; WT_DECL_RET; - WT_RET(__wt_verbose(session, WT_VERB_METADATA, + __wt_verbose(session, WT_VERB_METADATA, "Insert: key: %s, value: %s, tracking: %s, %s" "turtle", key, value, WT_META_TRACKING(session) ? "true" : "false", - __metadata_turtle(key) ? "" : "not ")); + __metadata_turtle(key) ? "" : "not "); if (__metadata_turtle(key)) WT_RET_MSG(session, EINVAL, @@ -186,10 +189,10 @@ __wt_metadata_update( WT_CURSOR *cursor; WT_DECL_RET; - WT_RET(__wt_verbose(session, WT_VERB_METADATA, + __wt_verbose(session, WT_VERB_METADATA, "Update: key: %s, value: %s, tracking: %s, %s" "turtle", key, value, WT_META_TRACKING(session) ? "true" : "false", - __metadata_turtle(key) ? "" : "not ")); + __metadata_turtle(key) ? "" : "not "); if (__metadata_turtle(key)) { WT_WITH_TURTLE_LOCK(session, ret, @@ -221,10 +224,10 @@ __wt_metadata_remove(WT_SESSION_IMPL *session, const char *key) WT_CURSOR *cursor; WT_DECL_RET; - WT_RET(__wt_verbose(session, WT_VERB_METADATA, + __wt_verbose(session, WT_VERB_METADATA, "Remove: key: %s, tracking: %s, %s" "turtle", key, WT_META_TRACKING(session) ? "true" : "false", - __metadata_turtle(key) ? "" : "not ")); + __metadata_turtle(key) ? "" : "not "); if (__metadata_turtle(key)) WT_RET_MSG(session, EINVAL, @@ -254,10 +257,10 @@ __wt_metadata_search(WT_SESSION_IMPL *session, const char *key, char **valuep) *valuep = NULL; - WT_RET(__wt_verbose(session, WT_VERB_METADATA, + __wt_verbose(session, WT_VERB_METADATA, "Search: key: %s, tracking: %s, %s" "turtle", key, WT_META_TRACKING(session) ? "true" : "false", - __metadata_turtle(key) ? "" : "not ")); + __metadata_turtle(key) ? "" : "not "); if (__metadata_turtle(key)) return (__wt_turtle_read(session, key, valuep)); diff --git a/src/third_party/wiredtiger/src/meta/meta_track.c b/src/third_party/wiredtiger/src/meta/meta_track.c index 3d8b7c46500..9655a0b26a7 100644 --- a/src/third_party/wiredtiger/src/meta/meta_track.c +++ b/src/third_party/wiredtiger/src/meta/meta_track.c @@ -310,12 +310,11 @@ done: /* Apply any tracked operations post-commit. */ * Start a group of operations that can be committed independent of the * main transaction. */ -int +void __wt_meta_track_sub_on(WT_SESSION_IMPL *session) { WT_ASSERT(session, session->meta_track_sub == NULL); session->meta_track_sub = session->meta_track_next; - return (0); } /* diff --git a/src/third_party/wiredtiger/src/os_common/os_fhandle.c b/src/third_party/wiredtiger/src/os_common/os_fhandle.c index 184a9df0e72..3fd5b5db773 100644 --- a/src/third_party/wiredtiger/src/os_common/os_fhandle.c +++ b/src/third_party/wiredtiger/src/os_common/os_fhandle.c @@ -24,23 +24,22 @@ __fhandle_method_finalize( "a WT_FILE_HANDLE.%s method must be configured", #name) WT_HANDLE_METHOD_REQ(close); - /* not required: fadvise */ - /* not required: fallocate */ - /* not required: fallocate_nolock */ + /* not required: fh_advise */ + /* not required: fh_extend */ + /* not required: fh_extend_nolock */ WT_HANDLE_METHOD_REQ(fh_lock); - /* not required: map */ - /* not required: map_discard */ - /* not required: map_preload */ - /* not required: map_unmap */ + /* not required: fh_map */ + /* not required: fh_map_discard */ + /* not required: fh_map_preload */ + /* not required: fh_unmap */ WT_HANDLE_METHOD_REQ(fh_read); WT_HANDLE_METHOD_REQ(fh_size); if (!readonly) WT_HANDLE_METHOD_REQ(fh_sync); - /* not required: sync_nowait */ - if (!readonly) { - WT_HANDLE_METHOD_REQ(fh_truncate); + /* not required: fh_sync_nowait */ + /* not required: fh_truncate */ + if (!readonly) WT_HANDLE_METHOD_REQ(fh_write); - } return (0); } @@ -188,7 +187,7 @@ __open_verbose( if (tmp->size != 0) WT_ERR(__wt_buf_catfmt(session, tmp, ")")); - ret = __wt_verbose(session, WT_VERB_FILEOPS, + __wt_verbose(session, WT_VERB_FILEOPS, "%s: file-open: type %s%s", name, file_type_tag, tmp->size == 0 ? "" : (char *)tmp->data); @@ -301,8 +300,7 @@ __wt_close(WT_SESSION_IMPL *session, WT_FH **fhp) *fhp = NULL; /* Track handle-close as a file operation, so open and close match. */ - WT_RET(__wt_verbose( - session, WT_VERB_FILEOPS, "%s: file-close", fh->name)); + __wt_verbose(session, WT_VERB_FILEOPS, "%s: file-close", fh->name); /* * If the reference count hasn't gone to 0, or if it's an in-memory diff --git a/src/third_party/wiredtiger/src/os_common/os_fs_inmemory.c b/src/third_party/wiredtiger/src/os_common/os_fs_inmemory.c index 178adc1dac8..70a82007300 100644 --- a/src/third_party/wiredtiger/src/os_common/os_fs_inmemory.c +++ b/src/third_party/wiredtiger/src/os_common/os_fs_inmemory.c @@ -390,41 +390,6 @@ __im_file_sync(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session) return (0); } -/* - * __im_file_truncate -- - * POSIX ftruncate. - */ -static int -__im_file_truncate( - WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, wt_off_t offset) -{ - WT_DECL_RET; - WT_FILE_HANDLE_INMEM *im_fh; - WT_FILE_SYSTEM_INMEM *im_fs; - WT_SESSION_IMPL *session; - size_t off; - - im_fh = (WT_FILE_HANDLE_INMEM *)file_handle; - im_fs = (WT_FILE_SYSTEM_INMEM *)file_handle->file_system; - session = (WT_SESSION_IMPL *)wt_session; - - __wt_spin_lock(session, &im_fs->lock); - - /* - * Grow the buffer as necessary, clear any new space in the file, and - * reset the file's data length. - */ - off = (size_t)offset; - WT_ERR(__wt_buf_grow(session, &im_fh->buf, off)); - if (im_fh->buf.size < off) - memset((uint8_t *)im_fh->buf.data + im_fh->buf.size, - 0, off - im_fh->buf.size); - im_fh->buf.size = off; - -err: __wt_spin_unlock(session, &im_fs->lock); - return (ret); -} - /* * __im_file_write -- * POSIX pwrite. @@ -526,7 +491,6 @@ __im_file_open(WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session, file_handle->fh_read = __im_file_read; file_handle->fh_size = __im_file_size; file_handle->fh_sync = __im_file_sync; - file_handle->fh_truncate = __im_file_truncate; file_handle->fh_write = __im_file_write; *file_handlep = file_handle; diff --git a/src/third_party/wiredtiger/src/os_common/os_fstream_stdio.c b/src/third_party/wiredtiger/src/os_common/os_fstream_stdio.c index eea2c80ff0e..0cc75e109a1 100644 --- a/src/third_party/wiredtiger/src/os_common/os_fstream_stdio.c +++ b/src/third_party/wiredtiger/src/os_common/os_fstream_stdio.c @@ -74,11 +74,9 @@ __stdio_init(WT_FSTREAM *fs, const char *name, FILE *fp) * __wt_os_stdio -- * Initialize the stdio configuration. */ -int +void __wt_os_stdio(WT_SESSION_IMPL *session) { __stdio_init(WT_STDERR(session), "stderr", stderr); __stdio_init(WT_STDOUT(session), "stdout", stdout); - - return (0); } diff --git a/src/third_party/wiredtiger/src/os_posix/os_fallocate.c b/src/third_party/wiredtiger/src/os_posix/os_fallocate.c index 9e5d9519900..111f6558816 100644 --- a/src/third_party/wiredtiger/src/os_posix/os_fallocate.c +++ b/src/third_party/wiredtiger/src/os_posix/os_fallocate.c @@ -18,8 +18,8 @@ * Linux fallocate call. */ static int -__posix_std_fallocate(WT_FILE_HANDLE *file_handle, - WT_SESSION *wt_session, wt_off_t offset, wt_off_t len) +__posix_std_fallocate( + WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, wt_off_t offset) { #if defined(HAVE_FALLOCATE) WT_DECL_RET; @@ -29,13 +29,12 @@ __posix_std_fallocate(WT_FILE_HANDLE *file_handle, pfh = (WT_FILE_HANDLE_POSIX *)file_handle; - WT_SYSCALL_RETRY(fallocate(pfh->fd, 0, offset, len), ret); + WT_SYSCALL_RETRY(fallocate(pfh->fd, 0, (wt_off_t)0, offset), ret); return (ret); #else WT_UNUSED(file_handle); WT_UNUSED(wt_session); WT_UNUSED(offset); - WT_UNUSED(len); return (ENOTSUP); #endif } @@ -45,8 +44,8 @@ __posix_std_fallocate(WT_FILE_HANDLE *file_handle, * Linux fallocate call (system call version). */ static int -__posix_sys_fallocate(WT_FILE_HANDLE *file_handle, - WT_SESSION *wt_session, wt_off_t offset, wt_off_t len) +__posix_sys_fallocate( + WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, wt_off_t offset) { #if defined(__linux__) && defined(SYS_fallocate) WT_DECL_RET; @@ -62,13 +61,13 @@ __posix_sys_fallocate(WT_FILE_HANDLE *file_handle, * Linux versions (RHEL 5.5), but not in the version of the C library. * This allows it to work everywhere the kernel supports it. */ - WT_SYSCALL_RETRY(syscall(SYS_fallocate, pfh->fd, 0, offset, len), ret); + WT_SYSCALL_RETRY( + syscall(SYS_fallocate, pfh->fd, 0, (wt_off_t)0, offset), ret); return (ret); #else WT_UNUSED(file_handle); WT_UNUSED(wt_session); WT_UNUSED(offset); - WT_UNUSED(len); return (ENOTSUP); #endif } @@ -78,8 +77,8 @@ __posix_sys_fallocate(WT_FILE_HANDLE *file_handle, * POSIX fallocate call. */ static int -__posix_posix_fallocate(WT_FILE_HANDLE *file_handle, - WT_SESSION *wt_session, wt_off_t offset, wt_off_t len) +__posix_posix_fallocate( + WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, wt_off_t offset) { #if defined(HAVE_POSIX_FALLOCATE) WT_DECL_RET; @@ -89,64 +88,72 @@ __posix_posix_fallocate(WT_FILE_HANDLE *file_handle, pfh = (WT_FILE_HANDLE_POSIX *)file_handle; - WT_SYSCALL_RETRY(posix_fallocate(pfh->fd, offset, len), ret); + WT_SYSCALL_RETRY(posix_fallocate(pfh->fd, (wt_off_t)0, offset), ret); return (ret); #else WT_UNUSED(file_handle); WT_UNUSED(wt_session); WT_UNUSED(offset); - WT_UNUSED(len); return (ENOTSUP); #endif } /* - * __wt_posix_file_fallocate -- - * POSIX fallocate. + * __wt_posix_file_extend -- + * Extend the file. */ int -__wt_posix_file_fallocate(WT_FILE_HANDLE *file_handle, - WT_SESSION *wt_session, wt_off_t offset, wt_off_t len) +__wt_posix_file_extend( + WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, wt_off_t offset) { /* - * The first fallocate call: figure out what fallocate call this system - * supports, if any. + * The first file extension call: figure out what this system has. * - * The function is configured as a locking fallocate call, so we know - * we're single-threaded through here. Set the nolock function first, - * then publish the NULL replacement to ensure the handle functions are + * This function is configured as a locking call, so we know we're + * single-threaded through here. Set the nolock function first, then + * publish the NULL replacement to ensure the handle functions are * always correct. * - * We've seen Linux systems where posix_fallocate has corrupted - * existing file data (even though that is explicitly disallowed - * by POSIX). FreeBSD and Solaris support posix_fallocate, and - * so far we've seen no problems leaving it unlocked. Check for - * fallocate (and the system call version of fallocate) first to - * avoid locking on Linux if at all possible. + * We've seen Linux systems where posix_fallocate has corrupted existing + * file data (even though that is explicitly disallowed by POSIX). + * FreeBSD and Solaris support posix_fallocate, and so far we've seen + * no problems leaving it unlocked. Check for fallocate (and the system + * call version of fallocate) first to avoid locking on Linux if at all + * possible. */ - if (__posix_std_fallocate(file_handle, wt_session, offset, len) == 0) { - file_handle->fh_allocate_nolock = __posix_std_fallocate; - WT_PUBLISH(file_handle->fh_allocate, NULL); + if (__posix_std_fallocate(file_handle, wt_session, offset) == 0) { + file_handle->fh_extend_nolock = __posix_std_fallocate; + WT_PUBLISH(file_handle->fh_extend, NULL); return (0); } - if (__posix_sys_fallocate(file_handle, wt_session, offset, len) == 0) { - file_handle->fh_allocate_nolock = __posix_sys_fallocate; - WT_PUBLISH(file_handle->fh_allocate, NULL); + if (__posix_sys_fallocate(file_handle, wt_session, offset) == 0) { + file_handle->fh_extend_nolock = __posix_sys_fallocate; + WT_PUBLISH(file_handle->fh_extend, NULL); return (0); } - if (__posix_posix_fallocate( - file_handle, wt_session, offset, len) == 0) { + if (__posix_posix_fallocate(file_handle, wt_session, offset) == 0) { #if defined(__linux__) - file_handle->fh_allocate = __posix_posix_fallocate; + file_handle->fh_extend = __posix_posix_fallocate; WT_WRITE_BARRIER(); #else - file_handle->fh_allocate_nolock = __posix_posix_fallocate; - WT_PUBLISH(file_handle->fh_allocate, NULL); + file_handle->fh_extend_nolock = __posix_posix_fallocate; + WT_PUBLISH(file_handle->fh_extend, NULL); #endif return (0); } - file_handle->fh_allocate = NULL; + /* + * Use the POSIX ftruncate call if there's nothing else, it can extend + * files. Note ftruncate requires locking. + */ + if (file_handle->fh_truncate != NULL && + file_handle->fh_truncate(file_handle, wt_session, offset) == 0) { + file_handle->fh_extend = file_handle->fh_truncate; + WT_WRITE_BARRIER(); + return (0); + } + + file_handle->fh_extend = NULL; WT_WRITE_BARRIER(); return (ENOTSUP); } diff --git a/src/third_party/wiredtiger/src/os_posix/os_fs.c b/src/third_party/wiredtiger/src/os_posix/os_fs.c index 11f38ec063b..c6272b5da52 100644 --- a/src/third_party/wiredtiger/src/os_posix/os_fs.c +++ b/src/third_party/wiredtiger/src/os_posix/os_fs.c @@ -469,6 +469,7 @@ __posix_file_sync_nowait(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session) } #endif +#ifdef HAVE_FTRUNCATE /* * __posix_file_truncate -- * POSIX ftruncate. @@ -490,6 +491,7 @@ __posix_file_truncate( WT_RET_MSG(session, ret, "%s: handle-truncate: ftruncate", file_handle->name); } +#endif /* * __posix_file_write -- @@ -536,7 +538,7 @@ __posix_file_write(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, static inline int __posix_open_file_cloexec(WT_SESSION_IMPL *session, int fd, const char *name) { -#if defined(HAVE_FCNTL) && defined(FD_CLOEXEC) && !defined(O_CLOEXEC) +#if defined(FD_CLOEXEC) && !defined(O_CLOEXEC) int f; /* @@ -701,7 +703,7 @@ directory_open: if (!pfh->direct_io) file_handle->fh_advise = __posix_file_advise; #endif - file_handle->fh_allocate = __wt_posix_file_fallocate; + file_handle->fh_extend = __wt_posix_file_extend; file_handle->fh_lock = __posix_file_lock; #ifdef WORDS_BIGENDIAN /* @@ -722,7 +724,9 @@ directory_open: #ifdef HAVE_SYNC_FILE_RANGE file_handle->fh_sync_nowait = __posix_file_sync_nowait; #endif +#ifdef HAVE_FTRUNCATE file_handle->fh_truncate = __posix_file_truncate; +#endif file_handle->fh_write = __posix_file_write; *file_handlep = file_handle; diff --git a/src/third_party/wiredtiger/src/os_posix/os_map.c b/src/third_party/wiredtiger/src/os_posix/os_map.c index b33f6d82e34..91ccc04ff7e 100644 --- a/src/third_party/wiredtiger/src/os_posix/os_map.c +++ b/src/third_party/wiredtiger/src/os_posix/os_map.c @@ -43,7 +43,7 @@ __wt_posix_map(WT_FILE_HANDLE *fh, WT_SESSION *wt_session, WT_RET(fh->fh_size(fh, wt_session, &file_size)); len = (size_t)file_size; - (void)__wt_verbose(session, WT_VERB_HANDLEOPS, + __wt_verbose(session, WT_VERB_HANDLEOPS, "%s: memory-map: %" WT_SIZET_FMT " bytes", fh->name, len); if ((map = mmap(NULL, len, @@ -162,7 +162,7 @@ __wt_posix_unmap(WT_FILE_HANDLE *fh, WT_SESSION *wt_session, session = (WT_SESSION_IMPL *)wt_session; - (void)__wt_verbose(session, WT_VERB_HANDLEOPS, + __wt_verbose(session, WT_VERB_HANDLEOPS, "%s: memory-unmap: %" WT_SIZET_FMT " bytes", fh->name, len); if (munmap(mapped_region, len) == 0) diff --git a/src/third_party/wiredtiger/src/os_posix/os_mtx_cond.c b/src/third_party/wiredtiger/src/os_posix/os_mtx_cond.c index 5f4e9a7cf2b..9f17d9ff381 100644 --- a/src/third_party/wiredtiger/src/os_posix/os_mtx_cond.c +++ b/src/third_party/wiredtiger/src/os_posix/os_mtx_cond.c @@ -19,10 +19,6 @@ __wt_cond_alloc(WT_SESSION_IMPL *session, WT_CONDVAR *cond; WT_DECL_RET; - /* - * !!! - * This function MUST handle a NULL session handle. - */ WT_RET(__wt_calloc_one(session, &cond)); WT_ERR(pthread_mutex_init(&cond->mtx, NULL)); @@ -42,10 +38,10 @@ err: __wt_free(session, cond); /* * __wt_cond_wait_signal -- - * Wait on a mutex, optionally timing out. If we get it - * before the time out period expires, let the caller know. + * Wait on a mutex, optionally timing out. If we get it before the time + * out period expires, let the caller know. */ -int +void __wt_cond_wait_signal( WT_SESSION_IMPL *session, WT_CONDVAR *cond, uint64_t usecs, bool *signalled) { @@ -58,17 +54,10 @@ __wt_cond_wait_signal( /* Fast path if already signalled. */ *signalled = true; if (__wt_atomic_addi32(&cond->waiters, 1) == 0) - return (0); + return; - /* - * !!! - * This function MUST handle a NULL session handle. - */ - if (session != NULL) { - WT_RET(__wt_verbose(session, WT_VERB_MUTEX, - "wait %s cond (%p)", cond->name, cond)); - WT_STAT_FAST_CONN_INCR(session, cond_wait); - } + __wt_verbose(session, WT_VERB_MUTEX, "wait %s", cond->name); + WT_STAT_FAST_CONN_INCR(session, cond_wait); WT_ERR(pthread_mutex_lock(&cond->mtx)); locked = true; @@ -96,20 +85,21 @@ __wt_cond_wait_signal( ret = 0; } - (void)__wt_atomic_subi32(&cond->waiters, 1); +err: (void)__wt_atomic_subi32(&cond->waiters, 1); -err: if (locked) + if (locked) WT_TRET(pthread_mutex_unlock(&cond->mtx)); if (ret == 0) - return (0); - WT_RET_MSG(session, ret, "pthread_cond_wait"); + return; + + WT_PANIC_MSG(session, ret, "pthread_cond_wait: %s", cond->name); } /* * __wt_cond_signal -- * Signal a waiting thread. */ -int +void __wt_cond_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond) { WT_DECL_RET; @@ -117,17 +107,11 @@ __wt_cond_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond) locked = false; - /* - * !!! - * This function MUST handle a NULL session handle. - */ - if (session != NULL) - WT_RET(__wt_verbose(session, WT_VERB_MUTEX, - "signal %s cond (%p)", cond->name, cond)); + __wt_verbose(session, WT_VERB_MUTEX, "signal %s", cond->name); /* Fast path if already signalled. */ if (cond->waiters == -1) - return (0); + return; if (cond->waiters > 0 || !__wt_atomic_casi32(&cond->waiters, 0, -1)) { WT_ERR(pthread_mutex_lock(&cond->mtx)); @@ -138,8 +122,9 @@ __wt_cond_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond) err: if (locked) WT_TRET(pthread_mutex_unlock(&cond->mtx)); if (ret == 0) - return (0); - WT_RET_MSG(session, ret, "pthread_cond_broadcast"); + return; + + WT_PANIC_MSG(session, ret, "pthread_cond_broadcast: %s", cond->name); } /* diff --git a/src/third_party/wiredtiger/src/os_win/os_dir.c b/src/third_party/wiredtiger/src/os_win/os_dir.c index dccacc1e446..f024d131387 100644 --- a/src/third_party/wiredtiger/src/os_win/os_dir.c +++ b/src/third_party/wiredtiger/src/os_win/os_dir.c @@ -19,11 +19,14 @@ __wt_win_directory_list(WT_FILE_SYSTEM *file_system, { DWORD windows_error; HANDLE findhandle; - WIN32_FIND_DATA finddata; + WIN32_FIND_DATAW finddata; WT_DECL_ITEM(pathbuf); + WT_DECL_ITEM(file_utf8); + WT_DECL_ITEM(pathbuf_wide); + WT_DECL_ITEM(prefix_wide); WT_DECL_RET; WT_SESSION_IMPL *session; - size_t dirallocsz, pathlen; + size_t dirallocsz, pathlen, prefix_widelen; uint32_t count; char *dir_copy, **entries; @@ -45,7 +48,11 @@ __wt_win_directory_list(WT_FILE_SYSTEM *file_system, WT_ERR(__wt_scr_alloc(session, pathlen + 3, &pathbuf)); WT_ERR(__wt_buf_fmt(session, pathbuf, "%s\\*", dir_copy)); - findhandle = FindFirstFileA(pathbuf->data, &finddata); + WT_ERR(__wt_to_utf16_string(session, pathbuf->data, &pathbuf_wide)); + WT_ERR(__wt_to_utf16_string(session, prefix, &prefix_wide)); + prefix_widelen = wcslen(prefix_wide->data); + + findhandle = FindFirstFileW(pathbuf_wide->data, &finddata); if (findhandle == INVALID_HANDLE_VALUE) { windows_error = __wt_getlasterror(); __wt_errx(session, @@ -59,21 +66,25 @@ __wt_win_directory_list(WT_FILE_SYSTEM *file_system, /* * Skip . and .. */ - if (strcmp(finddata.cFileName, ".") == 0 || - strcmp(finddata.cFileName, "..") == 0) + if (wcscmp(finddata.cFileName, L".") == 0 || + wcscmp(finddata.cFileName, L"..") == 0) continue; /* The list of files is optionally filtered by a prefix. */ if (prefix != NULL && - !WT_PREFIX_MATCH(finddata.cFileName, prefix)) + wcsncmp(finddata.cFileName, prefix_wide->data, + prefix_widelen) != 0) continue; WT_ERR(__wt_realloc_def( session, &dirallocsz, count + 1, &entries)); - WT_ERR(__wt_strdup( - session, finddata.cFileName, &entries[count])); + + WT_ERR(__wt_to_utf8_string( + session, finddata.cFileName, &file_utf8)); + WT_ERR(__wt_strdup(session, file_utf8->data, &entries[count])); ++count; - } while (FindNextFileA(findhandle, &finddata) != 0); + __wt_scr_free(session, &file_utf8); + } while (FindNextFileW(findhandle, &finddata) != 0); *dirlistp = entries; *countp = count; @@ -91,6 +102,9 @@ err: if (findhandle != INVALID_HANDLE_VALUE) __wt_free(session, dir_copy); __wt_scr_free(session, &pathbuf); + __wt_scr_free(session, &file_utf8); + __wt_scr_free(session, &pathbuf_wide); + __wt_scr_free(session, &prefix_wide); if (ret == 0) return (0); diff --git a/src/third_party/wiredtiger/src/os_win/os_dlopen.c b/src/third_party/wiredtiger/src/os_win/os_dlopen.c index 3da47bf23a3..6857be2a05e 100644 --- a/src/third_party/wiredtiger/src/os_win/os_dlopen.c +++ b/src/third_party/wiredtiger/src/os_win/os_dlopen.c @@ -25,11 +25,11 @@ __wt_dlopen(WT_SESSION_IMPL *session, const char *path, WT_DLH **dlhp) /* NULL means load from the current binary */ if (path == NULL) { - if (GetModuleHandleExA( + if (GetModuleHandleExW( 0, NULL, (HMODULE *)&dlh->handle) == FALSE) { windows_error = __wt_getlasterror(); __wt_errx(session, - "GetModuleHandleEx: %s: %s", + "GetModuleHandleExW: %s: %s", path, __wt_formatmessage(session, windows_error)); WT_ERR(__wt_map_windows_error(windows_error)); } diff --git a/src/third_party/wiredtiger/src/os_win/os_fs.c b/src/third_party/wiredtiger/src/os_win/os_fs.c index fc03e0a2595..7ab7178114b 100644 --- a/src/third_party/wiredtiger/src/os_win/os_fs.c +++ b/src/third_party/wiredtiger/src/os_win/os_fs.c @@ -17,17 +17,20 @@ __win_fs_exist(WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session, const char *name, bool *existp) { WT_DECL_RET; + WT_DECL_ITEM(name_wide); WT_SESSION_IMPL *session; WT_UNUSED(file_system); session = (WT_SESSION_IMPL *)wt_session; + *existp = false; - if (GetFileAttributesA(name) != INVALID_FILE_ATTRIBUTES) + WT_RET(__wt_to_utf16_string(session, name, &name_wide)); + + if (GetFileAttributesW(name_wide->data) != INVALID_FILE_ATTRIBUTES) *existp = true; - else - *existp = false; + __wt_scr_free(session, &name_wide); return (0); } @@ -40,6 +43,8 @@ __win_fs_remove(WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session, const char *name, uint32_t flags) { DWORD windows_error; + WT_DECL_RET; + WT_DECL_ITEM(name_wide); WT_SESSION_IMPL *session; WT_UNUSED(file_system); @@ -47,14 +52,18 @@ __win_fs_remove(WT_FILE_SYSTEM *file_system, session = (WT_SESSION_IMPL *)wt_session; - if (DeleteFileA(name) == FALSE) { + WT_RET(__wt_to_utf16_string(session, name, &name_wide)); + + if (DeleteFileW(name_wide->data) == FALSE) { windows_error = __wt_getlasterror(); __wt_errx(session, - "%s: file-remove: DeleteFileA: %s", + "%s: file-remove: DeleteFileW: %s", name, __wt_formatmessage(session, windows_error)); - return (__wt_map_windows_error(windows_error)); + WT_ERR(__wt_map_windows_error(windows_error)); } - return (0); + +err: __wt_scr_free(session, &name_wide); + return (ret); } /* @@ -66,35 +75,42 @@ __win_fs_rename(WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session, const char *from, const char *to, uint32_t flags) { DWORD windows_error; + WT_DECL_RET; + WT_DECL_ITEM(from_wide); + WT_DECL_ITEM(to_wide); WT_SESSION_IMPL *session; WT_UNUSED(file_system); WT_UNUSED(flags); - session = (WT_SESSION_IMPL *)wt_session; + WT_ERR(__wt_to_utf16_string(session, from, &from_wide)); + WT_ERR(__wt_to_utf16_string(session, to, &to_wide)); + /* * Check if file exists since Windows does not override the file if * it exists. */ - if (GetFileAttributesA(to) != INVALID_FILE_ATTRIBUTES) - if (DeleteFileA(to) == FALSE) { + if (GetFileAttributesW(to_wide->data) != INVALID_FILE_ATTRIBUTES) + if (DeleteFileW(to_wide->data) == FALSE) { windows_error = __wt_getlasterror(); __wt_errx(session, - "%s: file-rename: DeleteFileA: %s", + "%s: file-rename: DeleteFileW: %s", to, __wt_formatmessage(session, windows_error)); - return (__wt_map_windows_error(windows_error)); + WT_ERR(__wt_map_windows_error(windows_error)); } - if (MoveFileA(from, to) == FALSE) { + if (MoveFileW(from_wide->data, to_wide->data) == FALSE) { windows_error = __wt_getlasterror(); __wt_errx(session, - "%s to %s: file-rename: MoveFileA: %s", + "%s to %s: file-rename: MoveFileW: %s", from, to, __wt_formatmessage(session, windows_error)); - return (__wt_map_windows_error(windows_error)); + WT_ERR(__wt_map_windows_error(windows_error)); } - return (0); +err: __wt_scr_free(session, &from_wide); + __wt_scr_free(session, &to_wide); + return (ret); } /* @@ -106,24 +122,29 @@ __wt_win_fs_size(WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session, const char *name, wt_off_t *sizep) { DWORD windows_error; + WT_DECL_RET; WIN32_FILE_ATTRIBUTE_DATA data; + WT_DECL_ITEM(name_wide); WT_SESSION_IMPL *session; WT_UNUSED(file_system); - session = (WT_SESSION_IMPL *)wt_session; - if (GetFileAttributesExA(name, GetFileExInfoStandard, &data) != 0) { - *sizep = - ((int64_t)data.nFileSizeHigh << 32) | data.nFileSizeLow; - return (0); + WT_RET(__wt_to_utf16_string(session, name, &name_wide)); + + if (GetFileAttributesExW( + name_wide->data, GetFileExInfoStandard, &data) == 0) { + windows_error = __wt_getlasterror(); + __wt_errx(session, + "%s: file-size: GetFileAttributesEx: %s", + name, __wt_formatmessage(session, windows_error)); + WT_ERR(__wt_map_windows_error(windows_error)); } - windows_error = __wt_getlasterror(); - __wt_errx(session, - "%s: file-size: GetFileAttributesEx: %s", - name, __wt_formatmessage(session, windows_error)); - return (__wt_map_windows_error(windows_error)); + *sizep = ((int64_t)data.nFileSizeHigh << 32) | data.nFileSizeLow; + +err: __wt_scr_free(session, &name_wide); + return (ret); } /* @@ -330,11 +351,11 @@ __win_file_sync(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session) } /* - * __win_file_truncate -- - * Truncate a file. + * __win_file_set_end -- + * Truncate or extend a file. */ static int -__win_file_truncate( +__win_file_set_end( WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, wt_off_t len) { DWORD windows_error; @@ -349,13 +370,14 @@ __win_file_truncate( if (win_fh->filehandle_secondary == INVALID_HANDLE_VALUE) WT_RET_MSG(session, EINVAL, - "%s: handle-truncate: read-only", file_handle->name); + "%s: handle-set-end: no secondary handle", + file_handle->name); if (SetFilePointerEx(win_fh->filehandle_secondary, largeint, NULL, FILE_BEGIN) == FALSE) { windows_error = __wt_getlasterror(); __wt_errx(session, - "%s: handle-truncate: SetFilePointerEx: %s", + "%s: handle-set-end: SetFilePointerEx: %s", file_handle->name, __wt_formatmessage(session, windows_error)); return (__wt_map_windows_error(windows_error)); @@ -366,7 +388,7 @@ __win_file_truncate( return (EBUSY); windows_error = __wt_getlasterror(); __wt_errx(session, - "%s: handle-truncate: SetEndOfFile: %s", + "%s: handle-set-end: SetEndOfFile: %s", file_handle->name, __wt_formatmessage(session, windows_error)); return (__wt_map_windows_error(windows_error)); @@ -434,26 +456,26 @@ __win_open_file(WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session, DWORD dwCreationDisposition, windows_error; WT_CONNECTION_IMPL *conn; WT_DECL_RET; + WT_DECL_ITEM(name_wide); WT_FILE_HANDLE *file_handle; WT_FILE_HANDLE_WIN *win_fh; WT_SESSION_IMPL *session; int desired_access, f; WT_UNUSED(file_system); - - *file_handlep = NULL; - session = (WT_SESSION_IMPL *)wt_session; conn = S2C(session); + *file_handlep = NULL; WT_RET(__wt_calloc_one(session, &win_fh)); - win_fh->direct_io = false; /* Set up error handling. */ win_fh->filehandle = win_fh->filehandle_secondary = INVALID_HANDLE_VALUE; + WT_ERR(__wt_to_utf16_string(session, name, &name_wide)); + /* * Opening a file handle on a directory is only to support filesystems * that require a directory sync for durability, and Windows doesn't @@ -503,41 +525,41 @@ __win_open_file(WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session, if (file_type == WT_FS_OPEN_FILE_TYPE_DATA) f |= FILE_FLAG_RANDOM_ACCESS; - win_fh->filehandle = CreateFileA(name, desired_access, + win_fh->filehandle = CreateFileW(name_wide->data, desired_access, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwCreationDisposition, f, NULL); if (win_fh->filehandle == INVALID_HANDLE_VALUE) { if (LF_ISSET(WT_FS_OPEN_CREATE) && GetLastError() == ERROR_FILE_EXISTS) - win_fh->filehandle = CreateFileA(name, desired_access, - FILE_SHARE_READ | FILE_SHARE_WRITE, + win_fh->filehandle = CreateFileW(name_wide->data, + desired_access, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, f, NULL); if (win_fh->filehandle == INVALID_HANDLE_VALUE) { windows_error = __wt_getlasterror(); __wt_errx(session, win_fh->direct_io ? - "%s: handle-open: CreateFileA: failed with direct " + "%s: handle-open: CreateFileW: failed with direct " "I/O configured, some filesystem types do not " "support direct I/O: %s" : - "%s: handle-open: CreateFileA: %s", + "%s: handle-open: CreateFileW: %s", name, __wt_formatmessage(session, windows_error)); WT_ERR(__wt_map_windows_error(windows_error)); } } /* - * Open a second handle to file to support allocation/truncation - * concurrently with reads on the file. Writes would also move the file - * pointer. + * Open a second handle to file to support file extension/truncation + * concurrently with reads on the file. Writes would also move the + * file pointer. */ if (!LF_ISSET(WT_FS_OPEN_READONLY)) { - win_fh->filehandle_secondary = CreateFileA(name, desired_access, - FILE_SHARE_READ | FILE_SHARE_WRITE, + win_fh->filehandle_secondary = CreateFileW(name_wide->data, + desired_access, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, f, NULL); if (win_fh->filehandle_secondary == INVALID_HANDLE_VALUE) { windows_error = __wt_getlasterror(); __wt_errx(session, - "%s: handle-open: CreateFileA: secondary: %s", + "%s: handle-open: Creatively: secondary: %s", name, __wt_formatmessage(session, windows_error)); WT_ERR(__wt_map_windows_error(windows_error)); } @@ -562,14 +584,20 @@ directory_open: file_handle->fh_read = __win_file_read; file_handle->fh_size = __win_file_size; file_handle->fh_sync = __win_file_sync; - file_handle->fh_truncate = __win_file_truncate; + + /* Extend and truncate share the same implementation. */ + file_handle->fh_extend = __win_file_set_end; + file_handle->fh_truncate = __win_file_set_end; + file_handle->fh_write = __win_file_write; *file_handlep = file_handle; + __wt_scr_free(session, &name_wide); return (0); -err: WT_TRET(__win_file_close((WT_FILE_HANDLE *)win_fh, wt_session)); +err: __wt_scr_free(session, &name_wide); + WT_TRET(__win_file_close((WT_FILE_HANDLE *)win_fh, wt_session)); return (ret); } diff --git a/src/third_party/wiredtiger/src/os_win/os_map.c b/src/third_party/wiredtiger/src/os_win/os_map.c index 8f5b289062d..a03e6cc3e52 100644 --- a/src/third_party/wiredtiger/src/os_win/os_map.c +++ b/src/third_party/wiredtiger/src/os_win/os_map.c @@ -35,15 +35,15 @@ __wt_win_map(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, wt_session, file_handle->name, &file_size)); len = (size_t)file_size; - (void)__wt_verbose(session, WT_VERB_HANDLEOPS, + __wt_verbose(session, WT_VERB_HANDLEOPS, "%s: memory-map: %" WT_SIZET_FMT " bytes", file_handle->name, len); - mapped_cookie = CreateFileMappingA( + mapped_cookie = CreateFileMappingW( win_fh->filehandle, NULL, PAGE_READONLY, 0, 0, NULL); if (mapped_cookie == NULL) { windows_error = __wt_getlasterror(); __wt_errx(session, - "%s: memory-map: CreateFileMappingA: %s", + "%s: memory-map: CreateFileMappingW: %s", file_handle->name, __wt_formatmessage(session, windows_error)); return (__wt_map_windows_error(windows_error)); @@ -85,7 +85,7 @@ __wt_win_unmap(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, win_fh = (WT_FILE_HANDLE_WIN *)file_handle; session = (WT_SESSION_IMPL *)wt_session; - (void)__wt_verbose(session, WT_VERB_HANDLEOPS, + __wt_verbose(session, WT_VERB_HANDLEOPS, "%s: memory-unmap: %" WT_SIZET_FMT " bytes", file_handle->name, length); diff --git a/src/third_party/wiredtiger/src/os_win/os_mtx_cond.c b/src/third_party/wiredtiger/src/os_win/os_mtx_cond.c index 8645fdaccb3..27207d289a6 100644 --- a/src/third_party/wiredtiger/src/os_win/os_mtx_cond.c +++ b/src/third_party/wiredtiger/src/os_win/os_mtx_cond.c @@ -18,10 +18,6 @@ __wt_cond_alloc(WT_SESSION_IMPL *session, { WT_CONDVAR *cond; - /* - * !!! - * This function MUST handle a NULL session handle. - */ WT_RET(__wt_calloc_one(session, &cond)); InitializeCriticalSection(&cond->mtx); @@ -38,10 +34,10 @@ __wt_cond_alloc(WT_SESSION_IMPL *session, /* * __wt_cond_wait_signal -- - * Wait on a mutex, optionally timing out. If we get it - * before the time out period expires, let the caller know. + * Wait on a mutex, optionally timing out. If we get it before the time + * out period expires, let the caller know. */ -int +void __wt_cond_wait_signal( WT_SESSION_IMPL *session, WT_CONDVAR *cond, uint64_t usecs, bool *signalled) { @@ -55,17 +51,10 @@ __wt_cond_wait_signal( /* Fast path if already signalled. */ *signalled = true; if (__wt_atomic_addi32(&cond->waiters, 1) == 0) - return (0); + return; - /* - * !!! - * This function MUST handle a NULL session handle. - */ - if (session != NULL) { - WT_RET(__wt_verbose(session, WT_VERB_MUTEX, - "wait %s cond (%p)", cond->name, cond)); - WT_STAT_FAST_CONN_INCR(session, cond_wait); - } + __wt_verbose(session, WT_VERB_MUTEX, "wait %s", cond->name); + WT_STAT_FAST_CONN_INCR(session, cond_wait); EnterCriticalSection(&cond->mtx); locked = true; @@ -112,18 +101,19 @@ __wt_cond_wait_signal( LeaveCriticalSection(&cond->mtx); if (sleepret != 0) - return (0); + return; - __wt_errx(session, "SleepConditionVariableCS: %s", - __wt_formatmessage(session, windows_error)); - return (__wt_map_windows_error(windows_error)); + __wt_errx(session, "SleepConditionVariableCS: %s: %s", + cond->name, __wt_formatmessage(session, windows_error)); + WT_PANIC_MSG(session, __wt_map_windows_error(windows_error), + "SleepConditionVariableCS: %s", cond->name); } /* * __wt_cond_signal -- * Signal a waiting thread. */ -int +void __wt_cond_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond) { WT_DECL_RET; @@ -131,17 +121,11 @@ __wt_cond_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond) locked = false; - /* - * !!! - * This function MUST handle a NULL session handle. - */ - if (session != NULL) - WT_RET(__wt_verbose(session, WT_VERB_MUTEX, - "signal %s cond (%p)", cond->name, cond)); + __wt_verbose(session, WT_VERB_MUTEX, "signal %s", cond->name); /* Fast path if already signalled. */ if (cond->waiters == -1) - return (0); + return; if (cond->waiters > 0 || !__wt_atomic_casi32(&cond->waiters, 0, -1)) { EnterCriticalSection(&cond->mtx); @@ -152,8 +136,9 @@ __wt_cond_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond) if (locked) LeaveCriticalSection(&cond->mtx); if (ret == 0) - return (0); - WT_RET_MSG(session, ret, "WakeAllConditionVariable"); + return; + + WT_PANIC_MSG(session, ret, "WakeAllConditionVariable: %s", cond->name); } /* diff --git a/src/third_party/wiredtiger/src/os_win/os_utf8.c b/src/third_party/wiredtiger/src/os_win/os_utf8.c new file mode 100644 index 00000000000..f7d11c24f03 --- /dev/null +++ b/src/third_party/wiredtiger/src/os_win/os_utf8.c @@ -0,0 +1,84 @@ +/*- + * Copyright (c) 2014-2016 MongoDB, Inc. + * Copyright (c) 2008-2014 WiredTiger, Inc. + * All rights reserved. + * + * See the file LICENSE for redistribution information. + */ + +#include "wt_internal.h" + +/* + * __wt_to_utf16_string -- + * Convert UTF-8 encoded string to UTF-16. + */ +int +__wt_to_utf16_string( + WT_SESSION_IMPL *session, const char* utf8, WT_ITEM **outbuf) +{ + DWORD windows_error; + int bufferSize; + WT_DECL_RET; + + bufferSize = MultiByteToWideChar(CP_UTF8, 0, utf8, -1, NULL, 0); + windows_error = __wt_getlasterror(); + + if (bufferSize == 0 && windows_error != ERROR_INSUFFICIENT_BUFFER) { + __wt_errx(session, "MultiByteToWideChar: %s", + __wt_formatmessage(session, windows_error)); + return (__wt_map_windows_error(windows_error)); + } + + WT_RET(__wt_scr_alloc(session, bufferSize * sizeof(wchar_t), outbuf)); + bufferSize = MultiByteToWideChar( + CP_UTF8, 0, utf8, -1, (*outbuf)->mem, bufferSize); + + if (bufferSize == 0) { + windows_error = __wt_getlasterror(); + __wt_scr_free(session, outbuf); + __wt_errx(session, "MultiByteToWideChar: %s", + __wt_formatmessage(session, windows_error)); + return (__wt_map_windows_error(windows_error)); + } + + (*outbuf)->size = bufferSize; + return (0); +} + +/* + * __wt_to_utf8_string -- + * Convert UTF-16 encoded string to UTF-8. + */ +int +__wt_to_utf8_string( + WT_SESSION_IMPL *session, const wchar_t* wide, WT_ITEM **outbuf) +{ + DWORD windows_error; + int bufferSize; + WT_DECL_RET; + + bufferSize = WideCharToMultiByte( + CP_UTF8, 0, wide, -1, NULL, 0, NULL, NULL); + windows_error = __wt_getlasterror(); + + if (bufferSize == 0 && windows_error != ERROR_INSUFFICIENT_BUFFER) { + __wt_errx(session, "WideCharToMultiByte: %s", + __wt_formatmessage(session, windows_error)); + return (__wt_map_windows_error(windows_error)); + } + + WT_RET(__wt_scr_alloc(session, bufferSize, outbuf)); + + bufferSize = WideCharToMultiByte( + CP_UTF8, 0, wide, -1, (*outbuf)->mem, bufferSize, NULL, NULL); + if (bufferSize == 0) { + windows_error = __wt_getlasterror(); + __wt_scr_free(session, outbuf); + __wt_errx(session, "WideCharToMultiByte: %s", + __wt_formatmessage(session, windows_error)); + return (__wt_map_windows_error(windows_error)); + } + + (*outbuf)->size = bufferSize; + return (0); +} diff --git a/src/third_party/wiredtiger/src/reconcile/rec_track.c b/src/third_party/wiredtiger/src/reconcile/rec_track.c index 4a3a8a7e988..10a64fdf116 100644 --- a/src/third_party/wiredtiger/src/reconcile/rec_track.c +++ b/src/third_party/wiredtiger/src/reconcile/rec_track.c @@ -42,14 +42,14 @@ __ovfl_discard_verbose( unpack = &_unpack; __wt_cell_unpack(cell, unpack); - WT_ERR(__wt_verbose(session, WT_VERB_OVERFLOW, + __wt_verbose(session, WT_VERB_OVERFLOW, "discard: %s%s%p %s", tag == NULL ? "" : tag, tag == NULL ? "" : ": ", - page, - __wt_addr_string(session, unpack->data, unpack->size, tmp))); + (void *)page, + __wt_addr_string(session, unpack->data, unpack->size, tmp)); -err: __wt_scr_free(session, &tmp); + __wt_scr_free(session, &tmp); return (ret); } @@ -108,7 +108,7 @@ __ovfl_discard_wrapup(WT_SESSION_IMPL *session, WT_PAGE *page) * __ovfl_discard_wrapup_err -- * Resolve the page's overflow discard list after an error occurs. */ -static int +static void __ovfl_discard_wrapup_err(WT_SESSION_IMPL *session, WT_PAGE *page) { WT_OVFL_TRACK *track; @@ -117,8 +117,6 @@ __ovfl_discard_wrapup_err(WT_SESSION_IMPL *session, WT_PAGE *page) __wt_free(session, track->discard); track->discard_entries = track->discard_allocated = 0; - - return (0); } /* @@ -176,20 +174,20 @@ __ovfl_reuse_verbose(WT_SESSION_IMPL *session, WT_RET(__wt_scr_alloc(session, 64, &tmp)); - WT_ERR(__wt_verbose(session, WT_VERB_OVERFLOW, + __wt_verbose(session, WT_VERB_OVERFLOW, "reuse: %s%s%p %s (%s%s%s) {%.*s}", tag == NULL ? "" : tag, tag == NULL ? "" : ": ", - page, + (void *)page, __wt_addr_string( session, WT_OVFL_REUSE_ADDR(reuse), reuse->addr_size, tmp), F_ISSET(reuse, WT_OVFL_REUSE_INUSE) ? "inuse" : "", F_ISSET(reuse, WT_OVFL_REUSE_INUSE) && F_ISSET(reuse, WT_OVFL_REUSE_JUST_ADDED) ? ", " : "", F_ISSET(reuse, WT_OVFL_REUSE_JUST_ADDED) ? "just-added" : "", - WT_MIN(reuse->value_size, 40), (char *)WT_OVFL_REUSE_VALUE(reuse))); + WT_MIN(reuse->value_size, 40), (char *)WT_OVFL_REUSE_VALUE(reuse)); -err: __wt_scr_free(session, &tmp); + __wt_scr_free(session, &tmp); return (ret); } @@ -574,17 +572,17 @@ __ovfl_txnc_verbose(WT_SESSION_IMPL *session, WT_RET(__wt_scr_alloc(session, 64, &tmp)); - WT_ERR(__wt_verbose(session, WT_VERB_OVERFLOW, + __wt_verbose(session, WT_VERB_OVERFLOW, "txn-cache: %s%s%p %s %" PRIu64 " {%.*s}", tag == NULL ? "" : tag, tag == NULL ? "" : ": ", - page, + (void *)page, __wt_addr_string( session, WT_OVFL_TXNC_ADDR(txnc), txnc->addr_size, tmp), txnc->current, - WT_MIN(txnc->value_size, 40), (char *)WT_OVFL_TXNC_VALUE(txnc))); + WT_MIN(txnc->value_size, 40), (char *)WT_OVFL_TXNC_VALUE(txnc)); -err: __wt_scr_free(session, &tmp); + __wt_scr_free(session, &tmp); return (ret); } @@ -881,11 +879,11 @@ __wt_ovfl_track_wrapup(WT_SESSION_IMPL *session, WT_PAGE *page) WT_RET(__ovfl_reuse_wrapup(session, page)); if (track->ovfl_txnc[0] != NULL) { - WT_RET(__wt_writelock(session, S2BT(session)->ovfl_lock)); + __wt_writelock(session, S2BT(session)->ovfl_lock); ret = __ovfl_txnc_wrapup(session, page); - WT_TRET(__wt_writeunlock(session, S2BT(session)->ovfl_lock)); + __wt_writeunlock(session, S2BT(session)->ovfl_lock); } - return (0); + return (ret); } /* @@ -903,15 +901,15 @@ __wt_ovfl_track_wrapup_err(WT_SESSION_IMPL *session, WT_PAGE *page) track = page->modify->ovfl_track; if (track->discard != NULL) - WT_RET(__ovfl_discard_wrapup_err(session, page)); + __ovfl_discard_wrapup_err(session, page); if (track->ovfl_reuse[0] != NULL) WT_RET(__ovfl_reuse_wrapup_err(session, page)); if (track->ovfl_txnc[0] != NULL) { - WT_RET(__wt_writelock(session, S2BT(session)->ovfl_lock)); + __wt_writelock(session, S2BT(session)->ovfl_lock); ret = __ovfl_txnc_wrapup(session, page); - WT_TRET(__wt_writeunlock(session, S2BT(session)->ovfl_lock)); + __wt_writeunlock(session, S2BT(session)->ovfl_lock); } - return (0); + return (ret); } diff --git a/src/third_party/wiredtiger/src/reconcile/rec_write.c b/src/third_party/wiredtiger/src/reconcile/rec_write.c index 6bcb5457385..a9912628942 100644 --- a/src/third_party/wiredtiger/src/reconcile/rec_write.c +++ b/src/third_party/wiredtiger/src/reconcile/rec_write.c @@ -115,6 +115,7 @@ typedef struct { */ uint32_t page_size; /* Set page size */ uint32_t page_size_orig; /* Saved set page size */ + uint32_t max_raw_page_size; /* Max page size with raw compression */ /* * Second, the split size: if we're doing the page layout, split to a @@ -158,9 +159,16 @@ typedef struct { WT_ADDR addr; /* Split's written location */ uint32_t size; /* Split's size */ - uint32_t cksum; /* Split's checksum */ + uint32_t checksum; /* Split's checksum */ + void *disk_image; /* Split's disk image */ + /* + * Raw compression, the disk image being written is already + * compressed. + */ + bool already_compressed; + /* * Saved update list, supporting the WT_EVICT_UPDATE_RESTORE and * WT_EVICT_LOOKASIDE configurations. @@ -175,13 +183,6 @@ typedef struct { * column-store key. */ WT_ITEM key; /* Promoted row-store key */ - - /* - * During wrapup, after reconciling the root page, we write a - * final block as part of a checkpoint. If raw compression - * was configured, that block may have already been compressed. - */ - bool already_compressed; } *bnd; /* Saved boundaries */ uint32_t bnd_next; /* Next boundary slot */ uint32_t bnd_next_max; /* Maximum boundary slots used */ @@ -356,8 +357,8 @@ __wt_reconcile(WT_SESSION_IMPL *session, page = ref->page; mod = page->modify; - WT_RET(__wt_verbose(session, - WT_VERB_RECONCILE, "%s", __wt_page_type_string(page->type))); + __wt_verbose(session, + WT_VERB_RECONCILE, "%s", __wt_page_type_string(page->type)); /* We shouldn't get called with a clean page, that's an error. */ WT_ASSERT(session, __wt_page_is_modified(page)); @@ -371,21 +372,26 @@ __wt_reconcile(WT_SESSION_IMPL *session, * In-memory splits: reconciliation of an internal page cannot handle * a child page splitting during the reconciliation. */ - WT_RET(__wt_fair_lock(session, &page->page_lock)); + __wt_writelock(session, &page->page_lock); + + oldest_id = __wt_txn_oldest_id(session); + if (LF_ISSET(WT_EVICTING)) + mod->last_eviction_id = oldest_id; +#ifdef HAVE_DIAGNOSTIC /* * Check that transaction time always moves forward for a given page. * If this check fails, reconciliation can free something that a future * reconciliation will need. */ - oldest_id = __wt_txn_oldest_id(session); WT_ASSERT(session, WT_TXNID_LE(mod->last_oldest_id, oldest_id)); mod->last_oldest_id = oldest_id; +#endif /* Initialize the reconciliation structure for each new run. */ if ((ret = __rec_write_init( session, ref, flags, salvage, &session->reconcile)) != 0) { - WT_TRET(__wt_fair_unlock(session, &page->page_lock)); + __wt_writeunlock(session, &page->page_lock); return (ret); } r = session->reconcile; @@ -426,7 +432,7 @@ __wt_reconcile(WT_SESSION_IMPL *session, WT_TRET(__rec_write_wrapup_err(session, r, page)); /* Release the reconciliation lock. */ - WT_TRET(__wt_fair_unlock(session, &page->page_lock)); + __wt_writeunlock(session, &page->page_lock); /* Update statistics. */ WT_STAT_FAST_CONN_INCR(session, rec_pages); @@ -445,17 +451,32 @@ __wt_reconcile(WT_SESSION_IMPL *session, } /* - * Clean up reconciliation resources: some workloads have millions of - * boundary structures, and if associated with an application session - * pulled into doing forced eviction, they won't be discarded for the - * life of the session (or until session.reset is called). Discard all - * of the reconciliation resources if an application thread, not doing - * a checkpoint. - */ - __rec_bnd_cleanup(session, r, - F_ISSET(session, WT_SESSION_INTERNAL) || - WT_SESSION_IS_CHECKPOINT(session) ? false : true); + * When application threads perform eviction, don't cache block manager + * or reconciliation structures (even across calls), we can have a + * significant number of application threads doing eviction at the same + * time with large items. We ignore checkpoints, once the checkpoint + * completes, all unnecessary session resources will be discarded. + * + * Even in application threads doing checkpoints or in internal threads + * doing any reconciliation, clean up reconciliation resources. Some + * workloads have millions of boundary structures in a reconciliation + * and we don't want to tie that memory down, even across calls. + */ + if (WT_SESSION_IS_CHECKPOINT(session) || + F_ISSET(session, WT_SESSION_INTERNAL)) + __rec_bnd_cleanup(session, r, false); + else { + /* + * Clean up the underlying block manager memory too: it's not + * reconciliation, but threads discarding reconciliation + * structures want to clean up the block manager's structures + * as well, and there's no obvious place to do that. + */ + if (session->block_manager_cleanup != NULL) + WT_TRET(session->block_manager_cleanup(session)); + WT_TRET(__rec_destroy_session(session)); + } WT_RET(ret); /* @@ -624,8 +645,8 @@ __rec_root_write(WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t flags) WT_ILLEGAL_VALUE(session); } - WT_RET(__wt_verbose(session, WT_VERB_SPLIT, - "root page split -> %" PRIu32 " pages", mod->mod_multi_entries)); + __wt_verbose(session, WT_VERB_SPLIT, + "root page split -> %" PRIu32 " pages", mod->mod_multi_entries); /* * Create a new root page, initialize the array of child references, @@ -652,7 +673,7 @@ __rec_root_write(WT_SESSION_IMPL *session, WT_PAGE *page, uint32_t flags) WT_ASSERT(session, mod->mod_multi[i].supd == NULL); WT_ERR(__wt_multi_to_ref(session, - next, &mod->mod_multi[i], &pindex->index[i], NULL)); + next, &mod->mod_multi[i], &pindex->index[i], NULL, false)); pindex->index[i]->home = next; } @@ -1136,15 +1157,17 @@ __rec_txn_read(WT_SESSION_IMPL *session, WT_RECONCILE *r, if (!skipped && (F_ISSET(btree, WT_BTREE_LOOKASIDE) || __wt_txn_visible_all(session, max_txn))) { +#ifdef HAVE_DIAGNOSTIC /* * The checkpoint transaction is special. Make sure we never * write (metadata) updates from a checkpoint in a concurrent * session. */ - WT_ASSERT(session, *updp == NULL || - (txnid = (*updp)->txnid) == WT_TXN_NONE || + txnid = *updp == NULL ? WT_TXN_NONE : (*updp)->txnid; + WT_ASSERT(session, txnid == WT_TXN_NONE || txnid != S2C(session)->txn_global.checkpoint_txnid || WT_SESSION_IS_CHECKPOINT(session)); +#endif return (0); } @@ -1854,19 +1877,20 @@ __rec_split_bnd_init(WT_SESSION_IMPL *session, WT_BOUNDARY *bnd) __wt_free(session, bnd->addr.addr); WT_CLEAR(bnd->addr); bnd->size = 0; - bnd->cksum = 0; + bnd->checksum = 0; + __wt_free(session, bnd->disk_image); __wt_free(session, bnd->supd); bnd->supd_next = 0; bnd->supd_allocated = 0; + bnd->already_compressed = false; + /* * Don't touch the key, we re-use that memory in each new * reconciliation. */ - - bnd->already_compressed = false; } /* @@ -1960,10 +1984,19 @@ __rec_split_init(WT_SESSION_IMPL *session, * additional data because we don't know how well it will compress, and * we don't want to increment our way up to the amount of data needed by * the application to successfully compress to the target page size. + * Ideally accumulate data several times the page size without + * approaching the memory page maximum, but at least have data worth + * one page. + * + * There are cases when we grow the page size to accommodate large + * records, in those cases we split the pages once they have crossed + * the maximum size for a page with raw compression. */ r->page_size = r->page_size_orig = max; if (r->raw_compression) - r->page_size *= 10; + r->max_raw_page_size = r->page_size = + (uint32_t)WT_MIN(r->page_size * 10, + WT_MAX(r->page_size, btree->maxmempage / 2)); /* * Ensure the disk image buffer is large enough for the max object, as @@ -2305,7 +2338,7 @@ __rec_split(WT_SESSION_IMPL *session, WT_RECONCILE *r, size_t next_len) /* Hitting a page boundary resets the dictionary, in all cases. */ __rec_dictionary_reset(r); - inuse = WT_PTRDIFF32(r->first_free, dsk); + inuse = WT_PTRDIFF(r->first_free, dsk); switch (r->bnd_state) { case SPLIT_BOUNDARY: /* @@ -2475,7 +2508,7 @@ __rec_split_raw_worker(WT_SESSION_IMPL *session, WT_COMPRESSOR *compressor; WT_DECL_RET; WT_ITEM *dst, *write_ref; - WT_PAGE_HEADER *dsk, *dsk_dst; + WT_PAGE_HEADER *dsk, *dsk_dst, *disk_image; WT_SESSION *wt_session; size_t corrected_page_size, extra_skip, len, result_len; uint64_t recno; @@ -2592,11 +2625,9 @@ __rec_split_raw_worker(WT_SESSION_IMPL *session, /* * Don't create an image so large that any future update will - * cause a split in memory. Use half of the maximum size so - * we split very compressible pages that have reached the - * maximum size in memory into two equal blocks. + * cause a split in memory. */ - if (len > (size_t)btree->maxmempage / 2) + if (max_image_slot == 0 && len > (size_t)r->max_raw_page_size) max_image_slot = slots; } @@ -2658,7 +2689,7 @@ __rec_split_raw_worker(WT_SESSION_IMPL *session, r->page_size_orig, btree->split_pct, WT_BLOCK_COMPRESS_SKIP + extra_skip, (uint8_t *)dsk + WT_BLOCK_COMPRESS_SKIP, r->raw_offsets, - no_more_rows || max_image_slot == 0 ? slots : max_image_slot, + max_image_slot == 0 ? slots : max_image_slot, (uint8_t *)dst->mem + WT_BLOCK_COMPRESS_SKIP, result_len, no_more_rows || max_image_slot != 0, @@ -2761,7 +2792,8 @@ no_slots: if (result_slots != 0) { /* - * We have a block, finalize the header information. + * We have a block, finalize the compressed disk image's header + * information. */ dst->size = result_len + WT_BLOCK_COMPRESS_SKIP; dsk_dst = dst->mem; @@ -2770,6 +2802,26 @@ no_slots: r->raw_offsets[result_slots] + WT_BLOCK_COMPRESS_SKIP; dsk_dst->u.entries = r->raw_entries[result_slots - 1]; + /* + * Optionally keep the disk image in cache. Update the initial + * page-header fields to reflect the actual data being written. + * + * If updates are saved and need to be restored, we have to keep + * a copy of the disk image. Unfortunately, we don't yet know if + * there are updates to restore for the key range covered by the + * disk image just created. If there are any saved updates, take + * a copy of the disk image, it's freed later if not needed. + */ + if (F_ISSET(r, WT_EVICT_SCRUB) || + (F_ISSET(r, WT_EVICT_UPDATE_RESTORE) && r->supd_next > 0)) { + WT_RET(__wt_strndup(session, dsk, + dsk_dst->mem_size, &last->disk_image)); + disk_image = last->disk_image; + disk_image->recno = last->recno; + disk_image->mem_size = dsk_dst->mem_size; + disk_image->u.entries = dsk_dst->u.entries; + } + /* * There is likely a remnant in the working buffer that didn't * get compressed; copy it down to the start of the buffer and @@ -2883,48 +2935,6 @@ split_grow: /* return (0); } -/* - * __rec_raw_decompress -- - * Decompress a raw-compressed image. - */ -static int -__rec_raw_decompress( - WT_SESSION_IMPL *session, const void *image, size_t size, void *retp) -{ - WT_BTREE *btree; - WT_DECL_ITEM(tmp); - WT_DECL_RET; - WT_PAGE_HEADER const *dsk; - size_t result_len; - - btree = S2BT(session); - dsk = image; - - /* - * We skipped an update and we can't write a block, but unfortunately, - * the block has already been compressed. Decompress the block so we - * can subsequently re-instantiate it in memory. - */ - WT_RET(__wt_scr_alloc(session, dsk->mem_size, &tmp)); - memcpy(tmp->mem, image, WT_BLOCK_COMPRESS_SKIP); - WT_ERR(btree->compressor->decompress(btree->compressor, - &session->iface, - (uint8_t *)image + WT_BLOCK_COMPRESS_SKIP, - size - WT_BLOCK_COMPRESS_SKIP, - (uint8_t *)tmp->mem + WT_BLOCK_COMPRESS_SKIP, - dsk->mem_size - WT_BLOCK_COMPRESS_SKIP, - &result_len)); - if (result_len != dsk->mem_size - WT_BLOCK_COMPRESS_SKIP) - WT_ERR(__wt_illegal_value(session, btree->dhandle->name)); - - WT_ERR(__wt_strndup(session, tmp->data, dsk->mem_size, retp)); - WT_ASSERT(session, __wt_verify_dsk_image(session, - "[raw evict split]", tmp->data, dsk->mem_size, false) == 0); - -err: __wt_scr_free(session, &tmp); - return (ret); -} - /* * __rec_split_raw -- * Raw compression split routine. @@ -3032,7 +3042,7 @@ __rec_split_finish(WT_SESSION_IMPL *session, WT_RECONCILE *r) if (r->raw_compression && r->entries != 0) { while (r->entries != 0) { data_size = - WT_PTRDIFF32(r->first_free, r->disk_image.mem); + WT_PTRDIFF(r->first_free, r->disk_image.mem); if (data_size <= btree->allocsize) break; WT_RET(__rec_split_raw_worker(session, r, 0, true)); @@ -3155,14 +3165,13 @@ __rec_split_write(WT_SESSION_IMPL *session, uint32_t bnd_slot, i, j; int cmp; uint8_t addr[WT_BTREE_MAX_ADDR_COOKIE]; + bool need_image; btree = S2BT(session); dsk = buf->mem; page = r->page; mod = page->modify; - WT_RET(__wt_scr_alloc(session, 0, &key)); - /* Set the zero-length value flag in the page header. */ if (dsk->type == WT_PAGE_ROW_LEAF) { F_CLR(dsk, WT_PAGE_EMPTY_V_ALL | WT_PAGE_EMPTY_V_NONE); @@ -3173,6 +3182,8 @@ __rec_split_write(WT_SESSION_IMPL *session, F_SET(dsk, WT_PAGE_EMPTY_V_NONE); } + bnd->entries = r->entries; + /* Initialize the address (set the page type for the parent). */ switch (dsk->type) { case WT_PAGE_COL_FIX: @@ -3186,11 +3197,10 @@ __rec_split_write(WT_SESSION_IMPL *session, case WT_PAGE_ROW_INT: bnd->addr.type = WT_ADDR_INT; break; - WT_ILLEGAL_VALUE_ERR(session); + WT_ILLEGAL_VALUE(session); } - bnd->size = (uint32_t)buf->size; - bnd->cksum = 0; + bnd->checksum = 0; /* * Check if we've saved updates that belong to this block, and move @@ -3200,6 +3210,8 @@ __rec_split_write(WT_SESSION_IMPL *session, * This code requires a key be filled in for the next block (or the * last block flag be set, if there's no next block). */ + if (page->type == WT_PAGE_ROW_LEAF) + WT_RET(__wt_scr_alloc(session, 0, &key)); for (i = 0, supd = r->supd; i < r->supd_next; ++i, ++supd) { /* The last block gets all remaining saved updates. */ if (last_block) { @@ -3264,33 +3276,11 @@ supd_check_complete: * image, we can't actually write it. Instead, we will re-instantiate * the page using the disk image and any list of updates we skipped. */ - if (F_ISSET(r, WT_EVICT_IN_MEMORY) || - (F_ISSET(r, WT_EVICT_UPDATE_RESTORE) && bnd->supd != NULL)) { - - /* Statistics tracking that we used update/restore. */ - if (F_ISSET(r, WT_EVICT_UPDATE_RESTORE) && bnd->supd != NULL) - r->cache_write_restore = true; - - /* - * If the buffer is compressed (raw compression was configured), - * we have to decompress it so we can instantiate it later. It's - * a slow and convoluted path, but it's also a rare one and it's - * not worth making it faster. Else, the disk image is ready, - * copy it into place for later. It's possible the disk image - * has no items; we have to flag that for verification, it's a - * special case since read/writing empty pages isn't generally - * allowed. - */ - if (bnd->already_compressed) - WT_ERR(__rec_raw_decompress( - session, buf->data, buf->size, &bnd->disk_image)); - else { - WT_ERR(__wt_strndup( - session, buf->data, buf->size, &bnd->disk_image)); - WT_ASSERT(session, __wt_verify_dsk_image(session, - "[evict split]", buf->data, buf->size, true) == 0); - } - goto done; + if (F_ISSET(r, WT_EVICT_IN_MEMORY)) + goto copy_image; + if (F_ISSET(r, WT_EVICT_UPDATE_RESTORE) && bnd->supd != NULL) { + r->cache_write_restore = true; + goto copy_image; } /* @@ -3316,7 +3306,7 @@ supd_check_complete: */ dsk->write_gen = 0; memset(WT_BLOCK_HEADER_REF(dsk), 0, btree->block_header); - bnd->cksum = __wt_cksum(buf->data, buf->size); + bnd->checksum = __wt_checksum(buf->data, buf->size); /* * One last check: don't reuse blocks if compacting, the reason @@ -3329,32 +3319,30 @@ supd_check_complete: mod->mod_multi_entries > bnd_slot) { multi = &mod->mod_multi[bnd_slot]; if (multi->size == bnd->size && - multi->cksum == bnd->cksum) { + multi->checksum == bnd->checksum) { multi->addr.reuse = 1; bnd->addr = multi->addr; WT_STAT_FAST_DATA_INCR(session, rec_page_match); - goto done; + goto copy_image; } } } - bnd->entries = r->entries; - #ifdef HAVE_VERBOSE /* Output a verbose message if we create a page without many entries */ if (WT_VERBOSE_ISSET(session, WT_VERB_SPLIT) && r->entries < 6) - WT_ERR(__wt_verbose(session, WT_VERB_SPLIT, + __wt_verbose(session, WT_VERB_SPLIT, "Reconciliation creating a page with %" PRIu32 - " entries, memory footprint %" PRIu64 + " entries, memory footprint %" WT_SIZET_FMT ", page count %" PRIu32 ", %s, split state: %d\n", r->entries, r->page->memory_footprint, r->bnd_next, F_ISSET(r, WT_EVICTING) ? "evict" : "checkpoint", - r->bnd_state)); + r->bnd_state); #endif - WT_ERR(__wt_bt_write(session, - buf, addr, &addr_size, false, bnd->already_compressed)); + WT_ERR(__wt_bt_write(session, buf, addr, &addr_size, + false, F_ISSET(r, WT_CHECKPOINTING), bnd->already_compressed)); WT_ERR(__wt_strndup(session, addr, addr_size, &bnd->addr.addr)); bnd->addr.size = (uint8_t)addr_size; @@ -3364,9 +3352,29 @@ supd_check_complete: * the database's lookaside store. */ if (F_ISSET(r, WT_EVICT_LOOKASIDE) && bnd->supd != NULL) - ret = __rec_update_las(session, r, btree->id, bnd); + WT_ERR(__rec_update_las(session, r, btree->id, bnd)); + +copy_image: + /* + * If re-instantiating this page in memory (either because eviction + * wants to, or because we skipped updates to build the disk image), + * save a copy of the disk image. + * + * Raw compression might have already saved a copy of the disk image + * before we could know if we skipped updates to create it, and now + * we know if we're going to need it. + * + * Copy the disk image if we need a copy and don't already have one, + * discard any already saved copy we don't need. + */ + need_image = F_ISSET(r, WT_EVICT_SCRUB) || + (F_ISSET(r, WT_EVICT_UPDATE_RESTORE) && bnd->supd != NULL); + if (need_image && bnd->disk_image == NULL) + WT_ERR(__wt_strndup( + session, buf->data, buf->size, &bnd->disk_image)); + if (!need_image) + __wt_free(session, bnd->disk_image); -done: err: __wt_scr_free(session, &key); return (ret); } @@ -3403,7 +3411,7 @@ __rec_update_las(WT_SESSION_IMPL *session, */ __wt_las_set_written(session); - WT_ERR(__wt_las_cursor(session, &cursor, &session_flags)); + __wt_las_cursor(session, &cursor, &session_flags); /* Ensure enough room for a column-store key without checking. */ WT_ERR(__wt_scr_alloc(session, WT_INTPACK64_MAXSIZE, &key)); @@ -3566,8 +3574,9 @@ __wt_bulk_wrapup(WT_SESSION_IMPL *session, WT_CURSOR_BULK *cbulk) WT_PAGE *parent; WT_RECONCILE *r; - r = cbulk->reconcile; btree = S2BT(session); + if ((r = cbulk->reconcile) == NULL) + return (0); switch (btree->type) { case BTREE_COL_FIX: @@ -5531,22 +5540,22 @@ __rec_split_dump_keys(WT_SESSION_IMPL *session, WT_PAGE *page, WT_RECONCILE *r) if (page->type == WT_PAGE_ROW_INT || page->type == WT_PAGE_ROW_LEAF) WT_RET(__wt_scr_alloc(session, 0, &tkey)); - WT_ERR(__wt_verbose( - session, WT_VERB_SPLIT, "split: %" PRIu32 " pages", r->bnd_next)); + __wt_verbose( + session, WT_VERB_SPLIT, "split: %" PRIu32 " pages", r->bnd_next); for (bnd = r->bnd, i = 0; i < r->bnd_next; ++bnd, ++i) switch (page->type) { case WT_PAGE_ROW_INT: case WT_PAGE_ROW_LEAF: - WT_ERR(__wt_verbose(session, WT_VERB_SPLIT, + __wt_verbose(session, WT_VERB_SPLIT, "starting key %s", __wt_buf_set_printable( - session, bnd->key.data, bnd->key.size, tkey))); + session, bnd->key.data, bnd->key.size, tkey)); break; case WT_PAGE_COL_FIX: case WT_PAGE_COL_INT: case WT_PAGE_COL_VAR: - WT_ERR(__wt_verbose(session, WT_VERB_SPLIT, - "starting recno %" PRIu64, bnd->recno)); + __wt_verbose(session, WT_VERB_SPLIT, + "starting recno %" PRIu64, bnd->recno); break; WT_ILLEGAL_VALUE_ERR(session); } @@ -5611,9 +5620,10 @@ __rec_write_wrapup(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_PAGE *page) WT_RET(__wt_btree_block_free(session, mod->mod_replace.addr, mod->mod_replace.size)); - /* Discard the replacement page's address. */ + /* Discard the replacement page's address and disk image. */ __wt_free(session, mod->mod_replace.addr); mod->mod_replace.size = 0; + __wt_free(session, mod->mod_disk_image); break; WT_ILLEGAL_VALUE(session); } @@ -5632,8 +5642,8 @@ __rec_write_wrapup(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_PAGE *page) switch (r->bnd_next) { case 0: /* Page delete */ - WT_RET(__wt_verbose( - session, WT_VERB_RECONCILE, "page %p empty", page)); + __wt_verbose( + session, WT_VERB_RECONCILE, "page %p empty", (void *)page); WT_STAT_FAST_CONN_INCR(session, rec_page_delete); WT_STAT_FAST_DATA_INCR(session, rec_page_delete); @@ -5661,34 +5671,41 @@ __rec_write_wrapup(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_PAGE *page) bnd = &r->bnd[0]; /* - * If saving/restoring changes for this page and there's only - * one block, there's nothing to write. This is an in-memory - * configuration or a special case of forced eviction: set up + * If in-memory, or saving/restoring changes for this page and + * there's only one block, there's nothing to write. Set up * a single block as if to split, then use that disk image to - * rewrite the page in memory. + * rewrite the page in memory. This is separate from simple + * replacements where eviction has decided to retain the page + * in memory because the latter can't handle update lists and + * splits can. */ - if (bnd->disk_image != NULL) + if (F_ISSET(r, WT_EVICT_IN_MEMORY) || + (F_ISSET(r, WT_EVICT_UPDATE_RESTORE) && bnd->supd != NULL)) goto split; /* - * If this is a root page, then we don't have an address and we - * have to create a sync point. The address was cleared when - * we were about to write the buffer so we know what to do here. + * A root page, we don't have an address and we have to create + * a sync point. The address was cleared when we were about to + * write the buffer so we know what to do here. */ if (bnd->addr.addr == NULL) WT_RET(__wt_bt_write(session, &r->disk_image, - NULL, NULL, true, bnd->already_compressed)); + NULL, NULL, true, F_ISSET(r, WT_CHECKPOINTING), + bnd->already_compressed)); else { mod->mod_replace = bnd->addr; bnd->addr.addr = NULL; + + mod->mod_disk_image = bnd->disk_image; + bnd->disk_image = NULL; } mod->rec_result = WT_PM_REC_REPLACE; break; default: /* Page split */ - WT_RET(__wt_verbose(session, WT_VERB_RECONCILE, + __wt_verbose(session, WT_VERB_RECONCILE, "page %p reconciled into %" PRIu32 " pages", - page, r->bnd_next)); + (void *)page, r->bnd_next); switch (page->type) { case WT_PAGE_COL_INT: @@ -5815,19 +5832,26 @@ __rec_split_row(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_PAGE *page) WT_RET(__wt_row_ikey_alloc(session, 0, bnd->key.data, bnd->key.size, &multi->key.ikey)); - if (bnd->disk_image == NULL) { - multi->addr = bnd->addr; - multi->addr.reuse = 0; - multi->size = bnd->size; - multi->cksum = bnd->cksum; - bnd->addr.addr = NULL; - } else { + /* + * Copy any disk image. Don't take saved updates without a + * disk image (which happens if they have been saved to the + * lookaside table): they should be discarded along with the + * original page. + */ + multi->disk_image = bnd->disk_image; + bnd->disk_image = NULL; + if (multi->disk_image != NULL) { multi->supd = bnd->supd; multi->supd_entries = bnd->supd_next; bnd->supd = NULL; - multi->disk_image = bnd->disk_image; - bnd->disk_image = NULL; } + + /* Copy any address. */ + multi->addr = bnd->addr; + multi->addr.reuse = 0; + multi->size = bnd->size; + multi->checksum = bnd->checksum; + bnd->addr.addr = NULL; } mod->mod_multi_entries = r->bnd_next; @@ -5855,19 +5879,26 @@ __rec_split_col(WT_SESSION_IMPL *session, WT_RECONCILE *r, WT_PAGE *page) bnd = r->bnd, i = 0; i < r->bnd_next; ++multi, ++bnd, ++i) { multi->key.recno = bnd->recno; - if (bnd->disk_image == NULL) { - multi->addr = bnd->addr; - multi->addr.reuse = 0; - multi->size = bnd->size; - multi->cksum = bnd->cksum; - bnd->addr.addr = NULL; - } else { + /* + * Copy any disk image. Don't take saved updates without a + * disk image (which happens if they have been saved to the + * lookaside table): they should be discarded along with the + * original page. + */ + multi->disk_image = bnd->disk_image; + bnd->disk_image = NULL; + if (multi->disk_image != NULL) { multi->supd = bnd->supd; multi->supd_entries = bnd->supd_next; bnd->supd = NULL; - multi->disk_image = bnd->disk_image; - bnd->disk_image = NULL; } + + /* Copy any address. */ + multi->addr = bnd->addr; + multi->addr.reuse = 0; + multi->size = bnd->size; + multi->checksum = bnd->checksum; + bnd->addr.addr = NULL; } mod->mod_multi_entries = r->bnd_next; @@ -6143,7 +6174,8 @@ __rec_cell_build_ovfl(WT_SESSION_IMPL *session, /* Write the buffer. */ addr = buf; - WT_ERR(__wt_bt_write(session, tmp, addr, &size, false, false)); + WT_ERR(__wt_bt_write(session, tmp, + addr, &size, false, F_ISSET(r, WT_CHECKPOINTING), false)); /* * Track the overflow record (unless it's a bulk load, which diff --git a/src/third_party/wiredtiger/src/schema/schema_create.c b/src/third_party/wiredtiger/src/schema/schema_create.c index f250612d0ae..ed88e687a19 100644 --- a/src/third_party/wiredtiger/src/schema/schema_create.c +++ b/src/third_party/wiredtiger/src/schema/schema_create.c @@ -446,7 +446,7 @@ __create_index(WT_SESSION_IMPL *session, */ npublic_cols = 0; if (!have_extractor) { - WT_ERR(__wt_config_subinit(session, &kcols, &icols)); + __wt_config_subinit(session, &kcols, &icols); while ((ret = __wt_config_next(&kcols, &ckey, &cval)) == 0) ++npublic_cols; WT_ERR_NOTFOUND_OK(ret); @@ -465,7 +465,7 @@ __create_index(WT_SESSION_IMPL *session, * key_format, which we are calculating now, but not part of an index * cursor's key_format. */ - WT_ERR(__wt_config_subinit(session, &pkcols, &table->colconf)); + __wt_config_subinit(session, &pkcols, &table->colconf); for (i = 0; i < table->nkey_columns && (ret = __wt_config_next(&pkcols, &ckey, &cval)) == 0; i++) { @@ -581,7 +581,7 @@ __create_table(WT_SESSION_IMPL *session, WT_ERR_NOTFOUND_OK(ret); WT_ERR(__wt_config_gets(session, cfg, "colgroups", &cval)); - WT_ERR(__wt_config_subinit(session, &conf, &cval)); + __wt_config_subinit(session, &conf, &cval); for (ncolgroups = 0; (ret = __wt_config_next(&conf, &cgkey, &cgval)) == 0; ncolgroups++) diff --git a/src/third_party/wiredtiger/src/schema/schema_open.c b/src/third_party/wiredtiger/src/schema/schema_open.c index 1554d021953..44bd66e011a 100644 --- a/src/third_party/wiredtiger/src/schema/schema_open.c +++ b/src/third_party/wiredtiger/src/schema/schema_open.c @@ -54,7 +54,7 @@ __wt_schema_open_colgroups(WT_SESSION_IMPL *session, WT_TABLE *table) WT_RET(__wt_scr_alloc(session, 0, &buf)); - WT_ERR(__wt_config_subinit(session, &cparser, &table->cgconf)); + __wt_config_subinit(session, &cparser, &table->cgconf); /* Open each column group. */ for (i = 0; i < WT_COLGROUPS(table); i++) { @@ -175,7 +175,7 @@ __open_index(WT_SESSION_IMPL *session, WT_TABLE *table, WT_INDEX *idx) session, idx->config, "columns", &idx->colconf)); /* Start with the declared index columns. */ - WT_ERR(__wt_config_subinit(session, &colconf, &idx->colconf)); + __wt_config_subinit(session, &colconf, &idx->colconf); for (npublic_cols = 0; (ret = __wt_config_next(&colconf, &ckey, &cval)) == 0; ++npublic_cols) @@ -202,7 +202,7 @@ __open_index(WT_SESSION_IMPL *session, WT_TABLE *table, WT_INDEX *idx) * Now add any primary key columns from the table that are not * already part of the index key. */ - WT_ERR(__wt_config_subinit(session, &colconf, &table->colconf)); + __wt_config_subinit(session, &colconf, &table->colconf); for (i = 0; i < table->nkey_columns && (ret = __wt_config_next(&colconf, &ckey, &cval)) == 0; i++) { @@ -465,7 +465,7 @@ __schema_open_table(WT_SESSION_IMPL *session, * Count the number of columns: tables are "simple" if the columns * are not named. */ - WT_ERR(__wt_config_subinit(session, &cparser, &table->colconf)); + __wt_config_subinit(session, &cparser, &table->colconf); table->is_simple = true; while ((ret = __wt_config_next(&cparser, &ckey, &cval)) == 0) table->is_simple = false; @@ -482,7 +482,7 @@ __schema_open_table(WT_SESSION_IMPL *session, "colgroups", &table->cgconf)); /* Count the number of column groups. */ - WT_ERR(__wt_config_subinit(session, &cparser, &table->cgconf)); + __wt_config_subinit(session, &cparser, &table->cgconf); table->ncolgroups = 0; while ((ret = __wt_config_next(&cparser, &ckey, &cval)) == 0) ++table->ncolgroups; diff --git a/src/third_party/wiredtiger/src/schema/schema_plan.c b/src/third_party/wiredtiger/src/schema/schema_plan.c index 12a1aa9c22f..475902be887 100644 --- a/src/third_party/wiredtiger/src/schema/schema_plan.c +++ b/src/third_party/wiredtiger/src/schema/schema_plan.c @@ -45,7 +45,7 @@ __find_next_col(WT_SESSION_IMPL *session, WT_TABLE *table, cgcols: cval = colgroup->colconf; col = table->nkey_columns; } - WT_RET(__wt_config_subinit(session, &conf, &cval)); + __wt_config_subinit(session, &conf, &cval); for (; (ret = __wt_config_next(&conf, &k, &v)) == 0; col++) { if (k.len == colname->len && strncmp(colname->str, k.str, k.len) == 0) { @@ -105,7 +105,7 @@ __wt_schema_colcheck(WT_SESSION_IMPL *session, WT_RET_TEST(ret != WT_NOTFOUND, ret); /* Walk through the named columns. */ - WT_RET(__wt_config_subinit(session, &conf, colconf)); + __wt_config_subinit(session, &conf, colconf); for (ncols = 0; (ret = __wt_config_next(&conf, &k, &v)) == 0; ncols++) ; WT_RET_TEST(ret != WT_NOTFOUND, ret); @@ -140,7 +140,7 @@ __wt_table_check(WT_SESSION_IMPL *session, WT_TABLE *table) return (0); /* Walk through the columns. */ - WT_RET(__wt_config_subinit(session, &conf, &table->colconf)); + __wt_config_subinit(session, &conf, &table->colconf); /* Skip over the key columns. */ for (i = 0; i < table->nkey_columns; i++) @@ -186,7 +186,7 @@ __wt_struct_plan(WT_SESSION_IMPL *session, WT_TABLE *table, start_cg = start_col = UINT_MAX; /* -Wuninitialized */ /* Work through the value columns by skipping over the key columns. */ - WT_RET(__wt_config_initn(session, &conf, columns, len)); + __wt_config_initn(session, &conf, columns, len); if (value_only) for (i = 0; i < table->nkey_columns; i++) WT_RET(__wt_config_next(&conf, &k, &v)); @@ -281,7 +281,7 @@ __find_column_format(WT_SESSION_IMPL *session, WT_TABLE *table, WT_PACK pack; bool inkey; - WT_RET(__wt_config_subinit(session, &conf, &table->colconf)); + __wt_config_subinit(session, &conf, &table->colconf); WT_RET(__pack_init(session, &pack, table->key_format)); inkey = true; @@ -323,7 +323,7 @@ __wt_struct_reformat(WT_SESSION_IMPL *session, WT_TABLE *table, WT_DECL_RET; bool have_next; - WT_RET(__wt_config_initn(session, &config, columns, len)); + __wt_config_initn(session, &config, columns, len); /* * If an empty column list is specified, this will fail with * WT_NOTFOUND, that's okay. @@ -331,7 +331,7 @@ __wt_struct_reformat(WT_SESSION_IMPL *session, WT_TABLE *table, WT_RET_NOTFOUND_OK(ret = __wt_config_next(&config, &next_k, &next_v)); if (ret == WT_NOTFOUND) { if (extra_cols != NULL) { - WT_RET(__wt_config_init(session, &config, extra_cols)); + __wt_config_init(session, &config, extra_cols); WT_RET(__wt_config_next(&config, &next_k, &next_v)); extra_cols = NULL; } else if (format->size == 0) { @@ -347,7 +347,7 @@ __wt_struct_reformat(WT_SESSION_IMPL *session, WT_TABLE *table, have_next = ret == 0; if (!have_next && extra_cols != NULL) { - WT_RET(__wt_config_init(session, &config, extra_cols)); + __wt_config_init(session, &config, extra_cols); WT_RET(__wt_config_next(&config, &next_k, &next_v)); have_next = true; extra_cols = NULL; diff --git a/src/third_party/wiredtiger/src/schema/schema_stat.c b/src/third_party/wiredtiger/src/schema/schema_stat.c index c204d6b1a24..1cd39d97364 100644 --- a/src/third_party/wiredtiger/src/schema/schema_stat.c +++ b/src/third_party/wiredtiger/src/schema/schema_stat.c @@ -83,7 +83,7 @@ __curstat_size_only(WT_SESSION_IMPL *session, * we determine that neither of those conditions can be satisfied. */ WT_ERR(__wt_config_getones(session, tableconf, "columns", &colconf)); - WT_ERR(__wt_config_subinit(session, &cparser, &colconf)); + __wt_config_subinit(session, &cparser, &colconf); if ((ret = __wt_config_next(&cparser, &ckey, &cval)) == 0) goto err; diff --git a/src/third_party/wiredtiger/src/session/session_api.c b/src/third_party/wiredtiger/src/session/session_api.c index 85d0fb1151c..82ce934c250 100644 --- a/src/third_party/wiredtiger/src/session/session_api.c +++ b/src/third_party/wiredtiger/src/session/session_api.c @@ -17,12 +17,8 @@ static int __session_rollback_transaction(WT_SESSION *, const char *); * Unsupported session method. */ int -__wt_session_notsup(WT_SESSION *wt_session) +__wt_session_notsup(WT_SESSION_IMPL *session) { - WT_SESSION_IMPL *session; - - session = (WT_SESSION_IMPL *)wt_session; - WT_RET_MSG(session, ENOTSUP, "Unsupported session method"); } @@ -66,10 +62,16 @@ __wt_session_copy_values(WT_SESSION_IMPL *session) TAILQ_FOREACH(cursor, &session->cursors, q) if (F_ISSET(cursor, WT_CURSTD_VALUE_INT)) { - /* We have to do this with a transaction ID pinned. */ - WT_ASSERT(session, - WT_SESSION_TXN_STATE(session)->snap_min != - WT_TXN_NONE); +#ifdef HAVE_DIAGNOSTIC + /* + * We have to do this with a transaction ID pinned + * unless the cursor is reading from a checkpoint. + */ + WT_TXN_STATE *txn_state = WT_SESSION_TXN_STATE(session); + WT_ASSERT(session, txn_state->snap_min != WT_TXN_NONE || + (WT_PREFIX_MATCH(cursor->uri, "file:") && + F_ISSET((WT_CURSOR_BTREE *)cursor, WT_CBT_NO_TXN))); +#endif F_CLR(cursor, WT_CURSTD_VALUE_INT); WT_RET(__wt_buf_set(session, &cursor->value, @@ -514,7 +516,11 @@ __session_create(WT_SESSION *wt_session, const char *uri, const char *config) ret = __wt_session_create(session, uri, config); -err: API_END_RET_NOTFOUND_MAP(session, ret); +err: if (ret != 0) + WT_STAT_FAST_CONN_INCR(session, session_table_create_fail); + else + WT_STAT_FAST_CONN_INCR(session, session_table_create_success); + API_END_RET_NOTFOUND_MAP(session, ret); } /* @@ -525,10 +531,18 @@ static int __session_create_readonly( WT_SESSION *wt_session, const char *uri, const char *config) { + WT_DECL_RET; + WT_SESSION_IMPL *session; + WT_UNUSED(uri); WT_UNUSED(config); - return (__wt_session_notsup(wt_session)); + session = (WT_SESSION_IMPL *)wt_session; + SESSION_API_CALL_NOCONF(session, create); + + WT_STAT_FAST_CONN_INCR(session, session_table_create_fail); + ret = __wt_session_notsup(session); +err: API_END_RET(session, ret); } /* @@ -575,9 +589,16 @@ err: API_END_RET(session, ret); static int __session_log_flush_readonly(WT_SESSION *wt_session, const char *config) { + WT_DECL_RET; + WT_SESSION_IMPL *session; + WT_UNUSED(config); - return (__wt_session_notsup(wt_session)); + session = (WT_SESSION_IMPL *)wt_session; + SESSION_API_CALL_NOCONF(session, log_flush); + + ret = __wt_session_notsup(session); +err: API_END_RET(session, ret); } /* @@ -610,9 +631,16 @@ static int __session_log_printf_readonly(WT_SESSION *wt_session, const char *fmt, ...) WT_GCC_FUNC_ATTRIBUTE((format (printf, 2, 3))) { + WT_DECL_RET; + WT_SESSION_IMPL *session; + WT_UNUSED(fmt); - return (__wt_session_notsup(wt_session)); + session = (WT_SESSION_IMPL *)wt_session; + SESSION_API_CALL_NOCONF(session, log_printf); + + ret = __wt_session_notsup(session); +err: API_END_RET(session, ret); } /* @@ -635,7 +663,12 @@ __session_rebalance(WT_SESSION *wt_session, const char *uri, const char *config) ret = __wt_schema_worker(session, uri, __wt_bt_rebalance, NULL, cfg, WT_DHANDLE_EXCLUSIVE | WT_BTREE_REBALANCE))); -err: API_END_RET_NOTFOUND_MAP(session, ret); +err: if (ret != 0) + WT_STAT_FAST_CONN_INCR(session, session_table_rebalance_fail); + else + WT_STAT_FAST_CONN_INCR(session, + session_table_rebalance_success); + API_END_RET_NOTFOUND_MAP(session, ret); } /* @@ -646,10 +679,18 @@ static int __session_rebalance_readonly( WT_SESSION *wt_session, const char *uri, const char *config) { + WT_DECL_RET; + WT_SESSION_IMPL *session; + WT_UNUSED(uri); WT_UNUSED(config); - return (__wt_session_notsup(wt_session)); + session = (WT_SESSION_IMPL *)wt_session; + SESSION_API_CALL_NOCONF(session, rebalance); + + WT_STAT_FAST_CONN_INCR(session, session_table_rebalance_fail); + ret = __wt_session_notsup(session); +err: API_END_RET(session, ret); } /* @@ -675,7 +716,11 @@ __session_rename(WT_SESSION *wt_session, WT_WITH_TABLE_LOCK(session, ret, ret = __wt_schema_rename(session, uri, newuri, cfg)))); -err: API_END_RET_NOTFOUND_MAP(session, ret); +err: if (ret != 0) + WT_STAT_FAST_CONN_INCR(session, session_table_rename_fail); + else + WT_STAT_FAST_CONN_INCR(session, session_table_rename_success); + API_END_RET_NOTFOUND_MAP(session, ret); } /* @@ -686,11 +731,19 @@ static int __session_rename_readonly(WT_SESSION *wt_session, const char *uri, const char *newuri, const char *config) { + WT_DECL_RET; + WT_SESSION_IMPL *session; + WT_UNUSED(uri); WT_UNUSED(newuri); WT_UNUSED(config); - return (__wt_session_notsup(wt_session)); + session = (WT_SESSION_IMPL *)wt_session; + SESSION_API_CALL_NOCONF(session, rename); + + WT_STAT_FAST_CONN_INCR(session, session_table_rename_fail); + ret = __wt_session_notsup(session); +err: API_END_RET(session, ret); } /* @@ -738,8 +791,8 @@ __wt_session_drop(WT_SESSION_IMPL *session, const char *uri, const char *cfg[]) F_SET(session, WT_SESSION_LOCK_NO_WAIT); /* - * The checkpoint lock only is needed to avoid a spurious EBUSY error - * return. + * Take the checkpoint lock if there is a need to prevent the drop + * operation from failing with EBUSY due to an ongoing checkpoint. */ if (checkpoint_wait) WT_WITH_CHECKPOINT_LOCK(session, ret, @@ -775,7 +828,12 @@ __session_drop(WT_SESSION *wt_session, const char *uri, const char *config) ret = __wt_session_drop(session, uri, cfg); -err: /* Note: drop operations cannot be unrolled (yet?). */ +err: if (ret != 0) + WT_STAT_FAST_CONN_INCR(session, session_table_drop_fail); + else + WT_STAT_FAST_CONN_INCR(session, session_table_drop_success); + + /* Note: drop operations cannot be unrolled (yet?). */ API_END_RET_NOTFOUND_MAP(session, ret); } @@ -787,10 +845,18 @@ static int __session_drop_readonly( WT_SESSION *wt_session, const char *uri, const char *config) { + WT_DECL_RET; + WT_SESSION_IMPL *session; + WT_UNUSED(uri); WT_UNUSED(config); - return (__wt_session_notsup(wt_session)); + session = (WT_SESSION_IMPL *)wt_session; + SESSION_API_CALL_NOCONF(session, drop); + + WT_STAT_FAST_CONN_INCR(session, session_table_drop_fail); + ret = __wt_session_notsup(session); +err: API_END_RET(session, ret); } /* @@ -948,7 +1014,11 @@ __session_salvage(WT_SESSION *wt_session, const char *uri, const char *config) ret = __wt_schema_worker(session, uri, __wt_salvage, NULL, cfg, WT_DHANDLE_EXCLUSIVE | WT_BTREE_SALVAGE))); -err: API_END_RET_NOTFOUND_MAP(session, ret); +err: if (ret != 0) + WT_STAT_FAST_CONN_INCR(session, session_table_salvage_fail); + else + WT_STAT_FAST_CONN_INCR(session, session_table_salvage_success); + API_END_RET_NOTFOUND_MAP(session, ret); } /* @@ -959,10 +1029,18 @@ static int __session_salvage_readonly( WT_SESSION *wt_session, const char *uri, const char *config) { + WT_DECL_RET; + WT_SESSION_IMPL *session; + WT_UNUSED(uri); WT_UNUSED(config); - return (__wt_session_notsup(wt_session)); + session = (WT_SESSION_IMPL *)wt_session; + SESSION_API_CALL_NOCONF(session, salvage); + + WT_STAT_FAST_CONN_INCR(session, session_table_salvage_fail); + ret = __wt_session_notsup(session); +err: API_END_RET(session, ret); } /* @@ -1140,6 +1218,10 @@ __session_truncate(WT_SESSION *wt_session, err: TXN_API_END_RETRY(session, ret, 0); + if (ret != 0) + WT_STAT_FAST_CONN_INCR(session, session_table_truncate_fail); + else + WT_STAT_FAST_CONN_INCR(session, session_table_truncate_success); /* * Only map WT_NOTFOUND to ENOENT if a URI was specified. */ @@ -1154,12 +1236,20 @@ static int __session_truncate_readonly(WT_SESSION *wt_session, const char *uri, WT_CURSOR *start, WT_CURSOR *stop, const char *config) { + WT_DECL_RET; + WT_SESSION_IMPL *session; + WT_UNUSED(uri); WT_UNUSED(start); WT_UNUSED(stop); WT_UNUSED(config); - return (__wt_session_notsup(wt_session)); + session = (WT_SESSION_IMPL *)wt_session; + SESSION_API_CALL_NOCONF(session, truncate); + + WT_STAT_FAST_CONN_INCR(session, session_table_truncate_fail); + ret = __wt_session_notsup(session); +err: API_END_RET(session, ret); } /* @@ -1192,10 +1282,17 @@ static int __session_upgrade_readonly( WT_SESSION *wt_session, const char *uri, const char *config) { + WT_DECL_RET; + WT_SESSION_IMPL *session; + WT_UNUSED(uri); WT_UNUSED(config); - return (__wt_session_notsup(wt_session)); + session = (WT_SESSION_IMPL *)wt_session; + SESSION_API_CALL_NOCONF(session, upgrade); + + ret = __wt_session_notsup(session); +err: API_END_RET(session, ret); } /* @@ -1221,7 +1318,11 @@ __session_verify(WT_SESSION *wt_session, const char *uri, const char *config) ret = __wt_schema_worker(session, uri, __wt_verify, NULL, cfg, WT_DHANDLE_EXCLUSIVE | WT_BTREE_VERIFY))); -err: API_END_RET_NOTFOUND_MAP(session, ret); +err: if (ret != 0) + WT_STAT_FAST_CONN_INCR(session, session_table_verify_fail); + else + WT_STAT_FAST_CONN_INCR(session, session_table_verify_success); + API_END_RET_NOTFOUND_MAP(session, ret); } /* @@ -1399,7 +1500,7 @@ __session_transaction_sync(WT_SESSION *wt_session, const char *config) * our timeout. */ while (__wt_log_cmp(&session->bg_sync_lsn, &log->sync_lsn) > 0) { - WT_ERR(__wt_cond_signal(session, conn->log_file_cond)); + __wt_cond_signal(session, conn->log_file_cond); WT_ERR(__wt_epoch(session, &now)); waited_ms = WT_TIMEDIFF_MS(now, start); if (forever || waited_ms < timeout_ms) @@ -1410,8 +1511,7 @@ __session_transaction_sync(WT_SESSION *wt_session, const char *config) * computing the wait time in msecs and passing that * in, unchanged, as the usecs to wait). */ - WT_ERR(__wt_cond_wait( - session, log->log_sync_cond, waited_ms)); + __wt_cond_wait(session, log->log_sync_cond, waited_ms); else WT_ERR(ETIMEDOUT); } @@ -1426,9 +1526,16 @@ err: API_END_RET(session, ret); static int __session_transaction_sync_readonly(WT_SESSION *wt_session, const char *config) { + WT_DECL_RET; + WT_SESSION_IMPL *session; + WT_UNUSED(config); - return (__wt_session_notsup(wt_session)); + session = (WT_SESSION_IMPL *)wt_session; + SESSION_API_CALL_NOCONF(session, transaction_sync); + + ret = __wt_session_notsup(session); +err: API_END_RET(session, ret); } /* @@ -1486,9 +1593,16 @@ err: API_END_RET_NOTFOUND_MAP(session, ret); static int __session_checkpoint_readonly(WT_SESSION *wt_session, const char *config) { + WT_DECL_RET; + WT_SESSION_IMPL *session; + WT_UNUSED(config); - return (__wt_session_notsup(wt_session)); + session = (WT_SESSION_IMPL *)wt_session; + SESSION_API_CALL_NOCONF(session, checkpoint); + + ret = __wt_session_notsup(session); +err: API_END_RET(session, ret); } /* @@ -1512,7 +1626,7 @@ __session_snapshot(WT_SESSION *wt_session, const char *config) WT_ERR(__wt_txn_named_snapshot_config( session, cfg, &has_create, &has_drop)); - WT_ERR(__wt_writelock(session, txn_global->nsnap_rwlock)); + __wt_writelock(session, txn_global->nsnap_rwlock); /* Drop any snapshots to be removed first. */ if (has_drop) @@ -1522,7 +1636,7 @@ __session_snapshot(WT_SESSION *wt_session, const char *config) if (has_create) WT_ERR(__wt_txn_named_snapshot_begin(session, cfg)); -err: WT_TRET(__wt_writeunlock(session, txn_global->nsnap_rwlock)); +err: __wt_writeunlock(session, txn_global->nsnap_rwlock); API_END_RET_NOTFOUND_MAP(session, ret); } diff --git a/src/third_party/wiredtiger/src/session/session_compact.c b/src/third_party/wiredtiger/src/session/session_compact.c index 3f7b34d132f..47ed5298304 100644 --- a/src/third_party/wiredtiger/src/session/session_compact.c +++ b/src/third_party/wiredtiger/src/session/session_compact.c @@ -333,6 +333,10 @@ err: session->compact = NULL; */ WT_TRET(__wt_session_release_resources(session)); + if (ret != 0) + WT_STAT_FAST_CONN_INCR(session, session_table_compact_fail); + else + WT_STAT_FAST_CONN_INCR(session, session_table_compact_success); API_END_RET_NOTFOUND_MAP(session, ret); } @@ -344,8 +348,16 @@ int __wt_session_compact_readonly( WT_SESSION *wt_session, const char *uri, const char *config) { + WT_DECL_RET; + WT_SESSION_IMPL *session; + WT_UNUSED(uri); WT_UNUSED(config); - return (__wt_session_notsup(wt_session)); + session = (WT_SESSION_IMPL *)wt_session; + SESSION_API_CALL_NOCONF(session, compact); + + WT_STAT_FAST_CONN_INCR(session, session_table_compact_fail); + ret = __wt_session_notsup(session); +err: API_END_RET(session, ret); } diff --git a/src/third_party/wiredtiger/src/session/session_dhandle.c b/src/third_party/wiredtiger/src/session/session_dhandle.c index ddf4d3dfa33..a899bad1b1f 100644 --- a/src/third_party/wiredtiger/src/session/session_dhandle.c +++ b/src/third_party/wiredtiger/src/session/session_dhandle.c @@ -183,17 +183,17 @@ __wt_session_lock_dhandle( */ if (F_ISSET(dhandle, WT_DHANDLE_OPEN) && (!want_exclusive || lock_busy)) { - WT_RET(__wt_readlock(session, dhandle->rwlock)); + __wt_readlock(session, dhandle->rwlock); if (F_ISSET(dhandle, WT_DHANDLE_DEAD)) { *is_deadp = 1; - return ( - __wt_readunlock(session, dhandle->rwlock)); + __wt_readunlock(session, dhandle->rwlock); + return (0); } is_open = F_ISSET(dhandle, WT_DHANDLE_OPEN); if (is_open && !want_exclusive) return (0); - WT_RET(__wt_readunlock(session, dhandle->rwlock)); + __wt_readunlock(session, dhandle->rwlock); } else is_open = false; @@ -206,8 +206,8 @@ __wt_session_lock_dhandle( if ((ret = __wt_try_writelock(session, dhandle->rwlock)) == 0) { if (F_ISSET(dhandle, WT_DHANDLE_DEAD)) { *is_deadp = 1; - return ( - __wt_writeunlock(session, dhandle->rwlock)); + __wt_writeunlock(session, dhandle->rwlock); + return (0); } /* @@ -217,8 +217,7 @@ __wt_session_lock_dhandle( if (F_ISSET(dhandle, WT_DHANDLE_OPEN) && !want_exclusive) { lock_busy = false; - WT_RET( - __wt_writeunlock(session, dhandle->rwlock)); + __wt_writeunlock(session, dhandle->rwlock); continue; } @@ -287,12 +286,11 @@ __wt_session_release_btree(WT_SESSION_IMPL *session) locked = false; } if (locked) { - if (write_locked) + if (write_locked) { F_CLR(dhandle, WT_DHANDLE_EXCLUSIVE); - - WT_TRET(write_locked ? - __wt_writeunlock(session, dhandle->rwlock): - __wt_readunlock(session, dhandle->rwlock)); + __wt_writeunlock(session, dhandle->rwlock); + } else + __wt_readunlock(session, dhandle->rwlock); } session->dhandle = NULL; @@ -514,7 +512,7 @@ __wt_session_get_btree(WT_SESSION_IMPL *session, dhandle->excl_session = NULL; dhandle->excl_ref = 0; F_CLR(dhandle, WT_DHANDLE_EXCLUSIVE); - WT_RET(__wt_writeunlock(session, dhandle->rwlock)); + __wt_writeunlock(session, dhandle->rwlock); WT_WITH_SCHEMA_LOCK(session, ret, WT_WITH_HANDLE_LIST_LOCK(session, @@ -536,7 +534,7 @@ __wt_session_get_btree(WT_SESSION_IMPL *session, dhandle->excl_session = NULL; dhandle->excl_ref = 0; F_CLR(dhandle, WT_DHANDLE_EXCLUSIVE); - WT_TRET(__wt_writeunlock(session, dhandle->rwlock)); + __wt_writeunlock(session, dhandle->rwlock); WT_RET(ret); } diff --git a/src/third_party/wiredtiger/src/support/cond_auto.c b/src/third_party/wiredtiger/src/support/cond_auto.c index ec95622f333..69114b066ae 100644 --- a/src/third_party/wiredtiger/src/support/cond_auto.c +++ b/src/third_party/wiredtiger/src/support/cond_auto.c @@ -58,12 +58,12 @@ __wt_cond_auto_alloc( * __wt_cond_auto_signal -- * Signal a condition variable. */ -int +void __wt_cond_auto_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond) { WT_ASSERT(session, cond->min_wait != 0); - return (__wt_cond_signal(session, cond)); + __wt_cond_signal(session, cond); } /* @@ -73,7 +73,7 @@ __wt_cond_auto_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond) * TODO: Can this version of the API be removed, now that we have the * auto adjusting condition variables? */ -int +void __wt_cond_auto_wait_signal( WT_SESSION_IMPL *session, WT_CONDVAR *cond, bool progress, bool *signalled) { @@ -94,15 +94,12 @@ __wt_cond_auto_wait_signal( cond->max_wait, cond->prev_wait + delta); } - WT_RET(__wt_cond_wait_signal( - session, cond, cond->prev_wait, signalled)); + __wt_cond_wait_signal(session, cond, cond->prev_wait, signalled); if (progress || *signalled) WT_STAT_FAST_CONN_INCR(session, cond_auto_wait_reset); if (*signalled) cond->prev_wait = cond->min_wait; - - return (0); } /* @@ -110,7 +107,7 @@ __wt_cond_auto_wait_signal( * Wait on a mutex, optionally timing out. If we get it before the time * out period expires, let the caller know. */ -int +void __wt_cond_auto_wait( WT_SESSION_IMPL *session, WT_CONDVAR *cond, bool progress) { @@ -120,9 +117,7 @@ __wt_cond_auto_wait( * Call the signal version so the wait period is reset if the * condition is woken explicitly. */ - WT_RET(__wt_cond_auto_wait_signal(session, cond, progress, &signalled)); - - return (0); + __wt_cond_auto_wait_signal(session, cond, progress, &signalled); } /* diff --git a/src/third_party/wiredtiger/src/support/err.c b/src/third_party/wiredtiger/src/support/err.c index 93c0af37328..8bfac250b3a 100644 --- a/src/third_party/wiredtiger/src/support/err.c +++ b/src/third_party/wiredtiger/src/support/err.c @@ -118,7 +118,13 @@ __handler_failure(WT_SESSION_IMPL *session, handler->handle_error(handler, wt_session, error, s) == 0) return; + /* + * In case there is a failure in the default error handler, make sure + * we don't recursively try to report *that* error. + */ + session->event_handler = &__event_handler_default; (void)__handle_error_default(NULL, wt_session, error, s); + session->event_handler = handler; } /* @@ -149,6 +155,7 @@ __wt_event_handler_set(WT_SESSION_IMPL *session, WT_EVENT_HANDLER *handler) int __wt_eventv(WT_SESSION_IMPL *session, bool msg_event, int error, const char *file_name, int line_number, const char *fmt, va_list ap) + WT_GCC_FUNC_ATTRIBUTE((cold)) { WT_EVENT_HANDLER *handler; WT_DECL_RET; @@ -308,6 +315,7 @@ __wt_eventv(WT_SESSION_IMPL *session, bool msg_event, int error, */ void __wt_err(WT_SESSION_IMPL *session, int error, const char *fmt, ...) + WT_GCC_FUNC_ATTRIBUTE((cold)) WT_GCC_FUNC_ATTRIBUTE((format (printf, 3, 4))) { va_list ap; @@ -317,7 +325,7 @@ __wt_err(WT_SESSION_IMPL *session, int error, const char *fmt, ...) * an error value to return. */ va_start(ap, fmt); - (void)__wt_eventv(session, false, error, NULL, 0, fmt, ap); + WT_IGNORE_RET(__wt_eventv(session, false, error, NULL, 0, fmt, ap)); va_end(ap); } @@ -327,6 +335,7 @@ __wt_err(WT_SESSION_IMPL *session, int error, const char *fmt, ...) */ void __wt_errx(WT_SESSION_IMPL *session, const char *fmt, ...) + WT_GCC_FUNC_ATTRIBUTE((cold)) WT_GCC_FUNC_ATTRIBUTE((format (printf, 2, 3))) { va_list ap; @@ -336,7 +345,7 @@ __wt_errx(WT_SESSION_IMPL *session, const char *fmt, ...) * an error value to return. */ va_start(ap, fmt); - (void)__wt_eventv(session, false, 0, NULL, 0, fmt, ap); + WT_IGNORE_RET(__wt_eventv(session, false, 0, NULL, 0, fmt, ap)); va_end(ap); } @@ -392,6 +401,7 @@ info_msg(WT_SESSION_IMPL *session, const char *fmt, va_list ap) */ int __wt_msg(WT_SESSION_IMPL *session, const char *fmt, ...) + WT_GCC_FUNC_ATTRIBUTE((cold)) WT_GCC_FUNC_ATTRIBUTE((format (printf, 2, 3))) { WT_DECL_RET; @@ -468,6 +478,7 @@ __wt_progress(WT_SESSION_IMPL *session, const char *s, uint64_t v) void __wt_assert(WT_SESSION_IMPL *session, int error, const char *file_name, int line_number, const char *fmt, ...) + WT_GCC_FUNC_ATTRIBUTE((cold)) WT_GCC_FUNC_ATTRIBUTE((format (printf, 5, 6))) #ifdef HAVE_DIAGNOSTIC WT_GCC_FUNC_ATTRIBUTE((noreturn)) @@ -476,8 +487,8 @@ __wt_assert(WT_SESSION_IMPL *session, va_list ap; va_start(ap, fmt); - (void)__wt_eventv( - session, false, error, file_name, line_number, fmt, ap); + WT_IGNORE_RET(__wt_eventv( + session, false, error, file_name, line_number, fmt, ap)); va_end(ap); #ifdef HAVE_DIAGNOSTIC @@ -492,6 +503,7 @@ __wt_assert(WT_SESSION_IMPL *session, */ int __wt_panic(WT_SESSION_IMPL *session) + WT_GCC_FUNC_ATTRIBUTE((cold)) { F_SET(S2C(session), WT_CONN_PANIC); __wt_err(session, WT_PANIC, "the process must exit and restart"); @@ -515,6 +527,7 @@ __wt_panic(WT_SESSION_IMPL *session) */ int __wt_illegal_value(WT_SESSION_IMPL *session, const char *name) + WT_GCC_FUNC_ATTRIBUTE((cold)) { __wt_errx(session, "%s%s%s", name == NULL ? "" : name, name == NULL ? "" : ": ", @@ -535,6 +548,7 @@ __wt_illegal_value(WT_SESSION_IMPL *session, const char *name) */ int __wt_object_unsupported(WT_SESSION_IMPL *session, const char *uri) + WT_GCC_FUNC_ATTRIBUTE((cold)) { WT_RET_MSG(session, ENOTSUP, "unsupported object operation: %s", uri); } @@ -546,6 +560,7 @@ __wt_object_unsupported(WT_SESSION_IMPL *session, const char *uri) */ int __wt_bad_object_type(WT_SESSION_IMPL *session, const char *uri) + WT_GCC_FUNC_ATTRIBUTE((cold)) { if (WT_PREFIX_MATCH(uri, "backup:") || WT_PREFIX_MATCH(uri, "colgroup:") || diff --git a/src/third_party/wiredtiger/src/support/global.c b/src/third_party/wiredtiger/src/support/global.c index eba88bf2b20..aa69e0db9d6 100644 --- a/src/third_party/wiredtiger/src/support/global.c +++ b/src/third_party/wiredtiger/src/support/global.c @@ -55,13 +55,13 @@ __wt_global_once(void) return; } - __wt_cksum_init(); + __wt_checksum_init(); TAILQ_INIT(&__wt_process.connqh); #ifdef HAVE_DIAGNOSTIC /* Load debugging code the compiler might optimize out. */ - (void)__wt_breakpoint(); + __wt_breakpoint(); #endif } @@ -97,10 +97,14 @@ __wt_library_init(void) * __wt_breakpoint -- * A simple place to put a breakpoint, if you need one. */ -int +void __wt_breakpoint(void) { - return (0); + /* + * Yield the processor (just to keep the compiler from optimizing the + * function out). + */ + __wt_yield(); } /* diff --git a/src/third_party/wiredtiger/src/support/hazard.c b/src/third_party/wiredtiger/src/support/hazard.c index dee85586a4d..8ac8f5f9f6d 100644 --- a/src/third_party/wiredtiger/src/support/hazard.c +++ b/src/third_party/wiredtiger/src/support/hazard.c @@ -238,6 +238,25 @@ __wt_hazard_close(WT_SESSION_IMPL *session) (void *)session); } +/* + * __wt_hazard_count -- + * Count how many hazard pointers this session has on the given page. + */ +u_int +__wt_hazard_count(WT_SESSION_IMPL *session, WT_PAGE *page) +{ + WT_HAZARD *hp; + u_int count; + + for (count = 0, hp = session->hazard + session->hazard_size - 1; + hp >= session->hazard; + --hp) + if (hp->page == page) + ++count; + + return (count); +} + #ifdef HAVE_DIAGNOSTIC /* * __hazard_dump -- diff --git a/src/third_party/wiredtiger/src/support/huffman.c b/src/third_party/wiredtiger/src/support/huffman.c index 05612cdbe80..3ec282915ca 100644 --- a/src/third_party/wiredtiger/src/support/huffman.c +++ b/src/third_party/wiredtiger/src/support/huffman.c @@ -560,7 +560,7 @@ __wt_huffman_close(WT_SESSION_IMPL *session, void *huffman_arg) * __wt_print_huffman_code -- * Prints a symbol's Huffman code. */ -int +void __wt_print_huffman_code(void *huffman_arg, uint16_t symbol) { WT_HUFFMAN_CODE code; @@ -583,8 +583,6 @@ __wt_print_huffman_code(void *huffman_arg, uint16_t symbol) "%" PRIx16 ", length %" PRIu8 "\n", symbol, code.pattern, code.length); } - - return (0); } #endif diff --git a/src/third_party/wiredtiger/src/support/mtx_rw.c b/src/third_party/wiredtiger/src/support/mtx_rw.c index dbf73bb4f13..0bdde81c32f 100644 --- a/src/third_party/wiredtiger/src/support/mtx_rw.c +++ b/src/third_party/wiredtiger/src/support/mtx_rw.c @@ -45,19 +45,19 @@ * struct { * uint16_t writers; Now serving for writers * uint16_t readers; Now serving for readers - * uint16_t users; Next available ticket number + * uint16_t next; Next available ticket number * uint16_t __notused; Padding * } * * First, imagine a store's 'take a number' ticket algorithm. A customer takes * a unique ticket number and customers are served in ticket order. In the data * structure, 'writers' is the next writer to be served, 'readers' is the next - * reader to be served, and 'users' is the next available ticket number. + * reader to be served, and 'next' is the next available ticket number. * * Next, consider exclusive (write) locks. The 'now serving' number for writers * is 'writers'. To lock, 'take a number' and wait until that number is being * served; more specifically, atomically copy and increment the current value of - * 'users', and then wait until 'writers' equals that copied number. + * 'next', and then wait until 'writers' equals that copied number. * * Shared (read) locks are similar. Like writers, readers atomically get the * next number available. However, instead of waiting for 'writers' to equal @@ -74,7 +74,7 @@ * * For example, consider the following read (R) and write (W) lock requests: * - * writers readers users + * writers readers next * 0 0 0 * R: ticket 0, readers match OK 0 1 1 * R: ticket 1, readers match OK 0 2 2 @@ -92,7 +92,7 @@ * and the next ticket holder (reader or writer) will unblock when the writer * unlocks. An example, continuing from the last line of the above example: * - * writers readers users + * writers readers next * W: ticket 3, writers match OK 3 3 4 * R: ticket 4, readers no match block 3 3 5 * R: ticket 5, readers no match block 3 3 6 @@ -101,8 +101,8 @@ * R: ticket 4, readers match OK 4 5 7 * R: ticket 5, readers match OK 4 6 7 * - * The 'users' field is a 2-byte value so the available ticket number wraps at - * 64K requests. If a thread's lock request is not granted until the 'users' + * The 'next' field is a 2-byte value so the available ticket number wraps at + * 64K requests. If a thread's lock request is not granted until the 'next' * field cycles and the same ticket is taken by another thread, we could grant * a lock to two separate threads at the same time, and bad things happen: two * writer threads or a reader thread and a writer thread would run in parallel, @@ -124,7 +124,7 @@ __wt_rwlock_alloc( { WT_RWLOCK *rwlock; - WT_RET(__wt_verbose(session, WT_VERB_MUTEX, "rwlock: alloc %s", name)); + __wt_verbose(session, WT_VERB_MUTEX, "rwlock: alloc %s", name); WT_RET(__wt_calloc_one(session, &rwlock)); @@ -143,8 +143,6 @@ __wt_try_readlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) { wt_rwlock_t *l, new, old; - WT_RET(__wt_verbose( - session, WT_VERB_MUTEX, "rwlock: try_readlock %s", rwlock->name)); WT_STAT_FAST_CONN_INCR(session, rwlock_read); l = &rwlock->rwlock; @@ -157,14 +155,14 @@ __wt_try_readlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) * Do the cheap test to see if this can possibly succeed (and confirm * the lock is in the correct state to grant this read lock). */ - if (old.s.readers != old.s.users) + if (old.s.readers != old.s.next) return (EBUSY); /* * The replacement lock value is a result of allocating a new ticket and * incrementing the reader value to match it. */ - new.s.readers = new.s.users = old.s.users + 1; + new.s.readers = new.s.next = old.s.next + 1; return (__wt_atomic_cas64(&l->u, old.u, new.u) ? 0 : EBUSY); } @@ -172,15 +170,13 @@ __wt_try_readlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) * __wt_readlock -- * Get a shared lock. */ -int +void __wt_readlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) { wt_rwlock_t *l; uint16_t ticket; int pause_cnt; - WT_RET(__wt_verbose( - session, WT_VERB_MUTEX, "rwlock: readlock %s", rwlock->name)); WT_STAT_FAST_CONN_INCR(session, rwlock_read); WT_DIAGNOSTIC_YIELD; @@ -192,7 +188,7 @@ __wt_readlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) * value will wrap and two lockers will simultaneously be granted the * lock. */ - ticket = __wt_atomic_fetch_add16(&l->s.users, 1); + ticket = __wt_atomic_fetch_add16(&l->s.next, 1); for (pause_cnt = 0; ticket != l->s.readers;) { /* * We failed to get the lock; pause before retrying and if we've @@ -220,21 +216,18 @@ __wt_readlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) * lock see consistent data. */ WT_READ_BARRIER(); - - return (0); } /* * __wt_readunlock -- * Release a shared lock. */ -int +void __wt_readunlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) { wt_rwlock_t *l; - WT_RET(__wt_verbose( - session, WT_VERB_MUTEX, "rwlock: read unlock %s", rwlock->name)); + WT_UNUSED(session); l = &rwlock->rwlock; @@ -243,8 +236,6 @@ __wt_readunlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) * sure we don't race). */ (void)__wt_atomic_add16(&l->s.writers, 1); - - return (0); } /* @@ -256,8 +247,6 @@ __wt_try_writelock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) { wt_rwlock_t *l, new, old; - WT_RET(__wt_verbose( - session, WT_VERB_MUTEX, "rwlock: try_writelock %s", rwlock->name)); WT_STAT_FAST_CONN_INCR(session, rwlock_write); l = &rwlock->rwlock; @@ -270,11 +259,11 @@ __wt_try_writelock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) * Do the cheap test to see if this can possibly succeed (and confirm * the lock is in the correct state to grant this write lock). */ - if (old.s.writers != old.s.users) + if (old.s.writers != old.s.next) return (EBUSY); /* The replacement lock value is a result of allocating a new ticket. */ - ++new.s.users; + ++new.s.next; return (__wt_atomic_cas64(&l->u, old.u, new.u) ? 0 : EBUSY); } @@ -282,15 +271,13 @@ __wt_try_writelock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) * __wt_writelock -- * Wait to get an exclusive lock. */ -int +void __wt_writelock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) { wt_rwlock_t *l; uint16_t ticket; int pause_cnt; - WT_RET(__wt_verbose( - session, WT_VERB_MUTEX, "rwlock: writelock %s", rwlock->name)); WT_STAT_FAST_CONN_INCR(session, rwlock_write); l = &rwlock->rwlock; @@ -300,7 +287,7 @@ __wt_writelock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) * value will wrap and two lockers will simultaneously be granted the * lock. */ - ticket = __wt_atomic_fetch_add16(&l->s.users, 1); + ticket = __wt_atomic_fetch_add16(&l->s.next, 1); for (pause_cnt = 0; ticket != l->s.writers;) { /* * We failed to get the lock; pause before retrying and if we've @@ -319,21 +306,18 @@ __wt_writelock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) * lock see consistent data. */ WT_READ_BARRIER(); - - return (0); } /* * __wt_writeunlock -- * Release an exclusive lock. */ -int +void __wt_writeunlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) { wt_rwlock_t *l, new; - WT_RET(__wt_verbose( - session, WT_VERB_MUTEX, "rwlock: writeunlock %s", rwlock->name)); + WT_UNUSED(session); /* * Ensure that all updates made while the lock was held are visible to @@ -356,27 +340,42 @@ __wt_writeunlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) l->i.wr = new.i.wr; WT_DIAGNOSTIC_YIELD; - - return (0); } /* * __wt_rwlock_destroy -- * Destroy a read/write lock. */ -int +void __wt_rwlock_destroy(WT_SESSION_IMPL *session, WT_RWLOCK **rwlockp) { WT_RWLOCK *rwlock; rwlock = *rwlockp; /* Clear our caller's reference. */ if (rwlock == NULL) - return (0); + return; *rwlockp = NULL; - WT_RET(__wt_verbose( - session, WT_VERB_MUTEX, "rwlock: destroy %s", rwlock->name)); + __wt_verbose( + session, WT_VERB_MUTEX, "rwlock: destroy %s", rwlock->name); __wt_free(session, rwlock); - return (0); } + +#ifdef HAVE_DIAGNOSTIC +/* + * __wt_rwlock_islocked -- + * Return if a read/write lock is currently locked for reading or writing. + */ +bool +__wt_rwlock_islocked(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock) +{ + wt_rwlock_t *l; + + WT_UNUSED(session); + + l = &rwlock->rwlock; + + return (l->s.writers != l->s.next || l->s.readers != l->s.next); +} +#endif diff --git a/src/third_party/wiredtiger/src/support/stat.c b/src/third_party/wiredtiger/src/support/stat.c index d972f0c140f..81859ef1ca8 100644 --- a/src/third_party/wiredtiger/src/support/stat.c +++ b/src/third_party/wiredtiger/src/support/stat.c @@ -43,6 +43,7 @@ static const char * const __stats_dsrc_desc[] = { "btree: pages rewritten by compaction", "btree: row-store internal pages", "btree: row-store leaf pages", + "cache: bytes currently in the cache", "cache: bytes read into cache", "cache: bytes written from cache", "cache: checkpoint blocked page eviction", @@ -173,6 +174,7 @@ __wt_stat_dsrc_clear_single(WT_DSRC_STATS *stats) stats->btree_compact_rewrite = 0; stats->btree_row_internal = 0; stats->btree_row_leaf = 0; + /* not clearing cache_bytes_inuse */ stats->cache_bytes_read = 0; stats->cache_bytes_write = 0; stats->cache_eviction_checkpoint = 0; @@ -300,6 +302,7 @@ __wt_stat_dsrc_aggregate_single( to->btree_compact_rewrite += from->btree_compact_rewrite; to->btree_row_internal += from->btree_row_internal; to->btree_row_leaf += from->btree_row_leaf; + to->cache_bytes_inuse += from->cache_bytes_inuse; to->cache_bytes_read += from->cache_bytes_read; to->cache_bytes_write += from->cache_bytes_write; to->cache_eviction_checkpoint += from->cache_eviction_checkpoint; @@ -433,6 +436,7 @@ __wt_stat_dsrc_aggregate( WT_STAT_READ(from, btree_compact_rewrite); to->btree_row_internal += WT_STAT_READ(from, btree_row_internal); to->btree_row_leaf += WT_STAT_READ(from, btree_row_leaf); + to->cache_bytes_inuse += WT_STAT_READ(from, cache_bytes_inuse); to->cache_bytes_read += WT_STAT_READ(from, cache_bytes_read); to->cache_bytes_write += WT_STAT_READ(from, cache_bytes_write); to->cache_eviction_checkpoint += @@ -542,9 +546,12 @@ static const char * const __stats_connection_desc[] = { "block-manager: blocks written", "block-manager: bytes read", "block-manager: bytes written", + "block-manager: bytes written for checkpoint", "block-manager: mapped blocks read", "block-manager: mapped bytes read", + "cache: bytes belonging to page images in the cache", "cache: bytes currently in the cache", + "cache: bytes not belonging to page images in the cache", "cache: bytes read into cache", "cache: bytes written from cache", "cache: checkpoint blocked page eviction", @@ -555,10 +562,9 @@ static const char * const __stats_connection_desc[] = { "cache: eviction server candidate queue empty when topping up", "cache: eviction server candidate queue not empty when topping up", "cache: eviction server evicting pages", - "cache: eviction server populating queue, but not evicting pages", - "cache: eviction server skipped very large page", "cache: eviction server slept, because we did not make progress with eviction", "cache: eviction server unable to reach eviction goal", + "cache: eviction state", "cache: eviction worker thread evicting pages", "cache: failed eviction of pages that exceeded the in-memory maximum", "cache: files with active eviction walks", @@ -578,6 +584,8 @@ static const char * const __stats_connection_desc[] = { "cache: maximum page size at eviction", "cache: modified pages evicted", "cache: modified pages evicted by application threads", + "cache: overflow pages read into cache", + "cache: overflow values cached in memory", "cache: page split during eviction deepened the tree", "cache: page written requiring lookaside records", "cache: pages currently held in the cache", @@ -586,6 +594,7 @@ static const char * const __stats_connection_desc[] = { "cache: pages evicted by application threads", "cache: pages queued for eviction", "cache: pages queued for urgent eviction", + "cache: pages queued for urgent eviction during walk", "cache: pages read into cache", "cache: pages read into cache requiring lookaside entries", "cache: pages requested from the cache", @@ -597,7 +606,6 @@ static const char * const __stats_connection_desc[] = { "cache: percentage overhead", "cache: tracked bytes belonging to internal pages in the cache", "cache: tracked bytes belonging to leaf pages in the cache", - "cache: tracked bytes belonging to overflow pages in the cache", "cache: tracked dirty bytes in the cache", "cache: tracked dirty pages in the cache", "cache: unmodified pages evicted", @@ -677,6 +685,22 @@ static const char * const __stats_connection_desc[] = { "reconciliation: split objects currently awaiting free", "session: open cursor count", "session: open session count", + "session: table compact failed calls", + "session: table compact successful calls", + "session: table create failed calls", + "session: table create successful calls", + "session: table drop failed calls", + "session: table drop successful calls", + "session: table rebalance failed calls", + "session: table rebalance successful calls", + "session: table rename failed calls", + "session: table rename successful calls", + "session: table salvage failed calls", + "session: table salvage successful calls", + "session: table truncate failed calls", + "session: table truncate successful calls", + "session: table verify failed calls", + "session: table verify successful calls", "thread-state: active filesystem fsync calls", "thread-state: active filesystem read calls", "thread-state: active filesystem write calls", @@ -693,13 +717,13 @@ static const char * const __stats_connection_desc[] = { "transaction: transaction checkpoint max time (msecs)", "transaction: transaction checkpoint min time (msecs)", "transaction: transaction checkpoint most recent time (msecs)", + "transaction: transaction checkpoint scrub dirty target", + "transaction: transaction checkpoint scrub time (msecs)", "transaction: transaction checkpoint total time (msecs)", "transaction: transaction checkpoints", "transaction: transaction failures due to cache overflow", "transaction: transaction fsync calls for checkpoint after allocating the transaction ID", - "transaction: transaction fsync calls for checkpoint before allocating the transaction ID", "transaction: transaction fsync duration for checkpoint after allocating the transaction ID (usecs)", - "transaction: transaction fsync duration for checkpoint before allocating the transaction ID (usecs)", "transaction: transaction range of IDs currently pinned", "transaction: transaction range of IDs currently pinned by a checkpoint", "transaction: transaction range of IDs currently pinned by named snapshots", @@ -764,9 +788,12 @@ __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats) stats->block_write = 0; stats->block_byte_read = 0; stats->block_byte_write = 0; + stats->block_byte_write_checkpoint = 0; stats->block_map_read = 0; stats->block_byte_map_read = 0; + /* not clearing cache_bytes_image */ /* not clearing cache_bytes_inuse */ + /* not clearing cache_bytes_other */ stats->cache_bytes_read = 0; stats->cache_bytes_write = 0; stats->cache_eviction_checkpoint = 0; @@ -777,10 +804,9 @@ __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats) stats->cache_eviction_queue_empty = 0; stats->cache_eviction_queue_not_empty = 0; stats->cache_eviction_server_evicting = 0; - stats->cache_eviction_server_not_evicting = 0; - stats->cache_eviction_server_toobig = 0; stats->cache_eviction_server_slept = 0; stats->cache_eviction_slow = 0; + /* not clearing cache_eviction_state */ stats->cache_eviction_worker_evicting = 0; stats->cache_eviction_force_fail = 0; /* not clearing cache_eviction_walks_active */ @@ -800,6 +826,8 @@ __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats) /* not clearing cache_eviction_maximum_page_size */ stats->cache_eviction_dirty = 0; stats->cache_eviction_app_dirty = 0; + stats->cache_read_overflow = 0; + stats->cache_overflow_value = 0; stats->cache_eviction_deepen = 0; stats->cache_write_lookaside = 0; /* not clearing cache_pages_inuse */ @@ -807,6 +835,7 @@ __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats) stats->cache_eviction_force_delete = 0; stats->cache_eviction_app = 0; stats->cache_eviction_pages_queued = 0; + stats->cache_eviction_pages_queued_urgent = 0; stats->cache_eviction_pages_queued_oldest = 0; stats->cache_read = 0; stats->cache_read_lookaside = 0; @@ -819,7 +848,6 @@ __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats) /* not clearing cache_overhead */ /* not clearing cache_bytes_internal */ /* not clearing cache_bytes_leaf */ - /* not clearing cache_bytes_overflow */ /* not clearing cache_bytes_dirty */ /* not clearing cache_pages_dirty */ stats->cache_eviction_clean = 0; @@ -875,9 +903,9 @@ __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats) stats->log_write_lsn = 0; stats->log_write_lsn_skip = 0; stats->log_sync = 0; - stats->log_sync_duration = 0; + /* not clearing log_sync_duration */ stats->log_sync_dir = 0; - stats->log_sync_dir_duration = 0; + /* not clearing log_sync_dir_duration */ stats->log_writes = 0; stats->log_slot_consolidated = 0; /* not clearing log_max_filesize */ @@ -899,9 +927,25 @@ __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats) /* not clearing rec_split_stashed_objects */ /* not clearing session_cursor_open */ /* not clearing session_open */ - /* not clearing fsync_active */ - /* not clearing read_active */ - /* not clearing write_active */ + /* not clearing session_table_compact_fail */ + /* not clearing session_table_compact_success */ + /* not clearing session_table_create_fail */ + /* not clearing session_table_create_success */ + /* not clearing session_table_drop_fail */ + /* not clearing session_table_drop_success */ + /* not clearing session_table_rebalance_fail */ + /* not clearing session_table_rebalance_success */ + /* not clearing session_table_rename_fail */ + /* not clearing session_table_rename_success */ + /* not clearing session_table_salvage_fail */ + /* not clearing session_table_salvage_success */ + /* not clearing session_table_truncate_fail */ + /* not clearing session_table_truncate_success */ + /* not clearing session_table_verify_fail */ + /* not clearing session_table_verify_success */ + /* not clearing thread_fsync_active */ + /* not clearing thread_read_active */ + /* not clearing thread_write_active */ stats->page_busy_blocked = 0; stats->page_forcible_evict_blocked = 0; stats->page_locked_blocked = 0; @@ -915,13 +959,13 @@ __wt_stat_connection_clear_single(WT_CONNECTION_STATS *stats) /* not clearing txn_checkpoint_time_max */ /* not clearing txn_checkpoint_time_min */ /* not clearing txn_checkpoint_time_recent */ + /* not clearing txn_checkpoint_scrub_target */ + /* not clearing txn_checkpoint_scrub_time */ /* not clearing txn_checkpoint_time_total */ stats->txn_checkpoint = 0; stats->txn_fail_cache = 0; stats->txn_checkpoint_fsync_post = 0; - stats->txn_checkpoint_fsync_pre = 0; - stats->txn_checkpoint_fsync_post_duration = 0; - stats->txn_checkpoint_fsync_pre_duration = 0; + /* not clearing txn_checkpoint_fsync_post_duration */ /* not clearing txn_pinned_range */ /* not clearing txn_pinned_checkpoint_range */ /* not clearing txn_pinned_snapshot_range */ @@ -978,9 +1022,13 @@ __wt_stat_connection_aggregate( to->block_write += WT_STAT_READ(from, block_write); to->block_byte_read += WT_STAT_READ(from, block_byte_read); to->block_byte_write += WT_STAT_READ(from, block_byte_write); + to->block_byte_write_checkpoint += + WT_STAT_READ(from, block_byte_write_checkpoint); to->block_map_read += WT_STAT_READ(from, block_map_read); to->block_byte_map_read += WT_STAT_READ(from, block_byte_map_read); + to->cache_bytes_image += WT_STAT_READ(from, cache_bytes_image); to->cache_bytes_inuse += WT_STAT_READ(from, cache_bytes_inuse); + to->cache_bytes_other += WT_STAT_READ(from, cache_bytes_other); to->cache_bytes_read += WT_STAT_READ(from, cache_bytes_read); to->cache_bytes_write += WT_STAT_READ(from, cache_bytes_write); to->cache_eviction_checkpoint += @@ -999,13 +1047,10 @@ __wt_stat_connection_aggregate( WT_STAT_READ(from, cache_eviction_queue_not_empty); to->cache_eviction_server_evicting += WT_STAT_READ(from, cache_eviction_server_evicting); - to->cache_eviction_server_not_evicting += - WT_STAT_READ(from, cache_eviction_server_not_evicting); - to->cache_eviction_server_toobig += - WT_STAT_READ(from, cache_eviction_server_toobig); to->cache_eviction_server_slept += WT_STAT_READ(from, cache_eviction_server_slept); to->cache_eviction_slow += WT_STAT_READ(from, cache_eviction_slow); + to->cache_eviction_state += WT_STAT_READ(from, cache_eviction_state); to->cache_eviction_worker_evicting += WT_STAT_READ(from, cache_eviction_worker_evicting); to->cache_eviction_force_fail += @@ -1039,6 +1084,8 @@ __wt_stat_connection_aggregate( to->cache_eviction_dirty += WT_STAT_READ(from, cache_eviction_dirty); to->cache_eviction_app_dirty += WT_STAT_READ(from, cache_eviction_app_dirty); + to->cache_read_overflow += WT_STAT_READ(from, cache_read_overflow); + to->cache_overflow_value += WT_STAT_READ(from, cache_overflow_value); to->cache_eviction_deepen += WT_STAT_READ(from, cache_eviction_deepen); to->cache_write_lookaside += @@ -1050,6 +1097,8 @@ __wt_stat_connection_aggregate( to->cache_eviction_app += WT_STAT_READ(from, cache_eviction_app); to->cache_eviction_pages_queued += WT_STAT_READ(from, cache_eviction_pages_queued); + to->cache_eviction_pages_queued_urgent += + WT_STAT_READ(from, cache_eviction_pages_queued_urgent); to->cache_eviction_pages_queued_oldest += WT_STAT_READ(from, cache_eviction_pages_queued_oldest); to->cache_read += WT_STAT_READ(from, cache_read); @@ -1065,7 +1114,6 @@ __wt_stat_connection_aggregate( to->cache_overhead += WT_STAT_READ(from, cache_overhead); to->cache_bytes_internal += WT_STAT_READ(from, cache_bytes_internal); to->cache_bytes_leaf += WT_STAT_READ(from, cache_bytes_leaf); - to->cache_bytes_overflow += WT_STAT_READ(from, cache_bytes_overflow); to->cache_bytes_dirty += WT_STAT_READ(from, cache_bytes_dirty); to->cache_pages_dirty += WT_STAT_READ(from, cache_pages_dirty); to->cache_eviction_clean += WT_STAT_READ(from, cache_eviction_clean); @@ -1151,9 +1199,41 @@ __wt_stat_connection_aggregate( WT_STAT_READ(from, rec_split_stashed_objects); to->session_cursor_open += WT_STAT_READ(from, session_cursor_open); to->session_open += WT_STAT_READ(from, session_open); - to->fsync_active += WT_STAT_READ(from, fsync_active); - to->read_active += WT_STAT_READ(from, read_active); - to->write_active += WT_STAT_READ(from, write_active); + to->session_table_compact_fail += + WT_STAT_READ(from, session_table_compact_fail); + to->session_table_compact_success += + WT_STAT_READ(from, session_table_compact_success); + to->session_table_create_fail += + WT_STAT_READ(from, session_table_create_fail); + to->session_table_create_success += + WT_STAT_READ(from, session_table_create_success); + to->session_table_drop_fail += + WT_STAT_READ(from, session_table_drop_fail); + to->session_table_drop_success += + WT_STAT_READ(from, session_table_drop_success); + to->session_table_rebalance_fail += + WT_STAT_READ(from, session_table_rebalance_fail); + to->session_table_rebalance_success += + WT_STAT_READ(from, session_table_rebalance_success); + to->session_table_rename_fail += + WT_STAT_READ(from, session_table_rename_fail); + to->session_table_rename_success += + WT_STAT_READ(from, session_table_rename_success); + to->session_table_salvage_fail += + WT_STAT_READ(from, session_table_salvage_fail); + to->session_table_salvage_success += + WT_STAT_READ(from, session_table_salvage_success); + to->session_table_truncate_fail += + WT_STAT_READ(from, session_table_truncate_fail); + to->session_table_truncate_success += + WT_STAT_READ(from, session_table_truncate_success); + to->session_table_verify_fail += + WT_STAT_READ(from, session_table_verify_fail); + to->session_table_verify_success += + WT_STAT_READ(from, session_table_verify_success); + to->thread_fsync_active += WT_STAT_READ(from, thread_fsync_active); + to->thread_read_active += WT_STAT_READ(from, thread_read_active); + to->thread_write_active += WT_STAT_READ(from, thread_write_active); to->page_busy_blocked += WT_STAT_READ(from, page_busy_blocked); to->page_forcible_evict_blocked += WT_STAT_READ(from, page_forcible_evict_blocked); @@ -1175,18 +1255,18 @@ __wt_stat_connection_aggregate( WT_STAT_READ(from, txn_checkpoint_time_min); to->txn_checkpoint_time_recent += WT_STAT_READ(from, txn_checkpoint_time_recent); + to->txn_checkpoint_scrub_target += + WT_STAT_READ(from, txn_checkpoint_scrub_target); + to->txn_checkpoint_scrub_time += + WT_STAT_READ(from, txn_checkpoint_scrub_time); to->txn_checkpoint_time_total += WT_STAT_READ(from, txn_checkpoint_time_total); to->txn_checkpoint += WT_STAT_READ(from, txn_checkpoint); to->txn_fail_cache += WT_STAT_READ(from, txn_fail_cache); to->txn_checkpoint_fsync_post += WT_STAT_READ(from, txn_checkpoint_fsync_post); - to->txn_checkpoint_fsync_pre += - WT_STAT_READ(from, txn_checkpoint_fsync_pre); to->txn_checkpoint_fsync_post_duration += WT_STAT_READ(from, txn_checkpoint_fsync_post_duration); - to->txn_checkpoint_fsync_pre_duration += - WT_STAT_READ(from, txn_checkpoint_fsync_pre_duration); to->txn_pinned_range += WT_STAT_READ(from, txn_pinned_range); to->txn_pinned_checkpoint_range += WT_STAT_READ(from, txn_pinned_checkpoint_range); diff --git a/src/third_party/wiredtiger/src/support/thread_group.c b/src/third_party/wiredtiger/src/support/thread_group.c new file mode 100644 index 00000000000..f5ddabad7d4 --- /dev/null +++ b/src/third_party/wiredtiger/src/support/thread_group.c @@ -0,0 +1,336 @@ +/*- + * Copyright (c) 2014-2016 MongoDB, Inc. + * Copyright (c) 2008-2014 WiredTiger, Inc. + * All rights reserved. + * + * See the file LICENSE for redistribution information. + */ + +#include "wt_internal.h" + +/* + * __wt_thread_run -- + * General wrapper for any thread. + */ +WT_THREAD_RET +__wt_thread_run(void *arg) +{ + WT_DECL_RET; + WT_SESSION_IMPL *session; + WT_THREAD *thread; + + thread = (WT_THREAD*)arg; + session = thread->session; + + ret = thread->run_func(session, thread); + + if (ret != 0 && F_ISSET(thread, WT_THREAD_PANIC_FAIL)) + WT_PANIC_MSG(session, ret, + "Unrecoverable utility thread error"); + + /* + * The three cases when threads are expected to stop are: + * 1. When recovery is done. + * 2. When the connection is closing. + * 3. When a shutdown has been requested via clearing the run flag. + */ + WT_ASSERT(session, !F_ISSET(thread, WT_THREAD_RUN) || + F_ISSET(S2C(session), WT_CONN_CLOSING | WT_CONN_RECOVERING)); + + return (WT_THREAD_RET_VALUE); +} + +/* + * __thread_group_grow -- + * Increase the number of running threads in the group. + */ +static int +__thread_group_grow( + WT_SESSION_IMPL *session, WT_THREAD_GROUP *group, uint32_t new_count) +{ + WT_THREAD *thread; + + WT_ASSERT(session, + __wt_rwlock_islocked(session, group->lock)); + + /* + * Any bounds checking is done by the caller so we know that + * there is space in the array for new threads. + */ + while (group->current_threads < new_count) { + thread = group->threads[group->current_threads++]; + __wt_verbose(session, WT_VERB_THREAD_GROUP, + "Starting utility thread: %p:%"PRIu32"\n", + (void *)group, thread->id); + F_SET(thread, WT_THREAD_RUN); + WT_ASSERT(session, thread->session != NULL); + WT_RET(__wt_thread_create(thread->session, + &thread->tid, __wt_thread_run, thread)); + } + return (0); +} + +/* + * __thread_group_shrink -- + * Decrease the number of running threads in the group, and free any + * memory associated with slots larger than the new count. + */ +static int +__thread_group_shrink(WT_SESSION_IMPL *session, + WT_THREAD_GROUP *group, uint32_t new_count) +{ + WT_DECL_RET; + WT_SESSION *wt_session; + WT_THREAD *thread; + uint32_t current_slot; + + WT_ASSERT(session, + __wt_rwlock_islocked(session, group->lock)); + + for (current_slot = group->alloc; current_slot > new_count; ) { + /* + * The offset value is a counter not an array index, + * so adjust it before finding the last thread in the group. + */ + thread = group->threads[--current_slot]; + + if (thread == NULL) + continue; + + /* Wake threads to ensure they notice the state change */ + if (thread->tid != 0) { + __wt_verbose(session, WT_VERB_THREAD_GROUP, + "Stopping utility thread: %p:%"PRIu32"\n", + (void *)group, thread->id); + F_CLR(thread, WT_THREAD_RUN); + __wt_cond_signal(session, group->wait_cond); + WT_TRET(__wt_thread_join(session, thread->tid)); + thread->tid = 0; + } + + if (thread->session != NULL) { + wt_session = (WT_SESSION *)thread->session; + WT_TRET(wt_session->close(wt_session, NULL)); + thread->session = NULL; + } + __wt_free(session, thread); + group->threads[current_slot] = NULL; + } + + /* Update the thread group state to match our changes */ + group->current_threads = current_slot; + return (ret); +} + +/* + * __thread_group_resize -- + * Resize an array of utility threads already holding the lock. + */ +static int +__thread_group_resize( + WT_SESSION_IMPL *session, WT_THREAD_GROUP *group, + uint32_t new_min, uint32_t new_max, uint32_t flags) +{ + WT_CONNECTION_IMPL *conn; + WT_DECL_RET; + WT_THREAD *thread; + size_t alloc; + uint32_t i, session_flags; + + conn = S2C(session); + session_flags = 0; + + WT_ASSERT(session, + group->current_threads <= group->alloc && + __wt_rwlock_islocked(session, group->lock)); + + if (new_min == group->min && new_max == group->max) + return (0); + + /* + * Coll shrink to reduce the number of thread structures and running + * threads if required by the change in group size. + */ + WT_RET(__thread_group_shrink(session, group, new_max)); + + /* + * Only reallocate the thread array if it is the largest ever, since + * our realloc doesn't support shrinking the allocated size. + */ + if (group->alloc < new_max) { + alloc = group->alloc * sizeof(*group->threads); + WT_RET(__wt_realloc(session, &alloc, + new_max * sizeof(*group->threads), &group->threads)); + group->alloc = new_max; + } + + /* + * Initialize the structures based on the previous group size, not + * the previous allocated size. + */ + for (i = group->max; i < new_max; i++) { + WT_ERR(__wt_calloc_one(session, &thread)); + /* + * Threads get their own session and lookaside table cursor + * if the lookaside table is open. Note that threads are + * started during recovery, before the lookaside table is + * created. + */ + if (LF_ISSET(WT_THREAD_CAN_WAIT)) + session_flags = WT_SESSION_CAN_WAIT; + if (F_ISSET(conn, WT_CONN_LAS_OPEN)) + FLD_SET(session_flags, WT_SESSION_LOOKASIDE_CURSOR); + WT_ERR(__wt_open_internal_session(conn, group->name, + false, session_flags, &thread->session)); + if (LF_ISSET(WT_THREAD_PANIC_FAIL)) + F_SET(thread, WT_THREAD_PANIC_FAIL); + thread->id = i; + thread->run_func = group->run_func; + WT_ASSERT(session, group->threads[i] == NULL); + group->threads[i] = thread; + } + + if (group->current_threads < new_min) + WT_ERR(__thread_group_grow(session, group, new_min)); + +err: /* + * Update the thread group information even on failure to improve our + * chances of cleaning up properly. + */ + group->max = new_max; + group->min = new_min; + + /* + * An error resizing a thread array is fatal, it should only happen + * in an out of memory situation. + */ + if (ret != 0) { + WT_TRET(__wt_thread_group_destroy(session, group)); + WT_PANIC_RET(session, ret, "Error while resizing thread group"); + } + return (ret); +} + +/* + * __wt_thread_group_resize -- + * Resize an array of utility threads taking the lock. + */ +int +__wt_thread_group_resize( + WT_SESSION_IMPL *session, WT_THREAD_GROUP *group, + uint32_t new_min, uint32_t new_max, uint32_t flags) +{ + WT_DECL_RET; + + __wt_verbose(session, WT_VERB_THREAD_GROUP, + "Resize thread group: %p, from min: %" PRIu32 " -> %" PRIu32 + " from max: %" PRIu32 " -> %" PRIu32 "\n", + (void *)group, group->min, new_min, group->max, new_max); + + __wt_writelock(session, group->lock); + WT_TRET(__thread_group_resize(session, group, new_min, new_max, flags)); + __wt_writeunlock(session, group->lock); + return (ret); +} + +/* + * __wt_thread_group_create -- + * Create a new thread group, assumes incoming group structure is + * zero initialized. + */ +int +__wt_thread_group_create( + WT_SESSION_IMPL *session, WT_THREAD_GROUP *group, const char *name, + uint32_t min, uint32_t max, uint32_t flags, + int (*run_func)(WT_SESSION_IMPL *session, WT_THREAD *context)) +{ + WT_DECL_RET; + bool cond_alloced; + + /* Check that the structure is initialized as expected */ + WT_ASSERT(session, group->alloc == 0); + + cond_alloced = false; + + __wt_verbose(session, WT_VERB_THREAD_GROUP, + "Creating thread group: %p\n", (void *)group); + + WT_RET(__wt_rwlock_alloc(session, &group->lock, "Thread group")); + WT_ERR(__wt_cond_alloc( + session, "Thread group cond", false, &group->wait_cond)); + cond_alloced = true; + + __wt_writelock(session, group->lock); + group->run_func = run_func; + group->name = name; + + WT_TRET(__thread_group_resize(session, group, min, max, flags)); + __wt_writeunlock(session, group->lock); + + /* Cleanup on error to avoid leaking resources */ +err: if (ret != 0) { + if (cond_alloced) + WT_TRET(__wt_cond_destroy(session, &group->wait_cond)); + __wt_rwlock_destroy(session, &group->lock); + } + return (ret); +} + +/* + * __wt_thread_group_destroy -- + * Shut down a thread group. Our caller must hold the lock. + */ +int +__wt_thread_group_destroy(WT_SESSION_IMPL *session, WT_THREAD_GROUP *group) +{ + WT_DECL_RET; + + __wt_verbose(session, WT_VERB_THREAD_GROUP, + "Destroying thread group: %p\n", (void *)group); + + WT_ASSERT(session, __wt_rwlock_islocked(session, group->lock)); + + /* Shut down all threads and free associated resources. */ + WT_TRET(__thread_group_shrink(session, group, 0)); + + __wt_free(session, group->threads); + + WT_TRET(__wt_cond_destroy(session, &group->wait_cond)); + __wt_rwlock_destroy(session, &group->lock); + + /* + * Clear out any settings from the group, some structures are reused + * for different thread groups - in particular the eviction thread + * group for recovery and then normal runtime. + */ + memset(group, 0, sizeof(*group)); + + return (ret); +} + +/* + * __wt_thread_group_start_one -- + * Start a new thread if possible. + */ +int +__wt_thread_group_start_one( + WT_SESSION_IMPL *session, WT_THREAD_GROUP *group, bool wait) +{ + WT_DECL_RET; + + if (group->current_threads >= group->max) + return (0); + + if (wait) + __wt_writelock(session, group->lock); + else if (__wt_try_writelock(session, group->lock) != 0) + return (0); + + /* Recheck the bounds now that we hold the lock */ + if (group->current_threads < group->max) + WT_TRET(__thread_group_grow( + session, group, group->current_threads + 1)); + __wt_writeunlock(session, group->lock); + + return (ret); +} diff --git a/src/third_party/wiredtiger/src/txn/txn.c b/src/third_party/wiredtiger/src/txn/txn.c index d6d5760ea15..01e0fbbb634 100644 --- a/src/third_party/wiredtiger/src/txn/txn.c +++ b/src/third_party/wiredtiger/src/txn/txn.c @@ -185,7 +185,7 @@ __wt_txn_get_snapshot(WT_SESSION_IMPL *session) WT_ASSERT(session, prev_oldest_id == txn_global->oldest_id); txn_state->snap_min = snap_min; -done: WT_RET(__wt_readunlock(session, txn_global->scan_rwlock)); +done: __wt_readunlock(session, txn_global->scan_rwlock); __txn_sort_snapshot(session, n, current_id); return (0); } @@ -292,12 +292,12 @@ __wt_txn_update_oldest(WT_SESSION_IMPL *session, uint32_t flags) /* First do a read-only scan. */ if (wait) - WT_RET(__wt_readlock(session, txn_global->scan_rwlock)); + __wt_readlock(session, txn_global->scan_rwlock); else if ((ret = __wt_try_readlock(session, txn_global->scan_rwlock)) != 0) return (ret == EBUSY ? 0 : ret); __txn_oldest_scan(session, &oldest_id, &last_running, &oldest_session); - WT_RET(__wt_readunlock(session, txn_global->scan_rwlock)); + __wt_readunlock(session, txn_global->scan_rwlock); /* * If the state hasn't changed (or hasn't moved far enough for @@ -311,7 +311,7 @@ __wt_txn_update_oldest(WT_SESSION_IMPL *session, uint32_t flags) /* It looks like an update is necessary, wait for exclusive access. */ if (wait) - WT_RET(__wt_writelock(session, txn_global->scan_rwlock)); + __wt_writelock(session, txn_global->scan_rwlock); else if ((ret = __wt_try_writelock(session, txn_global->scan_rwlock)) != 0) return (ret == EBUSY ? 0 : ret); @@ -357,18 +357,18 @@ __wt_txn_update_oldest(WT_SESSION_IMPL *session, uint32_t flags) * but only when some progress is being made. */ if (WT_VERBOSE_ISSET(session, WT_VERB_TRANSACTION) && current_id - oldest_id > 10000 && oldest_session != NULL) { - WT_TRET(__wt_verbose(session, WT_VERB_TRANSACTION, + __wt_verbose(session, WT_VERB_TRANSACTION, "old snapshot %" PRIu64 " pinned in session %" PRIu32 " [%s]" " with snap_min %" PRIu64 "\n", oldest_id, oldest_session->id, oldest_session->lastop, - oldest_session->txn.snap_min)); + oldest_session->txn.snap_min); } #endif } -done: WT_TRET(__wt_writeunlock(session, txn_global->scan_rwlock)); +done: __wt_writeunlock(session, txn_global->scan_rwlock); return (ret); } @@ -480,6 +480,7 @@ __wt_txn_release(WT_SESSION_IMPL *session) */ __wt_txn_release_snapshot(session); txn->isolation = session->isolation; + /* Ensure the transaction flags are cleared on exit */ txn->flags = 0; } @@ -497,10 +498,12 @@ __wt_txn_commit(WT_SESSION_IMPL *session, const char *cfg[]) WT_TXN *txn; WT_TXN_OP *op; u_int i; + bool did_update; txn = &session->txn; conn = S2C(session); - WT_ASSERT(session, !F_ISSET(txn, WT_TXN_ERROR) || txn->mod_count == 0); + did_update = txn->mod_count != 0; + WT_ASSERT(session, !F_ISSET(txn, WT_TXN_ERROR) || !did_update); if (!F_ISSET(txn, WT_TXN_RUNNING)) WT_RET_MSG(session, EINVAL, "No transaction is active"); @@ -561,7 +564,7 @@ __wt_txn_commit(WT_SESSION_IMPL *session, const char *cfg[]) } /* If we are logging, write a commit log record. */ - if (ret == 0 && txn->mod_count > 0 && + if (ret == 0 && did_update && FLD_ISSET(conn->log_flags, WT_CONN_LOG_ENABLED) && !F_ISSET(session, WT_SESSION_NO_LOGGING)) { /* @@ -779,23 +782,20 @@ __wt_txn_global_init(WT_SESSION_IMPL *session, const char *cfg[]) * __wt_txn_global_destroy -- * Destroy the global transaction state. */ -int +void __wt_txn_global_destroy(WT_SESSION_IMPL *session) { WT_CONNECTION_IMPL *conn; - WT_DECL_RET; WT_TXN_GLOBAL *txn_global; conn = S2C(session); txn_global = &conn->txn_global; if (txn_global == NULL) - return (0); + return; __wt_spin_destroy(session, &txn_global->id_lock); - WT_TRET(__wt_rwlock_destroy(session, &txn_global->scan_rwlock)); - WT_TRET(__wt_rwlock_destroy(session, &txn_global->nsnap_rwlock)); + __wt_rwlock_destroy(session, &txn_global->scan_rwlock); + __wt_rwlock_destroy(session, &txn_global->nsnap_rwlock); __wt_free(session, txn_global->states); - - return (ret); } diff --git a/src/third_party/wiredtiger/src/txn/txn_ckpt.c b/src/third_party/wiredtiger/src/txn/txn_ckpt.c index 82c1fe7bdfe..91cee92b862 100644 --- a/src/third_party/wiredtiger/src/txn/txn_ckpt.c +++ b/src/third_party/wiredtiger/src/txn/txn_ckpt.c @@ -10,14 +10,16 @@ static int __checkpoint_lock_tree( WT_SESSION_IMPL *, bool, bool, const char *[]); +static int __checkpoint_mark_deletes(WT_SESSION_IMPL *, const char *[]); +static int __checkpoint_presync(WT_SESSION_IMPL *, const char *[]); static int __checkpoint_tree_helper(WT_SESSION_IMPL *, const char *[]); /* - * __wt_checkpoint_name_ok -- + * __checkpoint_name_ok -- * Complain if the checkpoint name isn't acceptable. */ -int -__wt_checkpoint_name_ok(WT_SESSION_IMPL *session, const char *name, size_t len) +static int +__checkpoint_name_ok(WT_SESSION_IMPL *session, const char *name, size_t len) { /* Check for characters we don't want to see in a metadata file. */ WT_RET(__wt_name_check(session, name, len)); @@ -107,11 +109,11 @@ __checkpoint_apply_all(WT_SESSION_IMPL *session, const char *cfg[], WT_RET(__wt_config_gets(session, cfg, "name", &cval)); named = cval.len != 0; if (named) - WT_RET(__wt_checkpoint_name_ok(session, cval.str, cval.len)); + WT_RET(__checkpoint_name_ok(session, cval.str, cval.len)); /* Step through the targets and optionally operate on each one. */ WT_ERR(__wt_config_gets(session, cfg, "target", &cval)); - WT_ERR(__wt_config_subinit(session, &targetconf, &cval)); + __wt_config_subinit(session, &targetconf, &cval); while ((ret = __wt_config_next(&targetconf, &k, &v)) == 0) { if (!target_list) { WT_ERR(__wt_scr_alloc(session, 512, &tmp)); @@ -183,6 +185,8 @@ __checkpoint_apply(WT_SESSION_IMPL *session, const char *cfg[], /* If we have already locked the handles, apply the operation. */ for (i = 0; i < session->ckpt_handle_next; ++i) { + if (session->ckpt_handle[i] == NULL) + continue; WT_WITH_DHANDLE(session, session->ckpt_handle[i], ret = (*op)(session, cfg)); WT_RET(ret); @@ -234,6 +238,7 @@ __checkpoint_data_source(WT_SESSION_IMPL *session, const char *cfg[]) int __wt_checkpoint_get_handles(WT_SESSION_IMPL *session, const char *cfg[]) { + WT_BTREE *btree; WT_DECL_RET; const char *name; @@ -258,6 +263,14 @@ __wt_checkpoint_get_handles(WT_SESSION_IMPL *session, const char *cfg[]) if ((ret = __wt_session_get_btree(session, name, NULL, NULL, 0)) != 0) return (ret == EBUSY ? 0 : ret); + /* + * Save the current eviction walk setting: checkpoint can interfere + * with eviction and we don't want to unfairly penalize (or promote) + * eviction in trees due to checkpoints. + */ + btree = S2BT(session); + btree->evict_walk_saved = btree->evict_walk_period; + WT_SAVE_DHANDLE(session, ret = __checkpoint_lock_tree(session, true, true, cfg)); if (ret != 0) { @@ -265,20 +278,192 @@ __wt_checkpoint_get_handles(WT_SESSION_IMPL *session, const char *cfg[]) return (ret); } + /* + * Flag that the handle is part of a checkpoint for the purposes + * of transaction visibility checks. + */ + WT_PUBLISH(btree->include_checkpoint_txn, true); + session->ckpt_handle[session->ckpt_handle_next++] = session->dhandle; return (0); } /* - * __checkpoint_write_leaves -- - * Write any dirty leaf pages for all checkpoint handles. + * __checkpoint_update_generation -- + * Update the checkpoint generation of the current tree. + * + * This indicates that the tree will not be visited again by the current + * checkpoint. + */ +static void +__checkpoint_update_generation(WT_SESSION_IMPL *session) +{ + WT_BTREE *btree; + + btree = S2BT(session); + if (!WT_IS_METADATA(session, session->dhandle)) + WT_PUBLISH(btree->include_checkpoint_txn, false); + + WT_PUBLISH(btree->checkpoint_gen, + S2C(session)->txn_global.checkpoint_gen); + WT_STAT_FAST_DATA_SET(session, + btree_checkpoint_generation, btree->checkpoint_gen); +} + +/* + * __checkpoint_reduce_dirty_cache -- + * Release clean trees from the list cached for checkpoints. */ static int -__checkpoint_write_leaves(WT_SESSION_IMPL *session, const char *cfg[]) +__checkpoint_reduce_dirty_cache(WT_SESSION_IMPL *session) { - WT_UNUSED(cfg); + WT_CACHE *cache; + WT_CONNECTION_IMPL *conn; + struct timespec start, last, stop; + double current_dirty, delta; + uint64_t bytes_written_last, bytes_written_start, bytes_written_total; + uint64_t cache_size, max_write; + uint64_t current_us, stepdown_us, total_ms, work_us; + bool progress; + + conn = S2C(session); + cache = conn->cache; + + /* Give up if scrubbing is disabled. */ + if (cache->eviction_checkpoint_target == 0 || + cache->eviction_checkpoint_target >= cache->eviction_dirty_trigger) + return (0); + + WT_RET(__wt_epoch(session, &start)); + last = start; + bytes_written_last = 0; + bytes_written_start = cache->bytes_written; + cache_size = conn->cache_size; + /* + * If the cache size is zero or very small, we're done. The cache + * size can briefly become zero if we're transitioning to a shared + * cache via reconfigure. This avoids potential divide by zero. + */ + if (cache_size < 10 * WT_MEGABYTE) + return (0); + stepdown_us = 10000; + work_us = 0; + progress = false; + + /* Step down the scrub target (as a percentage) in units of 10MB. */ + delta = WT_MIN(1.0, (100 * 10.0 * WT_MEGABYTE) / cache_size); + + /* + * Start with the scrub target equal to the expected maximum percentage + * of dirty data in cache. + */ + cache->eviction_scrub_limit = cache->eviction_dirty_trigger; + + /* Stop if we write as much dirty data as is currently in cache. */ + max_write = __wt_cache_dirty_leaf_inuse(cache); + + /* Step down the dirty target to the eviction trigger */ + for (;;) { + current_dirty = + (100.0 * __wt_cache_dirty_leaf_inuse(cache)) / cache_size; + if (current_dirty <= + (double)cache->eviction_checkpoint_target) + break; + + __wt_sleep(0, stepdown_us / 10); + WT_RET(__wt_epoch(session, &stop)); + current_us = WT_TIMEDIFF_US(stop, last); + total_ms = WT_TIMEDIFF_MS(stop, start); + bytes_written_total = + cache->bytes_written - bytes_written_start; + + if (current_dirty > cache->eviction_scrub_limit) { + /* + * We haven't reached the current target. + * + * Don't wait indefinitely: there might be dirty pages + * that can't be evicted. If we can't meet the target, + * give up and start the checkpoint for real. + */ + if (current_us > WT_MAX(WT_MILLION, 10 * stepdown_us) || + bytes_written_total > max_write) + break; + continue; + } + + /* + * Estimate how long the next step down of dirty data should + * take. + * + * The calculation here assumes that the system is writing from + * cache as fast as it can, and determines the write throughput + * based on the change in the bytes written from cache since + * the start of the call. We use that to estimate how long it + * will take to step the dirty target down by delta. + * + * Take care to avoid dividing by zero. + */ + if (bytes_written_total - bytes_written_last > WT_MEGABYTE && + work_us > 0) { + stepdown_us = (uint64_t)((delta * cache_size / 100) / + ((double)bytes_written_total / work_us)); + stepdown_us = WT_MAX(1, stepdown_us); + if (!progress) + stepdown_us = WT_MIN(stepdown_us, 200000); + progress = true; + + bytes_written_last = bytes_written_total; + } + + work_us += current_us; + + /* + * Smooth out step down: try to limit the impact on + * performance to 10% by waiting once we reach the last + * level. + */ + __wt_sleep(0, 10 * stepdown_us); + cache->eviction_scrub_limit = current_dirty - delta; + WT_STAT_FAST_CONN_SET(session, txn_checkpoint_scrub_target, + cache->eviction_scrub_limit); + WT_RET(__wt_epoch(session, &last)); + } - return (__wt_cache_op(session, WT_SYNC_WRITE_LEAVES)); + WT_RET(__wt_epoch(session, &stop)); + total_ms = WT_TIMEDIFF_MS(stop, start); + WT_STAT_FAST_CONN_SET(session, txn_checkpoint_scrub_time, total_ms); + + return (0); +} + +/* + * __checkpoint_release_clean_trees -- + * Release clean trees from the list cached for checkpoints. + */ +static int +__checkpoint_release_clean_trees(WT_SESSION_IMPL *session) +{ + WT_BTREE *btree; + WT_DATA_HANDLE *dhandle; + WT_DECL_RET; + u_int i; + + for (i = 0; i < session->ckpt_handle_next; i++) { + dhandle = session->ckpt_handle[i]; + btree = dhandle->handle; + if (!F_ISSET(btree, WT_BTREE_SKIP_CKPT)) + continue; + __wt_meta_ckptlist_free(session, btree->ckpt); + btree->ckpt = NULL; + WT_WITH_DHANDLE(session, dhandle, + __checkpoint_update_generation(session)); + session->ckpt_handle[i] = NULL; + WT_WITH_DHANDLE(session, dhandle, + ret = __wt_session_release_btree(session)); + WT_RET(ret); + } + + return (0); } /* @@ -328,10 +513,10 @@ __checkpoint_verbose_track(WT_SESSION_IMPL *session, * Get time diff in microseconds. */ msec = WT_TIMEDIFF_MS(stop, *start); - WT_RET(__wt_verbose(session, + __wt_verbose(session, WT_VERB_CHECKPOINT, "time: %" PRIu64 " us, gen: %" PRIu64 ": Full database checkpoint %s", - msec, S2C(session)->txn_global.checkpoint_gen, msg)); + msec, S2C(session)->txn_global.checkpoint_gen, msg); /* Update the timestamp so we are reporting intervals. */ memcpy(start, &stop, sizeof(*start)); @@ -352,6 +537,7 @@ __txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[]) { struct timespec fsync_start, fsync_stop; struct timespec start, stop, verb_timer; + WT_CACHE *cache; WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_TXN *txn; @@ -366,6 +552,7 @@ __txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[]) WT_SESSION_begin_transaction), "isolation=snapshot", NULL }; conn = S2C(session); + cache = conn->cache; txn = &session->txn; txn_global = &conn->txn_global; txn_state = WT_SESSION_TXN_STATE(session); @@ -384,21 +571,11 @@ __txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[]) /* Configure logging only if doing a full checkpoint. */ logging = FLD_ISSET(conn->log_flags, WT_CONN_LOG_ENABLED); - /* Keep track of handles acquired for locking. */ - WT_ERR(__wt_meta_track_on(session)); - tracking = true; + /* Reset the maximum page size seen by eviction. */ + conn->cache->evict_max_page_size = 0; - /* - * Get a list of handles we want to flush; this may pull closed objects - * into the session cache, but we're going to do that eventually anyway. - */ - WT_ASSERT(session, session->ckpt_handle_next == 0); - WT_WITH_SCHEMA_LOCK(session, ret, - WT_WITH_TABLE_LOCK(session, ret, - WT_WITH_HANDLE_LIST_LOCK(session, - ret = __checkpoint_apply_all( - session, cfg, __wt_checkpoint_get_handles, NULL)))); - WT_ERR(ret); + /* Initialize the verbose tracking timer */ + WT_ERR(__wt_epoch(session, &verb_timer)); /* * Update the global oldest ID so we do all possible cleanup. @@ -412,28 +589,11 @@ __txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[]) /* Flush data-sources before we start the checkpoint. */ WT_ERR(__checkpoint_data_source(session, cfg)); - WT_ERR(__wt_epoch(session, &verb_timer)); - WT_ERR(__checkpoint_verbose_track(session, - "starting write leaves", &verb_timer)); - - /* Flush dirty leaf pages before we start the checkpoint. */ - session->isolation = txn->isolation = WT_ISO_READ_COMMITTED; - WT_ERR(__checkpoint_apply(session, cfg, __checkpoint_write_leaves)); - /* - * The underlying flush routine scheduled an asynchronous flush - * after writing the leaf pages, but in order to minimize I/O - * while holding the schema lock, do a flush and wait for the - * completion. Do it after flushing the pages to give the - * asynchronous flush as much time as possible before we wait. + * Try to reduce the amount of dirty data in cache so there is less + * work do during the critical section of the checkpoint. */ - WT_ERR(__wt_epoch(session, &fsync_start)); - WT_ERR(__checkpoint_apply(session, cfg, __wt_checkpoint_sync)); - WT_ERR(__wt_epoch(session, &fsync_stop)); - fsync_duration_usecs = WT_TIMEDIFF_US(fsync_stop, fsync_start); - WT_STAT_FAST_CONN_INCR(session, txn_checkpoint_fsync_pre); - WT_STAT_FAST_CONN_INCRV(session, - txn_checkpoint_fsync_pre_duration, fsync_duration_usecs); + WT_ERR(__checkpoint_reduce_dirty_cache(session)); /* Tell logging that we are about to start a database checkpoint. */ if (full && logging) @@ -462,6 +622,36 @@ __txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[]) WT_STAT_FAST_CONN_SET(session, txn_checkpoint_generation, txn_global->checkpoint_gen); + /* Keep track of handles acquired for locking. */ + WT_ERR(__wt_meta_track_on(session)); + tracking = true; + + /* + * Get a list of handles we want to flush; for named checkpoints this + * may pull closed objects into the session cache. + * + * We want to skip checkpointing clean handles whenever possible. That + * is, when the checkpoint is not named or forced. However, we need to + * take care about ordering with respect to the checkpoint transaction. + * + * If we skip clean handles before starting the transaction, the + * checkpoint can miss updates in trees that become dirty as the + * checkpoint is starting. If we wait until the transaction has + * started before locking a handle, there could be a metadata-changing + * operation in between (e.g., salvage) that will cause a write + * conflict when the checkpoint goes to write the metadata. + * + * First, gather all handles, then start the checkpoint transaction, + * then release any clean handles. + */ + WT_ASSERT(session, session->ckpt_handle_next == 0); + WT_WITH_SCHEMA_LOCK(session, ret, + WT_WITH_TABLE_LOCK(session, ret, + WT_WITH_HANDLE_LIST_LOCK(session, + ret = __checkpoint_apply_all( + session, cfg, __wt_checkpoint_get_handles, NULL)))); + WT_ERR(ret); + /* * Start a snapshot transaction for the checkpoint. * @@ -488,7 +678,7 @@ __txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[]) * This allows ordinary visibility checks to move forward because * checkpoints often take a long time and only write to the metadata. */ - WT_ERR(__wt_writelock(session, txn_global->scan_rwlock)); + __wt_writelock(session, txn_global->scan_rwlock); txn_global->checkpoint_txnid = txn->id; txn_global->checkpoint_pinned = WT_MIN(txn->id, txn->snap_min); @@ -508,7 +698,24 @@ __txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[]) * details). */ txn_state->id = txn_state->snap_min = WT_TXN_NONE; - WT_ERR(__wt_writeunlock(session, txn_global->scan_rwlock)); + __wt_writeunlock(session, txn_global->scan_rwlock); + + /* + * Unblock updates -- we can figure out that any updates to clean pages + * after this point are too new to be written in the checkpoint. + */ + cache->eviction_scrub_limit = 0.0; + WT_STAT_FAST_CONN_SET(session, txn_checkpoint_scrub_target, 0); + + /* + * Mark old checkpoints that are being deleted and figure out which + * trees we can skip in this checkpoint. + * + * Release clean trees. Any updates made after this point will not + * visible to the checkpoint transaction. + */ + WT_ERR(__checkpoint_apply(session, cfg, __checkpoint_mark_deletes)); + WT_ERR(__checkpoint_release_clean_trees(session)); /* Tell logging that we have started a database checkpoint. */ if (full && logging) @@ -524,9 +731,13 @@ __txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[]) */ session->dhandle = NULL; - /* Release the snapshot so we aren't pinning pages in cache. */ + /* Release the snapshot so we aren't pinning updates in cache. */ __wt_txn_release_snapshot(session); + /* Mark all trees as open for business (particularly eviction). */ + WT_ERR(__checkpoint_apply(session, cfg, __checkpoint_presync)); + __wt_evict_server_wake(session); + WT_ERR(__checkpoint_verbose_track(session, "committing transaction", &verb_timer)); @@ -539,7 +750,7 @@ __txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[]) WT_ERR(__wt_epoch(session, &fsync_stop)); fsync_duration_usecs = WT_TIMEDIFF_US(fsync_stop, fsync_start); WT_STAT_FAST_CONN_INCR(session, txn_checkpoint_fsync_post); - WT_STAT_FAST_CONN_INCRV(session, + WT_STAT_FAST_CONN_SET(session, txn_checkpoint_fsync_post_duration, fsync_duration_usecs); WT_ERR(__checkpoint_verbose_track(session, @@ -589,6 +800,12 @@ __txn_checkpoint(WT_SESSION_IMPL *session, const char *cfg[]) ret = __wt_txn_checkpoint_log( session, false, WT_TXN_LOG_CKPT_SYNC, NULL)); + /* + * Now that the metadata is stable, re-open the metadata file for + * regular eviction by clearing the checkpoint_pinned flag. + */ + txn_global->checkpoint_pinned = WT_TXN_NONE; + if (full) { WT_ERR(__wt_epoch(session, &stop)); __checkpoint_stats(session, &start, &stop); @@ -611,6 +828,9 @@ err: /* if (tracking) WT_TRET(__wt_meta_track_off(session, false, ret != 0)); + cache->eviction_scrub_limit = 0.0; + WT_STAT_FAST_CONN_SET(session, txn_checkpoint_scrub_target, 0); + if (F_ISSET(txn, WT_TXN_RUNNING)) { /* * Clear the dhandle so the visibility check doesn't get @@ -636,9 +856,12 @@ err: /* WT_TXN_LOG_CKPT_STOP : WT_TXN_LOG_CKPT_CLEANUP, NULL)); } - for (i = 0; i < session->ckpt_handle_next; ++i) + for (i = 0; i < session->ckpt_handle_next; ++i) { + if (session->ckpt_handle[i] == NULL) + continue; WT_WITH_DHANDLE(session, session->ckpt_handle[i], WT_TRET(__wt_session_release_btree(session))); + } __wt_free(session, session->ckpt_handle); session->ckpt_handle_allocated = session->ckpt_handle_next = 0; @@ -838,7 +1061,7 @@ __checkpoint_lock_tree(WT_SESSION_IMPL *session, if (cval.len == 0) name = WT_CHECKPOINT; else { - WT_ERR(__wt_checkpoint_name_ok(session, cval.str, cval.len)); + WT_ERR(__checkpoint_name_ok(session, cval.str, cval.len)); WT_ERR(__wt_strndup(session, cval.str, cval.len, &name_alloc)); name = name_alloc; } @@ -848,15 +1071,15 @@ __checkpoint_lock_tree(WT_SESSION_IMPL *session, cval.len = 0; WT_ERR(__wt_config_gets(session, cfg, "drop", &cval)); if (cval.len != 0) { - WT_ERR(__wt_config_subinit(session, &dropconf, &cval)); + __wt_config_subinit(session, &dropconf, &cval); while ((ret = __wt_config_next(&dropconf, &k, &v)) == 0) { /* Disallow unsafe checkpoint names. */ if (v.len == 0) - WT_ERR(__wt_checkpoint_name_ok( + WT_ERR(__checkpoint_name_ok( session, k.str, k.len)); else - WT_ERR(__wt_checkpoint_name_ok( + WT_ERR(__checkpoint_name_ok( session, v.str, v.len)); if (v.len == 0) @@ -896,7 +1119,7 @@ __checkpoint_lock_tree(WT_SESSION_IMPL *session, * Hold the lock until we're done (blocking hot backups from starting), * we don't want to race with a future hot backup. */ - WT_ERR(__wt_readlock(session, conn->hot_backup_lock)); + __wt_readlock(session, conn->hot_backup_lock); hot_backup_locked = true; if (conn->hot_backup) WT_CKPT_FOREACH(ckptbase, ckpt) { @@ -970,8 +1193,7 @@ __checkpoint_lock_tree(WT_SESSION_IMPL *session, WT_ASSERT(session, !is_checkpoint || !F_ISSET(btree, WT_BTREE_SPECIAL_FLAGS)); - hot_backup_locked = false; - WT_ERR(__wt_readunlock(session, conn->hot_backup_lock)); + __wt_readunlock(session, conn->hot_backup_lock); WT_ASSERT(session, btree->ckpt == NULL); btree->ckpt = ckptbase; @@ -979,7 +1201,7 @@ __checkpoint_lock_tree(WT_SESSION_IMPL *session, return (0); err: if (hot_backup_locked) - WT_TRET(__wt_readunlock(session, conn->hot_backup_lock)); + __wt_readunlock(session, conn->hot_backup_lock); __wt_meta_ckptlist_free(session, ckptbase); __wt_free(session, name_alloc); @@ -988,42 +1210,23 @@ err: if (hot_backup_locked) } /* - * __checkpoint_tree -- - * Checkpoint a single tree. - * Assumes all necessary locks have been acquired by the caller. + * __checkpoint_mark_deletes -- + * Figure out what old checkpoints will be deleted, and whether the + * checkpoint can be skipped entirely. */ static int -__checkpoint_tree( - WT_SESSION_IMPL *session, bool is_checkpoint, const char *cfg[]) +__checkpoint_mark_deletes( + WT_SESSION_IMPL *session, const char *cfg[]) { - WT_BM *bm; WT_BTREE *btree; WT_CKPT *ckpt, *ckptbase; WT_CONFIG_ITEM cval; - WT_CONNECTION_IMPL *conn; - WT_DATA_HANDLE *dhandle; - WT_DECL_RET; - WT_LSN ckptlsn; const char *name; - int deleted, was_modified; - bool fake_ckpt, force; + int deleted; + bool force; btree = S2BT(session); - bm = btree->bm; ckptbase = btree->ckpt; - conn = S2C(session); - dhandle = session->dhandle; - fake_ckpt = false; - was_modified = btree->modified; - - /* - * Set the checkpoint LSN to the maximum LSN so that if logging is - * disabled, recovery will never roll old changes forward over the - * non-logged changes in this checkpoint. If logging is enabled, a - * real checkpoint LSN will be assigned for this checkpoint and - * overwrite this. - */ - WT_MAX_LSN(&ckptlsn); /* * Check for clean objects not requiring a checkpoint. @@ -1052,20 +1255,15 @@ __checkpoint_tree( force = false; F_CLR(btree, WT_BTREE_SKIP_CKPT); if (!btree->modified && cfg != NULL) { - ret = __wt_config_gets(session, cfg, "force", &cval); - if (ret != 0 && ret != WT_NOTFOUND) - WT_ERR(ret); - if (ret == 0 && cval.val != 0) - force = true; + WT_RET(__wt_config_gets(session, cfg, "force", &cval)); + force = cval.val != 0; } if (!btree->modified && !force) { - if (!is_checkpoint) - goto nockpt; - deleted = 0; WT_CKPT_FOREACH(ckptbase, ckpt) if (F_ISSET(ckpt, WT_CKPT_DELETE)) ++deleted; + /* * Complicated test: if the tree is clean and last two * checkpoints have the same name (correcting for internal @@ -1079,17 +1277,52 @@ __checkpoint_tree( (strcmp(name, (ckpt - 2)->name) == 0 || (WT_PREFIX_MATCH(name, WT_CHECKPOINT) && WT_PREFIX_MATCH((ckpt - 2)->name, WT_CHECKPOINT)))) { -nockpt: F_SET(btree, WT_BTREE_SKIP_CKPT); - WT_PUBLISH(btree->checkpoint_gen, - S2C(session)->txn_global.checkpoint_gen); - WT_STAT_FAST_DATA_SET(session, - btree_checkpoint_generation, - btree->checkpoint_gen); - ret = 0; - goto err; + F_SET(btree, WT_BTREE_SKIP_CKPT); + return (0); } } + return (0); +} + +/* + * __checkpoint_tree -- + * Checkpoint a single tree. + * Assumes all necessary locks have been acquired by the caller. + */ +static int +__checkpoint_tree( + WT_SESSION_IMPL *session, bool is_checkpoint, const char *cfg[]) +{ + WT_BM *bm; + WT_BTREE *btree; + WT_CKPT *ckpt, *ckptbase; + WT_CONNECTION_IMPL *conn; + WT_DATA_HANDLE *dhandle; + WT_DECL_RET; + WT_LSN ckptlsn; + int was_modified; + bool fake_ckpt; + + WT_UNUSED(cfg); + + btree = S2BT(session); + bm = btree->bm; + ckptbase = btree->ckpt; + conn = S2C(session); + dhandle = session->dhandle; + fake_ckpt = false; + was_modified = btree->modified; + + /* + * Set the checkpoint LSN to the maximum LSN so that if logging is + * disabled, recovery will never roll old changes forward over the + * non-logged changes in this checkpoint. If logging is enabled, a + * real checkpoint LSN will be assigned for this checkpoint and + * overwrite this. + */ + WT_MAX_LSN(&ckptlsn); + /* * If an object has never been used (in other words, if it could become * a bulk-loaded file), then we must fake the checkpoint. This is good @@ -1185,10 +1418,10 @@ fake: /* /* * If we wrote a checkpoint (rather than faking one), pages may be - * available for re-use. If tracking enabled, defer making pages - * available until transaction end. The exception is if the handle - * is being discarded, in which case the handle will be gone by the - * time we try to apply or unroll the meta tracking event. + * available for re-use. If tracking is enabled, defer making pages + * available until transaction end. The exception is if the handle is + * being discarded, in which case the handle will be gone by the time + * we try to apply or unroll the meta tracking event. */ if (!fake_ckpt) { if (WT_META_TRACKING(session) && is_checkpoint) @@ -1215,6 +1448,25 @@ err: /* return (ret); } +/* + * __checkpoint_presync -- + * Visit all handles after the checkpoint writes are complete and before + * syncing. At this point, all trees should be completely open for + * business. + */ +static int +__checkpoint_presync(WT_SESSION_IMPL *session, const char *cfg[]) +{ + WT_BTREE *btree; + + WT_UNUSED(cfg); + + btree = S2BT(session); + WT_ASSERT(session, !btree->include_checkpoint_txn); + btree->evict_walk_period = btree->evict_walk_saved; + return (0); +} + /* * __checkpoint_tree_helper -- * Checkpoint a tree (suitable for use in *_apply functions). @@ -1222,7 +1474,34 @@ err: /* static int __checkpoint_tree_helper(WT_SESSION_IMPL *session, const char *cfg[]) { - return (__checkpoint_tree(session, true, cfg)); + WT_BTREE *btree; + WT_DECL_RET; + + btree = S2BT(session); + + ret = __checkpoint_tree(session, true, cfg); + + /* + * Whatever happened, we aren't visiting this tree again in this + * checkpoint. Don't keep updates pinned any longer. + */ + __checkpoint_update_generation(session); + + /* + * In case this tree was being skipped by the eviction server + * during the checkpoint, restore the previous state. + */ + btree->evict_walk_period = btree->evict_walk_saved; + + /* + * Wake the eviction server, in case application threads have + * stalled while the eviction server decided it couldn't make + * progress. Without this, application threads will be stalled + * until the eviction server next wakes. + */ + __wt_evict_server_wake(session); + + return (ret); } /* @@ -1244,6 +1523,9 @@ __wt_checkpoint(WT_SESSION_IMPL *session, const char *cfg[]) WT_SAVE_DHANDLE(session, ret = __checkpoint_lock_tree(session, true, true, cfg)); WT_RET(ret); + WT_SAVE_DHANDLE(session, + ret = __checkpoint_mark_deletes(session, cfg)); + WT_RET(ret); return (__checkpoint_tree(session, true, cfg)); } @@ -1321,6 +1603,11 @@ __wt_checkpoint_close(WT_SESSION_IMPL *session, bool final) WT_SAVE_DHANDLE(session, ret = __checkpoint_lock_tree(session, false, need_tracking, NULL)); WT_ASSERT(session, ret == 0); + if (ret == 0) { + WT_SAVE_DHANDLE(session, + ret = __checkpoint_mark_deletes(session, NULL)); + WT_ASSERT(session, ret == 0); + } if (ret == 0) ret = __checkpoint_tree(session, false, NULL); diff --git a/src/third_party/wiredtiger/src/txn/txn_log.c b/src/third_party/wiredtiger/src/txn/txn_log.c index 470515244f3..f9dd9bee807 100644 --- a/src/third_party/wiredtiger/src/txn/txn_log.c +++ b/src/third_party/wiredtiger/src/txn/txn_log.c @@ -329,7 +329,7 @@ __wt_txn_checkpoint_log( case WT_TXN_LOG_CKPT_START: /* Take a copy of the transaction snapshot. */ txn->ckpt_nsnapshot = txn->snapshot_count; - recsize = txn->ckpt_nsnapshot * WT_INTPACK64_MAXSIZE; + recsize = (size_t)txn->ckpt_nsnapshot * WT_INTPACK64_MAXSIZE; WT_ERR(__wt_scr_alloc(session, recsize, &txn->ckpt_snapshot)); p = txn->ckpt_snapshot->mem; end = p + recsize; @@ -376,7 +376,7 @@ __wt_txn_checkpoint_log( * that case. */ if (!S2C(session)->hot_backup && txn->full_ckpt) - WT_ERR(__wt_log_ckpt(session, ckpt_lsn)); + __wt_log_ckpt(session, ckpt_lsn); /* FALLTHROUGH */ case WT_TXN_LOG_CKPT_CLEANUP: @@ -450,11 +450,10 @@ __wt_txn_truncate_log( * __wt_txn_truncate_end -- * Finish truncating a range of a file. */ -int +void __wt_txn_truncate_end(WT_SESSION_IMPL *session) { F_CLR(session, WT_SESSION_LOGGING_INMEM); - return (0); } /* diff --git a/src/third_party/wiredtiger/src/txn/txn_nsnap.c b/src/third_party/wiredtiger/src/txn/txn_nsnap.c index 5b8fed23a9f..d0110d9edd8 100644 --- a/src/third_party/wiredtiger/src/txn/txn_nsnap.c +++ b/src/third_party/wiredtiger/src/txn/txn_nsnap.c @@ -220,8 +220,7 @@ __wt_txn_named_snapshot_drop(WT_SESSION_IMPL *session, const char *cfg[]) /* We are done if there are no named drops */ if (names_config.len != 0) { - WT_RET(__wt_config_subinit( - session, &objectconf, &names_config)); + __wt_config_subinit(session, &objectconf, &names_config); while ((ret = __wt_config_next(&objectconf, &k, &v)) == 0) { ret = __nsnap_drop_one(session, &k); if (ret != 0) @@ -256,7 +255,7 @@ __wt_txn_named_snapshot_get(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *nameval) if (session->ncursors > 0) WT_RET(__wt_session_copy_values(session)); - WT_RET(__wt_readlock(session, txn_global->nsnap_rwlock)); + __wt_readlock(session, txn_global->nsnap_rwlock); TAILQ_FOREACH(nsnap, &txn_global->nsnaph, q) if (WT_STRING_MATCH(nsnap->name, nameval->str, nameval->len)) { txn->snap_min = txn_state->snap_min = nsnap->snap_min; @@ -268,7 +267,7 @@ __wt_txn_named_snapshot_get(WT_SESSION_IMPL *session, WT_CONFIG_ITEM *nameval) F_SET(txn, WT_TXN_HAS_SNAPSHOT); break; } - WT_RET(__wt_readunlock(session, txn_global->nsnap_rwlock)); + __wt_readunlock(session, txn_global->nsnap_rwlock); if (nsnap == NULL) WT_RET_MSG(session, EINVAL, @@ -352,7 +351,7 @@ __wt_txn_named_snapshot_config(WT_SESSION_IMPL *session, * __wt_txn_named_snapshot_destroy -- * Destroy all named snapshots on connection close */ -int +void __wt_txn_named_snapshot_destroy(WT_SESSION_IMPL *session) { WT_NAMED_SNAPSHOT *nsnap; @@ -365,6 +364,4 @@ __wt_txn_named_snapshot_destroy(WT_SESSION_IMPL *session) TAILQ_REMOVE(&txn_global->nsnaph, nsnap, q); __nsnap_destroy(session, nsnap); } - - return (0); } diff --git a/src/third_party/wiredtiger/src/txn/txn_recover.c b/src/third_party/wiredtiger/src/txn/txn_recover.c index bd004e0f837..ae21e58d9b6 100644 --- a/src/third_party/wiredtiger/src/txn/txn_recover.c +++ b/src/third_party/wiredtiger/src/txn/txn_recover.c @@ -60,9 +60,9 @@ __recovery_cursor(WT_SESSION_IMPL *session, WT_RECOVERY *r, else if (id >= r->nfiles || r->files[id].uri == NULL) { /* If a file is missing, output a verbose message once. */ if (!r->missing) - WT_RET(__wt_verbose(session, WT_VERB_RECOVERY, + __wt_verbose(session, WT_VERB_RECOVERY, "No file found with ID %u (max %u)", - id, r->nfiles)); + id, r->nfiles); r->missing = true; } else if (__wt_log_cmp(lsnp, &r->files[id].ckpt_lsn) >= 0) { /* @@ -89,11 +89,11 @@ __recovery_cursor(WT_SESSION_IMPL *session, WT_RECOVERY *r, */ #define GET_RECOVERY_CURSOR(session, r, lsnp, fileid, cp) \ WT_ERR(__recovery_cursor(session, r, lsnp, fileid, false, cp)); \ - WT_ERR(__wt_verbose(session, WT_VERB_RECOVERY, \ + __wt_verbose(session, WT_VERB_RECOVERY, \ "%s op %" PRIu32 " to file %" PRIu32 " at LSN %" PRIu32 \ "/%" PRIu32, \ cursor == NULL ? "Skipping" : "Applying", \ - optype, fileid, lsnp->l.file, lsnp->l.offset)); \ + optype, fileid, lsnp->l.file, lsnp->l.offset); \ if (cursor == NULL) \ break @@ -333,9 +333,9 @@ __recovery_setup_file(WT_RECOVERY *r, const char *uri, const char *config) (int)cval.len, cval.str); r->files[fileid].ckpt_lsn = lsn; - WT_RET(__wt_verbose(r->session, WT_VERB_RECOVERY, + __wt_verbose(r->session, WT_VERB_RECOVERY, "Recovering %s with id %" PRIu32 " @ (%" PRIu32 ", %" PRIu32 ")", - uri, fileid, lsn.l.file, lsn.l.offset)); + uri, fileid, lsn.l.file, lsn.l.offset); return (0); @@ -496,9 +496,9 @@ __wt_txn_recover(WT_SESSION_IMPL *session) * Pass WT_LOGSCAN_RECOVER so that old logs get truncated. */ r.metadata_only = false; - WT_ERR(__wt_verbose(session, WT_VERB_RECOVERY, + __wt_verbose(session, WT_VERB_RECOVERY, "Main recovery loop: starting at %" PRIu32 "/%" PRIu32, - r.ckpt_lsn.l.file, r.ckpt_lsn.l.offset)); + r.ckpt_lsn.l.file, r.ckpt_lsn.l.offset); WT_ERR(__wt_log_needs_recovery(session, &r.ckpt_lsn, &needs_rec)); /* * Check if the database was shut down cleanly. If not diff --git a/src/third_party/wiredtiger/src/utilities/util.h b/src/third_party/wiredtiger/src/utilities/util.h index 3882d814e3a..c2cf6c22aa4 100644 --- a/src/third_party/wiredtiger/src/utilities/util.h +++ b/src/third_party/wiredtiger/src/utilities/util.h @@ -33,7 +33,8 @@ void util_copyright(void); int util_create(WT_SESSION *, int, char *[]); int util_drop(WT_SESSION *, int, char *[]); int util_dump(WT_SESSION *, int, char *[]); -int util_err(WT_SESSION *, int, const char *, ...); +int util_err(WT_SESSION *, int, const char *, ...) + WT_GCC_FUNC_DECL_ATTRIBUTE((format (printf, 3, 4))); int util_flush(WT_SESSION *, const char *); int util_list(WT_SESSION *, int, char *[]); int util_load(WT_SESSION *, int, char *[]); diff --git a/src/third_party/wiredtiger/src/utilities/util_dump.c b/src/third_party/wiredtiger/src/utilities/util_dump.c index da70aea35be..7dde13ee837 100644 --- a/src/third_party/wiredtiger/src/utilities/util_dump.c +++ b/src/third_party/wiredtiger/src/utilities/util_dump.c @@ -18,10 +18,10 @@ static int dump_prefix(WT_SESSION *, bool, bool); static int dump_record(WT_CURSOR *, bool, bool); static int dump_suffix(WT_SESSION *, bool); static int dump_table_config(WT_SESSION *, WT_CURSOR *, const char *, bool); -static int dump_table_config_complex( - WT_SESSION *, WT_CURSOR *, WT_CURSOR *, const char *, const char *, bool); +static int dump_table_parts_config( + WT_SESSION *, WT_CURSOR *, const char *, const char *, bool); static int dup_json_string(const char *, char **); -static int print_config(WT_SESSION *, const char *, char *[], bool, bool); +static int print_config(WT_SESSION *, const char *, const char *, bool, bool); static int usage(void); int @@ -146,9 +146,9 @@ dump_config(WT_SESSION *session, const char *uri, bool hex, bool json) /* Open a metadata cursor. */ if ((ret = session->open_cursor( - session, "metadata:", NULL, NULL, &cursor)) != 0) { + session, "metadata:create", NULL, NULL, &cursor)) != 0) { fprintf(stderr, "%s: %s: session.open_cursor: %s\n", progname, - "metadata:", session->strerror(session, ret)); + "metadata:create", session->strerror(session, ret)); return (1); } /* @@ -202,7 +202,7 @@ dump_json_end(WT_SESSION *session) /* * dump_json_begin -- - * Output the dump file header prefix. + * Output a separator between two JSON outputs in a list. */ static int dump_json_separator(WT_SESSION *session) @@ -232,17 +232,8 @@ static int dump_table_config( WT_SESSION *session, WT_CURSOR *cursor, const char *uri, bool json) { - WT_CONFIG_ITEM cval; - WT_CURSOR *srch; WT_DECL_RET; - size_t len; - int tret; - bool complex_table; const char *name, *v; - char *p, **cfg, *_cfg[4] = {NULL, NULL, NULL, NULL}; - - p = NULL; - cfg = &_cfg[3]; /* Get the table name. */ if ((name = strchr(uri, ':')) == NULL) { @@ -257,106 +248,39 @@ dump_table_config( */ cursor->set_key(cursor, uri); if ((ret = cursor->search(cursor)) != 0) - WT_ERR(util_cerr(cursor, "search", ret)); + return (util_cerr(cursor, "search", ret)); if ((ret = cursor->get_value(cursor, &v)) != 0) - WT_ERR(util_cerr(cursor, "get_value", ret)); - if ((*--cfg = strdup(v)) == NULL) - WT_ERR(util_err(session, errno, NULL)); + return (util_cerr(cursor, "get_value", ret)); - /* - * Workaround for WiredTiger "simple" table handling. Simple tables - * have column-group entries, but they aren't listed in the metadata's - * table entry, and the name is different from other column-groups. - * Figure out if it's a simple table and in that case, retrieve the - * column-group's configuration value and the column-group's "source" - * entry, where the column-group entry overrides the source's. - */ - complex_table = false; - if (WT_PREFIX_MATCH(uri, "table:")) { - len = strlen("colgroup:") + strlen(name) + 1; - if ((p = malloc(len)) == NULL) - WT_ERR(util_err(session, errno, NULL)); - (void)snprintf(p, len, "colgroup:%s", name); - cursor->set_key(cursor, p); - if ((ret = cursor->search(cursor)) == 0) { - if ((ret = cursor->get_value(cursor, &v)) != 0) - WT_ERR(util_cerr(cursor, "get_value", ret)); - if ((*--cfg = strdup(v)) == NULL) - WT_ERR(util_err(session, errno, NULL)); - if ((ret =__wt_config_getones( - (WT_SESSION_IMPL *)session, - *cfg, "source", &cval)) != 0) - WT_ERR(util_err( - session, ret, "%s: source entry", p)); - free(p); - len = cval.len + 10; - if ((p = malloc(len)) == NULL) - WT_ERR(util_err(session, errno, NULL)); - (void)snprintf(p, len, "%.*s", (int)cval.len, cval.str); - cursor->set_key(cursor, p); - if ((ret = cursor->search(cursor)) != 0) - WT_ERR(util_cerr(cursor, "search", ret)); - if ((ret = cursor->get_value(cursor, &v)) != 0) - WT_ERR(util_cerr(cursor, "get_value", ret)); - if ((*--cfg = strdup(v)) == NULL) - WT_ERR(util_err(session, errno, NULL)); - } else - complex_table = true; - } + WT_RET(print_config(session, uri, v, json, true)); - WT_ERR(print_config(session, uri, cfg, json, true)); + WT_RET(dump_table_parts_config( + session, cursor, name, "colgroup:", json)); + WT_RET(dump_table_parts_config( + session, cursor, name, "index:", json)); - if (complex_table) { - /* - * The underlying table configuration function needs a second - * cursor: open one before calling it, it makes error handling - * hugely simpler. - */ - if ((ret = session->open_cursor( - session, "metadata:", NULL, NULL, &srch)) != 0) - WT_ERR(util_cerr(cursor, "open_cursor", ret)); - - if ((ret = dump_table_config_complex( - session, cursor, srch, name, "colgroup:", json)) == 0) - ret = dump_table_config_complex( - session, cursor, srch, name, "index:", json); - - if ((tret = srch->close(srch)) != 0) { - tret = util_cerr(cursor, "close", tret); - if (ret == 0) - ret = tret; - } - } else if (json && printf( - " \"colgroups\" : [],\n" - " \"indices\" : []\n") < 0) - WT_ERR(util_cerr(cursor, NULL, EIO)); - -err: free(p); - free(_cfg[0]); - free(_cfg[1]); - free(_cfg[2]); - return (ret); + return (0); } /* - * dump_table_config_complex -- - * Dump the column groups or indices for a table. + * dump_table_parts_config -- + * Dump the column groups or indices parts with a table. */ static int -dump_table_config_complex(WT_SESSION *session, WT_CURSOR *cursor, - WT_CURSOR *srch, const char *name, const char *entry, bool json) +dump_table_parts_config(WT_SESSION *session, WT_CURSOR *cursor, + const char *name, const char *entry, bool json) { - WT_CONFIG_ITEM cval; WT_DECL_RET; bool multiple; const char *groupname, *key, *sep; size_t len; int exact; const char *v; - char *p, *cfg[3] = {NULL, NULL, NULL}; + char *uriprefix; multiple = false; sep = ""; + uriprefix = NULL; if (json) { if (strcmp(entry, "colgroup:") == 0) { @@ -368,82 +292,61 @@ dump_table_config_complex(WT_SESSION *session, WT_CURSOR *cursor, if (printf(" \"%s\" : [", groupname) < 0) return (util_err(session, EIO, NULL)); } + + len = strlen(entry) + strlen(name) + 1; + if ((uriprefix = malloc(len)) == NULL) + return util_err(session, errno, NULL); + + snprintf(uriprefix, len, "%s%s", entry, name); + /* * Search the file looking for column group and index key/value pairs: * for each one, look up the related source information and append it * to the base record, where the column group and index configuration * overrides the source configuration. */ - cursor->set_key(cursor, entry); - if ((ret = cursor->search_near(cursor, &exact)) != 0) { - if (ret == WT_NOTFOUND) - return (0); + cursor->set_key(cursor, uriprefix); + ret = cursor->search_near(cursor, &exact); + free(uriprefix); + if (ret == WT_NOTFOUND) + return (0); + if (ret != 0) return (util_cerr(cursor, "search_near", ret)); - } - if (exact >= 0) + + /* + * An exact match is only possible for column groups, and indicates + * there is an implicit (unnamed) column group. Any configuration + * for such a column group has already been folded into the + * configuration for the associated table, so it is not interesting. + */ + if (exact > 0) goto match; - while ((ret = cursor->next(cursor)) == 0) { + while (exact != 0 && (ret = cursor->next(cursor)) == 0) { match: if ((ret = cursor->get_key(cursor, &key)) != 0) return (util_cerr(cursor, "get_key", ret)); /* Check if we've finished the list of entries. */ - if (!WT_PREFIX_MATCH(key, entry)) + if (!WT_PREFIX_MATCH(key, entry) || + !WT_PREFIX_MATCH(key + strlen(entry), name)) break; - /* - * Check for a table name match. This test will match "simple" - * table column-groups as well as the more complex ones, but - * the previous version of the test was wrong and we're only - * in this function in the case of complex tables. - */ - if (!WT_PREFIX_MATCH(key + strlen(entry), name)) - continue; - - /* Get the value. */ if ((ret = cursor->get_value(cursor, &v)) != 0) return (util_cerr(cursor, "get_value", ret)); - if ((cfg[1] = strdup(v)) == NULL) - return (util_err(session, errno, NULL)); - - /* Crack it and get the underlying source. */ - if ((ret = __wt_config_getones( - (WT_SESSION_IMPL *)session, cfg[1], "source", &cval)) != 0) - return ( - util_err(session, ret, "%s: source entry", key)); - - /* Nul-terminate the source entry. */ - len = cval.len + 10; - if ((p = malloc(len)) == NULL) - return (util_err(session, errno, NULL)); - (void)snprintf(p, len, "%.*s", (int)cval.len, cval.str); - srch->set_key(srch, p); - if ((ret = srch->search(srch)) != 0) - ret = util_err(session, ret, "%s: %s", key, p); - free(p); - if (ret != 0) - return (1); - - /* Get the source's value. */ - if ((ret = srch->get_value(srch, &v)) != 0) - return (util_cerr(cursor, "get_value", ret)); - if ((cfg[0] = strdup(v)) == NULL) - return (util_err(session, errno, NULL)); - if (json && printf("%s\n", multiple ? "," : "") < 0) + if (json && printf("%s\n", (multiple ? "," : "")) < 0) return (util_err(session, EIO, NULL)); /* * The dumped configuration string is the original key plus the * source's configuration, where the values of the original key * override any source configurations of the same name. */ - if (print_config(session, key, cfg, json, false) != 0) + if (print_config(session, key, v, json, false) != 0) return (util_err(session, EIO, NULL)); multiple = true; } - if (json && printf("\n ]%s\n", sep) < 0) + if (json && printf("%s]%s\n", + (multiple ? "\n " : ""), sep) < 0) return (util_err(session, EIO, NULL)); - free(cfg[0]); - free(cfg[1]); if (ret == 0 || ret == WT_NOTFOUND) return (0); @@ -573,11 +476,11 @@ dup_json_string(const char *str, char **result) * Output a key/value URI pair by combining v1 and v2. */ static int -print_config( - WT_SESSION *session, const char *key, char *cfg[], bool json, bool toplevel) +print_config(WT_SESSION *session, const char *key, const char *cfg, bool json, + bool toplevel) { WT_DECL_RET; - char *jsonconfig, *value_ret; + char *jsonconfig; /* * We have all of the object configuration, but don't have the default @@ -585,13 +488,9 @@ print_config( * defaults and collapse it all into one load configuration string. */ jsonconfig = NULL; - if ((ret = __wt_schema_create_final( - (WT_SESSION_IMPL *)session, cfg, &value_ret)) != 0) + if (json && (ret = dup_json_string(cfg, &jsonconfig)) != 0) return (util_err(session, ret, NULL)); - if (json && (ret = dup_json_string(value_ret, &jsonconfig)) != 0) { - free(value_ret); - return (util_err(session, ret, NULL)); - } + if (json) { if (toplevel) ret = printf( @@ -604,8 +503,7 @@ print_config( " \"config\" : \"%s\"\n" " }", key, jsonconfig); } else - ret = printf("%s\n%s\n", key, value_ret); - free(value_ret); + ret = printf("%s\n%s\n", key, cfg); free(jsonconfig); if (ret < 0) return (util_err(session, EIO, NULL)); diff --git a/src/third_party/wiredtiger/src/utilities/util_list.c b/src/third_party/wiredtiger/src/utilities/util_list.c index c7afea04b1c..e91dbfce05b 100644 --- a/src/third_party/wiredtiger/src/utilities/util_list.c +++ b/src/third_party/wiredtiger/src/utilities/util_list.c @@ -67,33 +67,29 @@ list_get_allocsize(WT_SESSION *session, const char *key, size_t *allocsize) WT_CONFIG_PARSER *parser; WT_DECL_RET; WT_EXTENSION_API *wt_api; + int tret; char *config; wt_api = session->connection->get_extension_api(session->connection); - if ((ret = - wt_api->metadata_search(wt_api, session, key, &config)) != 0) { - fprintf(stderr, "%s: %s: extension_api.metadata_search: %s\n", - progname, key, session->strerror(session, ret)); - return (ret); - } + if ((ret = wt_api->metadata_search(wt_api, session, key, &config)) != 0) + return (util_err( + session, ret, "%s: WT_EXTENSION_API.metadata_search", key)); if ((ret = wt_api->config_parser_open(wt_api, session, config, - strlen(config), &parser)) != 0) { - fprintf(stderr, "%s: extension_api.config_parser_open: %s\n", - progname, session->strerror(session, ret)); - return (ret); - } + strlen(config), &parser)) != 0) + return (util_err( + session, ret, "WT_EXTENSION_API.config_parser_open")); if ((ret = parser->get(parser, "allocation_size", &szvalue)) != 0) { - if (ret != WT_NOTFOUND) - fprintf(stderr, "%s: config_parser.get: %s\n", - progname, session->strerror(session, ret)); - (void)parser->close(parser); - return (ret); - } - if ((ret = parser->close(parser)) != 0) { - fprintf(stderr, "%s: config_parser.close: %s\n", - progname, session->strerror(session, ret)); + if (ret == WT_NOTFOUND) { + *allocsize = 0; + ret = 0; + } else + ret = util_err(session, ret, "WT_CONFIG_PARSER.get"); + if ((tret = parser->close(parser)) != 0) + (void)util_err(session, tret, "WT_CONFIG_PARSER.close"); return (ret); } + if ((ret = parser->close(parser)) != 0) + return (util_err(session, ret, "WT_CONFIG_PARSER.close")); *allocsize = (size_t)szvalue.val; return (0); } @@ -120,9 +116,8 @@ list_print(WT_SESSION *session, const char *name, bool cflag, bool vflag) if (ret == ENOENT) return (0); - fprintf(stderr, "%s: %s: session.open_cursor: %s\n", - progname, WT_METADATA_URI, session->strerror(session, ret)); - return (1); + return (util_err(session, + ret, "%s: WT_SESSION.open_cursor", WT_METADATA_URI)); } found = name == NULL; @@ -196,12 +191,8 @@ list_print_checkpoint(WT_SESSION *session, const char *key) return (ret == WT_NOTFOUND ? 0 : ret); /* We need the allocation size for decoding the checkpoint addr */ - if ((ret = list_get_allocsize(session, key, &allocsize)) != 0) { - if (ret == WT_NOTFOUND) - allocsize = 0; - else - return (ret); - } + if ((ret = list_get_allocsize(session, key, &allocsize)) != 0) + return (ret); /* Find the longest name, so we can pretty-print. */ len = 0; @@ -214,8 +205,7 @@ list_print_checkpoint(WT_SESSION *session, const char *key) WT_CKPT_FOREACH(ckptbase, ckpt) { if (allocsize != 0 && (ret = __wt_block_ckpt_decode( session, allocsize, ckpt->raw.data, &ci)) != 0) { - fprintf(stderr, "%s: __wt_block_buffer_to_ckpt: %s\n", - progname, session->strerror(session, ret)); + (void)util_err(session, ret, "__wt_block_ckpt_decode"); /* continue if damaged */ ci.root_size = 0; } @@ -248,7 +238,7 @@ list_print_checkpoint(WT_SESSION *session, const char *key) ci.root_size, ci.root_size); printf("\t\t" "root checksum: %" PRIu32 " (0x%" PRIx32 ")\n", - ci.root_cksum, ci.root_cksum); + ci.root_checksum, ci.root_checksum); } } diff --git a/src/third_party/wiredtiger/src/utilities/util_misc.c b/src/third_party/wiredtiger/src/utilities/util_misc.c index 3c4e8d2dfa1..0905bfa97be 100644 --- a/src/third_party/wiredtiger/src/utilities/util_misc.c +++ b/src/third_party/wiredtiger/src/utilities/util_misc.c @@ -141,11 +141,14 @@ util_flush(WT_SESSION *session, const char *uri) return (util_err(session, errno, NULL)); (void)snprintf(buf, len, "target=(\"%s\")", uri); - if ((ret = session->checkpoint(session, buf)) != 0) { - ret = util_err(session, ret, "%s: session.checkpoint", uri); - (void)session->drop(session, uri, NULL); - } - + ret = session->checkpoint(session, buf); free(buf); - return (ret); + + if (ret == 0) + return (0); + + (void)util_err(session, ret, "%s: session.checkpoint", uri); + if ((ret = session->drop(session, uri, NULL)) != 0) + (void)util_err(session, ret, "%s: session.drop", uri); + return (1); } diff --git a/src/third_party/wiredtiger/test/bloom/test_bloom.c b/src/third_party/wiredtiger/test/bloom/test_bloom.c index 9a7584f951f..7a298f000aa 100644 --- a/src/third_party/wiredtiger/test/bloom/test_bloom.c +++ b/src/third_party/wiredtiger/test/bloom/test_bloom.c @@ -160,8 +160,7 @@ run(void) item.size = g.c_key_max; for (i = 0; i < g.c_ops; i++) { item.data = g.entries[i]; - if ((ret = __wt_bloom_insert(bloomp, &item)) != 0) - testutil_die(ret, "__wt_bloom_insert: %" PRIu32, i); + __wt_bloom_insert(bloomp, &item); } testutil_check(__wt_bloom_finalize(bloomp)); diff --git a/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.c b/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.c index 6293d36f916..6b2f0d4466c 100644 --- a/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.c +++ b/src/third_party/wiredtiger/test/checkpoint/test_checkpoint.c @@ -34,7 +34,7 @@ static int handle_error(WT_EVENT_HANDLER *, WT_SESSION *, int, const char *); static int handle_message(WT_EVENT_HANDLER *, WT_SESSION *, const char *); static void onint(int) WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); -static int cleanup(void); +static void cleanup(void); static int usage(void); static int wt_connect(const char *); static int wt_shutdown(void); @@ -139,7 +139,7 @@ main(int argc, char *argv[]) printf(" %d: %d workers, %d tables\n", cnt, g.nworkers, g.ntables); - (void)cleanup(); /* Clean up previous runs */ + cleanup(); /* Clean up previous runs */ /* Setup a fresh set of cookies in the global array. */ if ((g.cookies = calloc( @@ -240,14 +240,13 @@ wt_shutdown(void) * cleanup -- * Clean up from previous runs. */ -static int +static void cleanup(void) { g.running = 0; g.ntables_created = 0; testutil_clean_work_dir(g.home); - return (0); } static int @@ -283,7 +282,7 @@ onint(int signo) { WT_UNUSED(signo); - (void)cleanup(); + cleanup(); fprintf(stderr, "\n"); exit(EXIT_FAILURE); diff --git a/src/third_party/wiredtiger/test/csuite/Makefile.am b/src/third_party/wiredtiger/test/csuite/Makefile.am index f842bc1316f..15db2fbcf46 100644 --- a/src/third_party/wiredtiger/test/csuite/Makefile.am +++ b/src/third_party/wiredtiger/test/csuite/Makefile.am @@ -10,15 +10,30 @@ noinst_PROGRAMS = test_wt1965_col_efficiency test_wt2246_col_append_SOURCES = wt2246_col_append/main.c noinst_PROGRAMS += test_wt2246_col_append +test_wt2323_join_visibility_SOURCES = wt2323_join_visibility/main.c +noinst_PROGRAMS += test_wt2323_join_visibility + test_wt2535_insert_race_SOURCES = wt2535_insert_race/main.c noinst_PROGRAMS += test_wt2535_insert_race test_wt2447_join_main_table_SOURCES = wt2447_join_main_table/main.c noinst_PROGRAMS += test_wt2447_join_main_table +test_wt2695_checksum_SOURCES = wt2695_checksum/main.c +noinst_PROGRAMS += test_wt2695_checksum + test_wt2592_join_schema_SOURCES = wt2592_join_schema/main.c noinst_PROGRAMS += test_wt2592_join_schema +test_wt2719_reconfig_SOURCES = wt2719_reconfig/main.c +noinst_PROGRAMS += test_wt2719_reconfig + +test_wt2834_join_bloom_fix_SOURCES = wt2834_join_bloom_fix/main.c +noinst_PROGRAMS += test_wt2834_join_bloom_fix + +test_wt2853_perf_SOURCES = wt2853_perf/main.c +noinst_PROGRAMS += test_wt2853_perf + # Run this during a "make check" smoke test. TESTS = $(noinst_PROGRAMS) LOG_COMPILER = $(TEST_WRAPPER) diff --git a/src/third_party/wiredtiger/test/csuite/wt1965_col_efficiency/main.c b/src/third_party/wiredtiger/test/csuite/wt1965_col_efficiency/main.c index 2882ce9cdf5..0dc367c0611 100644 --- a/src/third_party/wiredtiger/test/csuite/wt1965_col_efficiency/main.c +++ b/src/third_party/wiredtiger/test/csuite/wt1965_col_efficiency/main.c @@ -181,6 +181,5 @@ main(int argc, char *argv[]) testutil_assert(ret == WT_NOTFOUND); testutil_cleanup(opts); - - return (0); + return (EXIT_SUCCESS); } diff --git a/src/third_party/wiredtiger/test/csuite/wt2246_col_append/main.c b/src/third_party/wiredtiger/test/csuite/wt2246_col_append/main.c index 798970cbb6d..69683707d16 100644 --- a/src/third_party/wiredtiger/test/csuite/wt2246_col_append/main.c +++ b/src/third_party/wiredtiger/test/csuite/wt2246_col_append/main.c @@ -152,7 +152,5 @@ main(int argc, char *argv[]) (ce - cs) / (double)CLOCKS_PER_SEC); testutil_cleanup(opts); - /* NOTREACHED */ - - return (0); + return (EXIT_SUCCESS); } diff --git a/src/third_party/wiredtiger/test/csuite/wt2323_join_visibility/main.c b/src/third_party/wiredtiger/test/csuite/wt2323_join_visibility/main.c new file mode 100644 index 00000000000..bbf1626fe82 --- /dev/null +++ b/src/third_party/wiredtiger/test/csuite/wt2323_join_visibility/main.c @@ -0,0 +1,402 @@ +/*- + * Public Domain 2014-2016 MongoDB, Inc. + * Public Domain 2008-2014 WiredTiger, Inc. + * + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "test_util.h" + +/* + * JIRA ticket reference: WT-2323 + * + * Test case description: We create two kinds of threads that race: One kind + * is populating/updating records in a table with a few indices, the other + * is reading from a join of that table. The hope in constructing this test + * was to have the updates interleaved between reads of multiple indices by + * the join, yielding an inconsistent view of the data. In the main table, + * we insert account records, with a positive or negative balance. The + * negative balance accounts always have a flag set to non-zero, positive + * balances have the flag set to zero. The join we do is: + * + * select (*) from account where account.postal_code = '54321' and + * account.balance < 0 and account.flags == 0 + * + * which should always yield no results. + * + * Failure mode: This test never actually failed with any combination of + * parameters, with N_INSERT up to 50000000. It seems that a snapshot is + * implicitly allocated in the session used by a join by the set_key calls + * that occur before the first 'next' of the join cursor is done. Despite + * that, the test seems interesting enough to keep around, with the number + * of inserts set low as a default. + */ + +void (*custom_die)(void) = NULL; + +#define N_RECORDS 10000 +#define N_INSERT 500000 +#define N_INSERT_THREAD 2 +#define N_JOIN_THREAD 2 +#define S64 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789::" +#define S1024 (S64 S64 S64 S64 S64 S64 S64 S64 S64 S64 S64 S64 S64 S64 S64 S64) + +typedef struct { + char posturi[256]; + char baluri[256]; + char flaguri[256]; + char joinuri[256]; + bool bloom; + bool remove; +} SHARED_OPTS; + +typedef struct { + TEST_OPTS *testopts; + SHARED_OPTS *sharedopts; + int threadnum; + int nthread; + int done; + int joins; + int removes; + int inserts; + int notfounds; + int rollbacks; +} THREAD_ARGS; + +static void *thread_insert(void *); +static void *thread_join(void *); +static void test_join(TEST_OPTS *, SHARED_OPTS *, bool, bool); + +int +main(int argc, char *argv[]) +{ + SHARED_OPTS *sharedopts, _sharedopts; + TEST_OPTS *opts, _opts; + const char *tablename; + + opts = &_opts; + sharedopts = &_sharedopts; + memset(opts, 0, sizeof(*opts)); + memset(sharedopts, 0, sizeof(*sharedopts)); + + testutil_check(testutil_parse_opts(argc, argv, opts)); + testutil_make_work_dir(opts->home); + + tablename = strchr(opts->uri, ':'); + testutil_assert(tablename != NULL); + tablename++; + snprintf(sharedopts->posturi, sizeof(sharedopts->posturi), + "index:%s:post", tablename); + snprintf(sharedopts->baluri, sizeof(sharedopts->baluri), + "index:%s:bal", tablename); + snprintf(sharedopts->flaguri, sizeof(sharedopts->flaguri), + "index:%s:flag", tablename); + snprintf(sharedopts->joinuri, sizeof(sharedopts->joinuri), + "join:%s", opts->uri); + + testutil_check(wiredtiger_open(opts->home, NULL, + "create,cache_size=1G", &opts->conn)); + + test_join(opts, sharedopts, true, true); + test_join(opts, sharedopts, true, false); + test_join(opts, sharedopts, false, true); + test_join(opts, sharedopts, false, false); + + testutil_cleanup(opts); + + return (0); +} + +static void +test_join(TEST_OPTS *opts, SHARED_OPTS *sharedopts, bool bloom, + bool sometimes_remove) +{ + THREAD_ARGS insert_args[N_INSERT_THREAD], join_args[N_JOIN_THREAD]; + WT_CURSOR *maincur; + WT_SESSION *session; + pthread_t insert_tid[N_INSERT_THREAD], join_tid[N_JOIN_THREAD]; + int i; + + memset(insert_args, 0, sizeof(insert_args)); + memset(join_args, 0, sizeof(join_args)); + + sharedopts->bloom = bloom; + sharedopts->remove = sometimes_remove; + + fprintf(stderr, "Running with bloom=%d, remove=%d\n", + (int)bloom, (int)sometimes_remove); + + testutil_check( + opts->conn->open_session(opts->conn, NULL, NULL, &session)); + + /* + * Note: id is repeated as id2. This makes it easier to + * identify the primary key in dumps of the index files. + */ + testutil_check(session->create(session, opts->uri, + "key_format=i,value_format=iiSii," + "columns=(id,post,bal,extra,flag,id2)")); + + testutil_check(session->create(session, sharedopts->posturi, + "columns=(post)")); + testutil_check(session->create(session, sharedopts->baluri, + "columns=(bal)")); + testutil_check(session->create(session, sharedopts->flaguri, + "columns=(flag)")); + + /* + * Insert a single record with all items we need to + * call search() on, this makes our join logic easier. + */ + testutil_check(session->open_cursor(session, opts->uri, NULL, NULL, + &maincur)); + maincur->set_key(maincur, N_RECORDS); + maincur->set_value(maincur, 54321, 0, "", 0, N_RECORDS); + testutil_check(maincur->insert(maincur)); + testutil_check(maincur->close(maincur)); + + for (i = 0; i < N_INSERT_THREAD; ++i) { + insert_args[i].threadnum = i; + insert_args[i].nthread = N_INSERT_THREAD; + insert_args[i].testopts = opts; + insert_args[i].sharedopts = sharedopts; + testutil_check(pthread_create(&insert_tid[i], NULL, + thread_insert, (void *)&insert_args[i])); + } + + for (i = 0; i < N_JOIN_THREAD; ++i) { + join_args[i].threadnum = i; + join_args[i].nthread = N_JOIN_THREAD; + join_args[i].testopts = opts; + join_args[i].sharedopts = sharedopts; + testutil_check(pthread_create(&join_tid[i], NULL, + thread_join, (void *)&join_args[i])); + } + + /* + * Wait for insert threads to finish. When they + * are done, signal join threads to complete. + */ + for (i = 0; i < N_INSERT_THREAD; ++i) + testutil_check(pthread_join(insert_tid[i], NULL)); + + for (i = 0; i < N_JOIN_THREAD; ++i) + join_args[i].done = 1; + + for (i = 0; i < N_JOIN_THREAD; ++i) + testutil_check(pthread_join(join_tid[i], NULL)); + + fprintf(stderr, "\n"); + for (i = 0; i < N_JOIN_THREAD; ++i) { + fprintf(stderr, " join thread %d did %d joins\n", + i, join_args[i].joins); + } + for (i = 0; i < N_INSERT_THREAD; ++i) + fprintf(stderr, + " insert thread %d did " + "%d inserts, %d removes, %d notfound, %d rollbacks\n", + i, insert_args[i].inserts, insert_args[i].removes, + insert_args[i].notfounds, insert_args[i].rollbacks); + + testutil_check(session->drop(session, sharedopts->posturi, NULL)); + testutil_check(session->drop(session, sharedopts->baluri, NULL)); + testutil_check(session->drop(session, sharedopts->flaguri, NULL)); + testutil_check(session->drop(session, opts->uri, NULL)); + testutil_check(session->close(session, NULL)); +} + +static void *thread_insert(void *arg) +{ + SHARED_OPTS *sharedopts; + TEST_OPTS *opts; + THREAD_ARGS *threadargs; + WT_CURSOR *maincur; + WT_RAND_STATE rnd; + WT_SESSION *session; + int bal, i, flag, key, post, ret; + const char *extra = S1024; + + threadargs = (THREAD_ARGS *)arg; + opts = threadargs->testopts; + sharedopts = threadargs->sharedopts; + testutil_check(__wt_random_init_seed(NULL, &rnd)); + + testutil_check(opts->conn->open_session( + opts->conn, NULL, NULL, &session)); + + testutil_check(session->open_cursor(session, opts->uri, NULL, NULL, + &maincur)); + + for (i = 0; i < N_INSERT; i++) { + /* + * Insert threads may stomp on each other's records; + * that's okay. + */ + key = (int)(__wt_random(&rnd) % N_RECORDS); + maincur->set_key(maincur, key); + if (sharedopts->remove) + testutil_check(session->begin_transaction(session, + "isolation=snapshot")); + if (sharedopts->remove && __wt_random(&rnd) % 5 == 0 && + maincur->search(maincur) == 0) { + /* + * Another thread can be removing at the + * same time. + */ + ret = maincur->remove(maincur); + testutil_assert(ret == 0 || + (N_INSERT_THREAD > 1 && + (ret == WT_NOTFOUND || ret == WT_ROLLBACK))); + if (ret == 0) + threadargs->removes++; + else if (ret == WT_NOTFOUND) + threadargs->notfounds++; + else if (ret == WT_ROLLBACK) + threadargs->rollbacks++; + } else { + if (__wt_random(&rnd) % 2 == 0) + post = 54321; + else + post = i % 100000; + if (__wt_random(&rnd) % 2 == 0) { + bal = -100; + flag = 1; + } else { + bal = 1 + (i % 1000) * 100; + flag = 0; + } + maincur->set_value(maincur, post, bal, extra, flag, + key); + ret = maincur->insert(maincur); + testutil_assert(ret == 0 || + (N_INSERT_THREAD > 1 && ret == WT_ROLLBACK)); + testutil_check(maincur->reset(maincur)); + if (ret == 0) + threadargs->inserts++; + else if (ret == WT_ROLLBACK) + threadargs->rollbacks++; + } + if (sharedopts->remove) + testutil_check(session->commit_transaction(session, + NULL)); + if (i % 1000 == 0 && i != 0) { + if (i % 10000 == 0) + fprintf(stderr, "*"); + else + fprintf(stderr, "."); + } + } + testutil_check(maincur->close(maincur)); + testutil_check(session->close(session, NULL)); + return (NULL); +} + +static void *thread_join(void *arg) +{ + SHARED_OPTS *sharedopts; + TEST_OPTS *opts; + THREAD_ARGS *threadargs; + WT_CURSOR *postcur, *balcur, *flagcur, *joincur; + WT_SESSION *session; + int bal, flag, key, key2, post, ret; + char cfg[128]; + char *extra; + + threadargs = (THREAD_ARGS *)arg; + opts = threadargs->testopts; + sharedopts = threadargs->sharedopts; + + testutil_check(opts->conn->open_session( + opts->conn, NULL, NULL, &session)); + + testutil_check(session->open_cursor( + session, sharedopts->posturi, NULL, NULL, &postcur)); + testutil_check(session->open_cursor( + session, sharedopts->baluri, NULL, NULL, &balcur)); + testutil_check(session->open_cursor( + session, sharedopts->flaguri, NULL, NULL, &flagcur)); + + for (threadargs->joins = 0; threadargs->done == 0; + threadargs->joins++) { + testutil_check(session->open_cursor( + session, sharedopts->joinuri, NULL, NULL, &joincur)); + postcur->set_key(postcur, 54321); + testutil_check(postcur->search(postcur)); + testutil_check(session->join(session, joincur, postcur, + "compare=eq")); + + balcur->set_key(balcur, 0); + testutil_check(balcur->search(balcur)); + if (sharedopts->bloom) + sprintf(cfg, "compare=lt,strategy=bloom,count=%d", + N_RECORDS); + else + sprintf(cfg, "compare=lt"); + testutil_check(session->join(session, joincur, balcur, cfg)); + + flagcur->set_key(flagcur, 0); + testutil_check(flagcur->search(flagcur)); + if (sharedopts->bloom) + sprintf(cfg, "compare=eq,strategy=bloom,count=%d", + N_RECORDS); + else + sprintf(cfg, "compare=eq"); + testutil_check(session->join(session, joincur, flagcur, cfg)); + + /* Expect no values returned */ + ret = joincur->next(joincur); + if (ret == 0) { + /* + * The values may already have been changed, but + * print them for informational purposes. + */ + testutil_check(joincur->get_key(joincur, &key)); + testutil_check(joincur->get_value(joincur, &post, + &bal, &extra, &flag, &key2)); + fprintf(stderr, "FAIL: iteration %d: " + "key=%d/%d, postal_code=%d, balance=%d, flag=%d\n", + threadargs->joins, key, key2, post, bal, flag); + /* Save the results. */ + testutil_check(opts->conn->close(opts->conn, NULL)); + opts->conn = NULL; + return (NULL); + } + testutil_assert(ret == WT_NOTFOUND); + testutil_check(joincur->close(joincur)); + + /* + * Reset the cursors, potentially allowing the insert + * threads to proceed. + */ + testutil_check(postcur->reset(postcur)); + testutil_check(balcur->reset(balcur)); + testutil_check(flagcur->reset(flagcur)); + if (threadargs->joins % 100 == 0) + fprintf(stderr, "J"); + } + testutil_check(postcur->close(postcur)); + testutil_check(balcur->close(balcur)); + testutil_check(flagcur->close(flagcur)); + testutil_check(session->close(session, NULL)); + return (NULL); +} diff --git a/src/third_party/wiredtiger/test/csuite/wt2447_join_main_table/main.c b/src/third_party/wiredtiger/test/csuite/wt2447_join_main_table/main.c index a6f19cb0858..bbae61e7ed5 100644 --- a/src/third_party/wiredtiger/test/csuite/wt2447_join_main_table/main.c +++ b/src/third_party/wiredtiger/test/csuite/wt2447_join_main_table/main.c @@ -184,6 +184,5 @@ main(int argc, char *argv[]) testutil_assert(maincount == 2); testutil_cleanup(opts); - - return (0); + return (EXIT_SUCCESS); } diff --git a/src/third_party/wiredtiger/test/csuite/wt2695_checksum/main.c b/src/third_party/wiredtiger/test/csuite/wt2695_checksum/main.c new file mode 100644 index 00000000000..df6f562f719 --- /dev/null +++ b/src/third_party/wiredtiger/test/csuite/wt2695_checksum/main.c @@ -0,0 +1,143 @@ +/*- + * Public Domain 2014-2016 MongoDB, Inc. + * Public Domain 2008-2014 WiredTiger, Inc. + * + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "test_util.h" + +/* + * JIRA ticket reference: WT-2695 + * Test case description: Smoke-test the CRC. + */ + +void (*custom_die)(void) = NULL; + +static inline void +check(uint32_t hw, uint32_t sw, size_t len, const char *msg) +{ + testutil_checkfmt(hw == sw ? 0 : 1, + "%s checksum mismatch of %" WT_SIZET_FMT " bytes: %#08x != %#08x\n", + msg, len, hw, sw); +} + +#define DATASIZE (128 * 1024) +int +main(void) +{ + WT_RAND_STATE rnd; + size_t len; + uint32_t hw, sw; + u_int i, j; + uint8_t *data; + + /* Allocate aligned memory for the data. */ + data = dcalloc(DATASIZE, sizeof(uint8_t)); + + /* Initialize the RNG. */ + testutil_check(__wt_random_init_seed(NULL, &rnd)); + + /* Initialize the WiredTiger library checksum functions. */ + __wt_checksum_init(); + + /* + * Some simple known checksums. + */ + len = 1; + hw = __wt_checksum(data, len); + check(hw, (uint32_t)0x527d5351, len, "nul x1: hardware"); + sw = __wt_checksum_sw(data, len); + check(sw, (uint32_t)0x527d5351, len, "nul x1: software"); + + len = 2; + hw = __wt_checksum(data, len); + check(hw, (uint32_t)0xf16177d2, len, "nul x2: hardware"); + sw = __wt_checksum_sw(data, len); + check(sw, (uint32_t)0xf16177d2, len, "nul x2: software"); + + len = 3; + hw = __wt_checksum(data, len); + check(hw, (uint32_t)0x6064a37a, len, "nul x3: hardware"); + sw = __wt_checksum_sw(data, len); + check(sw, (uint32_t)0x6064a37a, len, "nul x3: software"); + + len = 4; + hw = __wt_checksum(data, len); + check(hw, (uint32_t)0x48674bc7, len, "nul x4: hardware"); + sw = __wt_checksum_sw(data, len); + check(sw, (uint32_t)0x48674bc7, len, "nul x4: software"); + + len = strlen("123456789"); + memcpy(data, "123456789", len); + hw = __wt_checksum(data, len); + check(hw, (uint32_t)0xe3069283, len, "known string #1: hardware"); + sw = __wt_checksum_sw(data, len); + check(sw, (uint32_t)0xe3069283, len, "known string #1: software"); + + len = strlen("The quick brown fox jumps over the lazy dog"); + memcpy(data, "The quick brown fox jumps over the lazy dog", len); + hw = __wt_checksum(data, len); + check(hw, (uint32_t)0x22620404, len, "known string #2: hardware"); + sw = __wt_checksum_sw(data, len); + check(sw, (uint32_t)0x22620404, len, "known string #2: software"); + + /* + * Offset the string by 1 to ensure the hardware code handles unaligned + * reads. + */ + hw = __wt_checksum(data + 1, len - 1); + check(hw, (uint32_t)0xae11f7f5, len, "known string #2: hardware"); + sw = __wt_checksum_sw(data + 1, len - 1); + check(sw, (uint32_t)0xae11f7f5, len, "known string #2: software"); + + /* + * Checksums of power-of-two data chunks. + */ + for (i = 0, len = 512; i < 1000; ++i) { + for (j = 0; j < len; ++j) + data[j] = __wt_random(&rnd) & 0xff; + hw = __wt_checksum(data, len); + sw = __wt_checksum_sw(data, len); + check(hw, sw, len, "random power-of-two"); + + len *= 2; + if (len > DATASIZE) + len = 512; + } + + /* + * Checksums of random data chunks. + */ + for (i = 0; i < 1000; ++i) { + len = __wt_random(&rnd) % DATASIZE; + for (j = 0; j < len; ++j) + data[j] = __wt_random(&rnd) & 0xff; + hw = __wt_checksum(data, len); + sw = __wt_checksum_sw(data, len); + check(hw, sw, len, "random"); + } + + free(data); + return (EXIT_SUCCESS); +} diff --git a/src/third_party/wiredtiger/test/csuite/wt2719_reconfig/main.c b/src/third_party/wiredtiger/test/csuite/wt2719_reconfig/main.c new file mode 100644 index 00000000000..4ec213c85ea --- /dev/null +++ b/src/third_party/wiredtiger/test/csuite/wt2719_reconfig/main.c @@ -0,0 +1,283 @@ +/*- + * Public Domain 2014-2016 MongoDB, Inc. + * Public Domain 2008-2014 WiredTiger, Inc. + * + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "test_util.h" + +/* + * JIRA ticket reference: WT-2719 + * Test case description: Fuzz testing for WiredTiger reconfiguration. + */ + +void (*custom_die)(void) = NULL; + +static const char *list[] = { + ",async=(enabled=0)", + ",async=(enabled=1)", + ",async=(ops_max=2048)", + ",async=(ops_max=2348)", + ",async=(ops_max=1790)", + ",async=(threads=10)", + ",async=(threads=7)", + ",async=(threads=17)", + + ",cache_overhead=13", + ",cache_overhead=27", + ",cache_overhead=8", + + ",cache_size=75MB", + ",cache_size=214MB", + ",cache_size=37MB", + + ",checkpoint=(log_size=104857600)", /* 100MB */ + ",checkpoint=(log_size=1073741824)", /* 1GB */ + ",checkpoint=(log_size=2)", + ",checkpoint=(log_size=0)", + ",checkpoint=(wait=100)", + ",checkpoint=(wait=10000)", + ",checkpoint=(wait=2)", + ",checkpoint=(wait=0)", + + ",error_prefix=\"prefix\"", + + ",eviction=(threads_min=7,threads_max=10)", + ",eviction=(threads_min=17,threads_max=18)", + ",eviction=(threads_min=3,threads_max=7)", + ",eviction=(threads_max=12,threads_min=10)", + ",eviction=(threads_max=18,threads_min=16)", + ",eviction=(threads_max=10,threads_min=9)", + + ",eviction_dirty_target=45", + ",eviction_dirty_target=87", + ",eviction_dirty_target=8", + + ",eviction_dirty_trigger=37", + ",eviction_dirty_trigger=98", + ",eviction_dirty_trigger=7", + + ",eviction_target=22", + ",eviction_target=84", + ",eviction_target=30", + + ",eviction_trigger=75", + ",eviction_trigger=95", + ",eviction_trigger=66", + + ",file_manager=(close_handle_minimum=200)", + ",file_manager=(close_handle_minimum=137)", + ",file_manager=(close_handle_minimum=226)", + ",file_manager=(close_idle_time=10000)", + ",file_manager=(close_idle_time=12000)", + ",file_manager=(close_idle_time=7)", + ",file_manager=(close_idle_time=0)", + ",file_manager=(close_scan_interval=50000)", + ",file_manager=(close_scan_interval=59000)", + ",file_manager=(close_scan_interval=3)", + + ",log=(archive=0)", + ",log=(archive=1)", + ",log=(prealloc=0)", + ",log=(prealloc=1)", + ",log=(zero_fill=0)", + ",log=(zero_fill=1)", + + ",lsm_manager=(merge=0)", + ",lsm_manager=(merge=1)", + ",lsm_manager=(worker_thread_max=5)", + ",lsm_manager=(worker_thread_max=18)", + ",lsm_manager=(worker_thread_max=3)", + + ",shared_cache=(chunk=20MB)", + ",shared_cache=(chunk=30MB)", + ",shared_cache=(chunk=5MB)", + ",shared_cache=(name=\"shared\")", + ",shared_cache=(name=\"none\")", + ",shared_cache=(quota=20MB)", + ",shared_cache=(quota=30MB)", + ",shared_cache=(quota=5MB)", + ",shared_cache=(quota=0)", + ",shared_cache=(reserve=20MB)", + ",shared_cache=(reserve=30MB)", + ",shared_cache=(reserve=5MB)", + ",shared_cache=(reserve=0)", + ",shared_cache=(size=100MB)", + ",shared_cache=(size=1GB)", + ",shared_cache=(size=75MB)", + + ",statistics=(\"all\")", + ",statistics=(\"fast\")", + ",statistics=(\"none\")", + ",statistics=(\"clear\")", + + ",statistics_log=(json=0)", + ",statistics_log=(json=1)", + ",statistics_log=(on_close=0)", + ",statistics_log=(on_close=1)", + ",statistics_log=(sources=(\"file:\"))", + ",statistics_log=(sources=())", + ",statistics_log=(timestamp=\"%b:%S\")", + ",statistics_log=(timestamp=\"%H:%M\")", + ",statistics_log=(wait=60)", + ",statistics_log=(wait=76)", + ",statistics_log=(wait=37)", + ",statistics_log=(wait=0)", + +#ifdef HAVE_VERBOSE + ",verbose=(\"api\")", + ",verbose=(\"block\")", + ",verbose=(\"checkpoint\")", + ",verbose=(\"compact\")", + ",verbose=(\"evict\")", + ",verbose=(\"evictserver\")", + ",verbose=(\"fileops\")", + ",verbose=(\"handleops\")", + ",verbose=(\"log\")", + ",verbose=(\"lsm\")", + ",verbose=(\"lsm_manager\")", + ",verbose=(\"metadata\")", + ",verbose=(\"mutex\")", + ",verbose=(\"overflow\")", + ",verbose=(\"read\")", + ",verbose=(\"rebalance\")", + ",verbose=(\"reconcile\")", + ",verbose=(\"recovery\")", + ",verbose=(\"salvage\")", + ",verbose=(\"shared_cache\")", + ",verbose=(\"split\")", + ",verbose=(\"temporary\")", + ",verbose=(\"transaction\")", + ",verbose=(\"verify\")", + ",verbose=(\"version\")", + ",verbose=(\"write\")", + ",verbose=()" +#endif +}; + +static int +handle_message(WT_EVENT_HANDLER *handler, + WT_SESSION *session, const char *message) +{ + (void)(handler); + (void)(session); + (void)(message); + + /* We configure verbose output, so just ignore. */ + return (0); +} + +static WT_EVENT_HANDLER event_handler = { NULL, handle_message, NULL, NULL }; + +int +main(int argc, char *argv[]) +{ + enum { CACHE_SHARED, CACHE_SET, CACHE_NONE } cache; + TEST_OPTS *opts, _opts; + WT_RAND_STATE rnd; + WT_SESSION *session; + size_t len; + u_int i, j; + int ret; + const char *p; + char *config; + + opts = &_opts; + memset(opts, 0, sizeof(*opts)); + opts->table_type = TABLE_ROW; + testutil_check(testutil_parse_opts(argc, argv, opts)); + testutil_make_work_dir(opts->home); + + testutil_check( + wiredtiger_open(opts->home, &event_handler, "create", &opts->conn)); + + /* Open an LSM file so the LSM reconfiguration options make sense. */ + testutil_check( + opts->conn->open_session(opts->conn, NULL, NULL, &session)); + testutil_check(session->create( + session, opts->uri, "type=lsm,key_format=S,value_format=S")); + + /* Initialize the RNG. */ + testutil_check(__wt_random_init_seed(NULL, &rnd)); + + /* Allocate memory for the config. */ + len = WT_ELEMENTS(list) * 64; + config = dmalloc(len); + + /* A linear pass through the list. */ + for (i = 0; i < WT_ELEMENTS(list); ++i) + if ((ret = opts->conn->reconfigure(opts->conn, list[i])) != 0) { + fprintf(stderr, "%s: %s\n", + list[i], session->strerror(session, ret)); + return (EXIT_FAILURE); + } + + /* + * A linear pass through the list, adding random elements. + * + * WiredTiger configurations are usually "the last one set wins", but + * "shared_cache" and "cache_set" options aren't allowed in the same + * configuration string. + */ + for (i = 0; i < WT_ELEMENTS(list); ++i) { + p = list[i]; + cache = CACHE_NONE; + if (WT_PREFIX_MATCH(p, ",shared_cache")) + cache = CACHE_SHARED; + else if (WT_PREFIX_MATCH(p, ",cache_size")) + cache = CACHE_SET; + strcpy(config, p); + + for (j = + (__wt_random(&rnd) % WT_ELEMENTS(list)) + 1; j > 0; --j) { + p = list[__wt_random(&rnd) % WT_ELEMENTS(list)]; + if (WT_PREFIX_MATCH(p, ",shared_cache")) { + if (cache == CACHE_SET) + continue; + cache = CACHE_SHARED; + } else if (WT_PREFIX_MATCH(p, ",cache_size")) { + if (cache == CACHE_SHARED) + continue; + cache = CACHE_SET; + } + strcat(config, p); + } + if ((ret = opts->conn->reconfigure(opts->conn, config)) != 0) { + fprintf(stderr, "%s: %s\n", + config, session->strerror(session, ret)); + return (EXIT_FAILURE); + } + } + + /* + * Turn on-close statistics off, if on-close is on and statistics were + * randomly turned off during the run, close would fail. + */ + testutil_check(opts->conn->reconfigure( + opts->conn, "statistics_log=(on_close=0)")); + + free(config); + testutil_cleanup(opts); + return (EXIT_SUCCESS); +} diff --git a/src/third_party/wiredtiger/test/csuite/wt2834_join_bloom_fix/main.c b/src/third_party/wiredtiger/test/csuite/wt2834_join_bloom_fix/main.c new file mode 100644 index 00000000000..1e2d919d3c7 --- /dev/null +++ b/src/third_party/wiredtiger/test/csuite/wt2834_join_bloom_fix/main.c @@ -0,0 +1,199 @@ +/*- + * Public Domain 2014-2016 MongoDB, Inc. + * Public Domain 2008-2014 WiredTiger, Inc. + * + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "test_util.h" + +/* + * JIRA ticket reference: WT-2834 + * Test case description: We are creating bank 'account' records, each + * having a postal_code, balance, and an 'overdrawn' flag. We insert + * records with various balances, and only set the overdrawn flag when the + * balance is negative. Then we set up a join to simulate this: + * + * select (*) from account where account.postal_code = '54321' and + * account.balance < 0 and not account.overdrawn + * + * Failure mode: We get results back from our join. + */ +void (*custom_die)(void) = NULL; + +#define N_RECORDS 100000 +#define N_INSERT 1000000 + +void populate(TEST_OPTS *opts); + +int +main(int argc, char *argv[]) +{ + TEST_OPTS *opts, _opts; + WT_CURSOR *maincur; + WT_CURSOR *postcur, *balancecur, *flagcur, *joincur; + WT_SESSION *session; + int balance, count, flag, key, key2, post, ret; + char cfg[128]; + const char *tablename; + char posturi[256]; + char balanceuri[256]; + char flaguri[256]; + char joinuri[256]; + + opts = &_opts; + memset(opts, 0, sizeof(*opts)); + + testutil_check(testutil_parse_opts(argc, argv, opts)); + testutil_make_work_dir(opts->home); + + testutil_check(wiredtiger_open(opts->home, NULL, + "create,cache_size=250M", &opts->conn)); + testutil_check( + opts->conn->open_session(opts->conn, NULL, NULL, &session)); + /* + * Note: repeated primary key 'id' as 'id2'. This makes + * it easier to dump an index and know which record we're + * looking at. + */ + testutil_check(session->create(session, opts->uri, + "key_format=i,value_format=iiii," + "columns=(id,post,balance,flag,id2)")); + + tablename = strchr(opts->uri, ':'); + testutil_assert(tablename != NULL); + tablename++; + snprintf(posturi, sizeof(posturi), "index:%s:post", tablename); + snprintf(balanceuri, sizeof(balanceuri), "index:%s:balance", tablename); + snprintf(flaguri, sizeof(flaguri), "index:%s:flag", tablename); + snprintf(joinuri, sizeof(joinuri), "join:%s", opts->uri); + + testutil_check(session->create(session, posturi, "columns=(post)")); + testutil_check(session->create(session, balanceuri, + "columns=(balance)")); + testutil_check(session->create(session, flaguri, "columns=(flag)")); + + /* + * Insert a single record with all items we are search for, + * this makes our logic easier. + */ + testutil_check(session->open_cursor(session, opts->uri, NULL, NULL, + &maincur)); + maincur->set_key(maincur, N_RECORDS); + maincur->set_value(maincur, 54321, 0, "", 0, N_RECORDS); + maincur->insert(maincur); + maincur->close(maincur); + testutil_check(session->close(session, NULL)); + + populate(opts); + + testutil_check(opts->conn->open_session( + opts->conn, NULL, NULL, &session)); + + testutil_check(session->open_cursor(session, + posturi, NULL, NULL, &postcur)); + testutil_check(session->open_cursor(session, + balanceuri, NULL, NULL, &balancecur)); + testutil_check(session->open_cursor(session, + flaguri, NULL, NULL, &flagcur)); + testutil_check(session->open_cursor(session, + joinuri, NULL, NULL, &joincur)); + + postcur->set_key(postcur, 54321); + testutil_check(postcur->search(postcur)); + testutil_check(session->join(session, joincur, postcur, + "compare=eq")); + + balancecur->set_key(balancecur, 0); + testutil_check(balancecur->search(balancecur)); + sprintf(cfg, "compare=lt,strategy=bloom,count=%d", + N_RECORDS / 100); + testutil_check(session->join(session, joincur, balancecur, cfg)); + + flagcur->set_key(flagcur, 0); + testutil_check(flagcur->search(flagcur)); + sprintf(cfg, "compare=eq,strategy=bloom,count=%d", + N_RECORDS / 100); + testutil_check(session->join(session, joincur, flagcur, cfg)); + + /* Expect no values returned */ + count = 0; + while ((ret = joincur->next(joincur)) == 0) { + /* + * The values may already have been changed, but + * print them for informational purposes. + */ + testutil_check(joincur->get_key(joincur, &key)); + testutil_check(joincur->get_value(joincur, &post, + &balance, &flag, &key2)); + fprintf(stderr, "FAIL: " + "key=%d/%d, postal_code=%d, balance=%d, flag=%d\n", + key, key2, post, balance, flag); + count++; + } + testutil_assert(count == 0); + + testutil_cleanup(opts); + /* NOTREACHED */ + + return (0); +} + +void populate(TEST_OPTS *opts) +{ + WT_CURSOR *maincur; + WT_SESSION *session; + uint32_t key; + int balance, i, flag, post; + WT_RAND_STATE rnd; + + testutil_check(__wt_random_init_seed(NULL, &rnd)); + + testutil_check(opts->conn->open_session( + opts->conn, NULL, NULL, &session)); + + testutil_check(session->open_cursor(session, opts->uri, NULL, NULL, + &maincur)); + + for (i = 0; i < N_INSERT; i++) { + testutil_check(session->begin_transaction(session, NULL)); + key = (__wt_random(&rnd) % (N_RECORDS)); + maincur->set_key(maincur, key); + if (__wt_random(&rnd) % 11 == 0) + post = 54321; + else + post = i % 100000; + if (__wt_random(&rnd) % 4 == 0) { + balance = -100; + flag = 1; + } else { + balance = 100 * (i + 1); + flag = 0; + } + maincur->set_value(maincur, post, balance, flag, key); + testutil_check(maincur->insert(maincur)); + testutil_check(session->commit_transaction(session, NULL)); + } + maincur->close(maincur); + session->close(session, NULL); +} diff --git a/src/third_party/wiredtiger/test/csuite/wt2853_perf/main.c b/src/third_party/wiredtiger/test/csuite/wt2853_perf/main.c new file mode 100644 index 00000000000..67ba4a20ada --- /dev/null +++ b/src/third_party/wiredtiger/test/csuite/wt2853_perf/main.c @@ -0,0 +1,330 @@ +/*- + * Public Domain 2014-2016 MongoDB, Inc. + * Public Domain 2008-2014 WiredTiger, Inc. + * + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +#include "test_util.h" + +/* + * JIRA ticket reference: WT-2853 + * + * Test case description: create two threads: one is populating/updating + * records in a table with a few indices, the other is reading from table and + * indices. The test is adapted from one that uses cursor joins, this test + * does not, but simulates some of the access patterns. + * + * Failure mode: after a second or two of progress by both threads, they both + * appear to slow dramatically, almost locking up. After some time (I've + * observed from a half minute to a few minutes), the lock up ends and both + * threads seem to be inserting and reading at a normal fast pace. That + * continues until the test ends (~30 seconds). + */ + +void (*custom_die)(void) = NULL; + +static void *thread_insert(void *); +static void *thread_get(void *); + +#define BLOOM false +#define N_RECORDS 10000 +#define N_INSERT 1000000 +#define N_INSERT_THREAD 1 +#define N_GET_THREAD 1 +#define S64 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789::" +#define S1024 (S64 S64 S64 S64 S64 S64 S64 S64 S64 S64 S64 S64 S64 S64 S64 S64) + +typedef struct { + char posturi[256]; + char baluri[256]; + char flaguri[256]; + bool bloom; +} SHARED_OPTS; + +typedef struct { + TEST_OPTS *testopts; + SHARED_OPTS *sharedopts; + int threadnum; + int nthread; + int done; + int njoins; + int nfail; +} THREAD_ARGS; + +int +main(int argc, char *argv[]) +{ + SHARED_OPTS *sharedopts, _sharedopts; + TEST_OPTS *opts, _opts; + THREAD_ARGS get_args[N_GET_THREAD], insert_args[N_INSERT_THREAD]; + WT_CURSOR *maincur; + WT_SESSION *session; + pthread_t get_tid[N_GET_THREAD], insert_tid[N_INSERT_THREAD]; + int i, nfail; + const char *tablename; + + opts = &_opts; + sharedopts = &_sharedopts; + + if (testutil_disable_long_tests()) + return (0); + memset(opts, 0, sizeof(*opts)); + memset(sharedopts, 0, sizeof(*sharedopts)); + memset(insert_args, 0, sizeof(insert_args)); + memset(get_args, 0, sizeof(get_args)); + nfail = 0; + + sharedopts->bloom = BLOOM; + testutil_check(testutil_parse_opts(argc, argv, opts)); + testutil_make_work_dir(opts->home); + + testutil_check(wiredtiger_open(opts->home, NULL, + "create,cache_size=1G", &opts->conn)); + + testutil_check( + opts->conn->open_session(opts->conn, NULL, NULL, &session)); + + /* + * Note: id is repeated as id2. This makes it easier to + * identify the primary key in dumps of the index files. + */ + testutil_check(session->create(session, opts->uri, + "key_format=i,value_format=iiSii," + "columns=(id,post,bal,extra,flag,id2)")); + + tablename = strchr(opts->uri, ':'); + testutil_assert(tablename != NULL); + tablename++; + snprintf(sharedopts->posturi, sizeof(sharedopts->posturi), + "index:%s:post", tablename); + snprintf(sharedopts->baluri, sizeof(sharedopts->baluri), + "index:%s:bal", tablename); + snprintf(sharedopts->flaguri, sizeof(sharedopts->flaguri), + "index:%s:flag", tablename); + + testutil_check(session->create(session, sharedopts->posturi, + "columns=(post)")); + testutil_check(session->create(session, sharedopts->baluri, + "columns=(bal)")); + testutil_check(session->create(session, sharedopts->flaguri, + "columns=(flag)")); + + /* + * Insert a single record with all items we need to + * call search() on, this makes our join logic easier. + */ + testutil_check(session->open_cursor(session, opts->uri, NULL, NULL, + &maincur)); + maincur->set_key(maincur, N_RECORDS); + maincur->set_value(maincur, 54321, 0, "", 0, N_RECORDS); + testutil_check(maincur->insert(maincur)); + testutil_check(maincur->close(maincur)); + testutil_check(session->close(session, NULL)); + + for (i = 0; i < N_INSERT_THREAD; ++i) { + insert_args[i].threadnum = i; + insert_args[i].nthread = N_INSERT_THREAD; + insert_args[i].testopts = opts; + insert_args[i].sharedopts = sharedopts; + testutil_check(pthread_create(&insert_tid[i], NULL, + thread_insert, (void *)&insert_args[i])); + } + + for (i = 0; i < N_GET_THREAD; ++i) { + get_args[i].threadnum = i; + get_args[i].nthread = N_GET_THREAD; + get_args[i].testopts = opts; + get_args[i].sharedopts = sharedopts; + testutil_check(pthread_create(&get_tid[i], NULL, + thread_get, (void *)&get_args[i])); + } + + /* + * Wait for insert threads to finish. When they + * are done, signal get threads to complete. + */ + for (i = 0; i < N_INSERT_THREAD; ++i) + testutil_check(pthread_join(insert_tid[i], NULL)); + + for (i = 0; i < N_GET_THREAD; ++i) + get_args[i].done = 1; + + for (i = 0; i < N_GET_THREAD; ++i) + testutil_check(pthread_join(get_tid[i], NULL)); + + fprintf(stderr, "\n"); + for (i = 0; i < N_GET_THREAD; ++i) { + fprintf(stderr, " thread %d did %d joins (%d fails)\n", i, + get_args[i].njoins, get_args[i].nfail); + nfail += get_args[i].nfail; + } + + testutil_assert(nfail == 0); + testutil_cleanup(opts); + + return (0); +} + +static void * +thread_insert(void *arg) +{ + TEST_OPTS *opts; + THREAD_ARGS *threadargs; + WT_CURSOR *maincur; + WT_RAND_STATE rnd; + WT_SESSION *session; + double elapsed; + time_t prevtime, curtime; /* 1 second resolution is okay */ + int bal, i, flag, key, post; + const char *extra = S1024; + + threadargs = (THREAD_ARGS *)arg; + opts = threadargs->testopts; + testutil_check(__wt_random_init_seed(NULL, &rnd)); + (void)time(&prevtime); + + testutil_check(opts->conn->open_session( + opts->conn, NULL, NULL, &session)); + + testutil_check(session->open_cursor(session, opts->uri, NULL, NULL, + &maincur)); + + for (i = 0; i < N_INSERT; i++) { + /* + * Insert threads may stomp on each other's records; + * that's okay. + */ + key = (int)(__wt_random(&rnd) % N_RECORDS); + testutil_check(session->begin_transaction(session, NULL)); + maincur->set_key(maincur, key); + if (__wt_random(&rnd) % 2 == 0) + post = 54321; + else + post = i % 100000; + if (__wt_random(&rnd) % 2 == 0) { + bal = -100; + flag = 1; + } else { + bal = 100 * (i + 1); + flag = 0; + } + maincur->set_value(maincur, post, bal, extra, flag, key); + testutil_check(maincur->insert(maincur)); + testutil_check(maincur->reset(maincur)); + testutil_check(session->commit_transaction(session, NULL)); + if (i % 1000 == 0 && i != 0) { + if (i % 10000 == 0) + fprintf(stderr, "*"); + else + fprintf(stderr, "."); + (void)time(&curtime); + if ((elapsed = difftime(curtime, prevtime)) > 5.0) { + fprintf(stderr, "\n" + "GAP: %.0f secs after %d inserts\n", + elapsed, i); + threadargs->nfail++; + } + prevtime = curtime; + } + } + testutil_check(maincur->close(maincur)); + testutil_check(session->close(session, NULL)); + return (NULL); +} + +static void * +thread_get(void *arg) +{ + SHARED_OPTS *sharedopts; + TEST_OPTS *opts; + THREAD_ARGS *threadargs; + WT_CURSOR *maincur, *postcur; + WT_SESSION *session; + double elapsed; + time_t prevtime, curtime; /* 1 second resolution is okay */ + int bal, flag, key, key2, post, bal2, flag2, post2; + char *extra; + + threadargs = (THREAD_ARGS *)arg; + opts = threadargs->testopts; + sharedopts = threadargs->sharedopts; + (void)time(&prevtime); + + testutil_check(opts->conn->open_session( + opts->conn, NULL, NULL, &session)); + testutil_check(session->open_cursor(session, opts->uri, NULL, NULL, + &maincur)); + + testutil_check(session->open_cursor( + session, sharedopts->posturi, NULL, NULL, &postcur)); + + for (threadargs->njoins = 0; threadargs->done == 0; + threadargs->njoins++) { + testutil_check(session->begin_transaction(session, NULL)); + postcur->set_key(postcur, 54321); + testutil_check(postcur->search(postcur)); + while (postcur->next(postcur) == 0) { + testutil_check(postcur->get_key(postcur, &post)); + testutil_check(postcur->get_value(postcur, &post2, + &bal, &extra, &flag, &key)); + testutil_assert(post == post2); + if (post != 54321) + break; + + maincur->set_key(maincur, key); + testutil_check(maincur->search(maincur)); + testutil_check(maincur->get_value(maincur, &post2, + &bal2, &extra, &flag2, &key2)); + testutil_check(maincur->reset(maincur)); + testutil_assert(key == key2); + testutil_assert(post == post2); + testutil_assert(bal == bal2); + testutil_assert(flag == flag2); + + testutil_assert((flag2 > 0 && bal2 < 0) || + (flag2 == 0 && bal2 >= 0)); + } + /* + * Reset the cursors, potentially allowing the insert + * threads to proceed. + */ + testutil_check(postcur->reset(postcur)); + if (threadargs->njoins % 100 == 0) + fprintf(stderr, "G"); + testutil_check(session->rollback_transaction(session, NULL)); + + (void)time(&curtime); + if ((elapsed = difftime(curtime, prevtime)) > 5.0) { + fprintf(stderr, "\n" + "GAP: %.0f secs after %d gets\n", + elapsed, threadargs->njoins); + threadargs->nfail++; + } + prevtime = curtime; + } + testutil_check(postcur->close(postcur)); + testutil_check(maincur->close(maincur)); + testutil_check(session->close(session, NULL)); + return (NULL); +} diff --git a/src/third_party/wiredtiger/test/cursor_order/cursor_order_ops.c b/src/third_party/wiredtiger/test/cursor_order/cursor_order_ops.c index a2185dd123f..58da49b2991 100644 --- a/src/third_party/wiredtiger/test/cursor_order/cursor_order_ops.c +++ b/src/third_party/wiredtiger/test/cursor_order/cursor_order_ops.c @@ -130,7 +130,8 @@ ops_start(SHARED_CONFIG *cfg) seconds = (stop.tv_sec - start.tv_sec) + (stop.tv_usec - start.tv_usec) * 1e-6; fprintf(stderr, "timer: %.2lf seconds (%d ops/second)\n", - seconds, (int)(((cfg->reverse_scanners + cfg->append_inserters) * + seconds, (int) + (((double)(cfg->reverse_scanners + cfg->append_inserters) * total_nops) / seconds)); /* Verify the files. */ diff --git a/src/third_party/wiredtiger/test/format/bdb.c b/src/third_party/wiredtiger/test/format/bdb.c index e56281f2c3e..8b61573fdf9 100644 --- a/src/third_party/wiredtiger/test/format/bdb.c +++ b/src/third_party/wiredtiger/test/format/bdb.c @@ -186,6 +186,7 @@ bdb_remove(uint64_t keyno, int *notfoundp) size_t size; int ret; + size = 0; key_gen(&keyitem, keyno); key.data = (void *)keyitem.data; key.size = (u_int32_t)keyitem.size; diff --git a/src/third_party/wiredtiger/test/format/config.h b/src/third_party/wiredtiger/test/format/config.h index 16fffb6fafe..6e3f5473479 100644 --- a/src/third_party/wiredtiger/test/format/config.h +++ b/src/third_party/wiredtiger/test/format/config.h @@ -70,8 +70,8 @@ static CONFIG c[] = { C_BOOL, 90, 0, 0, &g.c_auto_throttle, NULL }, { "backups", - "if backups are enabled", /* 5% */ - C_BOOL, 5, 0, 0, &g.c_backups, NULL }, + "if backups are enabled", /* 20% */ + C_BOOL, 20, 0, 0, &g.c_backups, NULL }, { "bitcnt", "number of bits for fixed-length column-store files", @@ -203,8 +203,8 @@ static CONFIG c[] = { C_BOOL, 0, 0, 0, &g.c_leak_memory, NULL }, { "logging", - "if logging configured", /* 30% */ - C_BOOL, 30, 0, 0, &g.c_logging, NULL }, + "if logging configured", /* 50% */ + C_BOOL, 50, 0, 0, &g.c_logging, NULL }, { "logging_archive", "if log file archival configured", /* 50% */ diff --git a/src/third_party/wiredtiger/test/format/format.h b/src/third_party/wiredtiger/test/format/format.h index ad5f408ac30..047be552308 100644 --- a/src/third_party/wiredtiger/test/format/format.h +++ b/src/third_party/wiredtiger/test/format/format.h @@ -29,6 +29,13 @@ #include "test_util.h" #ifdef BDB +/* + * Berkeley DB has an #ifdef we need to provide a value for, we'll see an + * undefined error if it's unset during a strict compile. + */ +#ifndef DB_DBM_HSEARCH +#define DB_DBM_HSEARCH 0 +#endif #include #include #endif @@ -69,12 +76,6 @@ #define FORMAT_OPERATION_REPS 3 /* 3 thread operations sets */ -#ifndef _WIN32 -#define SIZET_FMT "%zu" /* size_t format string */ -#else -#define SIZET_FMT "%Iu" /* size_t format string */ -#endif - typedef struct { char *progname; /* Program name */ @@ -238,7 +239,7 @@ typedef struct { } GLOBAL; extern GLOBAL g; -typedef struct { +typedef struct WT_COMPILER_TYPE_ALIGN(WT_CACHE_LINE_ALIGNMENT) { WT_RAND_STATE rnd; /* thread RNG state */ uint64_t search; /* operations */ @@ -260,7 +261,7 @@ typedef struct { #define TINFO_COMPLETE 2 /* Finished */ #define TINFO_JOINED 3 /* Resolved */ volatile int state; /* state */ -} TINFO WT_COMPILER_TYPE_ALIGN(WT_CACHE_LINE_ALIGNMENT); +} TINFO; #ifdef HAVE_BERKELEY_DB void bdb_close(void); diff --git a/src/third_party/wiredtiger/test/format/ops.c b/src/third_party/wiredtiger/test/format/ops.c index c97d82809a1..283e2912daa 100644 --- a/src/third_party/wiredtiger/test/format/ops.c +++ b/src/third_party/wiredtiger/test/format/ops.c @@ -342,7 +342,7 @@ snap_check(WT_CURSOR *cursor, switch (g.type) { case FIX: testutil_die(ret, - "snap_check: %" PRIu64 " search: " + "snapshot-isolation: %" PRIu64 " search: " "expected {0x%02x}, found {0x%02x}", start->keyno, start->deleted ? 0 : *(uint8_t *)start->vdata, @@ -350,7 +350,7 @@ snap_check(WT_CURSOR *cursor, /* NOTREACHED */ case ROW: testutil_die(ret, - "snap_check: %.*s search: " + "snapshot-isolation: %.*s search: " "expected {%.*s}, found {%.*s}", (int)key->size, key->data, start->deleted ? @@ -362,7 +362,7 @@ snap_check(WT_CURSOR *cursor, /* NOTREACHED */ case VAR: testutil_die(ret, - "snap_check: %" PRIu64 " search: " + "snapshot-isolation: %" PRIu64 " search: " "expected {%.*s}, found {%.*s}", start->keyno, start->deleted ? diff --git a/src/third_party/wiredtiger/test/format/rebalance.c b/src/third_party/wiredtiger/test/format/rebalance.c index d35dcec1d53..5fd86ef3317 100644 --- a/src/third_party/wiredtiger/test/format/rebalance.c +++ b/src/third_party/wiredtiger/test/format/rebalance.c @@ -42,7 +42,8 @@ wts_rebalance(void) /* Dump the current object. */ (void)snprintf(cmd, sizeof(cmd), - "../../wt -h %s dump -f %s/rebalance.orig %s", + ".." DIR_DELIM_STR ".." DIR_DELIM_STR "wt" + " -h %s dump -f %s/rebalance.orig %s", g.home, g.home, g.uri); testutil_checkfmt(system(cmd), "command failed: %s", cmd); @@ -66,13 +67,18 @@ wts_rebalance(void) wts_close(); (void)snprintf(cmd, sizeof(cmd), - "../../wt -h %s dump -f %s/rebalance.new %s", + ".." DIR_DELIM_STR ".." DIR_DELIM_STR "wt" + " -h %s dump -f %s/rebalance.new %s", g.home, g.home, g.uri); testutil_checkfmt(system(cmd), "command failed: %s", cmd); /* Compare the old/new versions of the object. */ (void)snprintf(cmd, sizeof(cmd), +#ifdef _WIN32 + "fc /b %s\\rebalance.orig %s\\rebalance.new > NUL", +#else "cmp %s/rebalance.orig %s/rebalance.new > /dev/null", +#endif g.home, g.home); testutil_checkfmt(system(cmd), "command failed: %s", cmd); } diff --git a/src/third_party/wiredtiger/test/format/salvage.c b/src/third_party/wiredtiger/test/format/salvage.c index 8274c556364..69805fb1018 100644 --- a/src/third_party/wiredtiger/test/format/salvage.c +++ b/src/third_party/wiredtiger/test/format/salvage.c @@ -107,7 +107,7 @@ found: if (fstat(fd, &sb) == -1) if ((fp = fopen(buf, "w")) == NULL) testutil_die(errno, "salvage-corrupt: open: %s", buf); (void)fprintf(fp, - "salvage-corrupt: offset %" PRIuMAX ", length " SIZET_FMT "\n", + "salvage-corrupt: offset %" PRIuMAX ", length %" WT_SIZET_FMT "\n", (uintmax_t)offset, len); fclose_and_clear(&fp); diff --git a/src/third_party/wiredtiger/test/format/smoke.sh b/src/third_party/wiredtiger/test/format/smoke.sh index 5fbc349f242..0c86b5e57c6 100755 --- a/src/third_party/wiredtiger/test/format/smoke.sh +++ b/src/third_party/wiredtiger/test/format/smoke.sh @@ -3,7 +3,7 @@ set -e # Smoke-test format as part of running "make check". -args="-1 -c "." data_source=table ops=100000 rows=10000 threads=4 compression=none logging_compression=none" +args="-1 -c "." data_source=table ops=50000 rows=10000 threads=4 compression=none logging_compression=none" $TEST_WRAPPER ./t $args file_type=fix $TEST_WRAPPER ./t $args file_type=row diff --git a/src/third_party/wiredtiger/test/format/t.c b/src/third_party/wiredtiger/test/format/t.c index 2eb2b078804..12258af8e51 100644 --- a/src/third_party/wiredtiger/test/format/t.c +++ b/src/third_party/wiredtiger/test/format/t.c @@ -44,7 +44,7 @@ int main(int argc, char *argv[]) { time_t start; - int ch, i, onerun, reps; + int ch, onerun, reps; const char *config, *home; config = NULL; @@ -114,14 +114,8 @@ main(int argc, char *argv[]) argc -= __wt_optind; argv += __wt_optind; - /* - * Initialize the global RNG. Start with the standard seeds, and then - * use seconds since the Epoch modulo a prime to run the RNG for some - * number of steps, so we don't start with the same values every time. - */ - __wt_random_init(&g.rnd); - for (i = (int)time(NULL) % 10007; i > 0; --i) - (void)__wt_random(&g.rnd); + /* Initialize the global RNG. */ + testutil_check(__wt_random_init_seed(NULL, &g.rnd)); /* Set up paths. */ path_setup(home); diff --git a/src/third_party/wiredtiger/test/format/util.c b/src/third_party/wiredtiger/test/format/util.c index cebe2153b3e..667f6d6bcb1 100644 --- a/src/third_party/wiredtiger/test/format/util.c +++ b/src/third_party/wiredtiger/test/format/util.c @@ -319,17 +319,23 @@ path_setup(const char *home) */ #undef CMD #ifdef _WIN32 -#define CMD "test -e %s || mkdir %s; " \ - "cd %s && del /s /q * >:nul && rd /s /q KVS; " \ - "mkdir KVS" +#define CMD "del /q rand.copy & " \ + "(IF EXIST %s\\rand copy /y %s\\rand rand.copy) & " \ + "(IF EXIST %s rd /s /q %s) & mkdir %s & " \ + "(IF EXIST rand.copy copy rand.copy %s\\rand) & " \ + "cd %s & mkdir KVS" + len = strlen(g.home) * 7 + strlen(CMD) + 1; + g.home_init = dmalloc(len); + snprintf(g.home_init, len, CMD, + g.home, g.home, g.home, g.home, g.home, g.home, g.home); #else #define CMD "test -e %s || mkdir %s; " \ "cd %s > /dev/null && rm -rf `ls | sed /rand/d`; " \ "mkdir KVS" -#endif len = strlen(g.home) * 3 + strlen(CMD) + 1; g.home_init = dmalloc(len); snprintf(g.home_init, len, CMD, g.home, g.home, g.home); +#endif /* Primary backup directory. */ len = strlen(g.home) + strlen("BACKUP") + 2; @@ -342,7 +348,7 @@ path_setup(const char *home) */ #undef CMD #ifdef _WIN32 -#define CMD "del %s/%s %s/%s /s /q >:nul && mkdir %s/%s %s/%s" +#define CMD "rd /s /q %s\\%s %s\\%s & mkdir %s\\%s %s\\%s" #else #define CMD "rm -rf %s/%s %s/%s && mkdir %s/%s %s/%s" #endif diff --git a/src/third_party/wiredtiger/test/format/wts.c b/src/third_party/wiredtiger/test/format/wts.c index 69195abc3d4..74c4bb902b3 100644 --- a/src/third_party/wiredtiger/test/format/wts.c +++ b/src/third_party/wiredtiger/test/format/wts.c @@ -154,6 +154,11 @@ wts_open(const char *home, bool set_api, WT_CONNECTION **connp) ",lsm_manager=(worker_thread_max=%" PRIu32 "),", g.c_lsm_worker_threads); + if (DATASOURCE("lsm") || g.c_cache < 20) { + p += snprintf(p, REMAIN(p, end), + ",eviction_dirty_target=80,eviction_dirty_trigger=95"); + } + /* Eviction worker configuration. */ if (g.c_evict_max != 0) p += snprintf(p, REMAIN(p, end), @@ -302,15 +307,16 @@ wts_init(void) /* * Ensure that we can service at least one operation per-thread - * concurrently without filling the cache with pinned pages. We - * choose a multiplier of three because the max configurations control - * on disk size and in memory pages are often significantly larger - * than their disk counterparts. + * concurrently without filling the cache with pinned pages. We choose + * a multiplier of three because the max configurations control on disk + * size and in memory pages are often significantly larger than their + * disk counterparts. We also apply the default eviction_dirty_trigger + * of 20% so that workloads don't get stuck with dirty pages in cache. */ maxintlpage = 1U << g.c_intl_page_max; maxleafpage = 1U << g.c_leaf_page_max; while (3 * g.c_threads * (maxintlpage + maxleafpage) > - g.c_cache << 20) { + (g.c_cache << 20) / 5) { if (maxleafpage <= 512 && maxintlpage <= 512) break; if (maxintlpage > 512) diff --git a/src/third_party/wiredtiger/test/java/com/wiredtiger/test/ConcurrentCloseTest.java b/src/third_party/wiredtiger/test/java/com/wiredtiger/test/ConcurrentCloseTest.java new file mode 100644 index 00000000000..fece0353bf0 --- /dev/null +++ b/src/third_party/wiredtiger/test/java/com/wiredtiger/test/ConcurrentCloseTest.java @@ -0,0 +1,179 @@ +/*- + * Public Domain 2014-2016 MongoDB, Inc. + * Public Domain 2008-2014 WiredTiger, Inc. + * + * This is free and unencumbered software released into the public domain. + * + * Anyone is free to copy, modify, publish, use, compile, sell, or + * distribute this software, either in source code form or as a compiled + * binary, for any purpose, commercial or non-commercial, and by any + * means. + * + * In jurisdictions that recognize copyright laws, the author or authors + * of this software dedicate any and all copyright interest in the + * software to the public domain. We make this dedication for the benefit + * of the public at large and to the detriment of our heirs and + * successors. We intend this dedication to be an overt act of + * relinquishment in perpetuity of all present and future rights to this + * software under copyright law. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ +package com.wiredtiger.test; + +import com.wiredtiger.db.Connection; +import com.wiredtiger.db.Cursor; +import com.wiredtiger.db.Session; +import com.wiredtiger.db.WiredTigerException; +import com.wiredtiger.db.wiredtiger; + +import static org.junit.Assert.assertEquals; + +import java.io.BufferedReader; +import java.io.File; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.List; + +import org.junit.Test; +import org.junit.Assert; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/* + * Test multiple threads concurrently inserting and reading. + * Each insert thread opens and closes for each record, so the + * test stresses the concurrency of these calls in particular. + * This is a test case for a problem reported in WT-2788. + */ +class InsertThread extends Thread { + private Connection conn; + private int threadId; + + public InsertThread(Connection conn, int threadId) { + this.conn = conn; + this.threadId = threadId; + } + + public void run() + { + try { + int ret; + for (int i = 0; i < 500; i++) { + Session session = conn.open_session(null); + Cursor cursor = session.open_cursor("table:cclose", null, + "overwrite"); + cursor.putKeyString("key"+threadId + "-" + i); + cursor.putValueString("value1"); + ret = cursor.insert(); + cursor.close(); + ret = session.close(null); + } + } catch (WiredTigerException wte) { + System.err.println("Exception " + wte); + } + } +} + +class ScanThread extends Thread { + private Connection conn; + + public ScanThread(Connection conn) { + this.conn = conn; + } + + public void run() + { + try { + int ret; + + Session session = conn.open_session(null); + Cursor cursor = session.open_cursor("table:cclose", null, null); + + /* Show all records. */ + while ((ret = cursor.next()) == 0) { + String key = cursor.getKeyString(); + String value = cursor.getValueString(); + System.out.println("Got record: " + key + " : " + value); + } + if (ret != wiredtiger.WT_NOTFOUND) + System.err.println("Cursor.next: " + + wiredtiger.wiredtiger_strerror(ret)); + cursor.close(); + session.close(null); + } catch (WiredTigerException wte) { + System.err.println("Exception " + wte); + } + } +} + +public class ConcurrentCloseTest { + Connection conn; + Session session; + + public static String home; + + public static final int NUM_THREADS = 10; + + @Test + public void test_threads() + { + setup(); + try { + List threads = new ArrayList(); + int i, ret; + + ret = session.create("table:cclose", "key_format=S,value_format=S"); + Cursor cursor = session.open_cursor("table:cclose", null, + "overwrite"); + cursor.putKeyString("key1"); + cursor.putValueString("value1"); + ret = cursor.insert(); + cursor.close(); + ret = session.close(null); + + for (i = 0; i < NUM_THREADS; i++) { + Thread insertThread = new InsertThread(conn, i); + Thread scanThread = new InsertThread(conn, i); + insertThread.start(); + scanThread.start(); + threads.add(insertThread); + threads.add(scanThread); + } + + for (Thread thread : threads) + try { + thread.join(); + ret = -1; + } + catch (InterruptedException ie) { + } + + ret = conn.close(null); + System.exit(ret); + } + catch (WiredTigerException wte) { + System.err.println("Exception: " + wte); + wte.printStackTrace(); + System.exit(1); + } + } + + private void setup() { + conn = wiredtiger.open("WT_HOME", "create"); + session = conn.open_session(null); + } + + private void teardown() { + session.close(""); + conn.close(""); + } + + +} diff --git a/src/third_party/wiredtiger/test/manydbs/Makefile.am b/src/third_party/wiredtiger/test/manydbs/Makefile.am index 2bc47ad7f2e..ff5985cf2a4 100644 --- a/src/third_party/wiredtiger/test/manydbs/Makefile.am +++ b/src/third_party/wiredtiger/test/manydbs/Makefile.am @@ -10,7 +10,8 @@ t_LDADD +=$(top_builddir)/libwiredtiger.la t_LDFLAGS = -static # Run this during a "make check" smoke test. -TESTS = smoke.sh +TESTS = $(noinst_PROGRAMS) +LOG_COMPILER = $(TEST_WRAPPER) clean-local: rm -rf WT_TEST *.core diff --git a/src/third_party/wiredtiger/test/manydbs/manydbs.c b/src/third_party/wiredtiger/test/manydbs/manydbs.c index e485e73067f..c5c9a9a7ccd 100644 --- a/src/third_party/wiredtiger/test/manydbs/manydbs.c +++ b/src/third_party/wiredtiger/test/manydbs/manydbs.c @@ -93,7 +93,7 @@ get_stat(WT_SESSION *stat_session, int stat_field, uint64_t *valuep) return (ret); } -static int +static void run_ops(int dbs) { WT_ITEM data; @@ -119,7 +119,6 @@ run_ops(int dbs) testutil_check(cursors[db]->insert(cursors[db])); } } - return (0); } int @@ -211,7 +210,7 @@ main(int argc, char *argv[]) WT_STAT_CONN_COND_AUTO_WAIT_RESET, &cond_reset_orig[i])); for (i = 0; i < MAX_IDLE_TIME; i += IDLE_INCR) { if (!idle) - testutil_check(run_ops(dbs)); + run_ops(dbs); printf("Sleep %d (%d of %d)\n", IDLE_INCR, i, MAX_IDLE_TIME); sleep(IDLE_INCR); } diff --git a/src/third_party/wiredtiger/test/manydbs/smoke.sh b/src/third_party/wiredtiger/test/manydbs/smoke.sh deleted file mode 100755 index c0e2976f154..00000000000 --- a/src/third_party/wiredtiger/test/manydbs/smoke.sh +++ /dev/null @@ -1,18 +0,0 @@ -#!/bin/sh - -set -e - -# Smoke-test format as part of running "make check". -# Run with: -# 1. The defaults -# 2. Set idle flag to turn off operations. -# 3. More dbs. -# -echo "manydbs: default with operations turned on" -$TEST_WRAPPER ./t -echo "manydbs: totally idle databases" -$TEST_WRAPPER ./t -I -echo "manydbs: 40 databases with operations" -$TEST_WRAPPER ./t -D 40 -echo "manydbs: 40 idle databases" -$TEST_WRAPPER ./t -I -D 40 diff --git a/src/third_party/wiredtiger/test/mciproject.yml b/src/third_party/wiredtiger/test/mciproject.yml index 3df1ce5805e..eb74914eb46 100644 --- a/src/third_party/wiredtiger/test/mciproject.yml +++ b/src/third_party/wiredtiger/test/mciproject.yml @@ -8,12 +8,12 @@ functions: command: git.get_project params: directory: wiredtiger - "fetch artifacts" : &fetch_artifacts + "fetch binaries" : &fetch_binaries - command: s3.get params: aws_key: ${aws_key} aws_secret: ${aws_secret} - remote_file: wiredtiger/${build_variant}/${revision}/artifacts/${build_id}.tgz + remote_file: wiredtiger/${build_variant}/${revision}/binaries/${build_id}.tgz bucket: build_external extract_to: wiredtiger @@ -23,6 +23,22 @@ pre: script: | rm -rf "wiredtiger" post: + - command: archive.targz_pack + params: + target: "wiredtiger.tgz" + source_dir: "wiredtiger" + include: + - "./**" + - command: s3.put + params: + aws_secret: ${aws_secret} + aws_key: ${aws_key} + local_file: wiredtiger.tgz + bucket: build_external + permissions: public-read + content_type: application/tar + display_name: Artifacts + remote_file: wiredtiger/${build_variant}/${revision}/artifacts/${build_id}.tgz - command: shell.exec params: script: | @@ -49,7 +65,7 @@ tasks: ./build_posix/reconf ${configure_env_vars|} ./configure --enable-diagnostic --enable-python --enable-zlib --enable-strict --enable-verbose ${make_command|make} ${smp_command|} 2>&1 - ${make_command|make} check 2>&1 + ${make_command|make} VERBOSE=1 check 2>&1 fi - command: archive.targz_pack params: @@ -65,14 +81,14 @@ tasks: bucket: build_external permissions: public-read content_type: application/tar - display_name: Artifacts - remote_file: wiredtiger/${build_variant}/${revision}/artifacts/${build_id}.tgz + display_name: Binaries + remote_file: wiredtiger/${build_variant}/${revision}/binaries/${build_id}.tgz - name: unit-test depends_on: - name: compile commands: - - func: "fetch artifacts" + - func: "fetch binaries" - command: shell.exec params: working_dir: "wiredtiger" @@ -85,7 +101,7 @@ tasks: depends_on: - name: compile commands: - - func: "fetch artifacts" + - func: "fetch binaries" - command: shell.exec params: working_dir: "wiredtiger" @@ -93,13 +109,13 @@ tasks: set -o errexit set -o verbose - scons.bat ${smp_command|} "CFLAGS=/Gv /wd4090 /wd4996 /we4047 /we4024 /TC /we4100" wiredtiger.dll libwiredtiger.lib + scons.bat ${smp_command|} "CFLAGS=/Gv /wd4090 /wd4996 /we4047 /we4024 /TC /we4100 /w4133" wiredtiger.dll libwiredtiger.lib - name: fops depends_on: - name: compile commands: - - func: "fetch artifacts" + - func: "fetch binaries" - command: shell.exec params: working_dir: "wiredtiger" @@ -112,6 +128,20 @@ tasks: ./test/fops/t fi + - name: format + depends_on: + - name: compile + commands: + - func: "fetch binaries" + - command: shell.exec + params: + working_dir: "wiredtiger" + script: | + set -o errexit + set -o verbose + # format assumes we run it from the format directory + cmd.exe /c "cd test\\format && ..\\..\\t_format.exe reverse=0 encryption=none logging_compression=none runs=20" + buildvariants: - name: ubuntu1404 display_name: Ubuntu 14.04 @@ -149,6 +179,7 @@ buildvariants: - name: compile - name: compile-windows-alt - name: unit-test + #- name: format - Enable when we have a solution for hangs and crashses - name: fops - name: osx-1010 diff --git a/src/third_party/wiredtiger/test/recovery/Makefile.am b/src/third_party/wiredtiger/test/recovery/Makefile.am index 19fc48dce47..3e7fce17d0e 100644 --- a/src/third_party/wiredtiger/test/recovery/Makefile.am +++ b/src/third_party/wiredtiger/test/recovery/Makefile.am @@ -14,8 +14,7 @@ truncated_log_LDADD +=$(top_builddir)/libwiredtiger.la truncated_log_LDFLAGS = -static # Run this during a "make check" smoke test. -TESTS = $(noinst_PROGRAMS) -LOG_COMPILER = $(TEST_WRAPPER) +TESTS = smoke.sh clean-local: rm -rf WT_TEST.* *.core diff --git a/src/third_party/wiredtiger/test/recovery/random-abort.c b/src/third_party/wiredtiger/test/recovery/random-abort.c index 85629eddec4..16065cec29e 100644 --- a/src/third_party/wiredtiger/test/recovery/random-abort.c +++ b/src/third_party/wiredtiger/test/recovery/random-abort.c @@ -91,7 +91,8 @@ thread_run(void *arg) if ((fp = fopen(buf, "w")) == NULL) testutil_die(errno, "fopen"); /* - * Set to no buffering. + * Set to line buffering. But that is advisory only. We've seen + * cases where the result files end up with partial lines. */ __wt_stream_set_line_buffer(fp); if ((ret = td->conn->open_session(td->conn, NULL, NULL, &session)) != 0) @@ -188,7 +189,7 @@ main(int argc, char *argv[]) WT_CURSOR *cursor; WT_SESSION *session; WT_RAND_STATE rnd; - uint64_t key; + uint64_t key, last_key; uint32_t absent, count, i, nth, timeout; int ch, status, ret; pid_t pid; @@ -317,12 +318,23 @@ main(int argc, char *argv[]) * in the table after recovery. Since we did write-no-sync, we * expect every key to have been recovered. */ - for (;; ++count) { + for (last_key = UINT64_MAX;; ++count, last_key = key) { ret = fscanf(fp, "%" SCNu64 "\n", &key); if (ret != EOF && ret != 1) testutil_die(errno, "fscanf"); if (ret == EOF) break; + /* + * If we're unlucky, the last line may be a partially + * written key at the end that can result in a false + * negative error for a missing record. Detect it. + */ + if (last_key != UINT64_MAX && key != last_key + 1) { + printf("%s: Ignore partial record %" PRIu64 + " last valid key %" PRIu64 "\n", + fname, key, last_key); + break; + } snprintf(kname, sizeof(kname), "%" PRIu64, key); cursor->set_key(cursor, kname); if ((ret = cursor->search(cursor)) != 0) { diff --git a/src/third_party/wiredtiger/test/recovery/smoke.sh b/src/third_party/wiredtiger/test/recovery/smoke.sh new file mode 100755 index 00000000000..c7677b64503 --- /dev/null +++ b/src/third_party/wiredtiger/test/recovery/smoke.sh @@ -0,0 +1,8 @@ +#! /bin/sh + +set -e + +# Smoke-test recovery as part of running "make check". + +$TEST_WRAPPER ./random-abort -t 10 -T 5 +$TEST_WRAPPER ./truncated-log diff --git a/src/third_party/wiredtiger/test/recovery/truncated-log.c b/src/third_party/wiredtiger/test/recovery/truncated-log.c index a7509c27566..c0effa85e95 100644 --- a/src/third_party/wiredtiger/test/recovery/truncated-log.c +++ b/src/third_party/wiredtiger/test/recovery/truncated-log.c @@ -45,11 +45,86 @@ static const char * const uri = "table:main"; "create,log=(file_max=100K,archive=false,enabled)," \ "transaction_sync=(enabled,method=none)" #define ENV_CONFIG_REC "log=(recover=on)" + #define LOG_FILE_1 "WiredTigerLog.0000000001" #define K_SIZE 16 #define V_SIZE 256 +/* + * Write a new log record into the log via log print, then open up a log + * cursor and walk the log to make sure we can read it. The reason for this + * test is that if there is a partial log record at the end of the previous + * log file and truncate does not exist, this tests that we can still read + * past that record. + */ +static void write_and_read_new(WT_SESSION *); +static void +write_and_read_new(WT_SESSION *session) +{ + WT_CURSOR *logc; + WT_ITEM logrec_key, logrec_value; + uint64_t txnid; + uint32_t fileid, log_file, log_offset, opcount, optype, rectype; + int ret; + bool saw_msg; + + /* + * Write a log record and force it to disk so we can read it. + */ + printf("Write log_printf record and verify.\n"); + if ((ret = session->log_printf(session, "Test Log Record")) != 0) + testutil_die(ret, "log_printf"); + if ((ret = session->log_flush(session, "sync=on")) != 0) + testutil_die(ret, "log_flush"); + if ((ret = session->open_cursor( + session, "log:", NULL, NULL, &logc)) != 0) + testutil_die(ret, "open_cursor: log"); + if ((ret = session->open_cursor( + session, "log:", NULL, NULL, &logc)) != 0) + testutil_die(ret, "open_cursor: log"); + saw_msg = false; + while ((ret = logc->next(logc)) == 0) { + /* + * We don't really need to get the key, but in case we want + * the LSN for some message, get it. + */ + if ((ret = logc->get_key(logc, + &log_file, &log_offset, &opcount)) != 0) + testutil_die(errno, "get_key"); + if ((ret = logc->get_value(logc, &txnid, &rectype, + &optype, &fileid, &logrec_key, &logrec_value)) != 0) + testutil_die(errno, "get_value"); + /* + * We should never see a record from log file 2. We wrote + * a record there, but then the record in log file 1 was + * truncated to be a partial record, ending the log there. + * So everything after that, including everything in log + * file 2, is invalid until we get to log file 3 which is where + * the post-recovery records will be written. + */ + if (log_file == 2) + testutil_die(EINVAL, "Found LSN in Log 2"); +#if 0 + printf("LSN [%" PRIu32 "][%" PRIu32 "].%" PRIu32 + ": record type %" PRIu32 " optype %" PRIu32 + " txnid %" PRIu64 " fileid %" PRIu32 "\n", + log_file, log_offset, opcount, + rectype, optype, txnid, fileid); +#endif + if (rectype == WT_LOGREC_MESSAGE) { + saw_msg = true; + printf("Application Record: %s\n", + (char *)logrec_value.data); + break; + } + } + if ((ret = logc->close(logc)) != 0) + testutil_die(ret, "log cursor close"); + if (!saw_msg) + testutil_die(EINVAL, "Did not traverse log printf record"); +} + static void usage(void) WT_GCC_FUNC_DECL_ATTRIBUTE((noreturn)); static void @@ -127,6 +202,10 @@ fill_db(void) if ((ret = cursor->insert(cursor)) != 0) testutil_die(ret, "WT_CURSOR.insert"); + /* + * Walking the ever growing log can be slow, so only start + * looking for the cross into log file 2 after a minimum. + */ if (i > min_key) { if ((ret = session->open_cursor( session, "log:", NULL, NULL, &logc)) != 0) @@ -135,15 +214,26 @@ fill_db(void) logc->set_key(logc, save_lsn.l.file, save_lsn.l.offset, 0); if ((ret = logc->search(logc)) != 0) - testutil_die(errno, "search"); + testutil_die(ret, "search"); } while ((ret = logc->next(logc)) == 0) { if ((ret = logc->get_key(logc, &lsn.l.file, &lsn.l.offset, &unused)) != 0) - testutil_die(errno, "get_key"); + testutil_die(ret, "get_key"); + /* + * Save the LSN so that we know the offset + * of the last LSN in log file 1 later. + */ if (lsn.l.file < 2) save_lsn = lsn; else { + /* + * If this is the first time through + * that the key is larger than the + * minimum key and we're already in + * log file 2 then we did not calculate + * correctly and the test should fail. + */ if (first) testutil_die(EINVAL, "min_key too high"); @@ -155,6 +245,8 @@ fill_db(void) } } first = false; + if ((ret = logc->close(logc)) != 0) + testutil_die(ret, "log cursor close"); } } if (fclose(fp) != 0) @@ -243,7 +335,9 @@ main(int argc, char *argv[]) if (offset > UINT64_MAX - V_SIZE) testutil_die(ERANGE, "offset"); new_offset = offset + V_SIZE; - printf("Parent: Truncate to %" PRIu64 "\n", new_offset); + printf("Parent: Log file 1: Key %" PRIu32 " at %" PRIu64 "\n", + max_key, offset); + printf("Parent: Truncate mid-record to %" PRIu64 "\n", new_offset); if ((ret = truncate(LOG_FILE_1, (wt_off_t)new_offset)) != 0) testutil_die(errno, "truncate"); @@ -263,13 +357,24 @@ main(int argc, char *argv[]) count = 0; while ((ret = cursor->next(cursor)) == 0) ++count; - if ((ret = conn->close(conn, NULL)) != 0) - testutil_die(ret, "WT_CONNECTION:close"); + /* + * The max key in the saved file is the key we truncated, but the + * key space starts at 0 and we're counting the records here, so we + * expect the max key number of records. + */ if (count > max_key) { printf("expected %" PRIu32 " records found %" PRIu32 "\n", max_key, count); return (EXIT_FAILURE); } printf("%" PRIu32 " records verified\n", count); + + /* + * Write a log record and then walk the log to make sure we can + * read that log record that is beyond the truncated record. + */ + write_and_read_new(session); + if ((ret = conn->close(conn, NULL)) != 0) + testutil_die(ret, "WT_CONNECTION:close"); return (EXIT_SUCCESS); } diff --git a/src/third_party/wiredtiger/test/salvage/salvage.c b/src/third_party/wiredtiger/test/salvage/salvage.c index c3349188623..bad0167ca8e 100644 --- a/src/third_party/wiredtiger/test/salvage/salvage.c +++ b/src/third_party/wiredtiger/test/salvage/salvage.c @@ -602,8 +602,8 @@ copy(u_int gen, u_int recno) dsk->recno = recno; dsk->write_gen = gen; blk = WT_BLOCK_HEADER_REF(buf); - blk->cksum = 0; - blk->cksum = __wt_cksum(dsk, PSIZE); + blk->checksum = 0; + blk->checksum = __wt_checksum(dsk, PSIZE); CHECK(fwrite(buf, 1, PSIZE, ofp) == PSIZE); } diff --git a/src/third_party/wiredtiger/test/suite/helper.py b/src/third_party/wiredtiger/test/suite/helper.py index f85d708880f..9f34b566b3c 100644 --- a/src/third_party/wiredtiger/test/suite/helper.py +++ b/src/third_party/wiredtiger/test/suite/helper.py @@ -179,6 +179,49 @@ def simple_populate_check(self, uri, rows): simple_populate_check_cursor(self, cursor, rows) cursor.close() +# population of a simple object, with a single index +# uri: object +# config: prefix of the session.create configuration string (defaults +# to string value formats) +# rows: entries to insert +def simple_index_populate(self, uri, config, rows): + self.pr('simple_index_populate: ' + uri + ' with ' + str(rows) + ' rows') + self.session.create(uri, 'value_format=S,columns=(key0,value0),' + config) + indxname = 'index:' + uri.split(":")[1] + self.session.create(indxname + ':index1', 'columns=(value0,key0)') + cursor = self.session.open_cursor(uri, None) + for i in range(1, rows + 1): + cursor[key_populate(cursor, i)] = value_populate(cursor, i) + cursor.close() + +def simple_index_populate_check_cursor(self, cursor, rows): + i = 0 + for key,val in cursor: + i += 1 + self.assertEqual(key, key_populate(cursor, i)) + if cursor.value_format == '8t' and val == 0: # deleted + continue + self.assertEqual(val, value_populate(cursor, i)) + self.assertEqual(i, rows) + +def simple_index_populate_check(self, uri, rows): + self.pr('simple_index_populate_check: ' + uri) + + # Check values in the main table. + cursor = self.session.open_cursor(uri, None) + simple_index_populate_check_cursor(self, cursor, rows) + + # Check values in the index. + indxname = 'index:' + uri.split(":")[1] + idxcursor = self.session.open_cursor(indxname + ':index1') + for i in range(1, rows + 1): + k = key_populate(cursor, i) + v = value_populate(cursor, i) + ik = (v,k) # The index key is columns=(v,k). + self.assertEqual(v, idxcursor[ik]) + idxcursor.close() + cursor.close() + # Return the value stored in a complex object. def complex_value_populate(cursor, i): return [str(i) + ': abcdefghijklmnopqrstuvwxyz'[0:i%26], diff --git a/src/third_party/wiredtiger/test/suite/run.py b/src/third_party/wiredtiger/test/suite/run.py index 6e7421b8b96..c37093a2a55 100644 --- a/src/third_party/wiredtiger/test/suite/run.py +++ b/src/third_party/wiredtiger/test/suite/run.py @@ -87,6 +87,7 @@ Options:\n\ -j N | --parallel N run all tests in parallel using N processes\n\ -l | --long run the entire test suite\n\ -p | --preserve preserve output files in WT_TEST/\n\ + -s N | --scenario N use scenario N (N can be number or symbolic)\n\ -t | --timestamp name WT_TEST according to timestamp\n\ -v N | --verbose N set verboseness to N (0<=N<=3, default=1)\n\ \n\ @@ -95,15 +96,27 @@ Tests:\n\ may be a subsuite name (e.g. \'base\' runs test_base*.py)\n\ \n\ When -C or -c are present, there may not be any tests named.\n\ + When -s is present, there must be a test named.\n\ ' # capture the category (AKA 'subsuite') part of a test name, # e.g. test_util03 -> util reCatname = re.compile(r"test_([^0-9]+)[0-9]*") -def addScenarioTests(tests, loader, testname): +def restrictScenario(testcases, restrict): + if restrict == '': + return testcases + elif restrict.isdigit(): + s = int(restrict) + return [t for t in testcases + if hasattr(t, 'scenario_number') and t.scenario_number == s] + else: + return [t for t in testcases + if hasattr(t, 'scenario_name') and t.scenario_name == restrict] + +def addScenarioTests(tests, loader, testname, scenario): loaded = loader.loadTestsFromName(testname) - tests.addTests(generate_scenarios(loaded)) + tests.addTests(restrictScenario(generate_scenarios(loaded), scenario)) def configRecord(cmap, tup): """ @@ -195,20 +208,20 @@ def configApply(suites, configfilename, configwrite): json.dump(configmap, f, sort_keys=True, indent=4) return newsuite -def testsFromArg(tests, loader, arg): +def testsFromArg(tests, loader, arg, scenario): # If a group of test is mentioned, do all tests in that group # e.g. 'run.py base' groupedfiles = glob.glob(suitedir + os.sep + 'test_' + arg + '*.py') if len(groupedfiles) > 0: for file in groupedfiles: - testsFromArg(tests, loader, os.path.basename(file)) + testsFromArg(tests, loader, os.path.basename(file), scenario) return # Explicit test class names if not arg[0].isdigit(): if arg.endswith('.py'): arg = arg[:-3] - addScenarioTests(tests, loader, arg) + addScenarioTests(tests, loader, arg, scenario) return # Deal with ranges @@ -217,7 +230,7 @@ def testsFromArg(tests, loader, arg): else: start, end = int(arg), int(arg) for t in xrange(start, end+1): - addScenarioTests(tests, loader, 'test%03d' % t) + addScenarioTests(tests, loader, 'test%03d' % t, scenario) if __name__ == '__main__': tests = unittest.TestSuite() @@ -228,6 +241,7 @@ if __name__ == '__main__': configfile = None configwrite = False dirarg = None + scenario = '' verbose = 1 args = sys.argv[1:] testargs = [] @@ -265,6 +279,12 @@ if __name__ == '__main__': if option == '-preserve' or option == 'p': preserve = True continue + if option == '-scenario' or option == 's': + if scenario != '' or len(args) == 0: + usage() + sys.exit(2) + scenario = args.pop(0) + continue if option == '-timestamp' or option == 't': timestamp = True continue @@ -303,15 +323,20 @@ if __name__ == '__main__': # Without any tests listed as arguments, do discovery if len(testargs) == 0: + if scenario != '': + sys.stderr.write( + 'run.py: specifying a scenario requires a test name\n') + usage() + sys.exit(2) from discover import defaultTestLoader as loader suites = loader.discover(suitedir) suites = sorted(suites, key=lambda c: str(list(c)[0])) if configfile != None: suites = configApply(suites, configfile, configwrite) - tests.addTests(generate_scenarios(suites)) + tests.addTests(restrictScenario(generate_scenarios(suites), '')) else: for arg in testargs: - testsFromArg(tests, loader, arg) + testsFromArg(tests, loader, arg, scenario) if debug: import pdb diff --git a/src/third_party/wiredtiger/test/suite/test_async01.py b/src/third_party/wiredtiger/test/suite/test_async01.py index 71a18a68121..9322748c30f 100644 --- a/src/third_party/wiredtiger/test/suite/test_async01.py +++ b/src/third_party/wiredtiger/test/suite/test_async01.py @@ -29,7 +29,7 @@ import sys, threading, wiredtiger, wttest from suite_subprocess import suite_subprocess from wiredtiger import WiredTigerError -from wtscenario import check_scenarios +from wtscenario import make_scenarios # TODO - tmp code def tty_pr(s): @@ -122,7 +122,7 @@ class test_async01(wttest.WiredTigerTestCase, suite_subprocess): async_threads = 3 current = {} - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file-col', dict(tablekind='col',uri='file')), ('file-fix', dict(tablekind='fix',uri='file')), ('file-row', dict(tablekind='row',uri='file')), diff --git a/src/third_party/wiredtiger/test/suite/test_async02.py b/src/third_party/wiredtiger/test/suite/test_async02.py index 7aa1b85a2f3..bc6b389fc27 100644 --- a/src/third_party/wiredtiger/test/suite/test_async02.py +++ b/src/third_party/wiredtiger/test/suite/test_async02.py @@ -29,7 +29,7 @@ import sys, threading, wiredtiger, wttest from suite_subprocess import suite_subprocess from wiredtiger import WiredTigerError -from wtscenario import check_scenarios +from wtscenario import make_scenarios class Callback(wiredtiger.AsyncCallback): def __init__(self, current): @@ -119,7 +119,7 @@ class test_async02(wttest.WiredTigerTestCase, suite_subprocess): async_threads = 3 current = {} - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file-col', dict(tablekind='col',uri='file')), ('file-fix', dict(tablekind='fix',uri='file')), ('file-row', dict(tablekind='row',uri='file')), diff --git a/src/third_party/wiredtiger/test/suite/test_backup02.py b/src/third_party/wiredtiger/test/suite/test_backup02.py index 095bfbe404a..398d55abd7a 100644 --- a/src/third_party/wiredtiger/test/suite/test_backup02.py +++ b/src/third_party/wiredtiger/test/suite/test_backup02.py @@ -30,13 +30,13 @@ import Queue import threading, time, wiredtiger, wttest from helper import key_populate, simple_populate from wtthread import backup_thread, checkpoint_thread, op_thread -from wtscenario import check_scenarios +from wtscenario import make_scenarios # test_backup02.py # Run background checkpoints and backsups repeatedly while doing inserts # in another thread class test_backup02(wttest.WiredTigerTestCase): - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('table', dict(uri='table:test',fmt='L',dsize=100,nops=200,nthreads=1,time=30)), ]) diff --git a/src/third_party/wiredtiger/test/suite/test_backup03.py b/src/third_party/wiredtiger/test/suite/test_backup03.py index e810a2ec714..053009c6edb 100644 --- a/src/third_party/wiredtiger/test/suite/test_backup03.py +++ b/src/third_party/wiredtiger/test/suite/test_backup03.py @@ -28,7 +28,7 @@ import glob, os, shutil, string from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios import wiredtiger, wttest from helper import compare_files,\ complex_populate, complex_populate_lsm, simple_populate @@ -56,25 +56,25 @@ class test_backup_target(wttest.WiredTigerTestCase, suite_subprocess): ('table:' + pfx + '.4', complex_populate_lsm, 3), ] list = [ - ( '1', dict(big=0,list=[0])), # Target objects individually - ( '2', dict(big=1,list=[1])), - ( '3', dict(big=2,list=[2])), - ( '4', dict(big=3,list=[3])), - ('5a', dict(big=0,list=[0,2])), # Target groups of objects - ('5b', dict(big=2,list=[0,2])), - ('6a', dict(big=1,list=[1,3])), - ('6b', dict(big=3,list=[1,3])), - ('7a', dict(big=0,list=[0,1,2])), - ('7b', dict(big=1,list=[0,1,2])), - ('7c', dict(big=2,list=[0,1,2])), - ('8a', dict(big=0,list=[0,1,2,3])), - ('8b', dict(big=1,list=[0,1,2,3])), - ('8c', dict(big=2,list=[0,1,2,3])), - ('8d', dict(big=3,list=[0,1,2,3])), - ( '9', dict(big=3,list=[])), # Backup everything + ( 'backup_1', dict(big=0,list=[0])), # Target objects individually + ( 'backup_2', dict(big=1,list=[1])), + ( 'backup_3', dict(big=2,list=[2])), + ( 'backup_4', dict(big=3,list=[3])), + ('backup_5a', dict(big=0,list=[0,2])), # Target groups of objects + ('backup_5b', dict(big=2,list=[0,2])), + ('backup_6a', dict(big=1,list=[1,3])), + ('backup_6b', dict(big=3,list=[1,3])), + ('backup_7a', dict(big=0,list=[0,1,2])), + ('backup_7b', dict(big=1,list=[0,1,2])), + ('backup_7c', dict(big=2,list=[0,1,2])), + ('backup_8a', dict(big=0,list=[0,1,2,3])), + ('backup_8b', dict(big=1,list=[0,1,2,3])), + ('backup_8c', dict(big=2,list=[0,1,2,3])), + ('backup_8d', dict(big=3,list=[0,1,2,3])), + ('backup_9', dict(big=3,list=[])), # Backup everything ] - scenarios = number_scenarios(multiply_scenarios('.', list)) + scenarios = make_scenarios(list) # Create a large cache, otherwise this test runs quite slowly. conn_config = 'cache_size=1G' diff --git a/src/third_party/wiredtiger/test/suite/test_backup04.py b/src/third_party/wiredtiger/test/suite/test_backup04.py index 852a22c1e0c..866e673dccb 100644 --- a/src/third_party/wiredtiger/test/suite/test_backup04.py +++ b/src/third_party/wiredtiger/test/suite/test_backup04.py @@ -30,7 +30,7 @@ import Queue import threading, time, wiredtiger, wttest import glob, os, shutil from suite_subprocess import suite_subprocess -from wtscenario import check_scenarios +from wtscenario import make_scenarios from wtthread import op_thread from helper import compare_files, key_populate @@ -54,7 +54,7 @@ class test_backup_target(wttest.WiredTigerTestCase, suite_subprocess): # and that is not what we want here. # pfx = 'test_backup' - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('table', dict(uri='table:test',dsize=100,nops=2000,nthreads=1,time=30)), ]) diff --git a/src/third_party/wiredtiger/test/suite/test_backup05.py b/src/third_party/wiredtiger/test/suite/test_backup05.py index fbe219d8de8..131732e9a89 100644 --- a/src/third_party/wiredtiger/test/suite/test_backup05.py +++ b/src/third_party/wiredtiger/test/suite/test_backup05.py @@ -35,7 +35,6 @@ import fnmatch, os, shutil, time from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios, prune_scenarios from helper import copy_wiredtiger_home import wiredtiger, wttest diff --git a/src/third_party/wiredtiger/test/suite/test_base02.py b/src/third_party/wiredtiger/test/suite/test_base02.py index 70117573241..2b51fe1b530 100644 --- a/src/third_party/wiredtiger/test/suite/test_base02.py +++ b/src/third_party/wiredtiger/test/suite/test_base02.py @@ -32,14 +32,14 @@ import json import wiredtiger, wttest -from wtscenario import check_scenarios +from wtscenario import make_scenarios # Test configuration strings. class test_base02(wttest.WiredTigerTestCase): name = 'test_base02a' extra_config = '' - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file', dict(uri='file:')), ('table', dict(uri='table:')), ('lsm', dict(uri='lsm:')), diff --git a/src/third_party/wiredtiger/test/suite/test_base05.py b/src/third_party/wiredtiger/test/suite/test_base05.py index f191f23561f..4bee0efcfe2 100644 --- a/src/third_party/wiredtiger/test/suite/test_base05.py +++ b/src/third_party/wiredtiger/test/suite/test_base05.py @@ -27,7 +27,7 @@ # OTHER DEALINGS IN THE SOFTWARE. import wiredtiger, wttest -from wtscenario import check_scenarios +from wtscenario import make_scenarios # test_base05.py # Cursor operations @@ -40,7 +40,7 @@ class test_base05(wttest.WiredTigerTestCase): table_name1 = 'test_base05a' table_name2 = 'test_base05b' nentries = 1000 - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('no_huffman', dict(extraconfig='')), ('huffman_key', dict(extraconfig='huffman_key="english"')), ('huffman_val', dict(extraconfig='huffman_value="english"')), diff --git a/src/third_party/wiredtiger/test/suite/test_bug003.py b/src/third_party/wiredtiger/test/suite/test_bug003.py index 739279a0141..28d71a534e2 100644 --- a/src/third_party/wiredtiger/test/suite/test_bug003.py +++ b/src/third_party/wiredtiger/test/suite/test_bug003.py @@ -30,7 +30,7 @@ # Regression tests. import wiredtiger, wttest -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # Regression tests. class test_bug003(wttest.WiredTigerTestCase): @@ -43,7 +43,7 @@ class test_bug003(wttest.WiredTigerTestCase): ('yes', dict(name=1)), ] - scenarios = number_scenarios(multiply_scenarios('.', types, ckpt)) + scenarios = make_scenarios(types, ckpt) # Confirm bulk-load isn't stopped by checkpoints. def test_bug003(self): diff --git a/src/third_party/wiredtiger/test/suite/test_bug006.py b/src/third_party/wiredtiger/test/suite/test_bug006.py index e522cdf96f7..314ba57038f 100644 --- a/src/third_party/wiredtiger/test/suite/test_bug006.py +++ b/src/third_party/wiredtiger/test/suite/test_bug006.py @@ -31,13 +31,13 @@ import wiredtiger, wttest from helper import key_populate, value_populate -from wtscenario import check_scenarios +from wtscenario import make_scenarios # Check that verify and salvage both raise exceptions if there is an open # cursor. class test_bug006(wttest.WiredTigerTestCase): name = 'test_bug006' - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file', dict(uri='file:')), ('table', dict(uri='table:')), ]) diff --git a/src/third_party/wiredtiger/test/suite/test_bug008.py b/src/third_party/wiredtiger/test/suite/test_bug008.py index 0243887e258..c4fa411f55e 100644 --- a/src/third_party/wiredtiger/test/suite/test_bug008.py +++ b/src/third_party/wiredtiger/test/suite/test_bug008.py @@ -31,13 +31,13 @@ import wiredtiger, wttest from helper import simple_populate, key_populate, value_populate -from wtscenario import check_scenarios +from wtscenario import make_scenarios # Test search/search-near operations, including invisible values and keys # past the end of the table. class test_bug008(wttest.WiredTigerTestCase): uri = 'file:test_bug008' # This is a btree layer test. - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('fix', dict(fmt='key_format=r,value_format=8t', empty=1, colvar=0)), ('row', dict(fmt='key_format=S', empty=0, colvar=0)), ('var', dict(fmt='key_format=r', empty=0, colvar=1)) diff --git a/src/third_party/wiredtiger/test/suite/test_bug009.py b/src/third_party/wiredtiger/test/suite/test_bug009.py index 4d10e4391d9..2bdfb7dec52 100644 --- a/src/third_party/wiredtiger/test/suite/test_bug009.py +++ b/src/third_party/wiredtiger/test/suite/test_bug009.py @@ -33,7 +33,6 @@ import wiredtiger, wttest from wiredtiger import stat -from wtscenario import multiply_scenarios, number_scenarios class test_bug009(wttest.WiredTigerTestCase): name = 'test_bug009' diff --git a/src/third_party/wiredtiger/test/suite/test_bug011.py b/src/third_party/wiredtiger/test/suite/test_bug011.py index 50dba1c48be..fceb7a22ddb 100644 --- a/src/third_party/wiredtiger/test/suite/test_bug011.py +++ b/src/third_party/wiredtiger/test/suite/test_bug011.py @@ -42,7 +42,7 @@ class test_bug011(wttest.WiredTigerTestCase): nops = 10000 # Add connection configuration for this test. def conn_config(self, dir): - return 'cache_size=10MB,hazard_max=' + str(self.ntables / 2) + return 'cache_size=10MB,eviction_dirty_target=99,eviction_dirty_trigger=99,hazard_max=' + str(self.ntables / 2) def test_eviction(self): cursors = [] diff --git a/src/third_party/wiredtiger/test/suite/test_bug016.py b/src/third_party/wiredtiger/test/suite/test_bug016.py new file mode 100644 index 00000000000..f7cb3c32559 --- /dev/null +++ b/src/third_party/wiredtiger/test/suite/test_bug016.py @@ -0,0 +1,109 @@ +#!/usr/bin/env python +# +# Public Domain 2014-2016 MongoDB, Inc. +# Public Domain 2008-2014 WiredTiger, Inc. +# +# This is free and unencumbered software released into the public domain. +# +# Anyone is free to copy, modify, publish, use, compile, sell, or +# distribute this software, either in source code form or as a compiled +# binary, for any purpose, commercial or non-commercial, and by any +# means. +# +# In jurisdictions that recognize copyright laws, the author or authors +# of this software dedicate any and all copyright interest in the +# software to the public domain. We make this dedication for the benefit +# of the public at large and to the detriment of our heirs and +# successors. We intend this dedication to be an overt act of +# relinquishment in perpetuity of all present and future rights to this +# software under copyright law. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +import wiredtiger, wttest + +# test_bug016.py +# WT-2757: WT_CURSOR.get_key() fails after WT_CURSOR.insert unless the +# cursor has a record number key with append configured. +class test_bug016(wttest.WiredTigerTestCase): + + # Insert a row into a simple column-store table configured to append. + # WT_CURSOR.get_key should succeed. + def test_simple_column_store_append(self): + uri='file:bug016' + self.session.create(uri, 'key_format=r,value_format=S') + cursor = self.session.open_cursor(uri, None, 'append') + cursor.set_value('value') + cursor.insert() + self.assertEquals(cursor.get_key(), 1) + + # Insert a row into a simple column-store table. + # WT_CURSOR.get_key should fail. + def test_simple_column_store(self): + uri='file:bug016' + self.session.create(uri, 'key_format=r,value_format=S') + cursor = self.session.open_cursor(uri, None) + cursor.set_key(37) + cursor.set_value('value') + cursor.insert() + self.assertRaisesWithMessage(wiredtiger.WiredTigerError, + lambda: cursor.get_key(), "/requires key be set/") + + # Insert a row into a simple row-store table. + # WT_CURSOR.get_key should fail. + def test_simple_row_store(self): + uri='file:bug016' + self.session.create(uri, 'key_format=S,value_format=S') + cursor = self.session.open_cursor(uri, None) + cursor.set_key('key') + cursor.set_value('value') + cursor.insert() + self.assertRaisesWithMessage(wiredtiger.WiredTigerError, + lambda: cursor.get_key(), "/requires key be set/") + + # Insert a row into a complex column-store table configured to append. + # WT_CURSOR.get_key should succeed. + def test_complex_column_store_append(self): + uri='table:bug016' + self.session.create( + uri, 'key_format=r,value_format=S,columns=(key,value)') + cursor = self.session.open_cursor(uri, None, 'append') + cursor.set_value('value') + cursor.insert() + self.assertEquals(cursor.get_key(), 1) + + # Insert a row into a complex column-store table. + # WT_CURSOR.get_key should fail. + def test_complex_column_store(self): + uri='table:bug016' + self.session.create( + uri, 'key_format=r,value_format=S,columns=(key,value)') + cursor = self.session.open_cursor(uri, None) + cursor.set_key(37) + cursor.set_value('value') + cursor.insert() + self.assertRaisesWithMessage(wiredtiger.WiredTigerError, + lambda: cursor.get_key(), "/requires key be set/") + + # Insert a row into a complex row-store table. + # WT_CURSOR.get_key should fail. + def test_complex_row_store(self): + uri='table:bug016' + self.session.create( + uri, 'key_format=S,value_format=S,columns=(key,value)') + cursor = self.session.open_cursor(uri, None) + cursor.set_key('key') + cursor.set_value('value') + cursor.insert() + self.assertRaisesWithMessage(wiredtiger.WiredTigerError, + lambda: cursor.get_key(), "/requires key be set/") + + +if __name__ == '__main__': + wttest.run() diff --git a/src/third_party/wiredtiger/test/suite/test_bulk01.py b/src/third_party/wiredtiger/test/suite/test_bulk01.py index 1add11af26b..5bacfafaa20 100644 --- a/src/third_party/wiredtiger/test/suite/test_bulk01.py +++ b/src/third_party/wiredtiger/test/suite/test_bulk01.py @@ -32,7 +32,7 @@ import wiredtiger, wttest from helper import key_populate, value_populate -from wtscenario import check_scenarios, multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # Smoke test bulk-load. class test_bulk_load(wttest.WiredTigerTestCase): @@ -52,7 +52,7 @@ class test_bulk_load(wttest.WiredTigerTestCase): ('integer', dict(valfmt='i')), ('string', dict(valfmt='S')), ] - scenarios = number_scenarios(multiply_scenarios('.', types, keyfmt, valfmt)) + scenarios = make_scenarios(types, keyfmt, valfmt) # Test a simple bulk-load def test_bulk_load(self): diff --git a/src/third_party/wiredtiger/test/suite/test_bulk02.py b/src/third_party/wiredtiger/test/suite/test_bulk02.py index fe8118209f2..af0b6d4485d 100644 --- a/src/third_party/wiredtiger/test/suite/test_bulk02.py +++ b/src/third_party/wiredtiger/test/suite/test_bulk02.py @@ -32,7 +32,7 @@ import shutil, os from helper import confirm_empty, key_populate, value_populate from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios import wiredtiger, wttest # test_bulkload_checkpoint @@ -47,7 +47,7 @@ class test_bulkload_checkpoint(wttest.WiredTigerTestCase, suite_subprocess): ('unnamed', dict(ckpt_type='unnamed')), ] - scenarios = number_scenarios(multiply_scenarios('.', types, ckpt_type)) + scenarios = make_scenarios(types, ckpt_type) # Bulk-load handles are skipped by checkpoints. # Named and unnamed checkpoint versions. @@ -90,8 +90,7 @@ class test_bulkload_backup(wttest.WiredTigerTestCase, suite_subprocess): ('different', dict(session_type='different')), ('same', dict(session_type='same')), ] - scenarios = number_scenarios( - multiply_scenarios('.', types, ckpt_type, session_type)) + scenarios = make_scenarios(types, ckpt_type, session_type) # Backup a set of chosen tables/files using the wt backup command. # The only files are bulk-load files, so they shouldn't be copied. diff --git a/src/third_party/wiredtiger/test/suite/test_checkpoint01.py b/src/third_party/wiredtiger/test/suite/test_checkpoint01.py index 6e1ad7814ed..78754dc82fa 100644 --- a/src/third_party/wiredtiger/test/suite/test_checkpoint01.py +++ b/src/third_party/wiredtiger/test/suite/test_checkpoint01.py @@ -28,7 +28,7 @@ import wiredtiger, wttest from helper import key_populate, complex_populate_lsm, simple_populate -from wtscenario import check_scenarios +from wtscenario import make_scenarios # test_checkpoint01.py # Checkpoint tests @@ -36,7 +36,7 @@ from wtscenario import check_scenarios # with a set of checkpoints, then confirm the checkpoint's values are correct, # including after other checkpoints are dropped. class test_checkpoint(wttest.WiredTigerTestCase): - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file', dict(uri='file:checkpoint',fmt='S')), ('table', dict(uri='table:checkpoint',fmt='S')) ]) @@ -139,7 +139,7 @@ class test_checkpoint(wttest.WiredTigerTestCase): # Check some specific cursor checkpoint combinations. class test_checkpoint_cursor(wttest.WiredTigerTestCase): - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file', dict(uri='file:checkpoint',fmt='S')), ('table', dict(uri='table:checkpoint',fmt='S')) ]) @@ -205,7 +205,7 @@ class test_checkpoint_cursor(wttest.WiredTigerTestCase): # Check that you can checkpoint targets. class test_checkpoint_target(wttest.WiredTigerTestCase): - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file', dict(uri='file:checkpoint',fmt='S')), ('table', dict(uri='table:checkpoint',fmt='S')) ]) @@ -252,7 +252,7 @@ class test_checkpoint_target(wttest.WiredTigerTestCase): # Check that you can't write checkpoint cursors. class test_checkpoint_cursor_update(wttest.WiredTigerTestCase): - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file-r', dict(uri='file:checkpoint',fmt='r')), ('file-S', dict(uri='file:checkpoint',fmt='S')), ('table-r', dict(uri='table:checkpoint',fmt='r')), @@ -277,7 +277,7 @@ class test_checkpoint_cursor_update(wttest.WiredTigerTestCase): # Check that WiredTigerCheckpoint works as a checkpoint specifier. class test_checkpoint_last(wttest.WiredTigerTestCase): - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file', dict(uri='file:checkpoint',fmt='S')), ('table', dict(uri='table:checkpoint',fmt='S')) ]) @@ -343,7 +343,7 @@ class test_checkpoint_lsm_name(wttest.WiredTigerTestCase): class test_checkpoint_empty(wttest.WiredTigerTestCase): - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file', dict(uri='file:checkpoint')), ('table', dict(uri='table:checkpoint')), ]) diff --git a/src/third_party/wiredtiger/test/suite/test_checkpoint02.py b/src/third_party/wiredtiger/test/suite/test_checkpoint02.py index 71c8792359c..ac57499a9e4 100644 --- a/src/third_party/wiredtiger/test/suite/test_checkpoint02.py +++ b/src/third_party/wiredtiger/test/suite/test_checkpoint02.py @@ -30,13 +30,13 @@ import Queue import threading, time, wiredtiger, wttest from helper import key_populate, simple_populate from wtthread import checkpoint_thread, op_thread -from wtscenario import check_scenarios +from wtscenario import make_scenarios # test_checkpoint02.py # Run background checkpoints repeatedly while doing inserts and other # operations in another thread class test_checkpoint02(wttest.WiredTigerTestCase): - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('table-100', dict(uri='table:test',fmt='L',dsize=100,nops=50000,nthreads=10)), ('table-10', dict(uri='table:test',fmt='L',dsize=10,nops=50000,nthreads=30)) ]) diff --git a/src/third_party/wiredtiger/test/suite/test_colgap.py b/src/third_party/wiredtiger/test/suite/test_colgap.py index 46682c23167..5cc363dbd4a 100644 --- a/src/third_party/wiredtiger/test/suite/test_colgap.py +++ b/src/third_party/wiredtiger/test/suite/test_colgap.py @@ -28,7 +28,7 @@ import wiredtiger, wttest from helper import simple_populate, key_populate, value_populate -from wtscenario import check_scenarios, multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # test_colgap.py # Test variable-length column-store gap performance. @@ -149,8 +149,8 @@ class test_colmax(wttest.WiredTigerTestCase): ('not-single', dict(single=0)), ] - scenarios = number_scenarios(multiply_scenarios(\ - '.', types, valfmt, record_number, bulk, reopen, single)) + scenarios = make_scenarios(\ + types, valfmt, record_number, bulk, reopen, single) # Test that variable-length column-store correctly/efficiently handles big # records (if it's not efficient, we'll just hang). diff --git a/src/third_party/wiredtiger/test/suite/test_collator.py b/src/third_party/wiredtiger/test/suite/test_collator.py index 34b5c20247f..a8103fb3671 100644 --- a/src/third_party/wiredtiger/test/suite/test_collator.py +++ b/src/third_party/wiredtiger/test/suite/test_collator.py @@ -28,7 +28,6 @@ import os import wiredtiger, wttest, run -from wtscenario import check_scenarios, number_scenarios # test_collator.py # Test indices using a custom extractor and collator. diff --git a/src/third_party/wiredtiger/test/suite/test_compact01.py b/src/third_party/wiredtiger/test/suite/test_compact01.py index 3af550708ed..183d75f9d31 100644 --- a/src/third_party/wiredtiger/test/suite/test_compact01.py +++ b/src/third_party/wiredtiger/test/suite/test_compact01.py @@ -30,7 +30,7 @@ import wiredtiger, wttest from helper import complex_populate, simple_populate, key_populate from suite_subprocess import suite_subprocess from wiredtiger import stat -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # test_compact.py # session level compact operation @@ -53,7 +53,7 @@ class test_compact(wttest.WiredTigerTestCase, suite_subprocess): ('method_reopen', dict(utility=0,reopen=1)), ('utility', dict(utility=1,reopen=0)), ] - scenarios = number_scenarios(multiply_scenarios('.', types, compact)) + scenarios = make_scenarios(types, compact) # We want a large cache so that eviction doesn't happen # (which could skew our compaction results). conn_config = 'cache_size=250MB,statistics=(all)' diff --git a/src/third_party/wiredtiger/test/suite/test_compact02.py b/src/third_party/wiredtiger/test/suite/test_compact02.py index 7ad05cd2536..eb21817bd90 100644 --- a/src/third_party/wiredtiger/test/suite/test_compact02.py +++ b/src/third_party/wiredtiger/test/suite/test_compact02.py @@ -32,7 +32,7 @@ import wiredtiger, wttest from wiredtiger import stat -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # Test basic compression class test_compact02(wttest.WiredTigerTestCase): @@ -57,8 +57,7 @@ class test_compact02(wttest.WiredTigerTestCase): ('64KB', dict(fileConfig='leaf_page_max=64KB')), ('128KB', dict(fileConfig='leaf_page_max=128KB')), ] - scenarios = \ - number_scenarios(multiply_scenarios('.', types, cacheSize, fileConfig)) + scenarios = make_scenarios(types, cacheSize, fileConfig) # We want about 22K records that total about 130Mb. That is an average # of 6196 bytes per record. Half the records should be smaller, about @@ -97,7 +96,7 @@ class test_compact02(wttest.WiredTigerTestCase): self.home = '.' conn_params = 'create,' + \ cacheSize + ',error_prefix="%s: ",' % self.shortid() + \ - 'statistics=(fast)' + 'statistics=(fast),eviction_dirty_target=99,eviction_dirty_trigger=99' try: self.conn = wiredtiger.wiredtiger_open(self.home, conn_params) except wiredtiger.WiredTigerError as e: diff --git a/src/third_party/wiredtiger/test/suite/test_compress01.py b/src/third_party/wiredtiger/test/suite/test_compress01.py index 94c748fc3e5..2a7e2a7e1a8 100644 --- a/src/third_party/wiredtiger/test/suite/test_compress01.py +++ b/src/third_party/wiredtiger/test/suite/test_compress01.py @@ -32,7 +32,7 @@ import os, run import wiredtiger, wttest -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # Test basic compression class test_compress01(wttest.WiredTigerTestCase): @@ -46,7 +46,7 @@ class test_compress01(wttest.WiredTigerTestCase): ('snappy', dict(compress='snappy')), ('none', dict(compress=None)), ] - scenarios = number_scenarios(multiply_scenarios('.', types, compress)) + scenarios = make_scenarios(types, compress) nrecords = 10000 bigvalue = "abcdefghij" * 1000 diff --git a/src/third_party/wiredtiger/test/suite/test_config03.py b/src/third_party/wiredtiger/test/suite/test_config03.py index e91c5de62f8..88ca6ae3f39 100644 --- a/src/third_party/wiredtiger/test/suite/test_config03.py +++ b/src/third_party/wiredtiger/test/suite/test_config03.py @@ -69,14 +69,11 @@ class test_config03(test_base03.test_base03): 'eviction_trigger', 'hazard_max', 'multiprocess', 'session_max', 'verbose' ] - all_scenarios = wtscenario.multiply_scenarios('_', + scenarios = wtscenario.make_scenarios( cache_size_scenarios, create_scenarios, error_prefix_scenarios, eviction_target_scenarios, eviction_trigger_scenarios, hazard_max_scenarios, multiprocess_scenarios, session_max_scenarios, - transactional_scenarios, verbose_scenarios) - - scenarios = wtscenario.prune_scenarios(all_scenarios, 1000) - scenarios = wtscenario.number_scenarios(scenarios) + transactional_scenarios, verbose_scenarios, prune=1000) #wttest.WiredTigerTestCase.printVerbose(2, 'test_config03: running ' + \ # str(len(scenarios)) + ' of ' + \ diff --git a/src/third_party/wiredtiger/test/suite/test_config04.py b/src/third_party/wiredtiger/test/suite/test_config04.py index dffa7479f1b..204aa7e27d5 100644 --- a/src/third_party/wiredtiger/test/suite/test_config04.py +++ b/src/third_party/wiredtiger/test/suite/test_config04.py @@ -197,7 +197,7 @@ class test_config04(wttest.WiredTigerTestCase): # Test an absolute path directory. if os.name == 'posix': - logdir = '/tmp/logdir' + logdir = os.path.abspath('absolutelogdir') os.mkdir(logdir) confstr = 'path=' + logdir self.common_log_test(confstr, logdir) diff --git a/src/third_party/wiredtiger/test/suite/test_cursor01.py b/src/third_party/wiredtiger/test/suite/test_cursor01.py index cf39d4a4ba4..8c66042eec0 100644 --- a/src/third_party/wiredtiger/test/suite/test_cursor01.py +++ b/src/third_party/wiredtiger/test/suite/test_cursor01.py @@ -27,7 +27,7 @@ # OTHER DEALINGS IN THE SOFTWARE. import wiredtiger, wttest -from wtscenario import check_scenarios +from wtscenario import make_scenarios # test_cursor01.py # Cursor operations @@ -41,7 +41,7 @@ class test_cursor01(wttest.WiredTigerTestCase): table_name1 = 'test_cursor01' nentries = 10 - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file-col', dict(tablekind='col',uri='file')), ('file-fix', dict(tablekind='fix',uri='file')), ('file-row', dict(tablekind='row',uri='file')), diff --git a/src/third_party/wiredtiger/test/suite/test_cursor02.py b/src/third_party/wiredtiger/test/suite/test_cursor02.py index eb1ba4dfc41..a83d30def47 100644 --- a/src/third_party/wiredtiger/test/suite/test_cursor02.py +++ b/src/third_party/wiredtiger/test/suite/test_cursor02.py @@ -28,7 +28,7 @@ import wiredtiger from test_cursor_tracker import TestCursorTracker -from wtscenario import check_scenarios +from wtscenario import make_scenarios # test_cursor02.py # Cursor operations on small tables. @@ -39,7 +39,7 @@ class test_cursor02(TestCursorTracker): key/value content and to track/verify content after inserts and removes. """ - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('row', dict(tablekind='row', uri='table')), ('lsm-row', dict(tablekind='row', uri='lsm')), ('col', dict(tablekind='col', uri='table')), diff --git a/src/third_party/wiredtiger/test/suite/test_cursor03.py b/src/third_party/wiredtiger/test/suite/test_cursor03.py index 63237f942ca..b4598483c12 100644 --- a/src/third_party/wiredtiger/test/suite/test_cursor03.py +++ b/src/third_party/wiredtiger/test/suite/test_cursor03.py @@ -28,7 +28,7 @@ import wiredtiger from test_cursor_tracker import TestCursorTracker -from wtscenario import multiply_scenarios +from wtscenario import make_scenarios # test_cursor03.py # Cursor operations on tables of various sizes, with key/values of various @@ -40,7 +40,7 @@ class test_cursor03(TestCursorTracker): key/value content and to track/verify content after inserts and removes. """ - scenarios = multiply_scenarios('.', [ + scenarios = make_scenarios([ ('row', dict(tablekind='row', keysize=None, valsize=None, uri='table')), ('lsm-row', dict(tablekind='row', keysize=None, valsize=None, uri='lsm')), ('col', dict(tablekind='col', keysize=None, valsize=None, uri='table')), diff --git a/src/third_party/wiredtiger/test/suite/test_cursor04.py b/src/third_party/wiredtiger/test/suite/test_cursor04.py index 6576c623f8a..8cbf922b5eb 100644 --- a/src/third_party/wiredtiger/test/suite/test_cursor04.py +++ b/src/third_party/wiredtiger/test/suite/test_cursor04.py @@ -27,7 +27,7 @@ # OTHER DEALINGS IN THE SOFTWARE. import wiredtiger, wttest -from wtscenario import check_scenarios +from wtscenario import make_scenarios # test_base04.py # Cursor operations @@ -38,7 +38,7 @@ class test_cursor04(wttest.WiredTigerTestCase): table_name1 = 'test_cursor04' nentries = 20 - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('row', dict(tablekind='row', uri='table')), ('lsm-row', dict(tablekind='row', uri='lsm')), ('col', dict(tablekind='col', uri='table')), diff --git a/src/third_party/wiredtiger/test/suite/test_cursor06.py b/src/third_party/wiredtiger/test/suite/test_cursor06.py index 5545c862dd7..3a6240bc6c7 100644 --- a/src/third_party/wiredtiger/test/suite/test_cursor06.py +++ b/src/third_party/wiredtiger/test/suite/test_cursor06.py @@ -29,13 +29,13 @@ import wiredtiger, wttest from helper import key_populate, value_populate, simple_populate from helper import complex_value_populate, complex_populate -from wtscenario import check_scenarios +from wtscenario import make_scenarios # test_cursor06.py # Test cursor reconfiguration. class test_cursor06(wttest.WiredTigerTestCase): name = 'reconfigure' - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file-r', dict(type='file:', config='key_format=r', complex=0)), ('file-S', dict(type='file:', config='key_format=S', complex=0)), ('lsm-S', dict(type='lsm:', config='key_format=S', complex=0)), diff --git a/src/third_party/wiredtiger/test/suite/test_cursor07.py b/src/third_party/wiredtiger/test/suite/test_cursor07.py index d8de0874d7f..d6078183fc1 100644 --- a/src/third_party/wiredtiger/test/suite/test_cursor07.py +++ b/src/third_party/wiredtiger/test/suite/test_cursor07.py @@ -33,7 +33,7 @@ import fnmatch, os, shutil, run, time from suite_subprocess import suite_subprocess from wiredtiger import stat -from wtscenario import check_scenarios +from wtscenario import make_scenarios import wttest class test_cursor07(wttest.WiredTigerTestCase, suite_subprocess): @@ -44,7 +44,7 @@ class test_cursor07(wttest.WiredTigerTestCase, suite_subprocess): # test that scenario for log cursors. nkeys = 7000 - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('regular', dict(reopen=False)), ('reopen', dict(reopen=True)) ]) diff --git a/src/third_party/wiredtiger/test/suite/test_cursor08.py b/src/third_party/wiredtiger/test/suite/test_cursor08.py index 1a379518224..3f8f50defa7 100644 --- a/src/third_party/wiredtiger/test/suite/test_cursor08.py +++ b/src/third_party/wiredtiger/test/suite/test_cursor08.py @@ -33,7 +33,7 @@ import fnmatch, os, shutil, run, time from suite_subprocess import suite_subprocess from wiredtiger import stat, WiredTigerError -from wtscenario import multiply_scenarios, number_scenarios, check_scenarios +from wtscenario import make_scenarios import wttest class test_cursor08(wttest.WiredTigerTestCase, suite_subprocess): @@ -42,17 +42,17 @@ class test_cursor08(wttest.WiredTigerTestCase, suite_subprocess): uri = 'table:' + tablename nkeys = 500 - reopens = check_scenarios([ + reopens = [ ('regular', dict(reopen=False)), ('reopen', dict(reopen=True)) - ]) - compress = check_scenarios([ + ] + compress = [ ('nop', dict(compress='nop')), ('snappy', dict(compress='snappy')), ('zlib', dict(compress='zlib')), ('none', dict(compress='none')), - ]) - scenarios = number_scenarios(multiply_scenarios('.', reopens, compress)) + ] + scenarios = make_scenarios(reopens, compress) # Load the compression extension, and enable it for logging. def conn_config(self, dir): return 'log=(archive=false,enabled,file_max=%s,' % self.logmax + \ diff --git a/src/third_party/wiredtiger/test/suite/test_cursor09.py b/src/third_party/wiredtiger/test/suite/test_cursor09.py index b77336bc1d7..a05caea4f1f 100644 --- a/src/third_party/wiredtiger/test/suite/test_cursor09.py +++ b/src/third_party/wiredtiger/test/suite/test_cursor09.py @@ -29,12 +29,12 @@ import wiredtiger, wttest from helper import key_populate, value_populate, simple_populate from helper import complex_populate, complex_value_populate -from wtscenario import check_scenarios +from wtscenario import make_scenarios # test_cursor09.py # JIRA WT-2217: insert resets key/value "set". class test_cursor09(wttest.WiredTigerTestCase): - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file-r', dict(type='file:', config='key_format=r', complex=0)), ('file-S', dict(type='file:', config='key_format=S', complex=0)), ('lsm-S', dict(type='lsm:', config='key_format=S', complex=0)), diff --git a/src/third_party/wiredtiger/test/suite/test_cursor_compare.py b/src/third_party/wiredtiger/test/suite/test_cursor_compare.py index 130f4e8ca96..179e20682d2 100644 --- a/src/third_party/wiredtiger/test/suite/test_cursor_compare.py +++ b/src/third_party/wiredtiger/test/suite/test_cursor_compare.py @@ -29,7 +29,7 @@ import wiredtiger, wttest, exceptions from helper import complex_populate, simple_populate, key_populate from helper import complex_populate_index_name -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # Test cursor comparisons. class test_cursor_comparison(wttest.WiredTigerTestCase): @@ -45,7 +45,7 @@ class test_cursor_comparison(wttest.WiredTigerTestCase): ('recno', dict(keyfmt='r')), ('string', dict(keyfmt='S')) ] - scenarios = number_scenarios(multiply_scenarios('.', types, keyfmt)) + scenarios = make_scenarios(types, keyfmt) def test_cursor_comparison(self): uri = self.type + 'compare' diff --git a/src/third_party/wiredtiger/test/suite/test_cursor_pin.py b/src/third_party/wiredtiger/test/suite/test_cursor_pin.py index 329759d8fc8..1aea49c32b0 100644 --- a/src/third_party/wiredtiger/test/suite/test_cursor_pin.py +++ b/src/third_party/wiredtiger/test/suite/test_cursor_pin.py @@ -28,7 +28,7 @@ import wiredtiger, wttest from helper import simple_populate, key_populate, value_populate -from wtscenario import check_scenarios +from wtscenario import make_scenarios # test_cursor_pin.py # Smoke-test fast-path searching for pinned pages before re-descending @@ -37,7 +37,7 @@ class test_cursor_pin(wttest.WiredTigerTestCase): uri = 'file:cursor_pin' nentries = 10000 config = 'allocation_size=512,leaf_page_max=512,value_format=S,key_format=' - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('recno', dict(keyfmt='r')), ('string', dict(keyfmt='S')), ]) diff --git a/src/third_party/wiredtiger/test/suite/test_cursor_random.py b/src/third_party/wiredtiger/test/suite/test_cursor_random.py index 16ce5cae685..8d7c230043b 100644 --- a/src/third_party/wiredtiger/test/suite/test_cursor_random.py +++ b/src/third_party/wiredtiger/test/suite/test_cursor_random.py @@ -29,7 +29,7 @@ import wiredtiger, wttest from helper import complex_populate, simple_populate from helper import key_populate, value_populate -from wtscenario import check_scenarios, multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # test_cursor_random.py # Cursor next_random operations @@ -42,7 +42,7 @@ class test_cursor_random(wttest.WiredTigerTestCase): ('sample', dict(config='next_random=true,next_random_sample_size=35')), ('not-sample', dict(config='next_random=true')) ] - scenarios =number_scenarios(multiply_scenarios('.', types, config)) + scenarios = make_scenarios(types, config) # Check that opening a random cursor on a row-store returns not-supported # for methods other than next, reconfigure and reset, and next returns @@ -136,7 +136,7 @@ class test_cursor_random(wttest.WiredTigerTestCase): # Check that opening a random cursor on column-store returns not-supported. class test_cursor_random_column(wttest.WiredTigerTestCase): - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file', dict(uri='file:random')), ('table', dict(uri='table:random')) ]) @@ -159,7 +159,7 @@ class test_cursor_random_invisible(wttest.WiredTigerTestCase): ('sample', dict(config='next_random=true,next_random_sample_size=35')), ('not-sample', dict(config='next_random=true')) ] - scenarios =number_scenarios(multiply_scenarios('.', types, config)) + scenarios = make_scenarios(types, config) def test_cursor_random_invisible_all(self): uri = self.type diff --git a/src/third_party/wiredtiger/test/suite/test_cursor_random02.py b/src/third_party/wiredtiger/test/suite/test_cursor_random02.py index 84ac0279fc4..93aa97f2282 100644 --- a/src/third_party/wiredtiger/test/suite/test_cursor_random02.py +++ b/src/third_party/wiredtiger/test/suite/test_cursor_random02.py @@ -29,7 +29,7 @@ import wiredtiger, wttest from helper import complex_populate, simple_populate from helper import key_populate, value_populate -from wtscenario import check_scenarios, multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # test_cursor_random02.py # Cursor next_random operations @@ -46,7 +46,7 @@ class test_cursor_random02(wttest.WiredTigerTestCase): ('10000', dict(records=10000)), ('50000', dict(records=50000)), ] - scenarios = number_scenarios(multiply_scenarios('.', config, records)) + scenarios = make_scenarios(config, records) # Check that next_random works in the presence of a larger set of values, # where the values are in an insert list. diff --git a/src/third_party/wiredtiger/test/suite/test_drop.py b/src/third_party/wiredtiger/test/suite/test_drop.py index 52ea7251ab5..a3e80214295 100644 --- a/src/third_party/wiredtiger/test/suite/test_drop.py +++ b/src/third_party/wiredtiger/test/suite/test_drop.py @@ -30,7 +30,7 @@ import os, time import wiredtiger, wttest from helper import confirm_does_not_exist, complex_populate, \ complex_populate_index_name, simple_populate -from wtscenario import check_scenarios +from wtscenario import make_scenarios # test_drop.py # session level drop operation @@ -38,7 +38,7 @@ class test_drop(wttest.WiredTigerTestCase): name = 'test_drop' extra_config = '' - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file', dict(uri='file:')), ('table', dict(uri='table:')), ('table-lsm', dict(uri='table:', extra_config=',type=lsm')), diff --git a/src/third_party/wiredtiger/test/suite/test_dump.py b/src/third_party/wiredtiger/test/suite/test_dump.py index 85196174c1b..280d5870359 100644 --- a/src/third_party/wiredtiger/test/suite/test_dump.py +++ b/src/third_party/wiredtiger/test/suite/test_dump.py @@ -30,9 +30,10 @@ import os, shutil import wiredtiger, wttest from helper import \ complex_populate, complex_populate_check, \ - simple_populate, simple_populate_check + simple_populate, simple_populate_check, \ + simple_index_populate, simple_index_populate_check from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # test_dump.py # Utilities: wt dump @@ -64,6 +65,9 @@ class test_dump(wttest.WiredTigerTestCase, suite_subprocess): ('table-simple', dict(uri='table:', config='', lsm=False, populate=simple_populate, populate_check=simple_populate_check)), + ('table-index', dict(uri='table:', config='', lsm=False, + populate=simple_index_populate, + populate_check=simple_index_populate_check)), ('table-simple-lsm', dict(uri='table:', config='type=lsm', lsm=True, populate=simple_populate, populate_check=simple_populate_check)), @@ -74,8 +78,7 @@ class test_dump(wttest.WiredTigerTestCase, suite_subprocess): populate=complex_populate, populate_check=complex_populate_check)) ] - scenarios = number_scenarios( - multiply_scenarios('.', types, keyfmt, dumpfmt)) + scenarios = make_scenarios(types, keyfmt, dumpfmt) # Extract the values lines from the dump output. def value_lines(self, fname): diff --git a/src/third_party/wiredtiger/test/suite/test_dupc.py b/src/third_party/wiredtiger/test/suite/test_dupc.py index ec55a36df4c..12b18f1ba79 100644 --- a/src/third_party/wiredtiger/test/suite/test_dupc.py +++ b/src/third_party/wiredtiger/test/suite/test_dupc.py @@ -33,7 +33,7 @@ import os, time import wiredtiger, wttest from helper import complex_populate, key_populate, simple_populate -from wtscenario import check_scenarios +from wtscenario import make_scenarios # Test session.open_cursor with cursor duplication. class test_duplicate_cursor(wttest.WiredTigerTestCase): @@ -42,7 +42,7 @@ class test_duplicate_cursor(wttest.WiredTigerTestCase): config = 'key_format=' - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file-r', dict(uri='file:', fmt='r')), ('file-S', dict(uri='file:', fmt='S')), ('table-r', dict(uri='table:', fmt='r')), diff --git a/src/third_party/wiredtiger/test/suite/test_durability01.py b/src/third_party/wiredtiger/test/suite/test_durability01.py index f578a79baf1..32cdd795914 100644 --- a/src/third_party/wiredtiger/test/suite/test_durability01.py +++ b/src/third_party/wiredtiger/test/suite/test_durability01.py @@ -34,7 +34,6 @@ import fnmatch, os, shutil, time from helper import copy_wiredtiger_home from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios, prune_scenarios import wttest class test_durability01(wttest.WiredTigerTestCase, suite_subprocess): diff --git a/src/third_party/wiredtiger/test/suite/test_empty.py b/src/third_party/wiredtiger/test/suite/test_empty.py index 50b79db70e4..9fe88107412 100644 --- a/src/third_party/wiredtiger/test/suite/test_empty.py +++ b/src/third_party/wiredtiger/test/suite/test_empty.py @@ -29,14 +29,14 @@ import os import wiredtiger, wttest from helper import key_populate -from wtscenario import check_scenarios +from wtscenario import make_scenarios # test_empty.py # Test that empty objects don't write anything other than a single sector. class test_empty(wttest.WiredTigerTestCase): name = 'test_empty' - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file-r', dict(type='file:', fmt='r')), ('file-S', dict(type='file:', fmt='S')), ('table-r', dict(type='table:', fmt='r')), diff --git a/src/third_party/wiredtiger/test/suite/test_encrypt01.py b/src/third_party/wiredtiger/test/suite/test_encrypt01.py index 0f2782204d2..d48605aaa83 100644 --- a/src/third_party/wiredtiger/test/suite/test_encrypt01.py +++ b/src/third_party/wiredtiger/test/suite/test_encrypt01.py @@ -32,7 +32,7 @@ import os, run, random import wiredtiger, wttest -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # Test basic encryption class test_encrypt01(wttest.WiredTigerTestCase): @@ -60,8 +60,7 @@ class test_encrypt01(wttest.WiredTigerTestCase): ('none-snappy', dict(log_compress=None, block_compress='snappy')), ('snappy-lz4', dict(log_compress='snappy', block_compress='lz4')), ] - scenarios = number_scenarios(multiply_scenarios('.', types, - encrypt, compress)) + scenarios = make_scenarios(types, encrypt, compress) nrecords = 5000 bigvalue = "abcdefghij" * 1001 # len(bigvalue) = 10010 diff --git a/src/third_party/wiredtiger/test/suite/test_encrypt02.py b/src/third_party/wiredtiger/test/suite/test_encrypt02.py index 0376b3e42e4..648686274c4 100644 --- a/src/third_party/wiredtiger/test/suite/test_encrypt02.py +++ b/src/third_party/wiredtiger/test/suite/test_encrypt02.py @@ -33,7 +33,7 @@ import os, run, random import wiredtiger, wttest from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # Test basic encryption class test_encrypt02(wttest.WiredTigerTestCase, suite_subprocess): @@ -48,7 +48,7 @@ class test_encrypt02(wttest.WiredTigerTestCase, suite_subprocess): ('keyid-pass', dict( encrypt='rotn', encrypt_args='name=rotn,keyid=11', secret_arg='ABC')), ] - scenarios = number_scenarios(encrypt_type) + scenarios = make_scenarios(encrypt_type) nrecords = 5000 bigvalue = "abcdefghij" * 1001 # len(bigvalue) = 10010 diff --git a/src/third_party/wiredtiger/test/suite/test_encrypt03.py b/src/third_party/wiredtiger/test/suite/test_encrypt03.py index 702d0a2369f..0dc1755d6eb 100644 --- a/src/third_party/wiredtiger/test/suite/test_encrypt03.py +++ b/src/third_party/wiredtiger/test/suite/test_encrypt03.py @@ -32,7 +32,7 @@ import os, run, random import wiredtiger, wttest -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # Test basic encryption class test_encrypt03(wttest.WiredTigerTestCase): @@ -48,7 +48,7 @@ class test_encrypt03(wttest.WiredTigerTestCase): #('noname', dict( sys_encrypt='rotn', sys_encrypt_args=',keyid=11', # file_encrypt='none', file_encrypt_args=',keyid=13')), ] - scenarios = number_scenarios(multiply_scenarios('.', types, encrypt)) + scenarios = make_scenarios(types, encrypt) # Override WiredTigerTestCase, we have extensions. def setUpConnectionOpen(self, dir): diff --git a/src/third_party/wiredtiger/test/suite/test_encrypt04.py b/src/third_party/wiredtiger/test/suite/test_encrypt04.py index d7c12d2cba8..97d2cee03a0 100644 --- a/src/third_party/wiredtiger/test/suite/test_encrypt04.py +++ b/src/third_party/wiredtiger/test/suite/test_encrypt04.py @@ -32,7 +32,7 @@ import os, run, random import wiredtiger, wttest -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios from suite_subprocess import suite_subprocess # Test basic encryption with mismatched configuration @@ -69,8 +69,7 @@ class test_encrypt04(wttest.WiredTigerTestCase, suite_subprocess): ('rotn11xyz_and_clear', dict( name2='rotn', keyid2='11', secretkey2='XYZ', fileinclear2=True)) ] - scenarios = number_scenarios(multiply_scenarios \ - ('.', encrypt_scen_1, encrypt_scen_2)) + scenarios = make_scenarios(encrypt_scen_1, encrypt_scen_2) nrecords = 5000 bigvalue = "abcdefghij" * 1001 # len(bigvalue) = 10010 diff --git a/src/third_party/wiredtiger/test/suite/test_encrypt05.py b/src/third_party/wiredtiger/test/suite/test_encrypt05.py index afd8a8103f9..19a3522b3d5 100644 --- a/src/third_party/wiredtiger/test/suite/test_encrypt05.py +++ b/src/third_party/wiredtiger/test/suite/test_encrypt05.py @@ -32,7 +32,7 @@ import os, run, random import wiredtiger, wttest -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # Test raw compression with encryption class test_encrypt05(wttest.WiredTigerTestCase): @@ -44,8 +44,7 @@ class test_encrypt05(wttest.WiredTigerTestCase): compress = [ ('zlib', dict(log_compress='zlib', block_compress='zlib')), ] - scenarios = number_scenarios(multiply_scenarios('.', - encrypt, compress)) + scenarios = make_scenarios(encrypt, compress) nrecords = 500 bigvalue = 'a' * 500 # we use values that will definitely give compression diff --git a/src/third_party/wiredtiger/test/suite/test_encrypt06.py b/src/third_party/wiredtiger/test/suite/test_encrypt06.py index 5c88b698aeb..9300583d099 100644 --- a/src/third_party/wiredtiger/test/suite/test_encrypt06.py +++ b/src/third_party/wiredtiger/test/suite/test_encrypt06.py @@ -32,7 +32,7 @@ import os, run, random import wiredtiger, wttest -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # Test encryption, when on, does not leak any information class test_encrypt06(wttest.WiredTigerTestCase): @@ -86,7 +86,7 @@ class test_encrypt06(wttest.WiredTigerTestCase): file0_encrypt='rotn', file0_encrypt_args=key13, encrypt0=True, file1_encrypt='none', file1_encrypt_args='', encrypt1=False)), ] - scenarios = number_scenarios(multiply_scenarios('.', encrypt, storagetype)) + scenarios = make_scenarios(encrypt, storagetype) nrecords = 1000 # Override WiredTigerTestCase, we have extensions. diff --git a/src/third_party/wiredtiger/test/suite/test_encrypt07.py b/src/third_party/wiredtiger/test/suite/test_encrypt07.py index 30f28e096a8..97ab1987d4f 100644 --- a/src/third_party/wiredtiger/test/suite/test_encrypt07.py +++ b/src/third_party/wiredtiger/test/suite/test_encrypt07.py @@ -32,7 +32,6 @@ import os, run, string, codecs import wiredtiger, wttest -from wtscenario import multiply_scenarios, number_scenarios import test_salvage # Run the regular salvage test, but with encryption on diff --git a/src/third_party/wiredtiger/test/suite/test_excl.py b/src/third_party/wiredtiger/test/suite/test_excl.py index 90926f51877..cea5756dfbb 100644 --- a/src/third_party/wiredtiger/test/suite/test_excl.py +++ b/src/third_party/wiredtiger/test/suite/test_excl.py @@ -27,11 +27,11 @@ # OTHER DEALINGS IN THE SOFTWARE. import wiredtiger, wttest -from wtscenario import check_scenarios +from wtscenario import make_scenarios # Test session.create with the exclusive configuration. class test_create_excl(wttest.WiredTigerTestCase): - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file', dict(type='file:')), ('table', dict(type='table:')) ]) diff --git a/src/third_party/wiredtiger/test/suite/test_huffman01.py b/src/third_party/wiredtiger/test/suite/test_huffman01.py index d71198e3151..be307550f2e 100644 --- a/src/third_party/wiredtiger/test/suite/test_huffman01.py +++ b/src/third_party/wiredtiger/test/suite/test_huffman01.py @@ -28,7 +28,7 @@ import os from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios import wiredtiger, wttest # test_huffman01.py @@ -52,7 +52,7 @@ class test_huffman01(wttest.WiredTigerTestCase, suite_subprocess): ('utf8', dict(huffval=',huffman_value=utf8t8file',vfile='t8file')), ('utf16', dict(huffval=',huffman_value=utf16t16file',vfile='t16file')), ] - scenarios = number_scenarios(multiply_scenarios('.', huffkey, huffval)) + scenarios = make_scenarios(huffkey, huffval) def test_huffman(self): dir = self.conn.get_home() diff --git a/src/third_party/wiredtiger/test/suite/test_huffman02.py b/src/third_party/wiredtiger/test/suite/test_huffman02.py index aa4329415a4..d74704daf58 100644 --- a/src/third_party/wiredtiger/test/suite/test_huffman02.py +++ b/src/third_party/wiredtiger/test/suite/test_huffman02.py @@ -28,7 +28,7 @@ import os from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios import wiredtiger, wttest # test_huffman02.py @@ -48,7 +48,7 @@ class test_huffman02(wttest.WiredTigerTestCase, suite_subprocess): ('file', dict(uri='file:huff')), ('table', dict(uri='table:huff')), ] - scenarios = number_scenarios(multiply_scenarios('.',type,huffkey, huffval)) + scenarios = make_scenarios(type, huffkey, huffval) def test_huffman(self): if self.keybad or self.valbad: diff --git a/src/third_party/wiredtiger/test/suite/test_index02.py b/src/third_party/wiredtiger/test/suite/test_index02.py new file mode 100644 index 00000000000..9f39df003b1 --- /dev/null +++ b/src/third_party/wiredtiger/test/suite/test_index02.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python +# +# Public Domain 2014-2016 MongoDB, Inc. +# Public Domain 2008-2014 WiredTiger, Inc. +# +# This is free and unencumbered software released into the public domain. +# +# Anyone is free to copy, modify, publish, use, compile, sell, or +# distribute this software, either in source code form or as a compiled +# binary, for any purpose, commercial or non-commercial, and by any +# means. +# +# In jurisdictions that recognize copyright laws, the author or authors +# of this software dedicate any and all copyright interest in the +# software to the public domain. We make this dedication for the benefit +# of the public at large and to the detriment of our heirs and +# successors. We intend this dedication to be an overt act of +# relinquishment in perpetuity of all present and future rights to this +# software under copyright law. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +import wiredtiger, wttest + +# test_index02.py +# test search_near in indices +class test_index02(wttest.WiredTigerTestCase): + '''Test search_near in indices''' + + basename = 'test_index02' + tablename = 'table:' + basename + indexname = 'index:' + basename + ":inverse" + + def test_search_near(self): + '''Create a table, look for a nonexistent key''' + self.session.create(self.tablename, 'key_format=r,value_format=Q,columns=(k,v)') + self.session.create(self.indexname, 'columns=(v)') + cur = self.session.open_cursor(self.tablename, None, "append") + cur.set_value(1) + cur.insert() + cur.set_value(5) + cur.insert() + cur.set_value(5) + cur.insert() + cur.set_value(5) + cur.insert() + cur.set_value(10) + cur.insert() + + # search near should find a match + cur2 = self.session.open_cursor(self.indexname, None, None) + cur2.set_key(5) + self.assertEqual(cur2.search_near(), 0) + + # Retry after reopening + self.reopen_conn() + cur3 = self.session.open_cursor(self.indexname, None, None) + cur3.set_key(5) + self.assertEqual(cur3.search_near(), 0) + +if __name__ == '__main__': + wttest.run() diff --git a/src/third_party/wiredtiger/test/suite/test_inmem01.py b/src/third_party/wiredtiger/test/suite/test_inmem01.py index 875ebb2bfa7..c6ae7ff6c4b 100644 --- a/src/third_party/wiredtiger/test/suite/test_inmem01.py +++ b/src/third_party/wiredtiger/test/suite/test_inmem01.py @@ -30,95 +30,73 @@ import wiredtiger, wttest from time import sleep from helper import simple_populate, simple_populate_check from helper import key_populate, value_populate -from wtscenario import check_scenarios +from wtscenario import make_scenarios # test_inmem01.py # Test in-memory configuration. class test_inmem01(wttest.WiredTigerTestCase): - name = 'inmem01' - """ - In memory configuration still creates files on disk, but has limits - in terms of how much data can be written. - Test various scenarios including: - - Add a small amount of data, ensure it is present. - - Add more data than would fit into the configured cache. - - Fill the cache with data, remove some data, ensure more data can be - inserted (after a reasonable amount of time for space to be reclaimed) - - Run queries after adding, removing and re-inserting data. - - Try out keeping a cursor open while adding new data. - """ - scenarios = check_scenarios([ - ('col', dict(tablekind='col')), - # Fixed length is very slow, disable it for now - #('fix', dict(tablekind='fix')), - ('row', dict(tablekind='row')) - ]) - - # create an in-memory database - conn_config = 'cache_size=5MB,' + \ - 'file_manager=(close_idle_time=0),in_memory=true' + uri = 'table:inmem01' + conn_config = \ + 'cache_size=5MB,file_manager=(close_idle_time=0),in_memory=true' + table_config = ',memory_page_max=32k,leaf_page_max=4k' - def get_table_config(self): - kf = 'key_format=' - vf = 'value_format=' - if self.tablekind == 'row': - kf = kf + 'S' - else: - kf = kf + 'r' # record format - if self.tablekind == 'fix': - vf = vf + '8t' - else: - vf = vf + 'S' - return 'memory_page_max=32k,leaf_page_max=4k,' + kf + ',' + vf + scenarios = make_scenarios([ + ('col', dict(fmt='key_format=r,value_format=S')), + ('fix', dict(fmt='key_format=r,value_format=8t')), + ('row', dict(fmt='key_format=S,value_format=S')) + ]) + # Smoke-test in-memory configurations, add a small amount of data and + # ensure it's visible. def test_insert(self): - table_config = self.get_table_config() - simple_populate(self, - "table:" + self.name, table_config, 1000) - # Ensure the data is visible. - simple_populate_check(self, 'table:' + self.name, 1000) + config = self.fmt + self.table_config + simple_populate(self, self.uri, config, 1000) + simple_populate_check(self, self.uri, 1000) + # Add more data than fits into the configured cache and verify it fails. def test_insert_over_capacity(self): - table_config = self.get_table_config() + config = self.fmt + self.table_config msg = '/WT_CACHE_FULL.*/' self.assertRaisesHavingMessage(wiredtiger.WiredTigerError, - lambda:simple_populate(self, - "table:" + self.name, table_config, 10000000), msg) + lambda:simple_populate(self, self.uri, config, 10000000), msg) - # Figure out the last key we inserted. - cursor = self.session.open_cursor('table:' + self.name, None) + # Figure out the last key we successfully inserted, and check all + # previous inserts are still there. + cursor = self.session.open_cursor(self.uri, None) cursor.prev() last_key = int(cursor.get_key()) - simple_populate_check(self, 'table:' + self.name, last_key) + simple_populate_check(self, self.uri, last_key) + # Fill the cache with data, remove some data, ensure more data can be + # inserted (after a reasonable amount of time for space to be reclaimed). def test_insert_over_delete(self): - table_config = self.get_table_config() + config = self.fmt + self.table_config msg = '/WT_CACHE_FULL.*/' self.assertRaisesHavingMessage(wiredtiger.WiredTigerError, - lambda:simple_populate(self, - "table:" + self.name, table_config, 10000000), msg) + lambda:simple_populate(self, self.uri, config, 10000000), msg) # Now that the database contains as much data as will fit into # the configured cache, verify removes succeed. - cursor = self.session.open_cursor('table:' + self.name, None) + cursor = self.session.open_cursor(self.uri, None) for i in range(1, 100): cursor.set_key(key_populate(cursor, i)) cursor.remove() + # Run queries after adding, removing and re-inserting data. + # Try out keeping a cursor open while adding new data. def test_insert_over_delete_replace(self): - table_config = self.get_table_config() + config = self.fmt + self.table_config msg = '/WT_CACHE_FULL.*/' self.assertRaisesHavingMessage(wiredtiger.WiredTigerError, - lambda:simple_populate(self, - "table:" + self.name, table_config, 10000000), msg) + lambda:simple_populate(self, self.uri, config, 10000000), msg) - cursor = self.session.open_cursor('table:' + self.name, None) + cursor = self.session.open_cursor(self.uri, None) cursor.prev() last_key = int(cursor.get_key()) # Now that the database contains as much data as will fit into # the configured cache, verify removes succeed. - cursor = self.session.open_cursor('table:' + self.name, None) + cursor = self.session.open_cursor(self.uri, None) for i in range(1, last_key / 4, 1): cursor.set_key(key_populate(cursor, i)) cursor.remove() diff --git a/src/third_party/wiredtiger/test/suite/test_intpack.py b/src/third_party/wiredtiger/test/suite/test_intpack.py index 187b2d7f579..b0cece09494 100644 --- a/src/third_party/wiredtiger/test/suite/test_intpack.py +++ b/src/third_party/wiredtiger/test/suite/test_intpack.py @@ -31,7 +31,7 @@ # import wiredtiger, wttest -from wtscenario import check_scenarios, number_scenarios +from wtscenario import make_scenarios class PackTester: def __init__(self, formatcode, validlow, validhigh, equals): @@ -126,22 +126,27 @@ class PackTester: class test_intpack(wttest.WiredTigerTestCase): name = 'test_intpack' - scenarios = check_scenarios([ - ('b', dict(formatcode='b', low=-128, high=127, nbits=8)), - ('B', dict(formatcode='B', low=0, high=255, nbits=8)), - ('8t', dict(formatcode='8t', low=0, high=255, nbits=8)), - ('5t', dict(formatcode='5t', low=0, high=31, nbits=5)), - ('h', dict(formatcode='h', low=-32768, high=32767, nbits=16)), - ('H', dict(formatcode='H', low=0, high=65535, nbits=16)), - ('i', dict(formatcode='i', low=-2147483648, high=2147483647, nbits=32)), - ('I', dict(formatcode='I', low=0, high=4294967295, nbits=32)), - ('l', dict(formatcode='l', low=-2147483648, high=2147483647, nbits=32)), - ('L', dict(formatcode='L', low=0, high=4294967295, nbits=32)), - ('q', dict(formatcode='q', low=-9223372036854775808, + # We have to be a bit verbose here with naming, as there can be problems with + # case insensitive test names:w + + scenarios = make_scenarios([ + ('int8_t_b', dict(formatcode='b', low=-128, high=127, nbits=8)), + ('uint8_t_B', dict(formatcode='B', low=0, high=255, nbits=8)), + ('fix_len_8t', dict(formatcode='8t', low=0, high=255, nbits=8)), + ('fix_len_5t', dict(formatcode='5t', low=0, high=31, nbits=5)), + ('int16_t_h', dict(formatcode='h', low=-32768, high=32767, nbits=16)), + ('uint16_t_H', dict(formatcode='H', low=0, high=65535, nbits=16)), + ('int32_t_i', dict(formatcode='i', low=-2147483648, high=2147483647, + nbits=32)), + ('uint32_t_I', dict(formatcode='I', low=0, high=4294967295, nbits=32)), + ('int32_t_l', dict(formatcode='l', low=-2147483648, high=2147483647, + nbits=32)), + ('uint32_t_L', dict(formatcode='L', low=0, high=4294967295, nbits=32)), + ('int64_t_q', dict(formatcode='q', low=-9223372036854775808, high=9223372036854775807, nbits=64)), - ('Q', dict(formatcode='Q', low=0, high=18446744073709551615, nbits=64)), + ('uint64_t_Q', dict(formatcode='Q', low=0, high=18446744073709551615, + nbits=64)), ]) - scenarios = check_scenarios(number_scenarios(scenarios)) def test_packing(self): pt = PackTester(self.formatcode, self.low, self.high, self.assertEquals) diff --git a/src/third_party/wiredtiger/test/suite/test_join01.py b/src/third_party/wiredtiger/test/suite/test_join01.py index f8d96a2718a..f3b13026896 100644 --- a/src/third_party/wiredtiger/test/suite/test_join01.py +++ b/src/third_party/wiredtiger/test/suite/test_join01.py @@ -27,7 +27,7 @@ # OTHER DEALINGS IN THE SOFTWARE. import wiredtiger, wttest -from wtscenario import check_scenarios, multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # test_join01.py # Join operations @@ -67,11 +67,9 @@ class test_join01(wttest.WiredTigerTestCase): ('order=2', dict(join_order=2)), ('order=3', dict(join_order=3)), ] - scenarios = number_scenarios(multiply_scenarios('.', type_scen, - bloom0_scen, bloom1_scen, - projection_scen, - nested_scen, stats_scen, - order_scen)) + scenarios = make_scenarios(type_scen, bloom0_scen, bloom1_scen, + projection_scen, nested_scen, stats_scen, + order_scen) # We need statistics for these tests. conn_config = 'statistics=(all)' diff --git a/src/third_party/wiredtiger/test/suite/test_join02.py b/src/third_party/wiredtiger/test/suite/test_join02.py index a691c499cf6..db11ed01039 100644 --- a/src/third_party/wiredtiger/test/suite/test_join02.py +++ b/src/third_party/wiredtiger/test/suite/test_join02.py @@ -27,7 +27,7 @@ # OTHER DEALINGS IN THE SOFTWARE. import wiredtiger, wttest, suite_random -from wtscenario import check_scenarios, multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # test_join02.py # Join operations @@ -48,7 +48,7 @@ class test_join02(wttest.WiredTigerTestCase): ('nobloom', dict(usebloom=False)) ] - scenarios = number_scenarios(multiply_scenarios('.', keyscen, bloomscen)) + scenarios = make_scenarios(keyscen, bloomscen) # Start our range from 1, since WT record numbers start at 1, # it makes things work out nicer. diff --git a/src/third_party/wiredtiger/test/suite/test_join03.py b/src/third_party/wiredtiger/test/suite/test_join03.py index 613d2396b07..af19d934d70 100644 --- a/src/third_party/wiredtiger/test/suite/test_join03.py +++ b/src/third_party/wiredtiger/test/suite/test_join03.py @@ -28,7 +28,6 @@ import os import wiredtiger, wttest, run -from wtscenario import check_scenarios, multiply_scenarios, number_scenarios # test_join03.py # Join operations diff --git a/src/third_party/wiredtiger/test/suite/test_join04.py b/src/third_party/wiredtiger/test/suite/test_join04.py index 7e2afb15285..b270cb7a21c 100644 --- a/src/third_party/wiredtiger/test/suite/test_join04.py +++ b/src/third_party/wiredtiger/test/suite/test_join04.py @@ -28,7 +28,6 @@ import os import wiredtiger, wttest, run -from wtscenario import check_scenarios, multiply_scenarios, number_scenarios # test_join04.py # Join operations diff --git a/src/third_party/wiredtiger/test/suite/test_join05.py b/src/third_party/wiredtiger/test/suite/test_join05.py index ef2be4c6460..7dcb3e08911 100644 --- a/src/third_party/wiredtiger/test/suite/test_join05.py +++ b/src/third_party/wiredtiger/test/suite/test_join05.py @@ -27,7 +27,6 @@ # OTHER DEALINGS IN THE SOFTWARE. import wiredtiger, wttest -from wtscenario import check_scenarios, multiply_scenarios, number_scenarios # test_join05.py # Tests based on JIRA reports diff --git a/src/third_party/wiredtiger/test/suite/test_join06.py b/src/third_party/wiredtiger/test/suite/test_join06.py index 9af6f93792f..a6681cdccd0 100644 --- a/src/third_party/wiredtiger/test/suite/test_join06.py +++ b/src/third_party/wiredtiger/test/suite/test_join06.py @@ -28,7 +28,7 @@ import os import wiredtiger, wttest, run -from wtscenario import check_scenarios, multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # test_join06.py # Join operations @@ -37,8 +37,10 @@ class test_join06(wttest.WiredTigerTestCase): nentries = 1000 isoscen = [ - ('isolation_read_uncommitted', dict(uncommitted=True)), - ('isolation_default', dict(uncommitted=False)) + ('isolation_read_uncommitted', dict(isolation='read-uncommitted')), + ('isolation_read_committed', dict(isolation='read-committed')), + ('isolation_default', dict(isolation='')), + ('isolation_snapshot', dict(isolation='snapshot')) ] bloomscen = [ @@ -46,7 +48,7 @@ class test_join06(wttest.WiredTigerTestCase): ('nobloom', dict(bloom=False)) ] - scenarios = number_scenarios(multiply_scenarios('.', isoscen, bloomscen)) + scenarios = make_scenarios(isoscen, bloomscen) def gen_values(self, i): s = str(i) # 345 => "345" @@ -79,8 +81,8 @@ class test_join06(wttest.WiredTigerTestCase): # TODO: needed? #self.reopen_conn() - if self.uncommitted: - self.session.begin_transaction('isolation=read-uncommitted') + if self.isolation != '': + self.session.begin_transaction('isolation=' + self.isolation) jc = self.session.open_cursor('join:table:join06', None, None) c0 = self.session.open_cursor('index:join06:index0', None, None) @@ -96,7 +98,7 @@ class test_join06(wttest.WiredTigerTestCase): self.assertEquals(0, c1.search()) self.session.join(jc, c1, joinconfig) - if self.uncommitted and self.bloom: + if self.isolation == 'read-uncommitted' and self.bloom: # Make sure that read-uncommitted with Bloom is not allowed. # This is detected on the first next() operation. msg = '/cannot be used with read-uncommitted/' @@ -106,7 +108,7 @@ class test_join06(wttest.WiredTigerTestCase): # Changes made in another session may or may not be visible to us, # depending on the isolation level. - if self.uncommitted: + if self.isolation == 'read-uncommitted': # isolation level is read-uncommitted, so we will see # additions deletions made in our other session. mbr = set(range(525,1000,10)) | set(range(55,100,10)) | set([520]) @@ -116,12 +118,11 @@ class test_join06(wttest.WiredTigerTestCase): mbr = set(range(520,600)) | set(range(53,60)) altered = False - while jc.next() == 0: [k] = jc.get_keys() [v0,v1] = jc.get_values() #self.tty('GOT: ' + str(k) + ': ' + str(jc.get_values())) - if altered and self.uncommitted: + if altered and self.isolation == 'read-uncommitted': self.assertEquals(self.gen_values2(k), [v0, v1]) else: self.assertEquals(self.gen_values(k), [v0, v1]) @@ -150,7 +151,7 @@ class test_join06(wttest.WiredTigerTestCase): jc.close() c1.close() c0.close() - if self.uncommitted: + if self.isolation != '': self.session.commit_transaction() self.session.drop('table:join06') diff --git a/src/third_party/wiredtiger/test/suite/test_join07.py b/src/third_party/wiredtiger/test/suite/test_join07.py index 36e91361329..2a32e678d72 100644 --- a/src/third_party/wiredtiger/test/suite/test_join07.py +++ b/src/third_party/wiredtiger/test/suite/test_join07.py @@ -28,7 +28,7 @@ import os, re, run import wiredtiger, wttest, suite_random -from wtscenario import check_scenarios, multiply_scenarios, number_scenarios +from wtscenario import make_scenarios class ParseException(Exception): def __init__(self, msg): @@ -198,7 +198,7 @@ class test_join07(wttest.WiredTigerTestCase): ('noextractor', dict(extractor=False)) ] - scenarios = number_scenarios(extractscen) + scenarios = make_scenarios(extractscen) # Return the wiredtiger_open extension argument for a shared library. def extensionArg(self, exts): diff --git a/src/third_party/wiredtiger/test/suite/test_join08.py b/src/third_party/wiredtiger/test/suite/test_join08.py index 6d674ab8193..d389fad706b 100644 --- a/src/third_party/wiredtiger/test/suite/test_join08.py +++ b/src/third_party/wiredtiger/test/suite/test_join08.py @@ -27,7 +27,6 @@ # OTHER DEALINGS IN THE SOFTWARE. import wiredtiger, wttest -from wtscenario import check_scenarios, multiply_scenarios, number_scenarios # test_join08.py # Test join error paths diff --git a/src/third_party/wiredtiger/test/suite/test_jsondump01.py b/src/third_party/wiredtiger/test/suite/test_jsondump01.py index 10262edc777..dc8027c2115 100644 --- a/src/third_party/wiredtiger/test/suite/test_jsondump01.py +++ b/src/third_party/wiredtiger/test/suite/test_jsondump01.py @@ -29,10 +29,12 @@ import os, json import wiredtiger, wttest from helper import \ - complex_populate, complex_populate_check_cursor,\ - simple_populate, simple_populate_check_cursor + complex_populate, complex_populate_check, complex_populate_check_cursor,\ + simple_populate, simple_populate_check, simple_populate_check_cursor, \ + simple_index_populate, simple_index_populate_check, \ + simple_index_populate_check_cursor, compare_files from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # A 'fake' cursor based on a set of rows. # It emulates a WT cursor well enough for the *_check_cursor methods. @@ -79,25 +81,34 @@ class test_jsondump01(wttest.WiredTigerTestCase, suite_subprocess): types = [ ('file', dict(uri='file:', config='', lsm=False, populate=simple_populate, - populate_check=simple_populate_check_cursor)), + populate_check=simple_populate_check, + populate_check_cursor=simple_populate_check_cursor)), ('lsm', dict(uri='lsm:', config='', lsm=True, populate=simple_populate, - populate_check=simple_populate_check_cursor)), + populate_check=simple_populate_check, + populate_check_cursor=simple_populate_check_cursor)), ('table-simple', dict(uri='table:', config='', lsm=False, populate=simple_populate, - populate_check=simple_populate_check_cursor)), + populate_check=simple_populate_check, + populate_check_cursor=simple_populate_check_cursor)), + ('table-index', dict(uri='table:', config='', lsm=False, + populate=simple_index_populate, + populate_check=simple_index_populate_check, + populate_check_cursor=simple_index_populate_check_cursor)), ('table-simple-lsm', dict(uri='table:', config='type=lsm', lsm=True, populate=simple_populate, - populate_check=simple_populate_check_cursor)), + populate_check=simple_populate_check, + populate_check_cursor=simple_populate_check_cursor)), ('table-complex', dict(uri='table:', config='', lsm=False, populate=complex_populate, - populate_check=complex_populate_check_cursor)), + populate_check=complex_populate_check, + populate_check_cursor=complex_populate_check_cursor)), ('table-complex-lsm', dict(uri='table:', config='type=lsm', lsm=True, populate=complex_populate, - populate_check=complex_populate_check_cursor)) + populate_check=complex_populate_check, + populate_check_cursor=complex_populate_check_cursor)) ] - scenarios = number_scenarios( - multiply_scenarios('.', types, keyfmt)) + scenarios = make_scenarios(types, keyfmt) # Dump using util, re-load using python's JSON, and do a content comparison. def test_jsondump_util(self): @@ -132,7 +143,7 @@ class test_jsondump01(wttest.WiredTigerTestCase, suite_subprocess): cursor = self.session.open_cursor(uri, None) fake = FakeCursor(cursor.key_format, cursor.value_format, data) cursor.close() - self.populate_check(self, fake, self.nentries) + self.populate_check_cursor(self, fake, self.nentries) # Dump using util, re-load using python's JSON, and do a content comparison. def test_jsonload_util(self): @@ -153,9 +164,18 @@ class test_jsondump01(wttest.WiredTigerTestCase, suite_subprocess): loadcmd.append('-a') self.runWt(loadcmd) - # check the contents of the data we read. - cursor = self.session.open_cursor(uri2, None) - self.populate_check(self, cursor, self.nentries) + # Check the contents of the data we read. + self.populate_check(self, uri2, self.nentries) + + # Reload into the original uri, and dump into another file. + self.session.drop(uri, None) + self.session.drop(uri2, None) + self.runWt(['load', '-jf', 'jsondump.out']) + self.runWt(['dump', '-j', uri], outfilename='jsondump2.out') + + # Compare the two outputs, and check the content again. + compare_files(self, 'jsondump.out', 'jsondump2.out') + self.populate_check(self, uri, self.nentries) if __name__ == '__main__': wttest.run() diff --git a/src/third_party/wiredtiger/test/suite/test_lsm01.py b/src/third_party/wiredtiger/test/suite/test_lsm01.py index 1f89cf38d77..f6cee20e896 100644 --- a/src/third_party/wiredtiger/test/suite/test_lsm01.py +++ b/src/third_party/wiredtiger/test/suite/test_lsm01.py @@ -54,12 +54,10 @@ class test_lsm01(wttest.WiredTigerTestCase): config_vars = [ 'chunk_size', 'merge_max', 'bloom', 'bloom_bit_count', 'bloom_hash_count' ] - all_scenarios = wtscenario.multiply_scenarios('_', + scenarios = wtscenario.make_scenarios( chunk_size_scenarios, merge_max_scenarios, bloom_scenarios, - bloom_bit_scenarios, bloom_hash_scenarios, record_count_scenarios) - - scenarios = wtscenario.prune_scenarios(all_scenarios, 500) - scenarios = wtscenario.number_scenarios(scenarios) + bloom_bit_scenarios, bloom_hash_scenarios, record_count_scenarios, + prune=500) # Test drop of an object. def test_lsm(self): diff --git a/src/third_party/wiredtiger/test/suite/test_metadata_cursor01.py b/src/third_party/wiredtiger/test/suite/test_metadata_cursor01.py index e759c14f846..7802f89f174 100644 --- a/src/third_party/wiredtiger/test/suite/test_metadata_cursor01.py +++ b/src/third_party/wiredtiger/test/suite/test_metadata_cursor01.py @@ -27,7 +27,7 @@ # OTHER DEALINGS IN THE SOFTWARE. import wiredtiger, wttest -from wtscenario import check_scenarios +from wtscenario import make_scenarios # test_metadata_cursor01.py # Metadata cursor operations @@ -39,7 +39,7 @@ class test_metadata_cursor01(wttest.WiredTigerTestCase): """ table_name1 = 'test_metadata_cursor01' - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('plain', {'metauri' : 'metadata:'}), ('create', {'metauri' : 'metadata:create'}), ]) diff --git a/src/third_party/wiredtiger/test/suite/test_nsnap01.py b/src/third_party/wiredtiger/test/suite/test_nsnap01.py index 5207b577ba4..7e8951750f8 100644 --- a/src/third_party/wiredtiger/test/suite/test_nsnap01.py +++ b/src/third_party/wiredtiger/test/suite/test_nsnap01.py @@ -30,7 +30,6 @@ # Named snapshots: basic API from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios from helper import simple_populate import wiredtiger, wttest diff --git a/src/third_party/wiredtiger/test/suite/test_nsnap02.py b/src/third_party/wiredtiger/test/suite/test_nsnap02.py index e4ed65ef72a..510c9d421ef 100644 --- a/src/third_party/wiredtiger/test/suite/test_nsnap02.py +++ b/src/third_party/wiredtiger/test/suite/test_nsnap02.py @@ -30,7 +30,6 @@ # Named snapshots: Combinations of dropping snapshots from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios from helper import simple_populate import wiredtiger, wttest diff --git a/src/third_party/wiredtiger/test/suite/test_nsnap03.py b/src/third_party/wiredtiger/test/suite/test_nsnap03.py index 0e853522940..3986c0c1a0a 100644 --- a/src/third_party/wiredtiger/test/suite/test_nsnap03.py +++ b/src/third_party/wiredtiger/test/suite/test_nsnap03.py @@ -30,7 +30,6 @@ # Named snapshots: Access and create from multiple sessions from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios from helper import simple_populate import wiredtiger, wttest diff --git a/src/third_party/wiredtiger/test/suite/test_nsnap04.py b/src/third_party/wiredtiger/test/suite/test_nsnap04.py index e8a5c9b6140..f9ef26b5600 100644 --- a/src/third_party/wiredtiger/test/suite/test_nsnap04.py +++ b/src/third_party/wiredtiger/test/suite/test_nsnap04.py @@ -30,7 +30,6 @@ # Named snapshots: Create snapshot from running transaction from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios from helper import simple_populate import wiredtiger, wttest diff --git a/src/third_party/wiredtiger/test/suite/test_overwrite.py b/src/third_party/wiredtiger/test/suite/test_overwrite.py index e22cdab4dea..4972a016bec 100644 --- a/src/third_party/wiredtiger/test/suite/test_overwrite.py +++ b/src/third_party/wiredtiger/test/suite/test_overwrite.py @@ -28,13 +28,13 @@ import wiredtiger, wttest from helper import key_populate, simple_populate -from wtscenario import check_scenarios +from wtscenario import make_scenarios # test_overwrite.py # cursor overwrite configuration method class test_overwrite(wttest.WiredTigerTestCase): name = 'overwrite' - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file-r', dict(type='file:',keyfmt='r')), ('file-S', dict(type='file:',keyfmt='S')), ('lsm-S', dict(type='lsm:',keyfmt='S')), diff --git a/src/third_party/wiredtiger/test/suite/test_perf001.py b/src/third_party/wiredtiger/test/suite/test_perf001.py index 1280639c9dd..b22ed2baeb0 100644 --- a/src/third_party/wiredtiger/test/suite/test_perf001.py +++ b/src/third_party/wiredtiger/test/suite/test_perf001.py @@ -32,13 +32,13 @@ import wiredtiger, wttest import random from time import clock, time -from wtscenario import check_scenarios +from wtscenario import make_scenarios # Test performance of inserting into a table with an index. class test_perf001(wttest.WiredTigerTestCase): table_name = 'test_perf001' - scenarios = check_scenarios([ + scenarios = make_scenarios([ #('file-file', dict(tabletype='file',indextype='file')), ('file-lsm', dict(tabletype='file',indextype='lsm')), #('lsm-file', dict(tabletype='lsm',indextype='file')), diff --git a/src/third_party/wiredtiger/test/suite/test_readonly01.py b/src/third_party/wiredtiger/test/suite/test_readonly01.py index 59e9743ab7e..e4b431ca1da 100644 --- a/src/third_party/wiredtiger/test/suite/test_readonly01.py +++ b/src/third_party/wiredtiger/test/suite/test_readonly01.py @@ -32,7 +32,7 @@ import fnmatch, os, shutil, time from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios, prune_scenarios +from wtscenario import make_scenarios import wttest class test_readonly01(wttest.WiredTigerTestCase, suite_subprocess): @@ -73,8 +73,7 @@ class test_readonly01(wttest.WiredTigerTestCase, suite_subprocess): create_params = 'key_format=r,value_format=8t')), ] - scenarios = multiply_scenarios('.', - basecfg_list, dir_list, log_list, types) + scenarios = make_scenarios(basecfg_list, dir_list, log_list, types) def conn_config(self, dir): self.home = dir diff --git a/src/third_party/wiredtiger/test/suite/test_rebalance.py b/src/third_party/wiredtiger/test/suite/test_rebalance.py index f2167e864c9..98bd81de602 100644 --- a/src/third_party/wiredtiger/test/suite/test_rebalance.py +++ b/src/third_party/wiredtiger/test/suite/test_rebalance.py @@ -29,7 +29,7 @@ import os, time import wiredtiger, wttest from helper import complex_populate, simple_populate -from wtscenario import check_scenarios +from wtscenario import make_scenarios # test_rebalance.py # session level rebalance operation @@ -41,7 +41,7 @@ class test_rebalance(wttest.WiredTigerTestCase): config = 'key_format=S,allocation_size=512,internal_page_max=512' + \ ',leaf_page_max=1k,lsm=(chunk_size=512k,merge_min=10)' - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file', dict(uri='file:')), ('table', dict(uri='table:')), ('lsm', dict(uri='lsm:')) diff --git a/src/third_party/wiredtiger/test/suite/test_reconfig01.py b/src/third_party/wiredtiger/test/suite/test_reconfig01.py index 419ff876dc2..fb3fb7edac6 100644 --- a/src/third_party/wiredtiger/test/suite/test_reconfig01.py +++ b/src/third_party/wiredtiger/test/suite/test_reconfig01.py @@ -92,8 +92,6 @@ class test_reconfig01(wttest.WiredTigerTestCase): self.conn.reconfigure("checkpoint=(wait=5)") self.conn.reconfigure("checkpoint=(log_size=0)") self.conn.reconfigure("checkpoint=(log_size=1M)") - self.conn.reconfigure("checkpoint=(wait=0,name=hi)") - self.conn.reconfigure("checkpoint=(wait=5,name=hi)") # Statistics logging: reconfigure the things we can reconfigure. def test_reconfig_statistics_log_ok(self): diff --git a/src/third_party/wiredtiger/test/suite/test_reconfig03.py b/src/third_party/wiredtiger/test/suite/test_reconfig03.py new file mode 100644 index 00000000000..e9d39ea5a76 --- /dev/null +++ b/src/third_party/wiredtiger/test/suite/test_reconfig03.py @@ -0,0 +1,66 @@ +#!/usr/bin/env python +# +# Public Domain 2014-2016 MongoDB, Inc. +# Public Domain 2008-2014 WiredTiger, Inc. +# +# This is free and unencumbered software released into the public domain. +# +# Anyone is free to copy, modify, publish, use, compile, sell, or +# distribute this software, either in source code form or as a compiled +# binary, for any purpose, commercial or non-commercial, and by any +# means. +# +# In jurisdictions that recognize copyright laws, the author or authors +# of this software dedicate any and all copyright interest in the +# software to the public domain. We make this dedication for the benefit +# of the public at large and to the detriment of our heirs and +# successors. We intend this dedication to be an overt act of +# relinquishment in perpetuity of all present and future rights to this +# software under copyright law. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +# IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +# OTHER DEALINGS IN THE SOFTWARE. + +import fnmatch, os, time +import wiredtiger, wttest +from helper import simple_populate + +# test_reconfig03.py +# Test the connection reconfiguration operations used in the MongoDB +# test reconfigwt.js. +class test_reconfig03(wttest.WiredTigerTestCase): + conn_config = 'log=(archive=false,enabled,file_max=100K,prealloc=false,zero_fill=false),checkpoint=(wait=1),cache_size=1G' + uri = "table:reconfig03" + + # Reconfigure similar to MongoDB tests. Sleep so that checkpoint + # can run after we've made modifications. + def test_reconfig03_mdb(self): + entries = 10000 + simple_populate(self, self.uri, 'key_format=S', entries) + time.sleep(1) + self.conn.reconfigure("eviction_target=81") + simple_populate(self, self.uri, 'key_format=S', entries * 2) + time.sleep(1) + self.conn.reconfigure("cache_size=81M") + simple_populate(self, self.uri, 'key_format=S', entries * 3) + time.sleep(1) + self.conn.reconfigure("eviction_dirty_target=82") + simple_populate(self, self.uri, 'key_format=S', entries * 4) + time.sleep(1) + self.conn.reconfigure("shared_cache=(chunk=11MB, name=bar, reserve=12MB, size=1G)") + + def test_reconfig03_log_size(self): + # + # Reconfigure checkpoint based on log size. + # + self.conn.reconfigure("checkpoint=(log_size=20)") + self.conn.reconfigure("checkpoint=(log_size=1M)") + self.conn.reconfigure("checkpoint=(log_size=0)") + +if __name__ == '__main__': + wttest.run() diff --git a/src/third_party/wiredtiger/test/suite/test_rename.py b/src/third_party/wiredtiger/test/suite/test_rename.py index af968a4a38d..1979bbb802a 100644 --- a/src/third_party/wiredtiger/test/suite/test_rename.py +++ b/src/third_party/wiredtiger/test/suite/test_rename.py @@ -31,7 +31,7 @@ import wiredtiger, wttest from helper import confirm_does_not_exist,\ complex_populate, complex_populate_check,\ simple_populate, simple_populate_check -from wtscenario import check_scenarios +from wtscenario import make_scenarios # test_rename.py # session level rename operation @@ -39,7 +39,7 @@ class test_rename(wttest.WiredTigerTestCase): name1 = 'test_rename1' name2 = 'test_rename2' - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file', dict(uri='file:')), ('table', dict(uri='table:')) ]) diff --git a/src/third_party/wiredtiger/test/suite/test_schema02.py b/src/third_party/wiredtiger/test/suite/test_schema02.py index b404261c066..bccc7dfc728 100644 --- a/src/third_party/wiredtiger/test/suite/test_schema02.py +++ b/src/third_party/wiredtiger/test/suite/test_schema02.py @@ -27,7 +27,7 @@ # OTHER DEALINGS IN THE SOFTWARE. import wiredtiger, wttest -from wtscenario import check_scenarios +from wtscenario import make_scenarios # test_schema02.py # Columns, column groups, indexes @@ -37,7 +37,7 @@ class test_schema02(wttest.WiredTigerTestCase): """ nentries = 1000 - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('normal', { 'idx_config' : '' }), ('lsm', { 'idx_config' : ',type=lsm' }), ]) diff --git a/src/third_party/wiredtiger/test/suite/test_schema03.py b/src/third_party/wiredtiger/test/suite/test_schema03.py index f48bfdf3cf8..81556393e78 100644 --- a/src/third_party/wiredtiger/test/suite/test_schema03.py +++ b/src/third_party/wiredtiger/test/suite/test_schema03.py @@ -29,7 +29,7 @@ import os import suite_random import wiredtiger, wtscenario, wttest -from wtscenario import check_scenarios +from wtscenario import make_scenarios try: # Windows does not getrlimit/setrlimit so we must catch the resource @@ -249,7 +249,7 @@ class test_schema03(wttest.WiredTigerTestCase): # but boost it up to this limit anyway. OPEN_FILE_LIMIT = 1000 - restart_scenarios = check_scenarios([('table', dict(s_restart=['table'],P=0.3)), + restart_scenarios = [('table', dict(s_restart=['table'],P=0.3)), ('colgroup0', dict(s_restart=['colgroup0'],P=0.3)), ('index0', dict(s_restart=['index0'],P=0.3)), ('colgroup1', dict(s_restart=['colgroup1'],P=0.3)), @@ -259,7 +259,7 @@ class test_schema03(wttest.WiredTigerTestCase): ('populate1', dict(s_restart=['populate1'],P=0.3)), ('ipop', dict(s_restart=['index0','populate0'],P=0.3)), ('all', dict(s_restart=['table','colgroup0','index0','colgroup1','index1','populate0','index2','populate1'],P=1.0)), - ]) + ] ntable_scenarios = wtscenario.quick_scenarios('s_ntable', [1,2,5,8], [1.0,0.4,0.5,0.5]) @@ -272,11 +272,10 @@ class test_schema03(wttest.WiredTigerTestCase): table_args_scenarios = wtscenario.quick_scenarios('s_extra_table_args', ['', ',type=file', ',type=lsm'], [0.5, 0.3, 0.2]) - all_scenarios = wtscenario.multiply_scenarios('_', restart_scenarios, ntable_scenarios, ncolgroup_scenarios, nindex_scenarios, idx_args_scenarios, table_args_scenarios) - - # Prune the scenarios according to the probabilities given above. - scenarios = wtscenario.prune_scenarios(all_scenarios, 30) - scenarios = wtscenario.number_scenarios(scenarios) + scenarios = wtscenario.make_scenarios( + restart_scenarios, ntable_scenarios, ncolgroup_scenarios, + nindex_scenarios, idx_args_scenarios, table_args_scenarios, + prune=30) # Note: the set can be reduced here for debugging, e.g. # scenarios = scenarios[40:44] diff --git a/src/third_party/wiredtiger/test/suite/test_schema04.py b/src/third_party/wiredtiger/test/suite/test_schema04.py index cd41138deb0..8ac81690819 100644 --- a/src/third_party/wiredtiger/test/suite/test_schema04.py +++ b/src/third_party/wiredtiger/test/suite/test_schema04.py @@ -28,7 +28,7 @@ import os import wiredtiger, wttest, run -from wtscenario import check_scenarios, number_scenarios +from wtscenario import make_scenarios # test_schema04.py # Test indices with duplicates @@ -47,7 +47,7 @@ class test_schema04(wttest.WiredTigerTestCase): """ nentries = 100 - scenarios = number_scenarios([ + scenarios = make_scenarios([ ('index-before', { 'create_index' : 0 }), ('index-during', { 'create_index' : 1 }), ('index-after', { 'create_index' : 2 }), diff --git a/src/third_party/wiredtiger/test/suite/test_schema05.py b/src/third_party/wiredtiger/test/suite/test_schema05.py index 89722d5f89a..89484cfc7bd 100644 --- a/src/third_party/wiredtiger/test/suite/test_schema05.py +++ b/src/third_party/wiredtiger/test/suite/test_schema05.py @@ -28,7 +28,7 @@ import os import wiredtiger, wttest, run -from wtscenario import check_scenarios, number_scenarios +from wtscenario import make_scenarios # test_schema05.py # Test indices using a custom extractor. @@ -51,7 +51,7 @@ class test_schema05(wttest.WiredTigerTestCase): nentries = 1000 nindices = 6 - scenarios = number_scenarios([ + scenarios = make_scenarios([ ('index-before', { 'create_index' : 0 }), ('index-during', { 'create_index' : 1 }), ('index-after', { 'create_index' : 2 }), diff --git a/src/third_party/wiredtiger/test/suite/test_schema06.py b/src/third_party/wiredtiger/test/suite/test_schema06.py index e72959edf2a..e0eec189137 100644 --- a/src/third_party/wiredtiger/test/suite/test_schema06.py +++ b/src/third_party/wiredtiger/test/suite/test_schema06.py @@ -27,6 +27,7 @@ # OTHER DEALINGS IN THE SOFTWARE. import wiredtiger, wttest +from wtscenario import make_scenarios # test_schema06.py # Repeatedly create and drop indices @@ -36,10 +37,10 @@ class test_schema06(wttest.WiredTigerTestCase): """ nentries = 1000 - scenarios = [ + scenarios = make_scenarios([ ('normal', { 'idx_config' : '' }), ('lsm', { 'idx_config' : ',type=lsm' }), - ] + ]) def flip(self, inum, val): """ diff --git a/src/third_party/wiredtiger/test/suite/test_split.py b/src/third_party/wiredtiger/test/suite/test_split.py index d09613e1c52..28bf6bc59b0 100644 --- a/src/third_party/wiredtiger/test/suite/test_split.py +++ b/src/third_party/wiredtiger/test/suite/test_split.py @@ -35,7 +35,6 @@ from wiredtiger import stat from helper import confirm_empty,\ key_populate, value_populate, simple_populate,\ complex_populate, complex_value_populate -from wtscenario import multiply_scenarios, number_scenarios # Test splits class test_split(wttest.WiredTigerTestCase): diff --git a/src/third_party/wiredtiger/test/suite/test_stat01.py b/src/third_party/wiredtiger/test/suite/test_stat01.py index 5c3259696eb..1ad51ee9882 100644 --- a/src/third_party/wiredtiger/test/suite/test_stat01.py +++ b/src/third_party/wiredtiger/test/suite/test_stat01.py @@ -29,7 +29,7 @@ import helper, wiredtiger, wttest from wiredtiger import stat from helper import key_populate, simple_populate -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # test_stat01.py # Statistics operations @@ -49,7 +49,7 @@ class test_stat01(wttest.WiredTigerTestCase): ('recno', dict(keyfmt='r')), ('string', dict(keyfmt='S')), ] - scenarios = number_scenarios(multiply_scenarios('.', types, keyfmt)) + scenarios = make_scenarios(types, keyfmt) conn_config = 'statistics=(all)' diff --git a/src/third_party/wiredtiger/test/suite/test_stat02.py b/src/third_party/wiredtiger/test/suite/test_stat02.py index 88371947b5b..ef3907e54b1 100644 --- a/src/third_party/wiredtiger/test/suite/test_stat02.py +++ b/src/third_party/wiredtiger/test/suite/test_stat02.py @@ -28,7 +28,7 @@ import itertools, wiredtiger, wttest from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios from wiredtiger import stat from helper import complex_populate, complex_populate_lsm, simple_populate @@ -57,8 +57,7 @@ class test_stat_cursor_config(wttest.WiredTigerTestCase): ('size', dict(cursor_config='size')) ] - scenarios = number_scenarios( - multiply_scenarios('.', uri, data_config, cursor_config)) + scenarios = make_scenarios(uri, data_config, cursor_config) # Turn on statistics for this test. def conn_config(self, dir): @@ -106,13 +105,13 @@ class test_stat_cursor_dsrc_clear(wttest.WiredTigerTestCase): pfx = 'test_stat_cursor_dsrc_clear' uri = [ - ('1', dict(uri='file:' + pfx, pop=simple_populate)), - ('2', dict(uri='table:' + pfx, pop=simple_populate)), - ('3', dict(uri='table:' + pfx, pop=complex_populate)), - ('4', dict(uri='table:' + pfx, pop=complex_populate_lsm)) + ('dsrc_clear_1', dict(uri='file:' + pfx, pop=simple_populate)), + ('dsrc_clear_2', dict(uri='table:' + pfx, pop=simple_populate)), + ('dsrc_clear_3', dict(uri='table:' + pfx, pop=complex_populate)), + ('dsrc_clear_4', dict(uri='table:' + pfx, pop=complex_populate_lsm)) ] - scenarios = number_scenarios(multiply_scenarios('.', uri)) + scenarios = make_scenarios(uri) conn_config = 'statistics=(all)' def test_stat_cursor_dsrc_clear(self): @@ -136,13 +135,13 @@ class test_stat_cursor_fast(wttest.WiredTigerTestCase): pfx = 'test_stat_cursor_fast' uri = [ - ('1', dict(uri='file:' + pfx, pop=simple_populate)), - ('2', dict(uri='table:' + pfx, pop=simple_populate)), - ('3', dict(uri='table:' + pfx, pop=complex_populate)), - ('4', dict(uri='table:' + pfx, pop=complex_populate_lsm)) + ('fast_1', dict(uri='file:' + pfx, pop=simple_populate)), + ('fast_2', dict(uri='table:' + pfx, pop=simple_populate)), + ('fast_3', dict(uri='table:' + pfx, pop=complex_populate)), + ('fast_4', dict(uri='table:' + pfx, pop=complex_populate_lsm)) ] - scenarios = number_scenarios(multiply_scenarios('.', uri)) + scenarios = make_scenarios(uri) conn_config = 'statistics=(all)' def test_stat_cursor_fast(self): @@ -180,13 +179,13 @@ class test_stat_cursor_dsrc_error(wttest.WiredTigerTestCase): pfx = 'test_stat_cursor_dsrc_error' uri = [ - ('1', dict(uri='file:' + pfx, pop=simple_populate)), - ('2', dict(uri='table:' + pfx, pop=simple_populate)), - ('3', dict(uri='table:' + pfx, pop=complex_populate)), - ('4', dict(uri='table:' + pfx, pop=complex_populate_lsm)) + ('dsrc_error_1', dict(uri='file:' + pfx, pop=simple_populate)), + ('dsrc_error_2', dict(uri='table:' + pfx, pop=simple_populate)), + ('dsrc_error_3', dict(uri='table:' + pfx, pop=complex_populate)), + ('dsrc_error_4', dict(uri='table:' + pfx, pop=complex_populate_lsm)) ] - scenarios = number_scenarios(multiply_scenarios('.', uri)) + scenarios = make_scenarios(uri) conn_config = 'statistics=(all)' def test_stat_cursor_dsrc_error(self): diff --git a/src/third_party/wiredtiger/test/suite/test_stat03.py b/src/third_party/wiredtiger/test/suite/test_stat03.py index 039ad1f7f8d..b17fe6eb91c 100644 --- a/src/third_party/wiredtiger/test/suite/test_stat03.py +++ b/src/third_party/wiredtiger/test/suite/test_stat03.py @@ -34,7 +34,7 @@ from helper import complex_populate, complex_populate_lsm, simple_populate from helper import key_populate, complex_value_populate, value_populate from helper import complex_populate_colgroup_count, complex_populate_index_count from helper import complex_populate_colgroup_name, complex_populate_index_name -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # test_stat03.py # Statistics reset test. @@ -51,7 +51,7 @@ class test_stat_cursor_reset(wttest.WiredTigerTestCase): dict(uri='table:' + pfx, pop=complex_populate_lsm)), ] - scenarios = number_scenarios(multiply_scenarios('.', uri)) + scenarios = make_scenarios(uri) conn_config = 'statistics=(all)' def stat_cursor(self, uri): diff --git a/src/third_party/wiredtiger/test/suite/test_stat04.py b/src/third_party/wiredtiger/test/suite/test_stat04.py index e7c39371f80..b5309efff37 100644 --- a/src/third_party/wiredtiger/test/suite/test_stat04.py +++ b/src/third_party/wiredtiger/test/suite/test_stat04.py @@ -28,7 +28,7 @@ import os, struct from suite_subprocess import suite_subprocess -from wtscenario import number_scenarios, multiply_scenarios +from wtscenario import make_scenarios import wiredtiger, wttest from wiredtiger import stat @@ -49,7 +49,7 @@ class test_stat04(wttest.WiredTigerTestCase, suite_subprocess): ('large', dict(nentries=100000, valuesize=1)), ('jumboval', dict(nentries=100, valuesize=4200000)), ] - scenarios = number_scenarios(multiply_scenarios('.', keyfmt, nentries)) + scenarios = make_scenarios(keyfmt, nentries) conn_config = 'statistics=(all)' def init_test(self): @@ -91,6 +91,7 @@ class test_stat04(wttest.WiredTigerTestCase, suite_subprocess): self.checkcount(uri, count) cursor[self.genkey(i)] = self.genvalue(i) count += 1 + # Remove a number of entries, at each step checking that stats match. for i in range(0, self.nentries / 37): cursor.set_key(self.genkey(i*11 % self.nentries)) @@ -99,5 +100,10 @@ class test_stat04(wttest.WiredTigerTestCase, suite_subprocess): self.checkcount(uri, count) cursor.close() + # Confirm the count is correct after writing to the backing file, + # that tests the on-disk format as well as the in-memory format. + self.reopen_conn() + self.checkcount(uri, count) + if __name__ == '__main__': wttest.run() diff --git a/src/third_party/wiredtiger/test/suite/test_stat05.py b/src/third_party/wiredtiger/test/suite/test_stat05.py index 9bcedd65089..62562f78ed6 100644 --- a/src/third_party/wiredtiger/test/suite/test_stat05.py +++ b/src/third_party/wiredtiger/test/suite/test_stat05.py @@ -28,7 +28,7 @@ import itertools, wiredtiger, wttest from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios from wiredtiger import stat from helper import complex_populate, complex_populate_lsm, simple_populate from helper import complex_value_populate, key_populate, value_populate @@ -43,16 +43,18 @@ class test_stat_cursor_config(wttest.WiredTigerTestCase): ('file', dict(uri='file:' + pfx, pop=simple_populate, cfg='')), ('table', dict(uri='table:' + pfx, pop=simple_populate, cfg='')), ('inmem', dict(uri='table:' + pfx, pop=simple_populate, cfg='', - conn_config='in_memory,statistics=(fast)')), + conn_config = 'in_memory,statistics=(fast)')), ('table-lsm', dict(uri='table:' + pfx, pop=simple_populate, - cfg=',type=lsm,lsm=(chunk_size=1MB,merge_min=2)')), + cfg=',type=lsm,lsm=(chunk_size=1MB,merge_min=2)', + conn_config = 'statistics=(fast),eviction_dirty_target=99,eviction_dirty_trigger=99')), ('complex', dict(uri='table:' + pfx, pop=complex_populate, cfg='')), ('complex-lsm', dict(uri='table:' + pfx, pop=complex_populate_lsm, - cfg=',lsm=(chunk_size=1MB,merge_min=2)')), + cfg=',lsm=(chunk_size=1MB,merge_min=2)', + conn_config = 'statistics=(fast),eviction_dirty_target=99,eviction_dirty_trigger=99')), ] - scenarios = number_scenarios(uri) + scenarios = make_scenarios(uri) def openAndWalkStatCursor(self): c = self.session.open_cursor( @@ -62,7 +64,6 @@ class test_stat_cursor_config(wttest.WiredTigerTestCase): count += 1 c.close() - # Open a size-only statistics cursor on various table types. Ensure that # the cursor open succeeds. Insert enough data that LSM tables to need to # switch and merge. diff --git a/src/third_party/wiredtiger/test/suite/test_sweep01.py b/src/third_party/wiredtiger/test/suite/test_sweep01.py index bccd2bce012..71f8fcb180e 100644 --- a/src/third_party/wiredtiger/test/suite/test_sweep01.py +++ b/src/third_party/wiredtiger/test/suite/test_sweep01.py @@ -33,8 +33,8 @@ import fnmatch, os, shutil, run, time from suite_subprocess import suite_subprocess +from wtscenario import make_scenarios from wiredtiger import stat -from wtscenario import multiply_scenarios, number_scenarios, prune_scenarios import wttest class test_sweep01(wttest.WiredTigerTestCase, suite_subprocess): @@ -55,7 +55,7 @@ class test_sweep01(wttest.WiredTigerTestCase, suite_subprocess): create_params = 'key_format=r,value_format=8t')), ] - scenarios = types + scenarios = make_scenarios(types) def test_ops(self): # diff --git a/src/third_party/wiredtiger/test/suite/test_sweep03.py b/src/third_party/wiredtiger/test/suite/test_sweep03.py index 061c2f5b37b..61078fa96b5 100644 --- a/src/third_party/wiredtiger/test/suite/test_sweep03.py +++ b/src/third_party/wiredtiger/test/suite/test_sweep03.py @@ -33,7 +33,7 @@ import fnmatch, os, shutil, run, time from suite_subprocess import suite_subprocess from wiredtiger import stat -from wtscenario import multiply_scenarios, number_scenarios, prune_scenarios +from wtscenario import make_scenarios import wttest class test_sweep03(wttest.WiredTigerTestCase, suite_subprocess): @@ -54,7 +54,7 @@ class test_sweep03(wttest.WiredTigerTestCase, suite_subprocess): create_params = 'key_format=r,value_format=8t')), ] - scenarios = types + scenarios = make_scenarios(types) def test_disable_idle_timeout1(self): # diff --git a/src/third_party/wiredtiger/test/suite/test_truncate01.py b/src/third_party/wiredtiger/test/suite/test_truncate01.py index 77a476e40c1..9a3518c6984 100644 --- a/src/third_party/wiredtiger/test/suite/test_truncate01.py +++ b/src/third_party/wiredtiger/test/suite/test_truncate01.py @@ -34,13 +34,13 @@ import wiredtiger, wttest from helper import confirm_empty,\ key_populate, value_populate, simple_populate,\ complex_populate, complex_value_populate -from wtscenario import check_scenarios, multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # Test truncation arguments. class test_truncate_arguments(wttest.WiredTigerTestCase): name = 'test_truncate' - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file', dict(type='file:')), ('table', dict(type='table:')) ]) @@ -80,7 +80,7 @@ class test_truncate_arguments(wttest.WiredTigerTestCase): # Test truncation of an object using its URI. class test_truncate_uri(wttest.WiredTigerTestCase): name = 'test_truncate' - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file', dict(type='file:')), ('table', dict(type='table:')) ]) @@ -115,7 +115,7 @@ class test_truncate_cursor_order(wttest.WiredTigerTestCase): ('recno', dict(keyfmt='r')), ('string', dict(keyfmt='S')), ] - scenarios = number_scenarios(multiply_scenarios('.', types, keyfmt)) + scenarios = make_scenarios(types, keyfmt) # Test an illegal order, then confirm that equal cursors works. def test_truncate_cursor_order(self): @@ -146,7 +146,7 @@ class test_truncate_cursor_end(wttest.WiredTigerTestCase): ('recno', dict(keyfmt='r')), ('string', dict(keyfmt='S')), ] - scenarios = number_scenarios(multiply_scenarios('.', types, keyfmt)) + scenarios = make_scenarios(types, keyfmt) # Test truncation of cursors past the end of the object. def test_truncate_cursor_order(self): @@ -205,8 +205,7 @@ class test_truncate_cursor(wttest.WiredTigerTestCase): ('big', dict(nentries=1000,skip=37)), ] - scenarios = number_scenarios( - multiply_scenarios('.', types, keyfmt, size, reopen)) + scenarios = make_scenarios(types, keyfmt, size, reopen) # Set a cursor key. def cursorKey(self, uri, key): diff --git a/src/third_party/wiredtiger/test/suite/test_truncate02.py b/src/third_party/wiredtiger/test/suite/test_truncate02.py index 6c11302787c..e57a65d2f97 100644 --- a/src/third_party/wiredtiger/test/suite/test_truncate02.py +++ b/src/third_party/wiredtiger/test/suite/test_truncate02.py @@ -32,7 +32,7 @@ import wiredtiger, wttest from helper import key_populate, value_populate, simple_populate -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # test_truncate_fast_delete # When deleting leaf pages that aren't in memory, we set transactional @@ -86,8 +86,7 @@ class test_truncate_fast_delete(wttest.WiredTigerTestCase): ('txn2', dict(commit=False)), ] - scenarios = number_scenarios( - multiply_scenarios('.', types, keyfmt, overflow, reads, writes, txn)) + scenarios = make_scenarios(types, keyfmt, overflow, reads, writes, txn) # Return the number of records visible to the cursor; test both forward # and backward iteration, they are different code paths in this case. diff --git a/src/third_party/wiredtiger/test/suite/test_txn01.py b/src/third_party/wiredtiger/test/suite/test_txn01.py index eb6963791fd..1ba74461088 100644 --- a/src/third_party/wiredtiger/test/suite/test_txn01.py +++ b/src/third_party/wiredtiger/test/suite/test_txn01.py @@ -27,13 +27,13 @@ # OTHER DEALINGS IN THE SOFTWARE. import wiredtiger, wttest -from wtscenario import check_scenarios +from wtscenario import make_scenarios # test_txn01.py # Transactions: basic functionality class test_txn01(wttest.WiredTigerTestCase): nentries = 1000 - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('col-f', dict(uri='file:text_txn01',key_format='r',value_format='S')), ('col-t', dict(uri='table:text_txn01',key_format='r',value_format='S')), ('fix-f', dict(uri='file:text_txn01',key_format='r',value_format='8t')), diff --git a/src/third_party/wiredtiger/test/suite/test_txn02.py b/src/third_party/wiredtiger/test/suite/test_txn02.py index fccf123d3bc..a0c2c12a47c 100644 --- a/src/third_party/wiredtiger/test/suite/test_txn02.py +++ b/src/third_party/wiredtiger/test/suite/test_txn02.py @@ -32,7 +32,7 @@ import fnmatch, os, shutil, time from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios, prune_scenarios +from wtscenario import make_scenarios import wttest class test_txn02(wttest.WiredTigerTestCase, suite_subprocess): @@ -81,22 +81,18 @@ class test_txn02(wttest.WiredTigerTestCase, suite_subprocess): txn3s = [('t3c', dict(txn3='commit')), ('t3r', dict(txn3='rollback'))] txn4s = [('t4c', dict(txn4='commit')), ('t4r', dict(txn4='rollback'))] - all_scenarios = multiply_scenarios('.', types, - op1s, txn1s, op2s, txn2s, op3s, txn3s, op4s, txn4s) - # This test generates thousands of potential scenarios. # For default runs, we'll use a small subset of them, for # long runs (when --long is set) we'll set a much larger limit. - scenarios = number_scenarios(prune_scenarios(all_scenarios, 20, 5000)) + scenarios = make_scenarios(types, + op1s, txn1s, op2s, txn2s, op3s, txn3s, op4s, txn4s, + prune=20, prunelong=5000) # Each check_log() call takes a second, so we don't call it for # every scenario, we'll limit it to the value of checklog_calls. checklog_calls = 100 if wttest.islongtest() else 2 checklog_mod = (len(scenarios) / checklog_calls + 1) - # scenarios = number_scenarios(multiply_scenarios('.', types, - # op1s, txn1s, op2s, txn2s, op3s, txn3s, op4s, txn4s)) [:3] - # Overrides WiredTigerTestCase def setUpConnectionOpen(self, dir): self.home = dir # Cycle through the different transaction_sync values in a diff --git a/src/third_party/wiredtiger/test/suite/test_txn03.py b/src/third_party/wiredtiger/test/suite/test_txn03.py index 97180a75949..18a0e096767 100644 --- a/src/third_party/wiredtiger/test/suite/test_txn03.py +++ b/src/third_party/wiredtiger/test/suite/test_txn03.py @@ -31,7 +31,7 @@ # import wiredtiger, wttest -from wtscenario import check_scenarios +from wtscenario import make_scenarios class test_txn03(wttest.WiredTigerTestCase): tablename = 'test_txn03' @@ -42,7 +42,7 @@ class test_txn03(wttest.WiredTigerTestCase): data_str2 = "TEST_VAL1" nentries = 1000 - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('var', dict(create_params = "key_format=S,value_format=S")), ]) diff --git a/src/third_party/wiredtiger/test/suite/test_txn04.py b/src/third_party/wiredtiger/test/suite/test_txn04.py index 9d9d2db62c6..ade39272f84 100644 --- a/src/third_party/wiredtiger/test/suite/test_txn04.py +++ b/src/third_party/wiredtiger/test/suite/test_txn04.py @@ -32,7 +32,7 @@ import shutil, os from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios import wttest class test_txn04(wttest.WiredTigerTestCase, suite_subprocess): @@ -62,7 +62,7 @@ class test_txn04(wttest.WiredTigerTestCase, suite_subprocess): ] txn1s = [('t1c', dict(txn1='commit')), ('t1r', dict(txn1='rollback'))] - scenarios = number_scenarios(multiply_scenarios('.', types, op1s, txn1s)) + scenarios = make_scenarios(types, op1s, txn1s) # Overrides WiredTigerTestCase def setUpConnectionOpen(self, dir): self.home = dir diff --git a/src/third_party/wiredtiger/test/suite/test_txn05.py b/src/third_party/wiredtiger/test/suite/test_txn05.py index bb68034ca04..9e84fe7d3fe 100644 --- a/src/third_party/wiredtiger/test/suite/test_txn05.py +++ b/src/third_party/wiredtiger/test/suite/test_txn05.py @@ -32,7 +32,7 @@ import fnmatch, os, shutil, time from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios import wttest class test_txn05(wttest.WiredTigerTestCase, suite_subprocess): @@ -63,8 +63,7 @@ class test_txn05(wttest.WiredTigerTestCase, suite_subprocess): ] txn1s = [('t1c', dict(txn1='commit')), ('t1r', dict(txn1='rollback'))] - scenarios = number_scenarios(multiply_scenarios('.', types, op1s, txn1s)) - # scenarios = number_scenarios(multiply_scenarios('.', types, op1s, txn1s))[:3] + scenarios = make_scenarios(types, op1s, txn1s) # Overrides WiredTigerTestCase def setUpConnectionOpen(self, dir): self.home = dir diff --git a/src/third_party/wiredtiger/test/suite/test_txn06.py b/src/third_party/wiredtiger/test/suite/test_txn06.py index 9c1d0335d47..e4636e40e2e 100644 --- a/src/third_party/wiredtiger/test/suite/test_txn06.py +++ b/src/third_party/wiredtiger/test/suite/test_txn06.py @@ -30,7 +30,6 @@ # Transactions: test long-running snapshots from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios from helper import simple_populate import wiredtiger, wttest diff --git a/src/third_party/wiredtiger/test/suite/test_txn07.py b/src/third_party/wiredtiger/test/suite/test_txn07.py index f74120e3590..f9577bad7f2 100644 --- a/src/third_party/wiredtiger/test/suite/test_txn07.py +++ b/src/third_party/wiredtiger/test/suite/test_txn07.py @@ -33,7 +33,7 @@ import fnmatch, os, shutil, run, time from suite_subprocess import suite_subprocess from wiredtiger import stat -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios import wttest class test_txn07(wttest.WiredTigerTestCase, suite_subprocess): @@ -70,8 +70,7 @@ class test_txn07(wttest.WiredTigerTestCase, suite_subprocess): ('none', dict(compress='')), ] - scenarios = number_scenarios(multiply_scenarios('.', types, op1s, txn1s, - compress)) + scenarios = make_scenarios(types, op1s, txn1s, compress) # Overrides WiredTigerTestCase def setUpConnectionOpen(self, dir): self.home = dir @@ -218,6 +217,13 @@ class test_txn07(wttest.WiredTigerTestCase, suite_subprocess): # Check the state after each commit/rollback. self.check_all(current, committed) + # + # Run printlog and make sure it exits with zero status. This should be + # run as soon as we can after the crash to try and conflict with the + # journal file read. + # + + self.runWt(['-h', self.backup_dir, 'printlog'], outfilename='printlog.out') stat_cursor = self.session.open_cursor('statistics:', None, None) clen = stat_cursor[stat.conn.log_compress_len][2] @@ -240,10 +246,5 @@ class test_txn07(wttest.WiredTigerTestCase, suite_subprocess): self.assertEqual(cwrites > 0, True) self.assertEqual((cfails > 0 or csmall > 0), True) - # - # Run printlog and make sure it exits with zero status. - # - self.runWt(['-h', self.backup_dir, 'printlog'], outfilename='printlog.out') - if __name__ == '__main__': wttest.run() diff --git a/src/third_party/wiredtiger/test/suite/test_txn08.py b/src/third_party/wiredtiger/test/suite/test_txn08.py index 36253856285..f0cdf08df07 100644 --- a/src/third_party/wiredtiger/test/suite/test_txn08.py +++ b/src/third_party/wiredtiger/test/suite/test_txn08.py @@ -33,7 +33,6 @@ import fnmatch, os, shutil, run, time from suite_subprocess import suite_subprocess from wiredtiger import stat -from wtscenario import multiply_scenarios, number_scenarios import wttest class test_txn08(wttest.WiredTigerTestCase, suite_subprocess): diff --git a/src/third_party/wiredtiger/test/suite/test_txn09.py b/src/third_party/wiredtiger/test/suite/test_txn09.py index f536d65205d..cfad8270ab1 100644 --- a/src/third_party/wiredtiger/test/suite/test_txn09.py +++ b/src/third_party/wiredtiger/test/suite/test_txn09.py @@ -32,7 +32,7 @@ import fnmatch, os, shutil, time from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios, prune_scenarios +from wtscenario import make_scenarios import wttest class test_txn09(wttest.WiredTigerTestCase, suite_subprocess): @@ -73,13 +73,12 @@ class test_txn09(wttest.WiredTigerTestCase, suite_subprocess): txn3s = [('t3c', dict(txn3='commit')), ('t3r', dict(txn3='rollback'))] txn4s = [('t4c', dict(txn4='commit')), ('t4r', dict(txn4='rollback'))] - all_scenarios = multiply_scenarios('.', types, - op1s, txn1s, op2s, txn2s, op3s, txn3s, op4s, txn4s) - # This test generates thousands of potential scenarios. # For default runs, we'll use a small subset of them, for # long runs (when --long is set) we'll set a much larger limit. - scenarios = number_scenarios(prune_scenarios(all_scenarios, 20, 5000)) + scenarios = make_scenarios(types, + op1s, txn1s, op2s, txn2s, op3s, txn3s, op4s, txn4s, + prune=20, prunelong=5000) # Overrides WiredTigerTestCase def setUpConnectionOpen(self, dir): diff --git a/src/third_party/wiredtiger/test/suite/test_txn10.py b/src/third_party/wiredtiger/test/suite/test_txn10.py index cf9c11dd4ab..a4745e60066 100644 --- a/src/third_party/wiredtiger/test/suite/test_txn10.py +++ b/src/third_party/wiredtiger/test/suite/test_txn10.py @@ -32,7 +32,6 @@ import fnmatch, os, shutil, time from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios, prune_scenarios import wttest class test_txn10(wttest.WiredTigerTestCase, suite_subprocess): diff --git a/src/third_party/wiredtiger/test/suite/test_txn12.py b/src/third_party/wiredtiger/test/suite/test_txn12.py index 8ae9df33990..32c058bea85 100644 --- a/src/third_party/wiredtiger/test/suite/test_txn12.py +++ b/src/third_party/wiredtiger/test/suite/test_txn12.py @@ -29,7 +29,6 @@ import wiredtiger, wttest from suite_subprocess import suite_subprocess from wiredtiger import stat -from wtscenario import multiply_scenarios, number_scenarios # test_txn12.py # test of commit following failed op in a read only transaction. diff --git a/src/third_party/wiredtiger/test/suite/test_txn13.py b/src/third_party/wiredtiger/test/suite/test_txn13.py index dd6a6dbcd6d..ae0250c06e8 100644 --- a/src/third_party/wiredtiger/test/suite/test_txn13.py +++ b/src/third_party/wiredtiger/test/suite/test_txn13.py @@ -33,7 +33,7 @@ #import fnmatch, os, shutil, run, time from suite_subprocess import suite_subprocess -from wtscenario import check_scenarios +from wtscenario import make_scenarios import wiredtiger, wttest class test_txn13(wttest.WiredTigerTestCase, suite_subprocess): @@ -43,7 +43,7 @@ class test_txn13(wttest.WiredTigerTestCase, suite_subprocess): nops = 1024 create_params = 'key_format=i,value_format=S' - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('1gb', dict(expect_err=False, valuesize=1048576)), ('2gb', dict(expect_err=False, valuesize=2097152)), ('4gb', dict(expect_err=True, valuesize=4194304)) diff --git a/src/third_party/wiredtiger/test/suite/test_txn14.py b/src/third_party/wiredtiger/test/suite/test_txn14.py index 371f4402567..f9ccabaab8b 100644 --- a/src/third_party/wiredtiger/test/suite/test_txn14.py +++ b/src/third_party/wiredtiger/test/suite/test_txn14.py @@ -32,7 +32,7 @@ import fnmatch, os, shutil, time from suite_subprocess import suite_subprocess -from wtscenario import multiply_scenarios, number_scenarios, prune_scenarios +from wtscenario import make_scenarios import wttest class test_txn14(wttest.WiredTigerTestCase, suite_subprocess): @@ -47,7 +47,7 @@ class test_txn14(wttest.WiredTigerTestCase, suite_subprocess): ('sync', dict(sync='on')), ('bg', dict(sync='background')), ] - scenarios = multiply_scenarios('.', sync_list) + scenarios = make_scenarios(sync_list) def simulate_crash_restart(self, olddir, newdir): ''' Simulate a crash from olddir and restart in newdir. ''' diff --git a/src/third_party/wiredtiger/test/suite/test_txn15.py b/src/third_party/wiredtiger/test/suite/test_txn15.py index 809dce4ebfa..c061c093b02 100644 --- a/src/third_party/wiredtiger/test/suite/test_txn15.py +++ b/src/third_party/wiredtiger/test/suite/test_txn15.py @@ -33,7 +33,7 @@ import fnmatch, os, shutil, time from suite_subprocess import suite_subprocess from wiredtiger import stat -from wtscenario import multiply_scenarios, number_scenarios, prune_scenarios +from wtscenario import make_scenarios import wttest class test_txn15(wttest.WiredTigerTestCase, suite_subprocess): @@ -71,7 +71,7 @@ class test_txn15(wttest.WiredTigerTestCase, suite_subprocess): ('c_none', dict(commit_sync=None)), ('c_off', dict(commit_sync='sync=off')), ] - scenarios = multiply_scenarios('.', conn_sync_enabled, conn_sync_method, + scenarios = make_scenarios(conn_sync_enabled, conn_sync_method, begin_sync, commit_sync) # Given the different configuration settings determine if this group diff --git a/src/third_party/wiredtiger/test/suite/test_upgrade.py b/src/third_party/wiredtiger/test/suite/test_upgrade.py index 357e437f14d..e4f92f8f8d8 100644 --- a/src/third_party/wiredtiger/test/suite/test_upgrade.py +++ b/src/third_party/wiredtiger/test/suite/test_upgrade.py @@ -29,14 +29,14 @@ import os, time import wiredtiger, wttest from helper import complex_populate, simple_populate -from wtscenario import check_scenarios +from wtscenario import make_scenarios # test_upgrade.py # session level upgrade operation class test_upgrade(wttest.WiredTigerTestCase): name = 'test_upgrade' - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('file', dict(uri='file:')), ('table', dict(uri='table:')) ]) diff --git a/src/third_party/wiredtiger/test/suite/test_util02.py b/src/third_party/wiredtiger/test/suite/test_util02.py index 475e856052a..421b0104484 100644 --- a/src/third_party/wiredtiger/test/suite/test_util02.py +++ b/src/third_party/wiredtiger/test/suite/test_util02.py @@ -29,7 +29,7 @@ import string, os import wiredtiger, wttest from suite_subprocess import suite_subprocess -from wtscenario import check_scenarios +from wtscenario import make_scenarios from helper import complex_populate # test_util02.py @@ -44,7 +44,7 @@ class test_util02(wttest.WiredTigerTestCase, suite_subprocess): nentries = 1000 stringclass = ''.__class__ - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('SS', dict(key_format='S',value_format='S')), ('rS', dict(key_format='r',value_format='S')), ('ri', dict(key_format='r',value_format='i')), diff --git a/src/third_party/wiredtiger/test/suite/test_util03.py b/src/third_party/wiredtiger/test/suite/test_util03.py index c3ea48b8f5e..e341c79ff9e 100644 --- a/src/third_party/wiredtiger/test/suite/test_util03.py +++ b/src/third_party/wiredtiger/test/suite/test_util03.py @@ -28,7 +28,7 @@ from suite_subprocess import suite_subprocess import wiredtiger, wttest -from wtscenario import check_scenarios +from wtscenario import make_scenarios # test_util03.py # Utilities: wt create @@ -36,7 +36,7 @@ class test_util03(wttest.WiredTigerTestCase, suite_subprocess): tablename = 'test_util03.a' nentries = 1000 - scenarios = check_scenarios([ + scenarios = make_scenarios([ ('none', dict(key_format=None,value_format=None)), ('SS', dict(key_format='S',value_format='S')), ('rS', dict(key_format='r',value_format='S')), diff --git a/src/third_party/wiredtiger/test/suite/test_util13.py b/src/third_party/wiredtiger/test/suite/test_util13.py index 222f42cd7f1..9804dc700ba 100644 --- a/src/third_party/wiredtiger/test/suite/test_util13.py +++ b/src/third_party/wiredtiger/test/suite/test_util13.py @@ -33,7 +33,7 @@ import itertools, wiredtiger, wttest from helper import complex_populate_cgconfig, complex_populate_cgconfig_lsm from helper import simple_populate from helper import complex_populate_check, simple_populate_check -from wtscenario import multiply_scenarios, number_scenarios +from wtscenario import make_scenarios # test_util13.py # Utilities: wt dump, as well as the dump cursor @@ -73,7 +73,7 @@ class test_util13(wttest.WiredTigerTestCase, suite_subprocess): cfg='merge_max=5')), ] - scenarios = number_scenarios(multiply_scenarios('.', types)) + scenarios = make_scenarios(types) def compare_config(self, expected_cfg, actual_cfg): # Replace '(' characters so configuration groups don't break parsing. diff --git a/src/third_party/wiredtiger/test/suite/wtscenario.py b/src/third_party/wiredtiger/test/suite/wtscenario.py index 7fad7c228fb..8576b3ac876 100644 --- a/src/third_party/wiredtiger/test/suite/wtscenario.py +++ b/src/third_party/wiredtiger/test/suite/wtscenario.py @@ -64,11 +64,37 @@ def log2chr(val): megabyte = 1024 * 1024 +def make_scenarios(*args, **kwargs): + """ + The standard way to create scenarios for WT tests. + Scenarios can be combined by listing them all as arguments. + A final prune= and/or prunelong= argument may be given that + forces the list of entries in the scenario to be pruned. + The result is a (combined) scenario that has been checked + for name duplicates and has been given names and numbers. + """ + scenes = multiply_scenarios('.', *args) + pruneval = None + prunelong = None + for key in kwargs: + if key == 'prune': + pruneval = kwargs[key] + elif key == 'prunelong': + prunelong = kwargs[key] + else: + raise AssertionError( + 'make_scenarios: unexpected named arg: ' + key) + if pruneval != None or prunelong != None: + pruneval = pruneval if pruneval != None else -1 + prunelong = prunelong if prunelong != None else -1 + scenes = prune_scenarios(scenes, pruneval, prunelong) + return number_scenarios(scenes) + def check_scenarios(scenes): """ - Make sure all scenarios have unique names + Make sure all scenarios have unique case insensitive names """ - assert len(scenes) == len(dict(scenes)) + assert len(scenes) == len(dict((k.lower(), v) for k, v in scenes)) return scenes def multiply_scenarios(sep, *args): @@ -81,8 +107,8 @@ def multiply_scenarios(sep, *args): result = scenes else: total = [] - for scena in scenes: - for scenb in result: + for scena in result: + for scenb in scenes: # Create a merged scenario with a concatenated name name = scena[0] + sep + scenb[0] tdict = {} @@ -235,7 +261,7 @@ class wtscenario: scen.lmax = lmax scen.cache_size = cache s.append((scen.shortName(), dict(session_create_scenario=scen))) - return s + return make_scenarios(s) def shortName(self): """ diff --git a/src/third_party/wiredtiger/test/suite/wttest.py b/src/third_party/wiredtiger/test/suite/wttest.py index 9e430fcdba7..788dd5d0307 100644 --- a/src/third_party/wiredtiger/test/suite/wttest.py +++ b/src/third_party/wiredtiger/test/suite/wttest.py @@ -212,8 +212,8 @@ class WiredTigerTestCase(unittest.TestCase): # help distinguish tests. scen = '' if hasattr(self, 'scenario_number') and hasattr(self, 'scenario_name'): - scen = '(scenario ' + str(self.scenario_number) + \ - ': ' + self.scenario_name + ')' + scen = ' -s ' + str(self.scenario_number) + \ + ' (' + self.scenario_name + ')' return self.simpleName() + scen def simpleName(self): @@ -293,6 +293,8 @@ class WiredTigerTestCase(unittest.TestCase): raise Exception(self.testdir + ": cannot remove directory") os.makedirs(self.testdir) os.chdir(self.testdir) + with open('testname.txt', 'w+') as namefile: + namefile.write(str(self) + '\n') self.fdSetUp() # tearDown needs a conn field, set it here in case the open fails. self.conn = None diff --git a/src/third_party/wiredtiger/test/thread/rw.c b/src/third_party/wiredtiger/test/thread/rw.c index 10f13b9eb04..c6107a06c49 100644 --- a/src/third_party/wiredtiger/test/thread/rw.c +++ b/src/third_party/wiredtiger/test/thread/rw.c @@ -175,8 +175,8 @@ reader_op(WT_SESSION *session, WT_CURSOR *cursor, INFO *s) if ((ret = cursor->search(cursor)) != 0 && ret != WT_NOTFOUND) testutil_die(ret, "cursor.search"); if (log_print) - (void)session->log_printf(session, - "Reader Thread %p key %017u", pthread_self(), keyno); + testutil_check(session->log_printf(session, + "Reader Thread %p key %017u", pthread_self(), keyno)); } /* @@ -276,8 +276,8 @@ writer_op(WT_SESSION *session, WT_CURSOR *cursor, INFO *s) testutil_die(ret, "cursor.update"); } if (log_print) - (void)session->log_printf(session, - "Writer Thread %p key %017u", pthread_self(), keyno); + testutil_check(session->log_printf(session, + "Writer Thread %p key %017u", pthread_self(), keyno)); } /* diff --git a/src/third_party/wiredtiger/test/thread/smoke.sh b/src/third_party/wiredtiger/test/thread/smoke.sh index 9a235b1d8e9..aa2f86c1def 100755 --- a/src/third_party/wiredtiger/test/thread/smoke.sh +++ b/src/third_party/wiredtiger/test/thread/smoke.sh @@ -4,10 +4,10 @@ set -e # Smoke-test format as part of running "make check". $TEST_WRAPPER ./t -t f -$TEST_WRAPPER ./t -S -F -t f +$TEST_WRAPPER ./t -S -F -n 1000 -t f $TEST_WRAPPER ./t -t r -$TEST_WRAPPER ./t -S -F -t r +$TEST_WRAPPER ./t -S -F -n 1000 -t r $TEST_WRAPPER ./t -t v -$TEST_WRAPPER ./t -S -F -t v +$TEST_WRAPPER ./t -S -F -n 1000 -t v diff --git a/src/third_party/wiredtiger/test/utility/misc.c b/src/third_party/wiredtiger/test/utility/misc.c index dfc655dec1a..096bc752726 100644 --- a/src/third_party/wiredtiger/test/utility/misc.c +++ b/src/third_party/wiredtiger/test/utility/misc.c @@ -82,12 +82,22 @@ testutil_clean_work_dir(char *dir) int ret; char *buf; +#ifdef _WIN32 /* Additional bytes for the Windows rd command. */ + len = 2 * strlen(dir) + strlen(RM_COMMAND) + + strlen(DIR_EXISTS_COMMAND) + 4; + if ((buf = malloc(len)) == NULL) + testutil_die(ENOMEM, "Failed to allocate memory"); + + snprintf(buf, len, "%s %s %s %s", DIR_EXISTS_COMMAND, dir, + RM_COMMAND, dir); +#else len = strlen(dir) + strlen(RM_COMMAND) + 1; if ((buf = malloc(len)) == NULL) testutil_die(ENOMEM, "Failed to allocate memory"); snprintf(buf, len, "%s%s", RM_COMMAND, dir); +#endif if ((ret = system(buf)) != 0 && ret != ENOENT) testutil_die(ret, "%s", buf); @@ -138,6 +148,23 @@ testutil_cleanup(TEST_OPTS *opts) free(opts->home); } +/* + * testutil_disable_long_tests -- + * Return if TESTUTIL_DISABLE_LONG_TESTS is set. + */ +bool +testutil_disable_long_tests(void) +{ + const char *res; + + if (__wt_getenv(NULL, + "TESTUTIL_DISABLE_LONG_TESTS", &res) == WT_NOTFOUND) + return (false); + + free((void *)res); + return (true); +} + /* * dcalloc -- * Call calloc, dying on failure. @@ -192,3 +219,18 @@ dstrdup(const void *str) return (p); testutil_die(errno, "strdup"); } + +/* + * dstrndup -- + * Call emulating strndup, dying on failure. Don't use actual strndup here + * as it is not supported within MSVC. + */ +void * +dstrndup(const char *str, size_t len) +{ + char *p; + + p = dcalloc(len + 1, sizeof(char)); + memcpy(p, str, len); + return (p); +} diff --git a/src/third_party/wiredtiger/test/utility/parse_opts.c b/src/third_party/wiredtiger/test/utility/parse_opts.c index 4054f318259..08aeafa9617 100644 --- a/src/third_party/wiredtiger/test/utility/parse_opts.c +++ b/src/third_party/wiredtiger/test/utility/parse_opts.c @@ -47,7 +47,7 @@ testutil_parse_opts(int argc, char * const *argv, TEST_OPTS *opts) opts->running = true; opts->verbose = false; - if ((opts->progname = strrchr(argv[0], '/')) == NULL) + if ((opts->progname = strrchr(argv[0], DIR_DELIM)) == NULL) opts->progname = argv[0]; else ++opts->progname; diff --git a/src/third_party/wiredtiger/test/utility/test_util.h b/src/third_party/wiredtiger/test/utility/test_util.h index 66ff8de2d19..3c1d0e2630a 100644 --- a/src/third_party/wiredtiger/test/utility/test_util.h +++ b/src/third_party/wiredtiger/test/utility/test_util.h @@ -29,9 +29,12 @@ #ifdef _WIN32 #define DIR_DELIM '\\' + #define DIR_DELIM_STR "\\" + #define DIR_EXISTS_COMMAND "IF EXIST " #define RM_COMMAND "rd /s /q " #else #define DIR_DELIM '/' + #define DIR_DELIM_STR "/" #define RM_COMMAND "rm -rf " #endif @@ -115,8 +118,10 @@ void *dcalloc(size_t, size_t); void *dmalloc(size_t); void *drealloc(void *, size_t); void *dstrdup(const void *); +void *dstrndup(const char *, size_t); void testutil_clean_work_dir(char *); void testutil_cleanup(TEST_OPTS *); +bool testutil_disable_long_tests(void); void testutil_make_work_dir(char *); int testutil_parse_opts(int, char * const *, TEST_OPTS *); void testutil_work_dir_from_path(char *, size_t, const char *); diff --git a/src/third_party/wiredtiger/test/windows/windows_shim.c b/src/third_party/wiredtiger/test/windows/windows_shim.c index 6e8da8f86d4..b161b29c2fa 100644 --- a/src/third_party/wiredtiger/test/windows/windows_shim.c +++ b/src/third_party/wiredtiger/test/windows/windows_shim.c @@ -104,6 +104,17 @@ pthread_rwlock_unlock(pthread_rwlock_t *rwlock) return (0); } +int +pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock) +{ + if (TryAcquireSRWLockExclusive(&rwlock->rwlock)) { + rwlock->exclusive_locked = GetCurrentThreadId(); + return (0); + } + + return (EBUSY); +} + int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock) { diff --git a/src/third_party/wiredtiger/test/windows/windows_shim.h b/src/third_party/wiredtiger/test/windows/windows_shim.h index f32edce88e7..a6050e92bca 100644 --- a/src/third_party/wiredtiger/test/windows/windows_shim.h +++ b/src/third_party/wiredtiger/test/windows/windows_shim.h @@ -30,6 +30,7 @@ #define WIN32_LEAN_AND_MEAN #include +#include #include #include #include @@ -109,6 +110,7 @@ int pthread_rwlock_init(pthread_rwlock_t *, const pthread_rwlockattr_t *); int pthread_rwlock_rdlock(pthread_rwlock_t *); int pthread_rwlock_unlock(pthread_rwlock_t *); +int pthread_rwlock_trywrlock(pthread_rwlock_t *); int pthread_rwlock_wrlock(pthread_rwlock_t *); int pthread_create(pthread_t *, const pthread_attr_t *, diff --git a/src/third_party/wiredtiger/tools/wtstats/stat_data.py b/src/third_party/wiredtiger/tools/wtstats/stat_data.py index a79cf1faf5e..1eb60c9d513 100644 --- a/src/third_party/wiredtiger/tools/wtstats/stat_data.py +++ b/src/third_party/wiredtiger/tools/wtstats/stat_data.py @@ -3,21 +3,26 @@ no_scale_per_second_list = [ 'async: current work queue length', 'async: maximum work queue length', + 'cache: bytes belonging to page images in the cache', 'cache: bytes currently in the cache', + 'cache: bytes not belonging to page images in the cache', 'cache: eviction currently operating in aggressive mode', + 'cache: eviction state', 'cache: files with active eviction walks', 'cache: hazard pointer maximum array length', 'cache: maximum bytes configured', 'cache: maximum page size at eviction', + 'cache: overflow values cached in memory', 'cache: pages currently held in the cache', 'cache: percentage overhead', 'cache: tracked bytes belonging to internal pages in the cache', 'cache: tracked bytes belonging to leaf pages in the cache', - 'cache: tracked bytes belonging to overflow pages in the cache', 'cache: tracked dirty bytes in the cache', 'cache: tracked dirty pages in the cache', 'connection: files currently open', 'data-handle: connection data handles currently active', + 'log: log sync time duration (usecs)', + 'log: log sync_dir time duration (usecs)', 'log: maximum log file size', 'log: number of pre-allocated log files to create', 'log: total log buffer size', @@ -28,6 +33,22 @@ no_scale_per_second_list = [ 'reconciliation: split objects currently awaiting free', 'session: open cursor count', 'session: open session count', + 'session: table compact failed calls', + 'session: table compact successful calls', + 'session: table create failed calls', + 'session: table create successful calls', + 'session: table drop failed calls', + 'session: table drop successful calls', + 'session: table rebalance failed calls', + 'session: table rebalance successful calls', + 'session: table rename failed calls', + 'session: table rename successful calls', + 'session: table salvage failed calls', + 'session: table salvage successful calls', + 'session: table truncate failed calls', + 'session: table truncate successful calls', + 'session: table verify failed calls', + 'session: table verify successful calls', 'thread-state: active filesystem fsync calls', 'thread-state: active filesystem read calls', 'thread-state: active filesystem write calls', @@ -36,7 +57,10 @@ no_scale_per_second_list = [ 'transaction: transaction checkpoint max time (msecs)', 'transaction: transaction checkpoint min time (msecs)', 'transaction: transaction checkpoint most recent time (msecs)', + 'transaction: transaction checkpoint scrub dirty target', + 'transaction: transaction checkpoint scrub time (msecs)', 'transaction: transaction checkpoint total time (msecs)', + 'transaction: transaction fsync duration for checkpoint after allocating the transaction ID (usecs)', 'transaction: transaction range of IDs currently pinned', 'transaction: transaction range of IDs currently pinned by a checkpoint', 'transaction: transaction range of IDs currently pinned by named snapshots', @@ -64,6 +88,7 @@ no_scale_per_second_list = [ 'btree: overflow pages', 'btree: row-store internal pages', 'btree: row-store leaf pages', + 'cache: bytes currently in the cache', 'cache: overflow values cached in memory', 'LSM: bloom filters in the LSM tree', 'LSM: chunks in the LSM tree', @@ -74,8 +99,11 @@ no_scale_per_second_list = [ ] no_clear_list = [ 'async: maximum work queue length', + 'cache: bytes belonging to page images in the cache', 'cache: bytes currently in the cache', + 'cache: bytes not belonging to page images in the cache', 'cache: eviction currently operating in aggressive mode', + 'cache: eviction state', 'cache: files with active eviction walks', 'cache: maximum bytes configured', 'cache: maximum page size at eviction', @@ -83,11 +111,12 @@ no_clear_list = [ 'cache: percentage overhead', 'cache: tracked bytes belonging to internal pages in the cache', 'cache: tracked bytes belonging to leaf pages in the cache', - 'cache: tracked bytes belonging to overflow pages in the cache', 'cache: tracked dirty bytes in the cache', 'cache: tracked dirty pages in the cache', 'connection: files currently open', 'data-handle: connection data handles currently active', + 'log: log sync time duration (usecs)', + 'log: log sync_dir time duration (usecs)', 'log: maximum log file size', 'log: number of pre-allocated log files to create', 'log: total log buffer size', @@ -98,6 +127,22 @@ no_clear_list = [ 'reconciliation: split objects currently awaiting free', 'session: open cursor count', 'session: open session count', + 'session: table compact failed calls', + 'session: table compact successful calls', + 'session: table create failed calls', + 'session: table create successful calls', + 'session: table drop failed calls', + 'session: table drop successful calls', + 'session: table rebalance failed calls', + 'session: table rebalance successful calls', + 'session: table rename failed calls', + 'session: table rename successful calls', + 'session: table salvage failed calls', + 'session: table salvage successful calls', + 'session: table truncate failed calls', + 'session: table truncate successful calls', + 'session: table verify failed calls', + 'session: table verify successful calls', 'thread-state: active filesystem fsync calls', 'thread-state: active filesystem read calls', 'thread-state: active filesystem write calls', @@ -106,11 +151,15 @@ no_clear_list = [ 'transaction: transaction checkpoint max time (msecs)', 'transaction: transaction checkpoint min time (msecs)', 'transaction: transaction checkpoint most recent time (msecs)', + 'transaction: transaction checkpoint scrub dirty target', + 'transaction: transaction checkpoint scrub time (msecs)', 'transaction: transaction checkpoint total time (msecs)', + 'transaction: transaction fsync duration for checkpoint after allocating the transaction ID (usecs)', 'transaction: transaction range of IDs currently pinned', 'transaction: transaction range of IDs currently pinned by a checkpoint', 'transaction: transaction range of IDs currently pinned by named snapshots', 'btree: btree checkpoint generation', + 'cache: bytes currently in the cache', 'session: open cursor count', ] prefix_list = [ diff --git a/src/third_party/wiredtiger/tools/wtstats/wtstats.py b/src/third_party/wiredtiger/tools/wtstats/wtstats.py index ff62d99e825..3549031c30f 100755 --- a/src/third_party/wiredtiger/tools/wtstats/wtstats.py +++ b/src/third_party/wiredtiger/tools/wtstats/wtstats.py @@ -137,6 +137,8 @@ def parse_wtperf_file(file, result): for i, v in enumerate(values): if v == 'N': v = 0 + if v == 'Y': + v = 1 # convert us to ms if '(ms)' in headings[i]: v = float(v) / 1000.0 -- cgit v1.2.1