1use crate::durability::Durability;
11use crate::error::ExceptionListener;
12use std::fmt;
13use std::path::PathBuf;
14use std::sync::Arc;
15
16#[derive(Clone, Default)]
21pub struct ExceptionListenerHolder(pub Option<Arc<dyn ExceptionListener>>);
22
23impl fmt::Debug for ExceptionListenerHolder {
24 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
25 match &self.0 {
26 None => f.write_str("None"),
27 Some(_) => f.write_str("Some(<ExceptionListener>)"),
28 }
29 }
30}
31
32#[derive(Debug, Clone)]
38pub struct EnvironmentConfig {
39 pub home: PathBuf,
44
45 pub allow_create: bool,
48
49 pub transactional: bool,
52
53 pub read_only: bool,
56
57 pub env_is_locking: bool,
61
62 pub shared_cache: bool,
67
68 pub env_recovery_force_checkpoint: bool,
71
72 pub env_recovery_force_new_file: bool,
75
76 pub halt_on_commit_after_checksum_exception: bool,
79
80 pub logging_level: Option<String>,
84
85 pub cache_size: u64,
92
93 pub cache_percent: u32,
97
98 pub max_off_heap_memory: u64,
101
102 pub max_disk: u64,
105
106 pub free_disk: u64,
110
111 pub run_in_compressor: bool,
117
118 pub run_checkpointer: bool,
121
122 pub run_cleaner: bool,
125
126 pub run_evictor: bool,
129
130 pub run_offheap_evictor: bool,
133
134 pub run_verifier: bool,
137
138 pub env_background_read_limit_kb: u32,
144
145 pub env_background_write_limit_kb: u32,
148
149 pub env_background_sleep_interval_us: u64,
153
154 pub env_check_leaks: bool,
165
166 pub env_forced_yield: bool,
174
175 pub env_fair_latches: bool,
184
185 pub env_latch_timeout_ms: u64,
194
195 pub env_ttl_clock_tolerance_ms: u64,
204
205 pub env_expiration_enabled: bool,
213
214 pub env_db_eviction: bool,
222
223 pub env_dup_convert_preload_all: bool,
226
227 pub adler32_chunk_size: usize,
230
231 pub log_file_max_bytes: u64,
237
238 pub log_file_cache_size: usize,
241
242 pub log_checksum_read: bool,
245
246 pub log_verify_checksums: bool,
250
251 pub log_fsync_timeout_ms: u64,
254
255 pub log_fsync_time_limit_ms: u64,
259
260 pub log_num_buffers: usize,
263
264 pub log_total_buffer_bytes: u64,
267
268 pub log_buffer_size: usize,
272
273 pub log_fault_read_size: usize,
276
277 pub log_iterator_read_size: usize,
280
281 pub log_iterator_max_size: usize,
284
285 pub log_n_data_directories: u32,
288
289 pub log_mem_only: bool,
292
293 pub log_detect_file_delete: bool,
296
297 pub log_detect_file_delete_interval_ms: u64,
300
301 pub log_flush_sync_interval_ms: u64,
304
305 pub log_flush_no_sync_interval_ms: u64,
309
310 pub log_use_odsync: bool,
314
315 pub log_use_write_queue: bool,
318
319 pub log_write_queue_size: usize,
322
323 pub log_group_commit_threshold: usize,
326
327 pub log_group_commit_interval_ms: u64,
330
331 pub node_max_entries: u32,
337
338 pub node_dup_tree_max_entries: u32,
341
342 pub tree_max_embedded_ln: u32,
346
347 pub tree_max_delta: u8,
351
352 pub tree_bin_delta: bool,
355
356 pub tree_min_memory: u64,
359
360 pub tree_compact_max_key_length: u32,
363
364 pub in_compressor_wakeup_interval_ms: u64,
370
371 pub compressor_deadlock_retry: u32,
374
375 pub compressor_lock_timeout_ms: u64,
378
379 pub compressor_purge_root: bool,
382
383 pub cleaner_min_utilization: u8,
389
390 pub cleaner_min_file_utilization: u8,
393
394 pub cleaner_threads: u32,
397
398 pub cleaner_min_file_count: u32,
401
402 pub cleaner_min_age: u32,
405
406 pub cleaner_bytes_interval: u64,
409
410 pub cleaner_wakeup_interval_ms: u64,
413
414 pub cleaner_fetch_obsolete_size: bool,
417
418 pub cleaner_adjust_utilization: bool,
421
422 pub cleaner_deadlock_retry: u32,
425
426 pub cleaner_lock_timeout_ms: u64,
429
430 pub cleaner_expunge: bool,
434
435 pub cleaner_use_deleted_dir: bool,
439
440 pub cleaner_max_batch_files: u32,
443
444 pub cleaner_read_size: usize,
447
448 pub cleaner_detail_max_memory_percentage: u32,
451
452 pub cleaner_look_ahead_cache_size: usize,
455
456 pub cleaner_foreground_proactive_migration: bool,
459
460 pub cleaner_background_proactive_migration: bool,
463
464 pub cleaner_lazy_migration: bool,
467
468 pub cleaner_expiration_enabled: bool,
471
472 pub checkpointer_bytes_interval: u64,
478
479 pub checkpointer_wakeup_interval_ms: u64,
482
483 pub checkpointer_min_interval_secs: u64,
486
487 pub checkpointer_deadlock_retry: u32,
490
491 pub checkpointer_high_priority: bool,
494
495 pub evictor_nodes_per_scan: usize,
501
502 pub evictor_evict_bytes: u64,
505
506 pub evictor_critical_percentage: u32,
509
510 pub evictor_lru_only: bool,
513
514 pub evictor_n_lru_lists: u32,
517
518 pub evictor_deadlock_retry: u32,
521
522 pub evictor_core_threads: usize,
525
526 pub evictor_max_threads: usize,
529
530 pub evictor_keep_alive_ms: u64,
533
534 pub evictor_allow_bin_deltas: bool,
537
538 pub offheap_evict_bytes: u64,
544
545 pub offheap_n_lru_lists: u32,
548
549 pub offheap_checksum: bool,
552
553 pub offheap_core_threads: usize,
556
557 pub offheap_max_threads: usize,
560
561 pub offheap_keep_alive_ms: u64,
564
565 pub lock_timeout_ms: u64,
571
572 pub lock_n_lock_tables: u32,
575
576 pub lock_deadlock_detect: bool,
579
580 pub lock_deadlock_detect_delay_ms: u64,
584
585 pub txn_timeout_ms: u64,
591
592 pub durability: Durability,
595
596 pub txn_no_sync: bool,
602
603 pub txn_write_no_sync: bool,
609
610 pub txn_serializable_isolation: bool,
620
621 pub txn_deadlock_stack_trace: bool,
624
625 pub txn_dump_locks: bool,
628
629 pub verify_schedule: String,
636
637 pub verify_log: bool,
640
641 pub verify_log_read_delay_ms: u64,
644
645 pub verify_btree: bool,
648
649 pub verify_secondaries: bool,
652
653 pub verify_data_records: bool,
656
657 pub verify_obsolete_records: bool,
660
661 pub verify_btree_batch_size: u32,
664
665 pub verify_btree_batch_delay_ms: u64,
668
669 pub dos_producer_queue_timeout_ms: u64,
675
676 pub stats_collect: bool,
690
691 pub stats_collect_interval_secs: u64,
694
695 pub stats_max_files: u32,
698
699 pub stats_file_row_count: u32,
702
703 pub stats_file_directory: Option<PathBuf>,
706
707 pub trace_file: bool,
713
714 pub trace_console: bool,
717
718 pub trace_db: bool,
721
722 pub trace_file_limit_bytes: u64,
725
726 pub trace_file_count: u32,
729
730 pub trace_level: Option<String>,
733
734 pub console_logging_level: Option<String>,
737
738 pub file_logging_level: Option<String>,
741
742 pub trace_level_lock_manager: Option<String>,
745
746 pub trace_level_recovery: Option<String>,
749
750 pub trace_level_evictor: Option<String>,
753
754 pub trace_level_cleaner: Option<String>,
757
758 pub startup_dump_threshold_ms: u64,
762
763 pub exception_listener: ExceptionListenerHolder,
772}
773
774impl EnvironmentConfig {
775 pub fn new(home: PathBuf) -> Self {
778 Self {
779 home,
780 allow_create: false,
782 transactional: false,
783 read_only: false,
784 env_is_locking: true,
785 shared_cache: false,
786 env_recovery_force_checkpoint: false,
787 env_recovery_force_new_file: false,
788 halt_on_commit_after_checksum_exception: false,
789 logging_level: None,
790 cache_size: 64 * 1024 * 1024, cache_percent: 0,
793 max_off_heap_memory: 0,
794 max_disk: 0,
795 free_disk: 5 * 1024 * 1024 * 1024, run_in_compressor: true,
798 run_checkpointer: true,
799 run_cleaner: true,
800 run_evictor: true,
801 run_offheap_evictor: false,
802 run_verifier: false,
803 env_background_read_limit_kb: 0,
805 env_background_write_limit_kb: 0,
806 env_background_sleep_interval_us: 0,
807 env_check_leaks: true,
809 env_forced_yield: false,
810 env_fair_latches: false,
811 env_latch_timeout_ms: 300_000,
812 env_ttl_clock_tolerance_ms: 0,
813 env_expiration_enabled: false,
814 env_db_eviction: false,
815 env_dup_convert_preload_all: true,
816 adler32_chunk_size: 0,
817 log_file_max_bytes: 10 * 1024 * 1024,
819 log_file_cache_size: 100,
820 log_checksum_read: true,
821 log_verify_checksums: false,
822 log_fsync_timeout_ms: 500_000,
823 log_fsync_time_limit_ms: 0,
824 log_num_buffers: 3,
825 log_total_buffer_bytes: 7 * 1024 * 1024,
826 log_buffer_size: 0,
827 log_fault_read_size: 2048,
828 log_iterator_read_size: 8192,
829 log_iterator_max_size: 16 * 1024 * 1024,
830 log_n_data_directories: 0,
831 log_mem_only: false,
832 log_detect_file_delete: false,
833 log_detect_file_delete_interval_ms: 3_000,
834 log_flush_sync_interval_ms: 0,
835 log_flush_no_sync_interval_ms: 0,
836 log_use_odsync: false,
837 log_use_write_queue: false,
838 log_write_queue_size: 1024 * 1024,
839 log_group_commit_threshold: 4,
840 log_group_commit_interval_ms: 1,
841 node_max_entries: 128,
843 node_dup_tree_max_entries: 128,
844 tree_max_embedded_ln: 16,
845 tree_max_delta: 25,
846 tree_bin_delta: true,
847 tree_min_memory: 0,
848 tree_compact_max_key_length: 16,
849 in_compressor_wakeup_interval_ms: 5_000,
851 compressor_deadlock_retry: 3,
852 compressor_lock_timeout_ms: 500,
853 compressor_purge_root: false,
854 cleaner_min_utilization: 50,
856 cleaner_min_file_utilization: 5,
857 cleaner_threads: 1,
858 cleaner_min_file_count: 2,
859 cleaner_min_age: 2,
860 cleaner_bytes_interval: 0,
861 cleaner_wakeup_interval_ms: 0,
862 cleaner_fetch_obsolete_size: false,
863 cleaner_adjust_utilization: false,
864 cleaner_deadlock_retry: 3,
865 cleaner_lock_timeout_ms: 500,
866 cleaner_expunge: true,
867 cleaner_use_deleted_dir: false,
868 cleaner_max_batch_files: 0,
869 cleaner_read_size: 8192,
870 cleaner_detail_max_memory_percentage: 2,
871 cleaner_look_ahead_cache_size: 32,
872 cleaner_foreground_proactive_migration: false,
873 cleaner_background_proactive_migration: false,
874 cleaner_lazy_migration: false,
875 cleaner_expiration_enabled: false,
876 checkpointer_bytes_interval: 20_000_000,
878 checkpointer_wakeup_interval_ms: 30_000,
879 checkpointer_min_interval_secs: 0,
880 checkpointer_deadlock_retry: 3,
881 checkpointer_high_priority: false,
882 evictor_nodes_per_scan: 10,
884 evictor_evict_bytes: 512 * 1024,
885 evictor_critical_percentage: 5,
886 evictor_lru_only: false,
887 evictor_n_lru_lists: 4,
888 evictor_deadlock_retry: 3,
889 evictor_core_threads: 1,
890 evictor_max_threads: 10,
891 evictor_keep_alive_ms: 60_000,
892 evictor_allow_bin_deltas: true,
893 offheap_evict_bytes: 512 * 1024,
895 offheap_n_lru_lists: 4,
896 offheap_checksum: false,
897 offheap_core_threads: 1,
898 offheap_max_threads: 10,
899 offheap_keep_alive_ms: 60_000,
900 lock_timeout_ms: 500,
902 lock_n_lock_tables: 16, lock_deadlock_detect: true,
904 lock_deadlock_detect_delay_ms: 0,
905 txn_timeout_ms: 0,
907 durability: Durability::default(),
908 txn_no_sync: false,
909 txn_write_no_sync: false,
910 txn_serializable_isolation: false,
911 txn_deadlock_stack_trace: false,
912 txn_dump_locks: false,
913 verify_schedule: String::new(),
915 verify_log: false,
916 verify_log_read_delay_ms: 0,
917 verify_btree: false,
918 verify_secondaries: true,
919 verify_data_records: false,
920 verify_obsolete_records: false,
921 verify_btree_batch_size: 1_000,
922 verify_btree_batch_delay_ms: 10,
923 dos_producer_queue_timeout_ms: 10_000,
925 stats_collect: false,
927 stats_collect_interval_secs: 300,
928 stats_max_files: 100,
929 stats_file_row_count: 1_000,
930 stats_file_directory: None,
931 trace_file: false,
933 trace_console: false,
934 trace_db: false,
935 trace_file_limit_bytes: 10 * 1024 * 1024,
936 trace_file_count: 10,
937 trace_level: None,
938 console_logging_level: None,
939 file_logging_level: None,
940 trace_level_lock_manager: None,
941 trace_level_recovery: None,
942 trace_level_evictor: None,
943 trace_level_cleaner: None,
944 startup_dump_threshold_ms: 0,
945 exception_listener: ExceptionListenerHolder(None),
946 }
947 }
948
949 pub fn set_allow_create(&mut self, v: bool) -> &mut Self {
954 self.allow_create = v;
955 self
956 }
957 pub fn with_allow_create(mut self, v: bool) -> Self {
958 self.allow_create = v;
959 self
960 }
961
962 pub fn set_transactional(&mut self, v: bool) -> &mut Self {
963 self.transactional = v;
964 self
965 }
966 pub fn with_transactional(mut self, v: bool) -> Self {
967 self.transactional = v;
968 self
969 }
970
971 pub fn set_read_only(&mut self, v: bool) -> &mut Self {
972 self.read_only = v;
973 self
974 }
975 pub fn with_read_only(mut self, v: bool) -> Self {
976 self.read_only = v;
977 self
978 }
979
980 pub fn set_env_is_locking(&mut self, v: bool) -> &mut Self {
981 self.env_is_locking = v;
982 self
983 }
984
985 pub fn set_shared_cache(&mut self, v: bool) -> &mut Self {
986 self.shared_cache = v;
987 self
988 }
989
990 pub fn set_env_recovery_force_checkpoint(&mut self, v: bool) -> &mut Self {
991 self.env_recovery_force_checkpoint = v;
992 self
993 }
994
995 pub fn set_env_recovery_force_new_file(&mut self, v: bool) -> &mut Self {
996 self.env_recovery_force_new_file = v;
997 self
998 }
999
1000 pub fn set_halt_on_commit_after_checksum_exception(
1001 &mut self,
1002 v: bool,
1003 ) -> &mut Self {
1004 self.halt_on_commit_after_checksum_exception = v;
1005 self
1006 }
1007
1008 pub fn set_logging_level(&mut self, level: String) -> &mut Self {
1009 self.logging_level = Some(level);
1010 self
1011 }
1012
1013 pub fn set_cache_size(&mut self, bytes: u64) -> &mut Self {
1018 self.cache_size = bytes;
1019 self
1020 }
1021 pub fn with_cache_size(mut self, bytes: u64) -> Self {
1022 self.cache_size = bytes;
1023 self
1024 }
1025
1026 pub fn set_cache_percent(&mut self, pct: u32) -> &mut Self {
1027 self.cache_percent = pct;
1028 self
1029 }
1030
1031 pub fn set_max_off_heap_memory(&mut self, bytes: u64) -> &mut Self {
1032 self.max_off_heap_memory = bytes;
1033 self
1034 }
1035
1036 pub fn set_max_disk(&mut self, bytes: u64) -> &mut Self {
1037 self.max_disk = bytes;
1038 self
1039 }
1040
1041 pub fn set_free_disk(&mut self, bytes: u64) -> &mut Self {
1042 self.free_disk = bytes;
1043 self
1044 }
1045
1046 pub fn set_run_in_compressor(&mut self, v: bool) -> &mut Self {
1051 self.run_in_compressor = v;
1052 self
1053 }
1054 pub fn set_run_checkpointer(&mut self, v: bool) -> &mut Self {
1055 self.run_checkpointer = v;
1056 self
1057 }
1058 pub fn set_run_cleaner(&mut self, v: bool) -> &mut Self {
1059 self.run_cleaner = v;
1060 self
1061 }
1062 pub fn set_run_evictor(&mut self, v: bool) -> &mut Self {
1063 self.run_evictor = v;
1064 self
1065 }
1066 pub fn set_run_offheap_evictor(&mut self, v: bool) -> &mut Self {
1067 self.run_offheap_evictor = v;
1068 self
1069 }
1070 pub fn set_run_verifier(&mut self, v: bool) -> &mut Self {
1071 self.run_verifier = v;
1072 self
1073 }
1074
1075 pub fn set_env_background_read_limit_kb(&mut self, kb: u32) -> &mut Self {
1080 self.env_background_read_limit_kb = kb;
1081 self
1082 }
1083 pub fn set_env_background_write_limit_kb(&mut self, kb: u32) -> &mut Self {
1084 self.env_background_write_limit_kb = kb;
1085 self
1086 }
1087 pub fn set_env_background_sleep_interval_us(
1088 &mut self,
1089 us: u64,
1090 ) -> &mut Self {
1091 self.env_background_sleep_interval_us = us;
1092 self
1093 }
1094
1095 pub fn set_env_check_leaks(&mut self, v: bool) -> &mut Self {
1100 self.env_check_leaks = v;
1101 self
1102 }
1103 pub fn set_env_forced_yield(&mut self, v: bool) -> &mut Self {
1104 self.env_forced_yield = v;
1105 self
1106 }
1107 pub fn set_env_fair_latches(&mut self, v: bool) -> &mut Self {
1108 self.env_fair_latches = v;
1109 self
1110 }
1111 pub fn set_env_latch_timeout_ms(&mut self, ms: u64) -> &mut Self {
1112 self.env_latch_timeout_ms = ms;
1113 self
1114 }
1115 pub fn set_env_ttl_clock_tolerance_ms(&mut self, ms: u64) -> &mut Self {
1116 self.env_ttl_clock_tolerance_ms = ms;
1117 self
1118 }
1119 pub fn set_env_expiration_enabled(&mut self, v: bool) -> &mut Self {
1120 self.env_expiration_enabled = v;
1121 self
1122 }
1123 pub fn set_env_db_eviction(&mut self, v: bool) -> &mut Self {
1124 self.env_db_eviction = v;
1125 self
1126 }
1127 pub fn set_adler32_chunk_size(&mut self, bytes: usize) -> &mut Self {
1128 self.adler32_chunk_size = bytes;
1129 self
1130 }
1131
1132 pub fn set_log_file_max_bytes(&mut self, bytes: u64) -> &mut Self {
1137 self.log_file_max_bytes = bytes;
1138 self
1139 }
1140 pub fn with_log_file_max_bytes(mut self, bytes: u64) -> Self {
1141 self.log_file_max_bytes = bytes;
1142 self
1143 }
1144 pub fn set_log_file_cache_size(&mut self, n: usize) -> &mut Self {
1145 self.log_file_cache_size = n;
1146 self
1147 }
1148 pub fn set_log_checksum_read(&mut self, v: bool) -> &mut Self {
1149 self.log_checksum_read = v;
1150 self
1151 }
1152 pub fn set_log_verify_checksums(&mut self, v: bool) -> &mut Self {
1153 self.log_verify_checksums = v;
1154 self
1155 }
1156 pub fn set_log_fsync_timeout_ms(&mut self, ms: u64) -> &mut Self {
1157 self.log_fsync_timeout_ms = ms;
1158 self
1159 }
1160 pub fn set_log_fsync_time_limit_ms(&mut self, ms: u64) -> &mut Self {
1161 self.log_fsync_time_limit_ms = ms;
1162 self
1163 }
1164 pub fn set_log_num_buffers(&mut self, n: usize) -> &mut Self {
1165 self.log_num_buffers = n;
1166 self
1167 }
1168 pub fn set_log_total_buffer_bytes(&mut self, bytes: u64) -> &mut Self {
1169 self.log_total_buffer_bytes = bytes;
1170 self
1171 }
1172 pub fn set_log_buffer_size(&mut self, bytes: usize) -> &mut Self {
1173 self.log_buffer_size = bytes;
1174 self
1175 }
1176 pub fn set_log_fault_read_size(&mut self, bytes: usize) -> &mut Self {
1177 self.log_fault_read_size = bytes;
1178 self
1179 }
1180 pub fn set_log_iterator_read_size(&mut self, bytes: usize) -> &mut Self {
1181 self.log_iterator_read_size = bytes;
1182 self
1183 }
1184 pub fn set_log_iterator_max_size(&mut self, bytes: usize) -> &mut Self {
1185 self.log_iterator_max_size = bytes;
1186 self
1187 }
1188 pub fn set_log_n_data_directories(&mut self, n: u32) -> &mut Self {
1189 self.log_n_data_directories = n;
1190 self
1191 }
1192 pub fn set_log_mem_only(&mut self, v: bool) -> &mut Self {
1193 self.log_mem_only = v;
1194 self
1195 }
1196 pub fn set_log_detect_file_delete(&mut self, v: bool) -> &mut Self {
1197 self.log_detect_file_delete = v;
1198 self
1199 }
1200 pub fn set_log_detect_file_delete_interval_ms(
1201 &mut self,
1202 ms: u64,
1203 ) -> &mut Self {
1204 self.log_detect_file_delete_interval_ms = ms;
1205 self
1206 }
1207 pub fn set_log_flush_sync_interval_ms(&mut self, ms: u64) -> &mut Self {
1208 self.log_flush_sync_interval_ms = ms;
1209 self
1210 }
1211 pub fn set_log_flush_no_sync_interval_ms(&mut self, ms: u64) -> &mut Self {
1212 self.log_flush_no_sync_interval_ms = ms;
1213 self
1214 }
1215 pub fn set_log_use_odsync(&mut self, v: bool) -> &mut Self {
1216 self.log_use_odsync = v;
1217 self
1218 }
1219 pub fn set_log_use_write_queue(&mut self, v: bool) -> &mut Self {
1220 self.log_use_write_queue = v;
1221 self
1222 }
1223 pub fn set_log_write_queue_size(&mut self, bytes: usize) -> &mut Self {
1224 self.log_write_queue_size = bytes;
1225 self
1226 }
1227 pub fn set_log_group_commit_threshold(&mut self, n: usize) -> &mut Self {
1228 self.log_group_commit_threshold = n;
1229 self
1230 }
1231 pub fn set_log_group_commit_interval_ms(&mut self, ms: u64) -> &mut Self {
1232 self.log_group_commit_interval_ms = ms;
1233 self
1234 }
1235 pub fn with_log_group_commit(
1236 mut self,
1237 threshold: usize,
1238 interval_ms: u64,
1239 ) -> Self {
1240 self.log_group_commit_threshold = threshold;
1241 self.log_group_commit_interval_ms = interval_ms;
1242 self
1243 }
1244
1245 pub fn set_node_max_entries(&mut self, n: u32) -> &mut Self {
1250 self.node_max_entries = n;
1251 self
1252 }
1253 pub fn set_node_dup_tree_max_entries(&mut self, n: u32) -> &mut Self {
1254 self.node_dup_tree_max_entries = n;
1255 self
1256 }
1257 pub fn set_tree_max_embedded_ln(&mut self, bytes: u32) -> &mut Self {
1258 self.tree_max_embedded_ln = bytes;
1259 self
1260 }
1261 pub fn set_tree_max_delta(&mut self, pct: u8) -> &mut Self {
1262 self.tree_max_delta = pct;
1263 self
1264 }
1265 pub fn set_tree_bin_delta(&mut self, v: bool) -> &mut Self {
1266 self.tree_bin_delta = v;
1267 self
1268 }
1269 pub fn set_tree_min_memory(&mut self, bytes: u64) -> &mut Self {
1270 self.tree_min_memory = bytes;
1271 self
1272 }
1273 pub fn set_tree_compact_max_key_length(&mut self, bytes: u32) -> &mut Self {
1274 self.tree_compact_max_key_length = bytes;
1275 self
1276 }
1277
1278 pub fn set_in_compressor_wakeup_interval_ms(
1283 &mut self,
1284 ms: u64,
1285 ) -> &mut Self {
1286 self.in_compressor_wakeup_interval_ms = ms;
1287 self
1288 }
1289 pub fn set_compressor_deadlock_retry(&mut self, n: u32) -> &mut Self {
1290 self.compressor_deadlock_retry = n;
1291 self
1292 }
1293 pub fn set_compressor_lock_timeout_ms(&mut self, ms: u64) -> &mut Self {
1294 self.compressor_lock_timeout_ms = ms;
1295 self
1296 }
1297 pub fn set_compressor_purge_root(&mut self, v: bool) -> &mut Self {
1298 self.compressor_purge_root = v;
1299 self
1300 }
1301
1302 pub fn set_cleaner_min_utilization(&mut self, pct: u8) -> &mut Self {
1307 self.cleaner_min_utilization = pct;
1308 self
1309 }
1310 pub fn with_cleaner_min_utilization(mut self, pct: u8) -> Self {
1311 self.cleaner_min_utilization = pct;
1312 self
1313 }
1314 pub fn set_cleaner_min_file_utilization(&mut self, pct: u8) -> &mut Self {
1315 self.cleaner_min_file_utilization = pct;
1316 self
1317 }
1318 pub fn set_cleaner_threads(&mut self, n: u32) -> &mut Self {
1319 self.cleaner_threads = n;
1320 self
1321 }
1322 pub fn set_cleaner_min_file_count(&mut self, n: u32) -> &mut Self {
1323 self.cleaner_min_file_count = n;
1324 self
1325 }
1326 pub fn set_cleaner_min_age(&mut self, checkpoints: u32) -> &mut Self {
1327 self.cleaner_min_age = checkpoints;
1328 self
1329 }
1330 pub fn set_cleaner_bytes_interval(&mut self, bytes: u64) -> &mut Self {
1331 self.cleaner_bytes_interval = bytes;
1332 self
1333 }
1334 pub fn set_cleaner_wakeup_interval_ms(&mut self, ms: u64) -> &mut Self {
1335 self.cleaner_wakeup_interval_ms = ms;
1336 self
1337 }
1338 pub fn set_cleaner_fetch_obsolete_size(&mut self, v: bool) -> &mut Self {
1339 self.cleaner_fetch_obsolete_size = v;
1340 self
1341 }
1342 pub fn set_cleaner_adjust_utilization(&mut self, v: bool) -> &mut Self {
1343 self.cleaner_adjust_utilization = v;
1344 self
1345 }
1346 pub fn set_cleaner_deadlock_retry(&mut self, n: u32) -> &mut Self {
1347 self.cleaner_deadlock_retry = n;
1348 self
1349 }
1350 pub fn set_cleaner_lock_timeout_ms(&mut self, ms: u64) -> &mut Self {
1351 self.cleaner_lock_timeout_ms = ms;
1352 self
1353 }
1354 pub fn set_cleaner_expunge(&mut self, v: bool) -> &mut Self {
1355 self.cleaner_expunge = v;
1356 self
1357 }
1358 pub fn set_cleaner_use_deleted_dir(&mut self, v: bool) -> &mut Self {
1359 self.cleaner_use_deleted_dir = v;
1360 self
1361 }
1362 pub fn set_cleaner_max_batch_files(&mut self, n: u32) -> &mut Self {
1363 self.cleaner_max_batch_files = n;
1364 self
1365 }
1366 pub fn set_cleaner_read_size(&mut self, bytes: usize) -> &mut Self {
1367 self.cleaner_read_size = bytes;
1368 self
1369 }
1370 pub fn set_cleaner_detail_max_memory_percentage(
1371 &mut self,
1372 pct: u32,
1373 ) -> &mut Self {
1374 self.cleaner_detail_max_memory_percentage = pct;
1375 self
1376 }
1377 pub fn set_cleaner_look_ahead_cache_size(&mut self, n: usize) -> &mut Self {
1378 self.cleaner_look_ahead_cache_size = n;
1379 self
1380 }
1381 pub fn set_cleaner_foreground_proactive_migration(
1382 &mut self,
1383 v: bool,
1384 ) -> &mut Self {
1385 self.cleaner_foreground_proactive_migration = v;
1386 self
1387 }
1388 pub fn set_cleaner_background_proactive_migration(
1389 &mut self,
1390 v: bool,
1391 ) -> &mut Self {
1392 self.cleaner_background_proactive_migration = v;
1393 self
1394 }
1395 pub fn set_cleaner_lazy_migration(&mut self, v: bool) -> &mut Self {
1396 self.cleaner_lazy_migration = v;
1397 self
1398 }
1399 pub fn set_cleaner_expiration_enabled(&mut self, v: bool) -> &mut Self {
1400 self.cleaner_expiration_enabled = v;
1401 self
1402 }
1403
1404 pub fn set_checkpointer_bytes_interval(&mut self, bytes: u64) -> &mut Self {
1409 self.checkpointer_bytes_interval = bytes;
1410 self
1411 }
1412 pub fn with_checkpointer_bytes_interval(mut self, bytes: u64) -> Self {
1413 self.checkpointer_bytes_interval = bytes;
1414 self
1415 }
1416 pub fn set_checkpointer_wakeup_interval_ms(
1417 &mut self,
1418 ms: u64,
1419 ) -> &mut Self {
1420 self.checkpointer_wakeup_interval_ms = ms;
1421 self
1422 }
1423 pub fn set_checkpointer_min_interval_secs(
1424 &mut self,
1425 secs: u64,
1426 ) -> &mut Self {
1427 self.checkpointer_min_interval_secs = secs;
1428 self
1429 }
1430 pub fn set_checkpointer_deadlock_retry(&mut self, n: u32) -> &mut Self {
1431 self.checkpointer_deadlock_retry = n;
1432 self
1433 }
1434 pub fn set_checkpointer_high_priority(&mut self, v: bool) -> &mut Self {
1435 self.checkpointer_high_priority = v;
1436 self
1437 }
1438
1439 pub fn set_evictor_nodes_per_scan(&mut self, n: usize) -> &mut Self {
1444 self.evictor_nodes_per_scan = n;
1445 self
1446 }
1447 pub fn with_evictor_nodes_per_scan(mut self, n: usize) -> Self {
1448 self.evictor_nodes_per_scan = n;
1449 self
1450 }
1451 pub fn set_evictor_evict_bytes(&mut self, bytes: u64) -> &mut Self {
1452 self.evictor_evict_bytes = bytes;
1453 self
1454 }
1455 pub fn set_evictor_critical_percentage(&mut self, pct: u32) -> &mut Self {
1456 self.evictor_critical_percentage = pct;
1457 self
1458 }
1459 pub fn set_evictor_lru_only(&mut self, v: bool) -> &mut Self {
1460 self.evictor_lru_only = v;
1461 self
1462 }
1463 pub fn set_evictor_n_lru_lists(&mut self, n: u32) -> &mut Self {
1464 self.evictor_n_lru_lists = n;
1465 self
1466 }
1467 pub fn set_evictor_deadlock_retry(&mut self, n: u32) -> &mut Self {
1468 self.evictor_deadlock_retry = n;
1469 self
1470 }
1471 pub fn set_evictor_core_threads(&mut self, n: usize) -> &mut Self {
1472 self.evictor_core_threads = n;
1473 self
1474 }
1475 pub fn set_evictor_max_threads(&mut self, n: usize) -> &mut Self {
1476 self.evictor_max_threads = n;
1477 self
1478 }
1479 pub fn set_evictor_keep_alive_ms(&mut self, ms: u64) -> &mut Self {
1480 self.evictor_keep_alive_ms = ms;
1481 self
1482 }
1483 pub fn set_evictor_allow_bin_deltas(&mut self, v: bool) -> &mut Self {
1484 self.evictor_allow_bin_deltas = v;
1485 self
1486 }
1487
1488 pub fn set_offheap_evict_bytes(&mut self, bytes: u64) -> &mut Self {
1493 self.offheap_evict_bytes = bytes;
1494 self
1495 }
1496 pub fn set_offheap_n_lru_lists(&mut self, n: u32) -> &mut Self {
1497 self.offheap_n_lru_lists = n;
1498 self
1499 }
1500 pub fn set_offheap_checksum(&mut self, v: bool) -> &mut Self {
1501 self.offheap_checksum = v;
1502 self
1503 }
1504 pub fn set_offheap_core_threads(&mut self, n: usize) -> &mut Self {
1505 self.offheap_core_threads = n;
1506 self
1507 }
1508 pub fn set_offheap_max_threads(&mut self, n: usize) -> &mut Self {
1509 self.offheap_max_threads = n;
1510 self
1511 }
1512 pub fn set_offheap_keep_alive_ms(&mut self, ms: u64) -> &mut Self {
1513 self.offheap_keep_alive_ms = ms;
1514 self
1515 }
1516
1517 pub fn set_lock_timeout(&mut self, ms: u64) -> &mut Self {
1522 self.lock_timeout_ms = ms;
1523 self
1524 }
1525 pub fn set_lock_n_lock_tables(&mut self, n: u32) -> &mut Self {
1526 self.lock_n_lock_tables = n;
1527 self
1528 }
1529 pub fn set_lock_deadlock_detect(&mut self, v: bool) -> &mut Self {
1530 self.lock_deadlock_detect = v;
1531 self
1532 }
1533 pub fn set_lock_deadlock_detect_delay_ms(&mut self, ms: u64) -> &mut Self {
1534 self.lock_deadlock_detect_delay_ms = ms;
1535 self
1536 }
1537
1538 pub fn set_txn_timeout(&mut self, ms: u64) -> &mut Self {
1543 self.txn_timeout_ms = ms;
1544 self
1545 }
1546 pub fn set_durability(&mut self, d: Durability) -> &mut Self {
1547 self.durability = d;
1548 self
1549 }
1550 pub fn with_durability(mut self, d: Durability) -> Self {
1551 self.durability = d;
1552 self
1553 }
1554 #[deprecated(
1559 since = "2.4.1",
1560 note = "use set_durability(Durability::commit_no_sync()) instead"
1561 )]
1562 pub fn set_txn_no_sync(&mut self, v: bool) -> &mut Self {
1563 self.txn_no_sync = v;
1564 self
1565 }
1566 #[deprecated(
1570 since = "2.4.1",
1571 note = "use with_durability(Durability::commit_no_sync()) instead"
1572 )]
1573 pub fn with_txn_no_sync(mut self, v: bool) -> Self {
1574 self.txn_no_sync = v;
1575 self
1576 }
1577 #[deprecated(
1581 since = "2.4.1",
1582 note = "use set_durability(Durability::commit_write_no_sync()) instead"
1583 )]
1584 pub fn set_txn_write_no_sync(&mut self, v: bool) -> &mut Self {
1585 self.txn_write_no_sync = v;
1586 self
1587 }
1588 pub fn set_txn_serializable_isolation(&mut self, v: bool) -> &mut Self {
1589 self.txn_serializable_isolation = v;
1590 self
1591 }
1592 pub fn set_txn_deadlock_stack_trace(&mut self, v: bool) -> &mut Self {
1593 self.txn_deadlock_stack_trace = v;
1594 self
1595 }
1596 pub fn set_txn_dump_locks(&mut self, v: bool) -> &mut Self {
1597 self.txn_dump_locks = v;
1598 self
1599 }
1600
1601 pub fn set_verify_schedule(&mut self, s: String) -> &mut Self {
1606 self.verify_schedule = s;
1607 self
1608 }
1609 pub fn set_verify_log(&mut self, v: bool) -> &mut Self {
1610 self.verify_log = v;
1611 self
1612 }
1613 pub fn set_verify_log_read_delay_ms(&mut self, ms: u64) -> &mut Self {
1614 self.verify_log_read_delay_ms = ms;
1615 self
1616 }
1617 pub fn set_verify_btree(&mut self, v: bool) -> &mut Self {
1618 self.verify_btree = v;
1619 self
1620 }
1621 pub fn set_verify_secondaries(&mut self, v: bool) -> &mut Self {
1622 self.verify_secondaries = v;
1623 self
1624 }
1625 pub fn set_verify_data_records(&mut self, v: bool) -> &mut Self {
1626 self.verify_data_records = v;
1627 self
1628 }
1629 pub fn set_verify_obsolete_records(&mut self, v: bool) -> &mut Self {
1630 self.verify_obsolete_records = v;
1631 self
1632 }
1633 pub fn set_verify_btree_batch_size(&mut self, n: u32) -> &mut Self {
1634 self.verify_btree_batch_size = n;
1635 self
1636 }
1637 pub fn set_verify_btree_batch_delay_ms(&mut self, ms: u64) -> &mut Self {
1638 self.verify_btree_batch_delay_ms = ms;
1639 self
1640 }
1641
1642 pub fn set_dos_producer_queue_timeout_ms(&mut self, ms: u64) -> &mut Self {
1647 self.dos_producer_queue_timeout_ms = ms;
1648 self
1649 }
1650
1651 pub fn set_stats_collect(&mut self, v: bool) -> &mut Self {
1656 self.stats_collect = v;
1657 self
1658 }
1659 pub fn set_stats_collect_interval_secs(&mut self, secs: u64) -> &mut Self {
1660 self.stats_collect_interval_secs = secs;
1661 self
1662 }
1663 pub fn set_stats_max_files(&mut self, n: u32) -> &mut Self {
1664 self.stats_max_files = n;
1665 self
1666 }
1667 pub fn set_stats_file_row_count(&mut self, n: u32) -> &mut Self {
1668 self.stats_file_row_count = n;
1669 self
1670 }
1671 pub fn set_stats_file_directory(&mut self, dir: PathBuf) -> &mut Self {
1672 self.stats_file_directory = Some(dir);
1673 self
1674 }
1675
1676 pub fn set_trace_file(&mut self, v: bool) -> &mut Self {
1681 self.trace_file = v;
1682 self
1683 }
1684 pub fn set_trace_console(&mut self, v: bool) -> &mut Self {
1685 self.trace_console = v;
1686 self
1687 }
1688 pub fn set_trace_db(&mut self, v: bool) -> &mut Self {
1689 self.trace_db = v;
1690 self
1691 }
1692 pub fn set_trace_file_limit_bytes(&mut self, bytes: u64) -> &mut Self {
1693 self.trace_file_limit_bytes = bytes;
1694 self
1695 }
1696 pub fn set_trace_file_count(&mut self, n: u32) -> &mut Self {
1697 self.trace_file_count = n;
1698 self
1699 }
1700 pub fn set_trace_level(&mut self, level: String) -> &mut Self {
1701 self.trace_level = Some(level);
1702 self
1703 }
1704 pub fn set_console_logging_level(&mut self, level: String) -> &mut Self {
1705 self.console_logging_level = Some(level);
1706 self
1707 }
1708 pub fn set_file_logging_level(&mut self, level: String) -> &mut Self {
1709 self.file_logging_level = Some(level);
1710 self
1711 }
1712 pub fn set_trace_level_lock_manager(&mut self, level: String) -> &mut Self {
1713 self.trace_level_lock_manager = Some(level);
1714 self
1715 }
1716 pub fn set_trace_level_recovery(&mut self, level: String) -> &mut Self {
1717 self.trace_level_recovery = Some(level);
1718 self
1719 }
1720 pub fn set_trace_level_evictor(&mut self, level: String) -> &mut Self {
1721 self.trace_level_evictor = Some(level);
1722 self
1723 }
1724 pub fn set_trace_level_cleaner(&mut self, level: String) -> &mut Self {
1725 self.trace_level_cleaner = Some(level);
1726 self
1727 }
1728 pub fn set_startup_dump_threshold_ms(&mut self, ms: u64) -> &mut Self {
1729 self.startup_dump_threshold_ms = ms;
1730 self
1731 }
1732
1733 pub fn set_exception_listener(
1742 &mut self,
1743 listener: Arc<dyn ExceptionListener>,
1744 ) -> &mut Self {
1745 self.exception_listener = ExceptionListenerHolder(Some(listener));
1746 self
1747 }
1748
1749 pub fn get_exception_listener(&self) -> Option<Arc<dyn ExceptionListener>> {
1751 self.exception_listener.0.clone()
1752 }
1753}
1754
1755impl Default for EnvironmentConfig {
1756 fn default() -> Self {
1757 Self::new(PathBuf::from("."))
1758 }
1759}
1760
1761#[cfg(test)]
1762mod tests {
1763 use super::*;
1764
1765 #[test]
1766 fn test_defaults_core() {
1767 let c = EnvironmentConfig::default();
1768 assert_eq!(c.home, PathBuf::from("."));
1769 assert!(!c.allow_create);
1770 assert!(!c.transactional);
1771 assert!(!c.read_only);
1772 assert!(c.env_is_locking);
1773 assert!(!c.shared_cache);
1774 assert!(!c.env_recovery_force_checkpoint);
1775 assert!(!c.env_recovery_force_new_file);
1776 assert!(!c.halt_on_commit_after_checksum_exception);
1777 }
1778
1779 #[test]
1780 fn test_defaults_memory() {
1781 let c = EnvironmentConfig::default();
1782 assert_eq!(c.cache_size, 64 * 1024 * 1024);
1783 assert_eq!(c.cache_percent, 0);
1784 assert_eq!(c.max_off_heap_memory, 0);
1785 assert_eq!(c.max_disk, 0);
1786 assert_eq!(c.free_disk, 5 * 1024 * 1024 * 1024);
1787 }
1788
1789 #[test]
1790 fn test_defaults_daemons() {
1791 let c = EnvironmentConfig::default();
1792 assert!(c.run_in_compressor);
1793 assert!(c.run_checkpointer);
1794 assert!(c.run_cleaner);
1795 assert!(c.run_evictor);
1796 assert!(!c.run_offheap_evictor);
1797 assert!(!c.run_verifier);
1798 }
1799
1800 #[test]
1801 fn test_defaults_log() {
1802 let c = EnvironmentConfig::default();
1803 assert_eq!(c.log_file_max_bytes, 10 * 1024 * 1024);
1804 assert_eq!(c.log_file_cache_size, 100);
1805 assert!(c.log_checksum_read);
1806 assert!(!c.log_verify_checksums);
1807 assert_eq!(c.log_fsync_timeout_ms, 500_000);
1808 assert_eq!(c.log_fsync_time_limit_ms, 0);
1809 assert_eq!(c.log_num_buffers, 3);
1810 assert_eq!(c.log_total_buffer_bytes, 7 * 1024 * 1024);
1811 assert_eq!(c.log_buffer_size, 0);
1812 assert_eq!(c.log_fault_read_size, 2048);
1813 assert_eq!(c.log_iterator_read_size, 8192);
1814 assert_eq!(c.log_iterator_max_size, 16 * 1024 * 1024);
1815 assert_eq!(c.log_n_data_directories, 0);
1816 assert!(!c.log_mem_only);
1817 assert!(!c.log_detect_file_delete);
1818 assert_eq!(c.log_detect_file_delete_interval_ms, 3_000);
1819 assert_eq!(c.log_flush_sync_interval_ms, 0);
1820 assert_eq!(c.log_flush_no_sync_interval_ms, 0);
1821 assert!(!c.log_use_odsync);
1822 assert!(!c.log_use_write_queue);
1823 assert_eq!(c.log_write_queue_size, 1024 * 1024);
1824 assert_eq!(c.log_group_commit_threshold, 4);
1825 assert_eq!(c.log_group_commit_interval_ms, 1);
1826 }
1827
1828 #[test]
1829 fn test_defaults_btree() {
1830 let c = EnvironmentConfig::default();
1831 assert_eq!(c.node_max_entries, 128);
1832 assert_eq!(c.node_dup_tree_max_entries, 128);
1833 assert_eq!(c.tree_max_embedded_ln, 16);
1834 assert_eq!(c.tree_max_delta, 25);
1835 assert!(c.tree_bin_delta);
1836 assert_eq!(c.tree_min_memory, 0);
1837 assert_eq!(c.tree_compact_max_key_length, 16);
1838 }
1839
1840 #[test]
1841 fn test_defaults_cleaner() {
1842 let c = EnvironmentConfig::default();
1843 assert_eq!(c.cleaner_min_utilization, 50);
1844 assert_eq!(c.cleaner_min_file_utilization, 5);
1845 assert_eq!(c.cleaner_threads, 1);
1846 assert_eq!(c.cleaner_min_file_count, 2);
1847 assert_eq!(c.cleaner_min_age, 2);
1848 assert_eq!(c.cleaner_bytes_interval, 0);
1849 assert_eq!(c.cleaner_wakeup_interval_ms, 0);
1850 assert!(!c.cleaner_fetch_obsolete_size);
1851 assert!(!c.cleaner_adjust_utilization);
1852 assert_eq!(c.cleaner_deadlock_retry, 3);
1853 assert_eq!(c.cleaner_lock_timeout_ms, 500);
1854 assert!(c.cleaner_expunge);
1855 assert!(!c.cleaner_use_deleted_dir);
1856 assert_eq!(c.cleaner_max_batch_files, 0);
1857 assert_eq!(c.cleaner_read_size, 8192);
1858 assert_eq!(c.cleaner_detail_max_memory_percentage, 2);
1859 assert_eq!(c.cleaner_look_ahead_cache_size, 32);
1860 assert!(!c.cleaner_foreground_proactive_migration);
1861 assert!(!c.cleaner_background_proactive_migration);
1862 assert!(!c.cleaner_lazy_migration);
1863 assert!(!c.cleaner_expiration_enabled);
1864 }
1865
1866 #[test]
1867 fn test_defaults_checkpointer() {
1868 let c = EnvironmentConfig::default();
1869 assert_eq!(c.checkpointer_bytes_interval, 20_000_000);
1870 assert_eq!(c.checkpointer_wakeup_interval_ms, 30_000);
1871 assert_eq!(c.checkpointer_min_interval_secs, 0);
1872 assert_eq!(c.checkpointer_deadlock_retry, 3);
1873 assert!(!c.checkpointer_high_priority);
1874 }
1875
1876 #[test]
1877 fn test_defaults_evictor() {
1878 let c = EnvironmentConfig::default();
1879 assert_eq!(c.evictor_nodes_per_scan, 10);
1880 assert_eq!(c.evictor_evict_bytes, 512 * 1024);
1881 assert_eq!(c.evictor_critical_percentage, 5);
1882 assert!(!c.evictor_lru_only);
1883 assert_eq!(c.evictor_n_lru_lists, 4);
1884 assert_eq!(c.evictor_deadlock_retry, 3);
1885 assert_eq!(c.evictor_core_threads, 1);
1886 assert_eq!(c.evictor_max_threads, 10);
1887 assert_eq!(c.evictor_keep_alive_ms, 60_000);
1888 assert!(c.evictor_allow_bin_deltas);
1889 }
1890
1891 #[test]
1892 fn test_defaults_offheap() {
1893 let c = EnvironmentConfig::default();
1894 assert_eq!(c.offheap_evict_bytes, 512 * 1024);
1895 assert_eq!(c.offheap_n_lru_lists, 4);
1896 assert!(!c.offheap_checksum);
1897 assert_eq!(c.offheap_core_threads, 1);
1898 assert_eq!(c.offheap_max_threads, 10);
1899 assert_eq!(c.offheap_keep_alive_ms, 60_000);
1900 }
1901
1902 #[test]
1903 fn test_defaults_locking() {
1904 let c = EnvironmentConfig::default();
1905 assert_eq!(c.lock_timeout_ms, 500);
1906 assert_eq!(c.lock_n_lock_tables, 16);
1907 assert!(c.lock_deadlock_detect);
1908 assert_eq!(c.lock_deadlock_detect_delay_ms, 0);
1909 }
1910
1911 #[test]
1912 fn test_defaults_txn() {
1913 let c = EnvironmentConfig::default();
1914 assert_eq!(c.txn_timeout_ms, 0);
1915 assert!(!c.txn_no_sync);
1916 assert!(!c.txn_write_no_sync);
1917 assert!(!c.txn_serializable_isolation);
1918 assert!(!c.txn_deadlock_stack_trace);
1919 assert!(!c.txn_dump_locks);
1920 }
1921
1922 #[test]
1923 fn test_defaults_verifier() {
1924 let c = EnvironmentConfig::default();
1925 assert_eq!(c.verify_schedule, "");
1926 assert!(!c.verify_log);
1927 assert_eq!(c.verify_log_read_delay_ms, 0);
1928 assert!(!c.verify_btree);
1929 assert!(c.verify_secondaries);
1930 assert!(!c.verify_data_records);
1931 assert!(!c.verify_obsolete_records);
1932 assert_eq!(c.verify_btree_batch_size, 1_000);
1933 assert_eq!(c.verify_btree_batch_delay_ms, 10);
1934 }
1935
1936 #[test]
1937 fn test_defaults_stats() {
1938 let c = EnvironmentConfig::default();
1939 assert!(!c.stats_collect);
1940 assert_eq!(c.stats_collect_interval_secs, 300);
1941 assert_eq!(c.stats_max_files, 100);
1942 assert_eq!(c.stats_file_row_count, 1_000);
1943 assert!(c.stats_file_directory.is_none());
1944 }
1945
1946 #[test]
1947 fn test_set_allow_create() {
1948 let mut c = EnvironmentConfig::default();
1949 c.set_allow_create(true);
1950 assert!(c.allow_create);
1951 }
1952
1953 #[test]
1954 fn test_set_cache_size() {
1955 let mut c = EnvironmentConfig::default();
1956 c.set_cache_size(128 * 1024 * 1024);
1957 assert_eq!(c.cache_size, 128 * 1024 * 1024);
1958 }
1959
1960 #[test]
1961 fn test_set_free_disk() {
1962 let mut c = EnvironmentConfig::default();
1963 c.set_free_disk(1024 * 1024 * 1024);
1964 assert_eq!(c.free_disk, 1024 * 1024 * 1024);
1965 }
1966
1967 #[test]
1968 fn test_set_log_params() {
1969 let mut c = EnvironmentConfig::default();
1970 c.set_log_file_max_bytes(20 * 1024 * 1024);
1971 c.set_log_num_buffers(5);
1972 c.set_log_total_buffer_bytes(5 * 1024 * 1024);
1973 c.set_log_iterator_read_size(16384);
1974 c.set_log_iterator_max_size(32 * 1024 * 1024);
1975 c.set_log_n_data_directories(2);
1976 c.set_log_mem_only(true);
1977 c.set_log_use_odsync(true);
1978 c.set_log_detect_file_delete(true);
1979 c.set_log_detect_file_delete_interval_ms(5000);
1980 c.set_log_flush_sync_interval_ms(1000);
1981 c.set_log_flush_no_sync_interval_ms(500);
1982 c.set_log_fsync_time_limit_ms(200);
1983 c.set_log_use_write_queue(true);
1984 c.set_log_write_queue_size(2 * 1024 * 1024);
1985 c.set_log_verify_checksums(true);
1986 assert_eq!(c.log_file_max_bytes, 20 * 1024 * 1024);
1987 assert_eq!(c.log_num_buffers, 5);
1988 assert_eq!(c.log_total_buffer_bytes, 5 * 1024 * 1024);
1989 assert_eq!(c.log_iterator_read_size, 16384);
1990 assert_eq!(c.log_iterator_max_size, 32 * 1024 * 1024);
1991 assert_eq!(c.log_n_data_directories, 2);
1992 assert!(c.log_mem_only);
1993 assert!(c.log_use_odsync);
1994 assert!(c.log_detect_file_delete);
1995 assert_eq!(c.log_detect_file_delete_interval_ms, 5000);
1996 assert_eq!(c.log_flush_sync_interval_ms, 1000);
1997 assert_eq!(c.log_flush_no_sync_interval_ms, 500);
1998 assert_eq!(c.log_fsync_time_limit_ms, 200);
1999 assert!(c.log_use_write_queue);
2000 assert_eq!(c.log_write_queue_size, 2 * 1024 * 1024);
2001 assert!(c.log_verify_checksums);
2002 }
2003
2004 #[test]
2005 fn test_set_btree_params() {
2006 let mut c = EnvironmentConfig::default();
2007 c.set_node_max_entries(256);
2008 c.set_node_dup_tree_max_entries(64);
2009 c.set_tree_max_embedded_ln(32);
2010 c.set_tree_max_delta(30);
2011 c.set_tree_bin_delta(false);
2012 c.set_tree_min_memory(1024);
2013 c.set_tree_compact_max_key_length(32);
2014 assert_eq!(c.node_max_entries, 256);
2015 assert_eq!(c.node_dup_tree_max_entries, 64);
2016 assert_eq!(c.tree_max_embedded_ln, 32);
2017 assert_eq!(c.tree_max_delta, 30);
2018 assert!(!c.tree_bin_delta);
2019 assert_eq!(c.tree_min_memory, 1024);
2020 assert_eq!(c.tree_compact_max_key_length, 32);
2021 }
2022
2023 #[test]
2024 fn test_set_cleaner_params() {
2025 let mut c = EnvironmentConfig::default();
2026 c.set_cleaner_threads(4);
2027 c.set_cleaner_min_file_count(5);
2028 c.set_cleaner_min_age(3);
2029 c.set_cleaner_expiration_enabled(true);
2030 c.set_cleaner_bytes_interval(5_000_000);
2031 c.set_cleaner_wakeup_interval_ms(10_000);
2032 c.set_cleaner_fetch_obsolete_size(true);
2033 c.set_cleaner_adjust_utilization(true);
2034 c.set_cleaner_deadlock_retry(5);
2035 c.set_cleaner_lock_timeout_ms(1000);
2036 c.set_cleaner_expunge(false);
2037 c.set_cleaner_use_deleted_dir(true);
2038 c.set_cleaner_max_batch_files(10);
2039 c.set_cleaner_detail_max_memory_percentage(5);
2040 c.set_cleaner_foreground_proactive_migration(true);
2041 c.set_cleaner_background_proactive_migration(true);
2042 c.set_cleaner_lazy_migration(true);
2043 assert_eq!(c.cleaner_threads, 4);
2044 assert_eq!(c.cleaner_min_file_count, 5);
2045 assert_eq!(c.cleaner_min_age, 3);
2046 assert!(c.cleaner_expiration_enabled);
2047 assert_eq!(c.cleaner_bytes_interval, 5_000_000);
2048 assert_eq!(c.cleaner_wakeup_interval_ms, 10_000);
2049 assert!(c.cleaner_fetch_obsolete_size);
2050 assert!(c.cleaner_adjust_utilization);
2051 assert_eq!(c.cleaner_deadlock_retry, 5);
2052 assert_eq!(c.cleaner_lock_timeout_ms, 1000);
2053 assert!(!c.cleaner_expunge);
2054 assert!(c.cleaner_use_deleted_dir);
2055 assert_eq!(c.cleaner_max_batch_files, 10);
2056 assert_eq!(c.cleaner_detail_max_memory_percentage, 5);
2057 assert!(c.cleaner_foreground_proactive_migration);
2058 assert!(c.cleaner_background_proactive_migration);
2059 assert!(c.cleaner_lazy_migration);
2060 }
2061
2062 #[test]
2063 fn test_set_checkpointer_params() {
2064 let mut c = EnvironmentConfig::default();
2065 c.set_checkpointer_wakeup_interval_ms(60_000);
2066 c.set_checkpointer_deadlock_retry(5);
2067 c.set_checkpointer_high_priority(true);
2068 assert_eq!(c.checkpointer_wakeup_interval_ms, 60_000);
2069 assert_eq!(c.checkpointer_deadlock_retry, 5);
2070 assert!(c.checkpointer_high_priority);
2071 }
2072
2073 #[test]
2074 fn test_set_evictor_params() {
2075 let mut c = EnvironmentConfig::default();
2076 c.set_evictor_evict_bytes(1024 * 1024);
2077 c.set_evictor_critical_percentage(10);
2078 c.set_evictor_n_lru_lists(8);
2079 c.set_evictor_deadlock_retry(5);
2080 c.set_evictor_keep_alive_ms(30_000);
2081 c.set_evictor_allow_bin_deltas(false);
2082 assert_eq!(c.evictor_evict_bytes, 1024 * 1024);
2083 assert_eq!(c.evictor_critical_percentage, 10);
2084 assert_eq!(c.evictor_n_lru_lists, 8);
2085 assert_eq!(c.evictor_deadlock_retry, 5);
2086 assert_eq!(c.evictor_keep_alive_ms, 30_000);
2087 assert!(!c.evictor_allow_bin_deltas);
2088 }
2089
2090 #[test]
2091 fn test_set_offheap_params() {
2092 let mut c = EnvironmentConfig::default();
2093 c.set_offheap_evict_bytes(1024 * 1024);
2094 c.set_offheap_n_lru_lists(8);
2095 c.set_offheap_checksum(true);
2096 c.set_offheap_core_threads(2);
2097 c.set_offheap_max_threads(4);
2098 c.set_offheap_keep_alive_ms(30_000);
2099 assert_eq!(c.offheap_evict_bytes, 1024 * 1024);
2100 assert_eq!(c.offheap_n_lru_lists, 8);
2101 assert!(c.offheap_checksum);
2102 assert_eq!(c.offheap_core_threads, 2);
2103 assert_eq!(c.offheap_max_threads, 4);
2104 assert_eq!(c.offheap_keep_alive_ms, 30_000);
2105 }
2106
2107 #[test]
2108 fn test_set_locking_params() {
2109 let mut c = EnvironmentConfig::default();
2110 c.set_lock_timeout(1000);
2111 c.set_lock_n_lock_tables(32);
2112 c.set_lock_deadlock_detect(false);
2113 c.set_lock_deadlock_detect_delay_ms(100);
2114 assert_eq!(c.lock_timeout_ms, 1000);
2115 assert_eq!(c.lock_n_lock_tables, 32);
2116 assert!(!c.lock_deadlock_detect);
2117 assert_eq!(c.lock_deadlock_detect_delay_ms, 100);
2118 }
2119
2120 #[test]
2121 #[allow(deprecated)] fn test_set_txn_params() {
2123 let mut c = EnvironmentConfig::default();
2124 c.set_txn_timeout(5000);
2125 c.set_txn_no_sync(true);
2126 c.set_txn_write_no_sync(true);
2127 c.set_txn_serializable_isolation(true);
2128 c.set_txn_deadlock_stack_trace(true);
2129 c.set_txn_dump_locks(true);
2130 assert_eq!(c.txn_timeout_ms, 5000);
2131 assert!(c.txn_no_sync);
2132 assert!(c.txn_write_no_sync);
2133 assert!(c.txn_serializable_isolation);
2134 assert!(c.txn_deadlock_stack_trace);
2135 assert!(c.txn_dump_locks);
2136 }
2137
2138 #[test]
2139 fn test_set_verifier_params() {
2140 let mut c = EnvironmentConfig::default();
2141 c.set_run_verifier(true);
2142 c.set_verify_schedule("0 2 * * *".to_string());
2143 c.set_verify_log(true);
2144 c.set_verify_log_read_delay_ms(50);
2145 c.set_verify_btree(true);
2146 c.set_verify_secondaries(false);
2147 c.set_verify_data_records(true);
2148 c.set_verify_obsolete_records(true);
2149 c.set_verify_btree_batch_size(500);
2150 c.set_verify_btree_batch_delay_ms(20);
2151 assert!(c.run_verifier);
2152 assert_eq!(c.verify_schedule, "0 2 * * *");
2153 assert!(c.verify_log);
2154 assert_eq!(c.verify_log_read_delay_ms, 50);
2155 assert!(c.verify_btree);
2156 assert!(!c.verify_secondaries);
2157 assert!(c.verify_data_records);
2158 assert!(c.verify_obsolete_records);
2159 assert_eq!(c.verify_btree_batch_size, 500);
2160 assert_eq!(c.verify_btree_batch_delay_ms, 20);
2161 }
2162
2163 #[test]
2164 fn test_set_stats_params() {
2165 let mut c = EnvironmentConfig::default();
2166 c.set_stats_collect(true);
2167 c.set_stats_collect_interval_secs(60);
2168 c.set_stats_max_files(50);
2169 c.set_stats_file_row_count(2000);
2170 c.set_stats_file_directory(PathBuf::from("/var/log/noxu"));
2171 assert!(c.stats_collect);
2172 assert_eq!(c.stats_collect_interval_secs, 60);
2173 assert_eq!(c.stats_max_files, 50);
2174 assert_eq!(c.stats_file_row_count, 2000);
2175 assert_eq!(
2176 c.stats_file_directory,
2177 Some(PathBuf::from("/var/log/noxu"))
2178 );
2179 }
2180
2181 #[test]
2182 fn test_set_trace_params() {
2183 let mut c = EnvironmentConfig::default();
2184 c.set_trace_file(true);
2185 c.set_trace_console(true);
2186 c.set_trace_file_limit_bytes(20 * 1024 * 1024);
2187 c.set_trace_file_count(5);
2188 c.set_trace_level("DEBUG".to_string());
2189 c.set_console_logging_level("WARN".to_string());
2190 c.set_file_logging_level("DEBUG".to_string());
2191 c.set_trace_level_lock_manager("TRACE".to_string());
2192 c.set_trace_level_recovery("TRACE".to_string());
2193 c.set_trace_level_evictor("DEBUG".to_string());
2194 c.set_trace_level_cleaner("DEBUG".to_string());
2195 c.set_startup_dump_threshold_ms(5000);
2196 assert!(c.trace_file);
2197 assert!(c.trace_console);
2198 assert_eq!(c.trace_file_limit_bytes, 20 * 1024 * 1024);
2199 assert_eq!(c.trace_file_count, 5);
2200 assert_eq!(c.trace_level, Some("DEBUG".to_string()));
2201 assert_eq!(c.console_logging_level, Some("WARN".to_string()));
2202 assert_eq!(c.file_logging_level, Some("DEBUG".to_string()));
2203 assert_eq!(c.trace_level_lock_manager, Some("TRACE".to_string()));
2204 assert_eq!(c.startup_dump_threshold_ms, 5000);
2205 }
2206
2207 #[test]
2208 #[allow(deprecated)] fn test_builder_chain() {
2210 let c = EnvironmentConfig::new(PathBuf::from("/data"))
2211 .with_allow_create(true)
2212 .with_transactional(true)
2213 .with_cache_size(512 * 1024 * 1024)
2214 .with_log_file_max_bytes(5 * 1024 * 1024)
2215 .with_cleaner_min_utilization(40)
2216 .with_checkpointer_bytes_interval(10_000_000)
2217 .with_evictor_nodes_per_scan(20)
2218 .with_log_group_commit(5, 10)
2219 .with_txn_no_sync(false)
2220 .with_durability(Durability::COMMIT_SYNC);
2221 assert_eq!(c.home, PathBuf::from("/data"));
2222 assert!(c.allow_create);
2223 assert!(c.transactional);
2224 assert_eq!(c.cache_size, 512 * 1024 * 1024);
2225 assert_eq!(c.log_file_max_bytes, 5 * 1024 * 1024);
2226 assert_eq!(c.cleaner_min_utilization, 40);
2227 assert_eq!(c.checkpointer_bytes_interval, 10_000_000);
2228 assert_eq!(c.evictor_nodes_per_scan, 20);
2229 assert_eq!(c.log_group_commit_threshold, 5);
2230 assert_eq!(c.log_group_commit_interval_ms, 10);
2231 assert!(!c.txn_no_sync);
2232 assert_eq!(c.durability, Durability::COMMIT_SYNC);
2233 }
2234
2235 #[test]
2236 fn test_env_behaviour_params() {
2237 let mut c = EnvironmentConfig::default();
2238 c.set_env_check_leaks(false);
2239 c.set_env_forced_yield(true);
2240 c.set_env_fair_latches(true);
2241 c.set_env_latch_timeout_ms(60_000);
2242 c.set_env_ttl_clock_tolerance_ms(100);
2243 c.set_env_expiration_enabled(true);
2244 c.set_env_db_eviction(true);
2245 c.set_adler32_chunk_size(4096);
2246 c.set_env_background_read_limit_kb(10_000);
2247 c.set_env_background_write_limit_kb(5_000);
2248 c.set_env_background_sleep_interval_us(100);
2249 assert!(!c.env_check_leaks);
2250 assert!(c.env_forced_yield);
2251 assert!(c.env_fair_latches);
2252 assert_eq!(c.env_latch_timeout_ms, 60_000);
2253 assert_eq!(c.env_ttl_clock_tolerance_ms, 100);
2254 assert!(c.env_expiration_enabled);
2255 assert!(c.env_db_eviction);
2256 assert_eq!(c.adler32_chunk_size, 4096);
2257 assert_eq!(c.env_background_read_limit_kb, 10_000);
2258 assert_eq!(c.env_background_write_limit_kb, 5_000);
2259 assert_eq!(c.env_background_sleep_interval_us, 100);
2260 }
2261
2262 #[test]
2263 fn test_compressor_params() {
2264 let mut c = EnvironmentConfig::default();
2265 c.set_in_compressor_wakeup_interval_ms(1000);
2266 c.set_compressor_deadlock_retry(5);
2267 c.set_compressor_lock_timeout_ms(1000);
2268 c.set_compressor_purge_root(true);
2269 assert_eq!(c.in_compressor_wakeup_interval_ms, 1000);
2270 assert_eq!(c.compressor_deadlock_retry, 5);
2271 assert_eq!(c.compressor_lock_timeout_ms, 1000);
2272 assert!(c.compressor_purge_root);
2273 }
2274
2275 #[test]
2276 fn test_dos_cursor_params() {
2277 let mut c = EnvironmentConfig::default();
2278 c.set_dos_producer_queue_timeout_ms(5000);
2279 assert_eq!(c.dos_producer_queue_timeout_ms, 5000);
2280 }
2281
2282 #[test]
2283 fn test_clone() {
2284 let c1 = EnvironmentConfig::default()
2285 .with_allow_create(true)
2286 .with_cache_size(256 * 1024 * 1024);
2287 let c2 = c1.clone();
2288 assert_eq!(c1.allow_create, c2.allow_create);
2289 assert_eq!(c1.cache_size, c2.cache_size);
2290 assert_eq!(c1.free_disk, c2.free_disk);
2291 }
2292}