summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Gorrod <alexander.gorrod@mongodb.com>2016-09-13 10:27:16 +1000
committerAlex Gorrod <alexander.gorrod@mongodb.com>2016-09-13 10:36:27 +1000
commit7d2acd6395ec84beca34718a75371bc11f0c9f60 (patch)
treeac372d3831c551de7397d1058a9d8703e059720f
parent5cb9cc75fe39e183b004ca3f0b641098d06e279c (diff)
downloadmongo-7d2acd6395ec84beca34718a75371bc11f0c9f60.tar.gz
Import wiredtiger: 911c940adab547d36ac305fc627a79e637fa3c40 from branch mongodb-3.2r3.2.10-rc0
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
-rw-r--r--src/third_party/wiredtiger/SConscript17
-rw-r--r--src/third_party/wiredtiger/SConstruct39
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/Makefile.am12
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/config.c71
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/1bn-lsm-50r50u.wtperf20
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/1bn-lsm-80r20u.wtperf18
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/1bn-lsm-populate.wtperf19
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/1bn-lsm-rdonly.wtperf18
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/2bn-lsm-50r50u.wtperf20
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/2bn-lsm-80r20u.wtperf18
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/2bn-lsm-populate.wtperf19
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/2bn-lsm-rdonly.wtperf18
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/500m-btree-50r50u.wtperf17
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/500m-btree-80r20u.wtperf17
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/500m-btree-populate.wtperf24
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/500m-btree-rdonly.wtperf17
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/500m-lsm-50r50u.wtperf20
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/500m-lsm-80r20u.wtperf18
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/500m-lsm-populate.wtperf19
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/500m-lsm-rdonly.wtperf18
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/50m-lsm-50r50u.wtperf19
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/50m-lsm-80r20u.wtperf17
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/50m-lsm-populate.wtperf18
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/50m-lsm-rdonly.wtperf17
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/checkpoint-schema-race.wtperf20
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/checkpoint-stress-schema-ops.wtperf (renamed from src/third_party/wiredtiger/bench/wtperf/runners/checkpoint_stress_schema_ops.wtperf)0
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/checkpoint-stress.wtperf23
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/evict-btree-stress-multi.wtperf12
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/fruit-lsm.wtperf22
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/fruit-short.wtperf20
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/log-append-large.wtperf10
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/log-append-zero.wtperf8
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/log-append.wtperf8
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/log-nockpt.wtperf12
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/log-noprealloc.wtperf11
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/log.wtperf27
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/mongodb-secondary-apply.wtperf21
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/multi-btree-zipfian-populate.wtperf19
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/multi-btree-zipfian-workload.wtperf18
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/overflow-10k-short.wtperf19
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/overflow-10k.wtperf16
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/overflow-130k-short.wtperf19
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/runners/overflow-130k.wtperf18
-rwxr-xr-xsrc/third_party/wiredtiger/bench/wtperf/runners/wtperf_run.sh13
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/wtperf.c295
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/wtperf.h94
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/wtperf_opt.i5
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/wtperf_throttle.c13
-rw-r--r--src/third_party/wiredtiger/bench/wtperf/wtperf_truncate.c35
-rw-r--r--src/third_party/wiredtiger/build_posix/Make.subdirs8
-rw-r--r--src/third_party/wiredtiger/build_posix/aclocal/ax_pkg_swig.m410
-rw-r--r--src/third_party/wiredtiger/build_posix/aclocal/options.m413
-rw-r--r--src/third_party/wiredtiger/build_posix/aclocal/strict.m41
-rw-r--r--src/third_party/wiredtiger/build_posix/configure.ac.in21
-rw-r--r--src/third_party/wiredtiger/build_win/wiredtiger_config.h9
-rw-r--r--src/third_party/wiredtiger/dist/api_config.py6
-rw-r--r--src/third_party/wiredtiger/dist/api_data.py111
-rw-r--r--src/third_party/wiredtiger/dist/filelist8
-rw-r--r--src/third_party/wiredtiger/dist/flags.py6
-rwxr-xr-xsrc/third_party/wiredtiger/dist/s_all16
-rw-r--r--src/third_party/wiredtiger/dist/s_funcs.list1
-rwxr-xr-xsrc/third_party/wiredtiger/dist/s_longlines1
-rwxr-xr-xsrc/third_party/wiredtiger/dist/s_prototypes10
-rw-r--r--src/third_party/wiredtiger/dist/s_string.ok46
-rwxr-xr-xsrc/third_party/wiredtiger/dist/s_style7
-rw-r--r--src/third_party/wiredtiger/dist/s_void134
-rwxr-xr-xsrc/third_party/wiredtiger/dist/s_win2
-rw-r--r--src/third_party/wiredtiger/dist/stat.py11
-rw-r--r--src/third_party/wiredtiger/dist/stat_data.py74
-rw-r--r--src/third_party/wiredtiger/examples/c/ex_all.c14
-rw-r--r--src/third_party/wiredtiger/examples/c/ex_encrypt.c6
-rw-r--r--src/third_party/wiredtiger/examples/c/ex_file_system.c4
-rw-r--r--src/third_party/wiredtiger/ext/collators/revint/revint_collator.c12
-rw-r--r--src/third_party/wiredtiger/ext/compressors/zlib/zlib_compress.c2
-rw-r--r--src/third_party/wiredtiger/ext/encryptors/rotn/rotn_encrypt.c13
-rw-r--r--src/third_party/wiredtiger/ext/test/kvs_bdb/kvs_bdb.c7
-rw-r--r--src/third_party/wiredtiger/lang/java/Makefile.am1
-rw-r--r--src/third_party/wiredtiger/lang/java/wiredtiger.i1
-rw-r--r--src/third_party/wiredtiger/src/async/async_api.c22
-rw-r--r--src/third_party/wiredtiger/src/async/async_op.c7
-rw-r--r--src/third_party/wiredtiger/src/async/async_worker.c11
-rw-r--r--src/third_party/wiredtiger/src/block/block_addr.c42
-rw-r--r--src/third_party/wiredtiger/src/block/block_ckpt.c116
-rw-r--r--src/third_party/wiredtiger/src/block/block_compact.c65
-rw-r--r--src/third_party/wiredtiger/src/block/block_ext.c77
-rw-r--r--src/third_party/wiredtiger/src/block/block_map.c2
-rw-r--r--src/third_party/wiredtiger/src/block/block_mgr.c52
-rw-r--r--src/third_party/wiredtiger/src/block/block_open.c31
-rw-r--r--src/third_party/wiredtiger/src/block/block_read.c42
-rw-r--r--src/third_party/wiredtiger/src/block/block_session.c2
-rw-r--r--src/third_party/wiredtiger/src/block/block_slvg.c26
-rw-r--r--src/third_party/wiredtiger/src/block/block_vrfy.c13
-rw-r--r--src/third_party/wiredtiger/src/block/block_write.c203
-rw-r--r--src/third_party/wiredtiger/src/bloom/bloom.c16
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_compact.c4
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_curnext.c2
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_curprev.c2
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_cursor.c2
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_debug.c478
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_discard.c19
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_handle.c25
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_io.c21
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_ovfl.c15
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_page.c7
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_read.c50
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_rebalance.c20
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_slvg.c91
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_split.c197
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_stat.c5
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_sync.c62
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_vrfy.c10
-rw-r--r--src/third_party/wiredtiger/src/btree/bt_walk.c20
-rw-r--r--src/third_party/wiredtiger/src/btree/row_key.c6
-rw-r--r--src/third_party/wiredtiger/src/btree/row_modify.c15
-rw-r--r--src/third_party/wiredtiger/src/btree/row_srch.c2
-rw-r--r--src/third_party/wiredtiger/src/cache/cache_las.c6
-rw-r--r--src/third_party/wiredtiger/src/checksum/arm64/crc32-arm64.c101
-rw-r--r--src/third_party/wiredtiger/src/checksum/power8/crc32_wrapper.c36
-rw-r--r--src/third_party/wiredtiger/src/checksum/software/checksum.c (renamed from src/third_party/wiredtiger/src/checksum/checksum.c)172
-rw-r--r--src/third_party/wiredtiger/src/checksum/x86/crc32-x86.c160
-rw-r--r--src/third_party/wiredtiger/src/checksum/zseries/LICENSE.TXT482
-rw-r--r--src/third_party/wiredtiger/src/checksum/zseries/README.md61
-rw-r--r--src/third_party/wiredtiger/src/checksum/zseries/crc32-s390x.c96
-rw-r--r--src/third_party/wiredtiger/src/checksum/zseries/crc32-s390x.h12
-rw-r--r--src/third_party/wiredtiger/src/checksum/zseries/crc32le-vx.S280
-rw-r--r--src/third_party/wiredtiger/src/checksum/zseries/slicing-consts.h2096
-rw-r--r--src/third_party/wiredtiger/src/checksum/zseries/vx-insn.h480
-rw-r--r--src/third_party/wiredtiger/src/config/config.c24
-rw-r--r--src/third_party/wiredtiger/src/config/config_api.c11
-rw-r--r--src/third_party/wiredtiger/src/config/config_check.c10
-rw-r--r--src/third_party/wiredtiger/src/config/config_collapse.c4
-rw-r--r--src/third_party/wiredtiger/src/config/config_def.c356
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_api.c14
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_cache.c104
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_cache_pool.c103
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_ckpt.c61
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_dhandle.c32
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_handle.c2
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_log.c133
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_open.c33
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_stat.c9
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_sweep.c35
-rw-r--r--src/third_party/wiredtiger/src/cursor/cur_backup.c54
-rw-r--r--src/third_party/wiredtiger/src/cursor/cur_config.c4
-rw-r--r--src/third_party/wiredtiger/src/cursor/cur_ds.c5
-rw-r--r--src/third_party/wiredtiger/src/cursor/cur_dump.c4
-rw-r--r--src/third_party/wiredtiger/src/cursor/cur_file.c38
-rw-r--r--src/third_party/wiredtiger/src/cursor/cur_index.c56
-rw-r--r--src/third_party/wiredtiger/src/cursor/cur_join.c23
-rw-r--r--src/third_party/wiredtiger/src/cursor/cur_json.c11
-rw-r--r--src/third_party/wiredtiger/src/cursor/cur_log.c28
-rw-r--r--src/third_party/wiredtiger/src/cursor/cur_metadata.c163
-rw-r--r--src/third_party/wiredtiger/src/cursor/cur_stat.c28
-rw-r--r--src/third_party/wiredtiger/src/cursor/cur_std.c7
-rw-r--r--src/third_party/wiredtiger/src/cursor/cur_table.c19
-rw-r--r--src/third_party/wiredtiger/src/docs/custom-file-systems.dox43
-rw-r--r--src/third_party/wiredtiger/src/docs/license.dox15
-rw-r--r--src/third_party/wiredtiger/src/docs/readonly.dox3
-rw-r--r--src/third_party/wiredtiger/src/docs/spell.ok5
-rw-r--r--src/third_party/wiredtiger/src/docs/tune-cache.dox50
-rw-r--r--src/third_party/wiredtiger/src/docs/upgrading.dox41
-rw-r--r--src/third_party/wiredtiger/src/docs/wtperf.dox6
-rw-r--r--src/third_party/wiredtiger/src/evict/evict_lru.c1421
-rw-r--r--src/third_party/wiredtiger/src/evict/evict_page.c221
-rw-r--r--src/third_party/wiredtiger/src/include/api.h6
-rw-r--r--src/third_party/wiredtiger/src/include/block.h15
-rw-r--r--src/third_party/wiredtiger/src/include/btmem.h54
-rw-r--r--src/third_party/wiredtiger/src/include/btree.h16
-rw-r--r--src/third_party/wiredtiger/src/include/btree.i257
-rw-r--r--src/third_party/wiredtiger/src/include/buf.i3
-rw-r--r--src/third_party/wiredtiger/src/include/cache.h117
-rw-r--r--src/third_party/wiredtiger/src/include/cache.i186
-rw-r--r--src/third_party/wiredtiger/src/include/connection.h19
-rw-r--r--src/third_party/wiredtiger/src/include/cursor.h10
-rw-r--r--src/third_party/wiredtiger/src/include/cursor.i2
-rw-r--r--src/third_party/wiredtiger/src/include/error.h4
-rw-r--r--src/third_party/wiredtiger/src/include/extern.h1181
-rw-r--r--src/third_party/wiredtiger/src/include/extern_posix.h42
-rw-r--r--src/third_party/wiredtiger/src/include/extern_win.h42
-rw-r--r--src/third_party/wiredtiger/src/include/flags.h22
-rw-r--r--src/third_party/wiredtiger/src/include/hardware.h11
-rw-r--r--src/third_party/wiredtiger/src/include/intpack.i8
-rw-r--r--src/third_party/wiredtiger/src/include/log.h4
-rw-r--r--src/third_party/wiredtiger/src/include/misc.h5
-rw-r--r--src/third_party/wiredtiger/src/include/misc.i23
-rw-r--r--src/third_party/wiredtiger/src/include/mutex.h20
-rw-r--r--src/third_party/wiredtiger/src/include/mutex.i126
-rw-r--r--src/third_party/wiredtiger/src/include/os_fhandle.i92
-rw-r--r--src/third_party/wiredtiger/src/include/os_fs.i16
-rw-r--r--src/third_party/wiredtiger/src/include/os_fstream.i15
-rw-r--r--src/third_party/wiredtiger/src/include/packing.i6
-rw-r--r--src/third_party/wiredtiger/src/include/queue.h174
-rw-r--r--src/third_party/wiredtiger/src/include/serial.i4
-rw-r--r--src/third_party/wiredtiger/src/include/stat.h41
-rw-r--r--src/third_party/wiredtiger/src/include/thread_group.h61
-rw-r--r--src/third_party/wiredtiger/src/include/txn.i25
-rw-r--r--src/third_party/wiredtiger/src/include/wiredtiger.in753
-rw-r--r--src/third_party/wiredtiger/src/include/wt_internal.h11
-rw-r--r--src/third_party/wiredtiger/src/log/log.c287
-rw-r--r--src/third_party/wiredtiger/src/log/log_slot.c2
-rw-r--r--src/third_party/wiredtiger/src/lsm/lsm_cursor.c29
-rw-r--r--src/third_party/wiredtiger/src/lsm/lsm_manager.c26
-rw-r--r--src/third_party/wiredtiger/src/lsm/lsm_merge.c47
-rw-r--r--src/third_party/wiredtiger/src/lsm/lsm_meta.c51
-rw-r--r--src/third_party/wiredtiger/src/lsm/lsm_stat.c4
-rw-r--r--src/third_party/wiredtiger/src/lsm/lsm_tree.c135
-rw-r--r--src/third_party/wiredtiger/src/lsm/lsm_work_unit.c72
-rw-r--r--src/third_party/wiredtiger/src/lsm/lsm_worker.c11
-rw-r--r--src/third_party/wiredtiger/src/meta/meta_ckpt.c11
-rw-r--r--src/third_party/wiredtiger/src/meta/meta_table.c19
-rw-r--r--src/third_party/wiredtiger/src/meta/meta_track.c3
-rw-r--r--src/third_party/wiredtiger/src/os_common/os_fhandle.c26
-rw-r--r--src/third_party/wiredtiger/src/os_common/os_fs_inmemory.c36
-rw-r--r--src/third_party/wiredtiger/src/os_common/os_fstream_stdio.c4
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_fallocate.c85
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_fs.c8
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_map.c4
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_mtx_cond.c49
-rw-r--r--src/third_party/wiredtiger/src/os_win/os_dir.c32
-rw-r--r--src/third_party/wiredtiger/src/os_win/os_dlopen.c4
-rw-r--r--src/third_party/wiredtiger/src/os_win/os_fs.c126
-rw-r--r--src/third_party/wiredtiger/src/os_win/os_map.c8
-rw-r--r--src/third_party/wiredtiger/src/os_win/os_mtx_cond.c49
-rw-r--r--src/third_party/wiredtiger/src/os_win/os_utf8.c84
-rw-r--r--src/third_party/wiredtiger/src/reconcile/rec_track.c42
-rw-r--r--src/third_party/wiredtiger/src/reconcile/rec_write.c370
-rw-r--r--src/third_party/wiredtiger/src/schema/schema_create.c6
-rw-r--r--src/third_party/wiredtiger/src/schema/schema_open.c10
-rw-r--r--src/third_party/wiredtiger/src/schema/schema_plan.c16
-rw-r--r--src/third_party/wiredtiger/src/schema/schema_stat.c2
-rw-r--r--src/third_party/wiredtiger/src/session/session_api.c180
-rw-r--r--src/third_party/wiredtiger/src/session/session_compact.c14
-rw-r--r--src/third_party/wiredtiger/src/session/session_dhandle.c28
-rw-r--r--src/third_party/wiredtiger/src/support/cond_auto.c17
-rw-r--r--src/third_party/wiredtiger/src/support/err.c23
-rw-r--r--src/third_party/wiredtiger/src/support/global.c12
-rw-r--r--src/third_party/wiredtiger/src/support/hazard.c19
-rw-r--r--src/third_party/wiredtiger/src/support/huffman.c4
-rw-r--r--src/third_party/wiredtiger/src/support/mtx_rw.c85
-rw-r--r--src/third_party/wiredtiger/src/support/stat.c136
-rw-r--r--src/third_party/wiredtiger/src/support/thread_group.c336
-rw-r--r--src/third_party/wiredtiger/src/txn/txn.c32
-rw-r--r--src/third_party/wiredtiger/src/txn/txn_ckpt.c499
-rw-r--r--src/third_party/wiredtiger/src/txn/txn_log.c7
-rw-r--r--src/third_party/wiredtiger/src/txn/txn_nsnap.c11
-rw-r--r--src/third_party/wiredtiger/src/txn/txn_recover.c16
-rw-r--r--src/third_party/wiredtiger/src/utilities/util.h3
-rw-r--r--src/third_party/wiredtiger/src/utilities/util_dump.c210
-rw-r--r--src/third_party/wiredtiger/src/utilities/util_list.c54
-rw-r--r--src/third_party/wiredtiger/src/utilities/util_misc.c15
-rw-r--r--src/third_party/wiredtiger/test/bloom/test_bloom.c3
-rw-r--r--src/third_party/wiredtiger/test/checkpoint/test_checkpoint.c9
-rw-r--r--src/third_party/wiredtiger/test/csuite/Makefile.am15
-rw-r--r--src/third_party/wiredtiger/test/csuite/wt1965_col_efficiency/main.c3
-rw-r--r--src/third_party/wiredtiger/test/csuite/wt2246_col_append/main.c4
-rw-r--r--src/third_party/wiredtiger/test/csuite/wt2323_join_visibility/main.c402
-rw-r--r--src/third_party/wiredtiger/test/csuite/wt2447_join_main_table/main.c3
-rw-r--r--src/third_party/wiredtiger/test/csuite/wt2695_checksum/main.c143
-rw-r--r--src/third_party/wiredtiger/test/csuite/wt2719_reconfig/main.c283
-rw-r--r--src/third_party/wiredtiger/test/csuite/wt2834_join_bloom_fix/main.c199
-rw-r--r--src/third_party/wiredtiger/test/csuite/wt2853_perf/main.c330
-rw-r--r--src/third_party/wiredtiger/test/cursor_order/cursor_order_ops.c3
-rw-r--r--src/third_party/wiredtiger/test/format/bdb.c1
-rw-r--r--src/third_party/wiredtiger/test/format/config.h8
-rw-r--r--src/third_party/wiredtiger/test/format/format.h17
-rw-r--r--src/third_party/wiredtiger/test/format/ops.c6
-rw-r--r--src/third_party/wiredtiger/test/format/rebalance.c10
-rw-r--r--src/third_party/wiredtiger/test/format/salvage.c2
-rwxr-xr-xsrc/third_party/wiredtiger/test/format/smoke.sh2
-rw-r--r--src/third_party/wiredtiger/test/format/t.c12
-rw-r--r--src/third_party/wiredtiger/test/format/util.c16
-rw-r--r--src/third_party/wiredtiger/test/format/wts.c16
-rw-r--r--src/third_party/wiredtiger/test/java/com/wiredtiger/test/ConcurrentCloseTest.java179
-rw-r--r--src/third_party/wiredtiger/test/manydbs/Makefile.am3
-rw-r--r--src/third_party/wiredtiger/test/manydbs/manydbs.c5
-rwxr-xr-xsrc/third_party/wiredtiger/test/manydbs/smoke.sh18
-rw-r--r--src/third_party/wiredtiger/test/mciproject.yml49
-rw-r--r--src/third_party/wiredtiger/test/recovery/Makefile.am3
-rw-r--r--src/third_party/wiredtiger/test/recovery/random-abort.c18
-rwxr-xr-xsrc/third_party/wiredtiger/test/recovery/smoke.sh8
-rw-r--r--src/third_party/wiredtiger/test/recovery/truncated-log.c115
-rw-r--r--src/third_party/wiredtiger/test/salvage/salvage.c4
-rw-r--r--src/third_party/wiredtiger/test/suite/helper.py43
-rw-r--r--src/third_party/wiredtiger/test/suite/run.py41
-rw-r--r--src/third_party/wiredtiger/test/suite/test_async01.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_async02.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_backup02.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_backup03.py36
-rw-r--r--src/third_party/wiredtiger/test/suite/test_backup04.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_backup05.py1
-rw-r--r--src/third_party/wiredtiger/test/suite/test_base02.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_base05.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_bug003.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_bug006.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_bug008.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_bug009.py1
-rw-r--r--src/third_party/wiredtiger/test/suite/test_bug011.py2
-rw-r--r--src/third_party/wiredtiger/test/suite/test_bug016.py109
-rw-r--r--src/third_party/wiredtiger/test/suite/test_bulk01.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_bulk02.py7
-rw-r--r--src/third_party/wiredtiger/test/suite/test_checkpoint01.py14
-rw-r--r--src/third_party/wiredtiger/test/suite/test_checkpoint02.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_colgap.py6
-rw-r--r--src/third_party/wiredtiger/test/suite/test_collator.py1
-rw-r--r--src/third_party/wiredtiger/test/suite/test_compact01.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_compact02.py7
-rw-r--r--src/third_party/wiredtiger/test/suite/test_compress01.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_config03.py7
-rw-r--r--src/third_party/wiredtiger/test/suite/test_config04.py2
-rw-r--r--src/third_party/wiredtiger/test/suite/test_cursor01.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_cursor02.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_cursor03.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_cursor04.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_cursor06.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_cursor07.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_cursor08.py12
-rw-r--r--src/third_party/wiredtiger/test/suite/test_cursor09.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_cursor_compare.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_cursor_pin.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_cursor_random.py8
-rw-r--r--src/third_party/wiredtiger/test/suite/test_cursor_random02.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_drop.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_dump.py11
-rw-r--r--src/third_party/wiredtiger/test/suite/test_dupc.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_durability01.py1
-rw-r--r--src/third_party/wiredtiger/test/suite/test_empty.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_encrypt01.py5
-rw-r--r--src/third_party/wiredtiger/test/suite/test_encrypt02.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_encrypt03.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_encrypt04.py5
-rw-r--r--src/third_party/wiredtiger/test/suite/test_encrypt05.py5
-rw-r--r--src/third_party/wiredtiger/test/suite/test_encrypt06.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_encrypt07.py1
-rw-r--r--src/third_party/wiredtiger/test/suite/test_excl.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_huffman01.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_huffman02.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_index02.py68
-rw-r--r--src/third_party/wiredtiger/test/suite/test_inmem01.py88
-rw-r--r--src/third_party/wiredtiger/test/suite/test_intpack.py35
-rw-r--r--src/third_party/wiredtiger/test/suite/test_join01.py10
-rw-r--r--src/third_party/wiredtiger/test/suite/test_join02.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_join03.py1
-rw-r--r--src/third_party/wiredtiger/test/suite/test_join04.py1
-rw-r--r--src/third_party/wiredtiger/test/suite/test_join05.py1
-rw-r--r--src/third_party/wiredtiger/test/suite/test_join06.py23
-rw-r--r--src/third_party/wiredtiger/test/suite/test_join07.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_join08.py1
-rw-r--r--src/third_party/wiredtiger/test/suite/test_jsondump01.py50
-rw-r--r--src/third_party/wiredtiger/test/suite/test_lsm01.py8
-rw-r--r--src/third_party/wiredtiger/test/suite/test_metadata_cursor01.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_nsnap01.py1
-rw-r--r--src/third_party/wiredtiger/test/suite/test_nsnap02.py1
-rw-r--r--src/third_party/wiredtiger/test/suite/test_nsnap03.py1
-rw-r--r--src/third_party/wiredtiger/test/suite/test_nsnap04.py1
-rw-r--r--src/third_party/wiredtiger/test/suite/test_overwrite.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_perf001.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_readonly01.py5
-rw-r--r--src/third_party/wiredtiger/test/suite/test_rebalance.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_reconfig01.py2
-rw-r--r--src/third_party/wiredtiger/test/suite/test_reconfig03.py66
-rw-r--r--src/third_party/wiredtiger/test/suite/test_rename.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_schema02.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_schema03.py15
-rw-r--r--src/third_party/wiredtiger/test/suite/test_schema04.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_schema05.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_schema06.py5
-rw-r--r--src/third_party/wiredtiger/test/suite/test_split.py1
-rw-r--r--src/third_party/wiredtiger/test/suite/test_stat01.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_stat02.py35
-rw-r--r--src/third_party/wiredtiger/test/suite/test_stat03.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_stat04.py10
-rw-r--r--src/third_party/wiredtiger/test/suite/test_stat05.py13
-rw-r--r--src/third_party/wiredtiger/test/suite/test_sweep01.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_sweep03.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_truncate01.py13
-rw-r--r--src/third_party/wiredtiger/test/suite/test_truncate02.py5
-rw-r--r--src/third_party/wiredtiger/test/suite/test_txn01.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_txn02.py12
-rw-r--r--src/third_party/wiredtiger/test/suite/test_txn03.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_txn04.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_txn05.py5
-rw-r--r--src/third_party/wiredtiger/test/suite/test_txn06.py1
-rw-r--r--src/third_party/wiredtiger/test/suite/test_txn07.py17
-rw-r--r--src/third_party/wiredtiger/test/suite/test_txn08.py1
-rw-r--r--src/third_party/wiredtiger/test/suite/test_txn09.py9
-rw-r--r--src/third_party/wiredtiger/test/suite/test_txn10.py1
-rw-r--r--src/third_party/wiredtiger/test/suite/test_txn12.py1
-rw-r--r--src/third_party/wiredtiger/test/suite/test_txn13.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_txn14.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_txn15.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_upgrade.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_util02.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_util03.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/test_util13.py4
-rw-r--r--src/third_party/wiredtiger/test/suite/wtscenario.py36
-rw-r--r--src/third_party/wiredtiger/test/suite/wttest.py6
-rw-r--r--src/third_party/wiredtiger/test/thread/rw.c8
-rwxr-xr-xsrc/third_party/wiredtiger/test/thread/smoke.sh6
-rw-r--r--src/third_party/wiredtiger/test/utility/misc.c42
-rw-r--r--src/third_party/wiredtiger/test/utility/parse_opts.c2
-rw-r--r--src/third_party/wiredtiger/test/utility/test_util.h5
-rw-r--r--src/third_party/wiredtiger/test/windows/windows_shim.c11
-rw-r--r--src/third_party/wiredtiger/test/windows/windows_shim.h2
-rw-r--r--src/third_party/wiredtiger/tools/wtstats/stat_data.py53
-rwxr-xr-xsrc/third_party/wiredtiger/tools/wtstats/wtstats.py2
405 files changed, 14069 insertions, 6540 deletions
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
index b69ead7f8b1..b69ead7f8b1 100644
--- 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
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/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. */
@@ -155,6 +154,23 @@ randomize_value(CONFIG_THREAD *thread, char *value_buf)
}
/*
+ * 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
* scratch buffer.
@@ -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 <wt_internal.h>
+#include "test_util.h"
+
#include <assert.h>
#include <math.h>
-#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 <sebastian-huber@web.de>
-# Copyright (c) 2008 Alan W. Irwin <irwin@beluga.phys.uvic.ca>
+# Copyright (c) 2008 Alan W. Irwin
# Copyright (c) 2008 Rafael Laboissiere <rafael@laboissiere.net>
-# Copyright (c) 2008 Andrew Collier <colliera@ukzn.ac.za>
+# Copyright (c) 2008 Andrew Collier
# Copyright (c) 2011 Murray Cumming <murrayc@openismus.com>
#
# 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 <code>50 * leaf_page_max</code>, and an upper bound of
- <code>cache_size / 2</code>. This limit is soft - it is possible
+ bound of <code>leaf_page_max</code>, and an upper bound of
+ <code>cache_size / 10</code>. 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 <stdlib.h>
#include <string.h>
+/*
+ * 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 <db.h>
#include <wiredtiger.h>
#include <wiredtiger_ext.h>
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
@@ -475,6 +461,15 @@ __ckpt_process(WT_SESSION_IMPL *session, WT_BLOCK *block, WT_CKPT *ckptbase)
}
/*
+ * 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
* much time away from real work: we read the historic checkpoint
@@ -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
@@ -381,16 +381,6 @@ restart: /*
__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
* hazard pointer is required, release the one we hold.
@@ -404,6 +394,16 @@ restart: /*
}
/*
+ * 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
* handle restart or not-found returns, it would require
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 <asm/hwcap.h>
+#include <sys/auxv.h>
+
+#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/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/checksum.c b/src/third_party/wiredtiger/src/checksum/software/checksum.c
index b6a76dacfd8..30362584a3e 100644
--- a/src/third_party/wiredtiger/src/checksum/checksum.c
+++ b/src/third_party/wiredtiger/src/checksum/software/checksum.c
@@ -41,15 +41,7 @@
#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.
+ * The CRC slicing tables.
*/
static const uint32_t g_crc_slicing[8][256] = {
#ifdef WORDS_BIGENDIAN
@@ -1103,13 +1095,12 @@ static const uint32_t g_crc_slicing[8][256] = {
#endif
};
-#if !defined(__powerpc64__)
/*
- * __wt_cksum_sw --
+ * __wt_checksum_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
+__wt_checksum_sw(const void *chunk, size_t len)
{
uint32_t crc, next;
size_t nqwords;
@@ -1172,158 +1163,3 @@ __wt_cksum_sw(const void *chunk, size_t len)
#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/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 <brueckner@linux.vnet.ibm.com>
+ Anton Blanchard <anton@au.ibm.com>
+ Bryan Chan <bryan.chan@ca.ibm.com>
+ Chris Zou <chriszou@ca.ibm.com>
+
+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 <brueckner@linux.vnet.ibm.com>
+ *
+ */
+#include <sys/types.h>
+#include <endian.h>
+#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 <sys/types.h>
+
+/* 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 <brueckner@linux.vnet.ibm.com>
+ */
+
+#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 <brueckner@linux.vnet.ibm.com>
+ */
+
+#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;
@@ -34,24 +33,6 @@ __ckpt_server_config(WT_SESSION_IMPL *session, const char **cfg, bool *startp)
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
* size also require logging be enabled.
@@ -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);
}
/*
@@ -64,6 +60,16 @@ __conn_dhandle_alloc(WT_SESSION_IMPL *session,
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
@@ -37,22 +37,6 @@ __curstat_print_value(WT_SESSION_IMPL *session, uint64_t v, WT_ITEM *buf)
}
/*
- * __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}
</table>
-@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.
<table>
@hrow{Distribution Files, Copyright Holder, License}
-@row{\c src/support/power8/*, Anton Blanchard, <a href="http://opensource.org/licenses/Apache-2.0">Apache License\, Version 2.0</a> or the <a href="http://www.gnu.org/licenses/gpl-2.0-standalone.html">GNU General Public License\, version 2 or later</a>}
+@row{\c src/support/power8/*, Anton Blanchard\, IBM Corp., <a href="http://opensource.org/licenses/Apache-2.0">Apache License\, Version 2.0</a> or the <a href="http://www.gnu.org/licenses/gpl-2.0-standalone.html">GNU General Public License\, version 2 or later</a>}
+</table>
+
+@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.
+
+<table>
+@hrow{Distribution Files, Copyright Holder, License}
+@row{\c src/support/zseries/*, IBM Corp., <a href="http://opensource.org/licenses/Apache-2.0">Apache License\, Version 2.0</a> or the <a href="http://www.gnu.org/licenses/gpl-2.0-standalone.html">GNU General Public License\, version 2 or later</a>}
</table>
@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
<dl>
+<dt>Cache management defaults</dt>
+<dd>
+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.
+</dd>
+
+<dt>Checkpoint server created checkpoint names</dt>
+<dd>
+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.
+</dd>
+
<dt>Statistics logging path</dt>
<dd>
-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.
+</dd>
+
+<dt>Deprecated statistics field</dt>
+<dd>
+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.
</dd>
</dl><hr>
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);
}
/*
@@ -140,10 +143,33 @@ __wt_evict_list_clear_page(WT_SESSION_IMPL *session, WT_REF *ref)
}
/*
+ * __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
}
@@ -322,110 +351,31 @@ __evict_server(WT_SESSION_IMPL *session, bool *did_work)
}
/*
- * __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);
@@ -1464,43 +1467,6 @@ fast: /* If the page can't be evicted, give up. */
}
/*
- * __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,46 +1743,109 @@ __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,14 +31,23 @@ __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);
@@ -46,6 +55,55 @@ __evict_exclusive(WT_SESSION_IMPL *session, WT_REF *ref)
}
/*
+ * __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
@@ -222,13 +257,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
* page re-instantiated (for example, by searching) and never written.
@@ -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,24 +325,15 @@ __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.
*
* Publish: a barrier to ensure the structure fields are set
@@ -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
@@ -55,28 +55,66 @@ __wt_btree_block_free(
}
/*
+ * __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.
*/
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);
}
/*
@@ -136,6 +174,22 @@ __wt_cache_decr_check_uint64(
}
/*
+ * __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");
}
}
@@ -196,18 +263,17 @@ __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)
@@ -261,21 +334,52 @@ __wt_cache_dirty_decr(WT_SESSION_IMPL *session, WT_PAGE *page)
}
/*
+ * __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.
*/
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. */
@@ -318,16 +425,6 @@ __wt_update_list_memsize(WT_UPDATE *upd)
}
/*
- * __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,72 +1260,16 @@ __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.
@@ -143,26 +169,19 @@ struct __wt_cache {
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
@@ -7,6 +7,17 @@
*/
/*
+ * __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.
*/
@@ -68,6 +79,33 @@ __wt_cache_read_gen_new(WT_SESSION_IMPL *session, WT_PAGE *page)
}
/*
+ * __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.
*/
@@ -78,21 +116,26 @@ __wt_cache_pages_inuse(WT_CACHE *cache)
}
/*
+ * __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.
*/
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));
}
/*
@@ -139,28 +216,18 @@ __wt_session_can_wait(WT_SESSION_IMPL *session)
}
/*
- * __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,12 +299,28 @@ 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
* block eviction), we don't want to highjack the thread for eviction.
@@ -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, &notused));
+ __wt_cond_wait_signal(session, cond, usecs, &notused);
}
/*
@@ -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;
@@ -59,24 +59,6 @@ struct __wt_rwlock {
};
/*
- * 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:
*
* WiredTiger uses spinlocks for fast mutual exclusion (where operations done
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 <code>50 * leaf_page_max</code>\, and an
- * upper bound of <code>cache_size / 2</code>. This limit is soft - it
+ * adjusted to a lower bound of <code>leaf_page_max</code>\, and an
+ * upper bound of <code>cache_size / 10</code>. 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{&nbsp;&nbsp;&nbsp;&nbsp;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{&nbsp;&nbsp;&nbsp;&nbsp;name, the checkpoint name., a string;
- * default \c "WiredTigerCheckpoint".}
* @config{&nbsp;&nbsp;&nbsp;&nbsp;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{&nbsp;&nbsp;&nbsp;&nbsp;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{&nbsp;&nbsp;&nbsp;&nbsp;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{&nbsp;&nbsp;&nbsp;&nbsp;name, the
- * checkpoint name., a string; default \c "WiredTigerCheckpoint".}
- * @config{&nbsp;&nbsp;&nbsp;&nbsp;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{&nbsp;&nbsp;&nbsp;&nbsp;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 <code>"write_through=[data]"</code>. 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 <sys/mman.h>
+#endif
#include <sys/stat.h>
+#ifndef _WIN32
#include <sys/time.h>
#include <sys/uio.h>
#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
@@ -947,6 +959,39 @@ __wt_log_acquire(WT_SESSION_IMPL *session, uint64_t recsize, WT_LOGSLOT *slot)
}
/*
+ * __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
* truncate the log file indicated in the given LSN. If not set,
@@ -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
@@ -391,41 +391,6 @@ __im_file_sync(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session)
}
/*
- * __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,10 +159,17 @@ 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;
@@ -2771,6 +2803,26 @@ no_slots:
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
* update the starting record number, free space and so on.
@@ -2884,48 +2936,6 @@ split_grow: /*
}
/*
- * __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)
@@ -1216,13 +1449,59 @@ err: /*
}
/*
+ * __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).
*/
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 <assert.h>
#include <db.h>
#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<Thread> threads = new ArrayList<Thread>();
+ 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/<testname>\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);
@@ -139,6 +149,23 @@ testutil_cleanup(TEST_OPTS *opts)
}
/*
+ * 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
@@ -105,6 +105,17 @@ pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
}
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)
{
AcquireSRWLockExclusive(&rwlock->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 <windows.h>
+#include <errno.h>
#include <stdint.h>
#include <direct.h>
#include <io.h>
@@ -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