1use std::time::Duration;
4
5#[cfg(feature = "bench-profile")]
6mod enabled {
7 use std::{
8 cell::RefCell,
9 sync::atomic::{AtomicBool, Ordering},
10 time::Duration,
11 };
12
13 use tiberius::BulkLoadStats;
14
15 #[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
17 pub struct DirectWriteProfile {
18 pub measure_batch: Duration,
20 pub row_range_split: Duration,
22 pub append_encode: Duration,
24 pub send_total: Duration,
26 pub rows: u64,
28 pub batches: u64,
30 pub row_ranges: u64,
32 pub encoded_bytes: u64,
34 pub max_row_range_bytes: u64,
36 pub nvarchar_utf16_bytes: u64,
38 pub varbinary_bytes: u64,
40 pub null_cells: u64,
42 pub packet_write_calls: u64,
44 pub packets_written: u64,
46 pub packet_payload_bytes: u64,
48 pub max_packet_payload_bytes: u64,
50 pub max_buffered_bytes_before_write: u64,
52 pub buffered_bytes_after_last_write: u64,
54 pub finalized_packet_payload_bytes: u64,
56 pub bulk_write_packets_elapsed: Duration,
58 pub bulk_write_to_wire_calls: u64,
60 pub bulk_write_to_wire_elapsed: Duration,
62 pub bulk_write_to_wire_payload_bytes: u64,
64 pub bulk_max_write_to_wire_elapsed: Duration,
66 pub bulk_max_write_to_wire_payload_bytes: u64,
68 pub bulk_flush_calls: u64,
70 pub bulk_flush_elapsed: Duration,
72 pub bulk_max_flush_elapsed: Duration,
74 pub bulk_finalize_elapsed: Duration,
76 pub bulk_finalize_write_to_wire_elapsed: Duration,
78 pub bulk_finalize_flush_elapsed: Duration,
80 pub bulk_finalize_result_elapsed: Duration,
82 pub bulk_connection_write_calls: u64,
84 pub bulk_connection_write_payload_bytes: u64,
86 pub bulk_connection_write_ready_elapsed: Duration,
88 pub bulk_connection_write_encode_elapsed: Duration,
90 pub bulk_connection_write_flush_elapsed: Duration,
92 pub bulk_connection_write_max_ready_elapsed: Duration,
94 pub bulk_connection_write_max_encode_elapsed: Duration,
96 pub bulk_connection_write_max_flush_elapsed: Duration,
98 pub bulk_connection_write_max_payload_bytes: u64,
100 pub bulk_direct_packet_write_calls: u64,
102 pub bulk_direct_packet_payload_bytes: u64,
104 pub bulk_direct_packet_header_bytes: u64,
106 pub bulk_direct_packet_max_payload_bytes: u64,
108 pub bulk_direct_packet_final_calls: u64,
110 pub bulk_direct_packet_final_payload_bytes: u64,
112 pub bulk_direct_packet_final_header_bytes: u64,
114 pub bulk_direct_packet_raw_stream_calls: u64,
116 pub bulk_direct_packet_tls_stream_calls: u64,
118 pub bulk_direct_packet_low_level_write_calls: u64,
120 pub bulk_direct_packet_low_level_write_bytes: u64,
122 pub bulk_direct_packet_max_low_level_write_bytes: u64,
124 pub bulk_direct_packet_write_elapsed: Duration,
126 pub bulk_direct_packet_max_write_elapsed: Duration,
128 pub bulk_direct_packet_header_write_calls: u64,
130 pub bulk_direct_packet_header_write_bytes: u64,
132 pub bulk_direct_packet_header_max_write_bytes: u64,
134 pub bulk_direct_packet_header_write_elapsed: Duration,
136 pub bulk_direct_packet_header_max_write_elapsed: Duration,
138 pub bulk_direct_packet_header_partial_writes: u64,
140 pub bulk_direct_packet_payload_write_calls: u64,
142 pub bulk_direct_packet_payload_write_bytes: u64,
144 pub bulk_direct_packet_payload_max_write_bytes: u64,
146 pub bulk_direct_packet_payload_write_elapsed: Duration,
148 pub bulk_direct_packet_payload_max_write_elapsed: Duration,
150 pub bulk_direct_packet_payload_partial_writes: u64,
152 pub bulk_direct_packet_poll_write_polls: u64,
154 pub bulk_direct_packet_poll_write_pending_count: u64,
156 pub bulk_direct_packet_poll_write_pending_elapsed: Duration,
158 pub bulk_direct_packet_poll_write_max_pending_elapsed: Duration,
160 pub bulk_direct_packet_poll_write_ready_count: u64,
162 pub bulk_direct_packet_poll_write_ready_elapsed: Duration,
164 pub bulk_direct_packet_poll_write_max_ready_elapsed: Duration,
166 pub bulk_direct_packet_flush_calls: u64,
168 pub bulk_direct_packet_flush_elapsed: Duration,
170 pub bulk_direct_packet_max_flush_elapsed: Duration,
172 pub bulk_direct_packet_flush_pending_count: u64,
174 pub bulk_direct_packet_flush_pending_elapsed: Duration,
176 pub bulk_direct_packet_flush_max_pending_elapsed: Duration,
178 }
179
180 impl DirectWriteProfile {
181 pub fn send_without_append_encode(&self) -> Duration {
183 self.send_total.saturating_sub(self.append_encode)
184 }
185 }
186
187 thread_local! {
188 static DIRECT_PROFILE: RefCell<Option<DirectWriteProfile>> = const { RefCell::new(None) };
189 }
190 static DIRECT_DATE_FAST_PATH_DISABLED: AtomicBool = AtomicBool::new(false);
191 static DIRECT_FIXED_WIDTH_FAST_PATH_DISABLED: AtomicBool = AtomicBool::new(false);
192
193 #[derive(Debug)]
195 pub struct DirectDateFastPathOverride {
196 previous: bool,
197 }
198
199 #[derive(Debug)]
201 pub struct DirectFixedWidthFastPathOverride {
202 previous: bool,
203 }
204
205 impl Drop for DirectDateFastPathOverride {
206 fn drop(&mut self) {
207 DIRECT_DATE_FAST_PATH_DISABLED.store(self.previous, Ordering::Relaxed);
208 }
209 }
210
211 impl Drop for DirectFixedWidthFastPathOverride {
212 fn drop(&mut self) {
213 DIRECT_FIXED_WIDTH_FAST_PATH_DISABLED.store(self.previous, Ordering::Relaxed);
214 }
215 }
216
217 pub fn disable_direct_date_fast_path_for_scope() -> DirectDateFastPathOverride {
219 DirectDateFastPathOverride {
220 previous: DIRECT_DATE_FAST_PATH_DISABLED.swap(true, Ordering::Relaxed),
221 }
222 }
223
224 pub fn disable_direct_fixed_width_fast_path_for_scope() -> DirectFixedWidthFastPathOverride {
226 DirectFixedWidthFastPathOverride {
227 previous: DIRECT_FIXED_WIDTH_FAST_PATH_DISABLED.swap(true, Ordering::Relaxed),
228 }
229 }
230
231 pub(crate) fn direct_date_fast_path_disabled() -> bool {
232 DIRECT_DATE_FAST_PATH_DISABLED.load(Ordering::Relaxed)
233 }
234
235 pub(crate) fn direct_fixed_width_fast_path_disabled() -> bool {
236 DIRECT_FIXED_WIDTH_FAST_PATH_DISABLED.load(Ordering::Relaxed)
237 }
238
239 pub fn start_direct_write_profile() {
243 DIRECT_PROFILE.with(|profile| {
244 *profile.borrow_mut() = Some(DirectWriteProfile::default());
245 });
246 }
247
248 pub fn finish_direct_write_profile() -> Option<DirectWriteProfile> {
250 DIRECT_PROFILE.with(|profile| profile.borrow_mut().take())
251 }
252
253 pub(crate) fn record_measure_batch(elapsed: Duration) {
254 with_profile(|profile| profile.measure_batch += elapsed);
255 }
256
257 pub(crate) fn record_row_range_split(elapsed: Duration) {
258 with_profile(|profile| profile.row_range_split += elapsed);
259 }
260
261 pub(crate) fn record_append_encode(elapsed: Duration) {
262 with_profile(|profile| profile.append_encode += elapsed);
263 }
264
265 pub(crate) fn record_send_total(elapsed: Duration) {
266 with_profile(|profile| profile.send_total += elapsed);
267 }
268
269 pub(crate) fn record_accepted_batch(rows: usize) {
270 with_profile(|profile| {
271 profile.rows = profile.rows.saturating_add(usize_to_u64_saturating(rows));
272 profile.batches = profile.batches.saturating_add(1);
273 });
274 }
275
276 pub(crate) fn record_row_range(encoded_bytes: usize) {
277 with_profile(|profile| {
278 let encoded_bytes = usize_to_u64_saturating(encoded_bytes);
279 profile.row_ranges = profile.row_ranges.saturating_add(1);
280 profile.encoded_bytes = profile.encoded_bytes.saturating_add(encoded_bytes);
281 profile.max_row_range_bytes = profile.max_row_range_bytes.max(encoded_bytes);
282 });
283 }
284
285 pub(crate) fn record_nvarchar_utf16_bytes(encoded_bytes: usize) {
286 with_profile(|profile| {
287 profile.nvarchar_utf16_bytes = profile
288 .nvarchar_utf16_bytes
289 .saturating_add(usize_to_u64_saturating(encoded_bytes));
290 });
291 }
292
293 pub(crate) fn record_varbinary_bytes(encoded_bytes: usize) {
294 with_profile(|profile| {
295 profile.varbinary_bytes = profile
296 .varbinary_bytes
297 .saturating_add(usize_to_u64_saturating(encoded_bytes));
298 });
299 }
300
301 pub(crate) fn record_null_cell() {
302 with_profile(|profile| {
303 profile.null_cells = profile.null_cells.saturating_add(1);
304 });
305 }
306
307 pub(crate) fn record_bulk_load_stats(stats: BulkLoadStats) {
308 let packet = stats.packet;
309 let timing = stats.write_timing;
310 let connection = timing.connection_write;
311 let direct = timing.direct_packet_write;
312
313 with_profile(|profile| {
314 profile.packet_write_calls = profile
315 .packet_write_calls
316 .saturating_add(packet.write_packets_calls);
317 profile.packets_written = profile
318 .packets_written
319 .saturating_add(packet.packets_written);
320 profile.packet_payload_bytes = profile
321 .packet_payload_bytes
322 .saturating_add(packet.packet_payload_bytes);
323 profile.max_packet_payload_bytes = profile
324 .max_packet_payload_bytes
325 .max(usize_to_u64_saturating(packet.max_packet_payload_bytes));
326 profile.max_buffered_bytes_before_write =
327 profile
328 .max_buffered_bytes_before_write
329 .max(usize_to_u64_saturating(
330 packet.max_buffered_bytes_before_write,
331 ));
332 profile.buffered_bytes_after_last_write =
333 usize_to_u64_saturating(packet.buffered_bytes_after_last_write);
334 profile.finalized_packet_payload_bytes = profile
335 .finalized_packet_payload_bytes
336 .saturating_add(usize_to_u64_saturating(
337 packet.finalized_packet_payload_bytes,
338 ));
339 profile.bulk_write_packets_elapsed += timing.write_packets_elapsed;
340 profile.bulk_write_to_wire_calls = profile
341 .bulk_write_to_wire_calls
342 .saturating_add(timing.write_to_wire_calls);
343 profile.bulk_write_to_wire_elapsed += timing.write_to_wire_elapsed;
344 profile.bulk_write_to_wire_payload_bytes = profile
345 .bulk_write_to_wire_payload_bytes
346 .saturating_add(timing.write_to_wire_payload_bytes);
347 profile.bulk_max_write_to_wire_elapsed = profile
348 .bulk_max_write_to_wire_elapsed
349 .max(timing.max_write_to_wire_elapsed);
350 profile.bulk_max_write_to_wire_payload_bytes = profile
351 .bulk_max_write_to_wire_payload_bytes
352 .max(usize_to_u64_saturating(
353 timing.max_write_to_wire_payload_bytes,
354 ));
355 profile.bulk_flush_calls = profile.bulk_flush_calls.saturating_add(timing.flush_calls);
356 profile.bulk_flush_elapsed += timing.flush_elapsed;
357 profile.bulk_max_flush_elapsed =
358 profile.bulk_max_flush_elapsed.max(timing.max_flush_elapsed);
359 profile.bulk_finalize_elapsed += timing.finalize_elapsed;
360 profile.bulk_finalize_write_to_wire_elapsed += timing.finalize_write_to_wire_elapsed;
361 profile.bulk_finalize_flush_elapsed += timing.finalize_flush_elapsed;
362 profile.bulk_finalize_result_elapsed += timing.finalize_result_elapsed;
363 profile.bulk_connection_write_calls = profile
364 .bulk_connection_write_calls
365 .saturating_add(connection.calls);
366 profile.bulk_connection_write_payload_bytes = profile
367 .bulk_connection_write_payload_bytes
368 .saturating_add(connection.payload_bytes);
369 profile.bulk_connection_write_ready_elapsed += connection.ready_elapsed;
370 profile.bulk_connection_write_encode_elapsed += connection.encode_elapsed;
371 profile.bulk_connection_write_flush_elapsed += connection.flush_elapsed;
372 profile.bulk_connection_write_max_ready_elapsed = profile
373 .bulk_connection_write_max_ready_elapsed
374 .max(connection.max_ready_elapsed);
375 profile.bulk_connection_write_max_encode_elapsed = profile
376 .bulk_connection_write_max_encode_elapsed
377 .max(connection.max_encode_elapsed);
378 profile.bulk_connection_write_max_flush_elapsed = profile
379 .bulk_connection_write_max_flush_elapsed
380 .max(connection.max_flush_elapsed);
381 profile.bulk_connection_write_max_payload_bytes = profile
382 .bulk_connection_write_max_payload_bytes
383 .max(usize_to_u64_saturating(connection.max_payload_bytes));
384 profile.bulk_direct_packet_write_calls = profile
385 .bulk_direct_packet_write_calls
386 .saturating_add(direct.calls);
387 profile.bulk_direct_packet_payload_bytes = profile
388 .bulk_direct_packet_payload_bytes
389 .saturating_add(direct.payload_bytes);
390 profile.bulk_direct_packet_header_bytes = profile
391 .bulk_direct_packet_header_bytes
392 .saturating_add(direct.header_bytes);
393 profile.bulk_direct_packet_max_payload_bytes = profile
394 .bulk_direct_packet_max_payload_bytes
395 .max(usize_to_u64_saturating(direct.max_payload_bytes));
396 profile.bulk_direct_packet_final_calls = profile
397 .bulk_direct_packet_final_calls
398 .saturating_add(direct.final_calls);
399 profile.bulk_direct_packet_final_payload_bytes = profile
400 .bulk_direct_packet_final_payload_bytes
401 .saturating_add(direct.final_payload_bytes);
402 profile.bulk_direct_packet_final_header_bytes = profile
403 .bulk_direct_packet_final_header_bytes
404 .saturating_add(direct.final_header_bytes);
405 profile.bulk_direct_packet_raw_stream_calls = profile
406 .bulk_direct_packet_raw_stream_calls
407 .saturating_add(direct.raw_stream_calls);
408 profile.bulk_direct_packet_tls_stream_calls = profile
409 .bulk_direct_packet_tls_stream_calls
410 .saturating_add(direct.tls_stream_calls);
411 profile.bulk_direct_packet_low_level_write_calls = profile
412 .bulk_direct_packet_low_level_write_calls
413 .saturating_add(direct.write_calls);
414 profile.bulk_direct_packet_low_level_write_bytes = profile
415 .bulk_direct_packet_low_level_write_bytes
416 .saturating_add(direct.write_bytes);
417 profile.bulk_direct_packet_max_low_level_write_bytes = profile
418 .bulk_direct_packet_max_low_level_write_bytes
419 .max(usize_to_u64_saturating(direct.max_write_bytes));
420 profile.bulk_direct_packet_write_elapsed += direct.write_elapsed;
421 profile.bulk_direct_packet_max_write_elapsed = profile
422 .bulk_direct_packet_max_write_elapsed
423 .max(direct.max_write_elapsed);
424 profile.bulk_direct_packet_header_write_calls = profile
425 .bulk_direct_packet_header_write_calls
426 .saturating_add(direct.header_write_calls);
427 profile.bulk_direct_packet_header_write_bytes = profile
428 .bulk_direct_packet_header_write_bytes
429 .saturating_add(direct.header_write_bytes);
430 profile.bulk_direct_packet_header_max_write_bytes = profile
431 .bulk_direct_packet_header_max_write_bytes
432 .max(usize_to_u64_saturating(direct.header_max_write_bytes));
433 profile.bulk_direct_packet_header_write_elapsed += direct.header_write_elapsed;
434 profile.bulk_direct_packet_header_max_write_elapsed = profile
435 .bulk_direct_packet_header_max_write_elapsed
436 .max(direct.header_max_write_elapsed);
437 profile.bulk_direct_packet_header_partial_writes = profile
438 .bulk_direct_packet_header_partial_writes
439 .saturating_add(direct.header_partial_writes);
440 profile.bulk_direct_packet_payload_write_calls = profile
441 .bulk_direct_packet_payload_write_calls
442 .saturating_add(direct.payload_write_calls);
443 profile.bulk_direct_packet_payload_write_bytes = profile
444 .bulk_direct_packet_payload_write_bytes
445 .saturating_add(direct.payload_write_bytes);
446 profile.bulk_direct_packet_payload_max_write_bytes = profile
447 .bulk_direct_packet_payload_max_write_bytes
448 .max(usize_to_u64_saturating(direct.payload_max_write_bytes));
449 profile.bulk_direct_packet_payload_write_elapsed += direct.payload_write_elapsed;
450 profile.bulk_direct_packet_payload_max_write_elapsed = profile
451 .bulk_direct_packet_payload_max_write_elapsed
452 .max(direct.payload_max_write_elapsed);
453 profile.bulk_direct_packet_payload_partial_writes = profile
454 .bulk_direct_packet_payload_partial_writes
455 .saturating_add(direct.payload_partial_writes);
456 profile.bulk_direct_packet_poll_write_polls = profile
457 .bulk_direct_packet_poll_write_polls
458 .saturating_add(direct.poll_write_polls);
459 profile.bulk_direct_packet_poll_write_pending_count = profile
460 .bulk_direct_packet_poll_write_pending_count
461 .saturating_add(direct.poll_write_pending_count);
462 profile.bulk_direct_packet_poll_write_pending_elapsed +=
463 direct.poll_write_pending_elapsed;
464 profile.bulk_direct_packet_poll_write_max_pending_elapsed = profile
465 .bulk_direct_packet_poll_write_max_pending_elapsed
466 .max(direct.poll_write_max_pending_elapsed);
467 profile.bulk_direct_packet_poll_write_ready_count = profile
468 .bulk_direct_packet_poll_write_ready_count
469 .saturating_add(direct.poll_write_ready_count);
470 profile.bulk_direct_packet_poll_write_ready_elapsed += direct.poll_write_ready_elapsed;
471 profile.bulk_direct_packet_poll_write_max_ready_elapsed = profile
472 .bulk_direct_packet_poll_write_max_ready_elapsed
473 .max(direct.poll_write_max_ready_elapsed);
474 profile.bulk_direct_packet_flush_calls = profile
475 .bulk_direct_packet_flush_calls
476 .saturating_add(direct.flush_calls);
477 profile.bulk_direct_packet_flush_elapsed += direct.flush_elapsed;
478 profile.bulk_direct_packet_max_flush_elapsed = profile
479 .bulk_direct_packet_max_flush_elapsed
480 .max(direct.max_flush_elapsed);
481 profile.bulk_direct_packet_flush_pending_count = profile
482 .bulk_direct_packet_flush_pending_count
483 .saturating_add(direct.flush_pending_count);
484 profile.bulk_direct_packet_flush_pending_elapsed += direct.flush_pending_elapsed;
485 profile.bulk_direct_packet_flush_max_pending_elapsed = profile
486 .bulk_direct_packet_flush_max_pending_elapsed
487 .max(direct.flush_max_pending_elapsed);
488 });
489 }
490
491 fn with_profile(update: impl FnOnce(&mut DirectWriteProfile)) {
492 DIRECT_PROFILE.with(|profile| {
493 if let Some(profile) = profile.borrow_mut().as_mut() {
494 update(profile);
495 }
496 });
497 }
498
499 fn usize_to_u64_saturating(value: usize) -> u64 {
500 u64::try_from(value).unwrap_or(u64::MAX)
501 }
502}
503
504#[cfg(not(feature = "bench-profile"))]
505mod disabled {
506 use std::time::Duration;
507
508 pub(crate) fn record_measure_batch(_elapsed: Duration) {}
509
510 pub(crate) fn record_row_range_split(_elapsed: Duration) {}
511
512 pub(crate) fn record_append_encode(_elapsed: Duration) {}
513
514 pub(crate) fn record_send_total(_elapsed: Duration) {}
515
516 pub(crate) fn record_accepted_batch(_rows: usize) {}
517
518 pub(crate) fn record_row_range(_encoded_bytes: usize) {}
519
520 pub(crate) fn record_nvarchar_utf16_bytes(_encoded_bytes: usize) {}
521
522 pub(crate) fn record_varbinary_bytes(_encoded_bytes: usize) {}
523
524 pub(crate) fn record_null_cell() {}
525
526 pub(crate) fn direct_date_fast_path_disabled() -> bool {
527 false
528 }
529
530 pub(crate) fn direct_fixed_width_fast_path_disabled() -> bool {
531 false
532 }
533}
534
535#[cfg(not(feature = "bench-profile"))]
536pub(crate) use disabled::*;
537#[cfg(feature = "bench-profile")]
538pub use enabled::{
539 DirectDateFastPathOverride, DirectFixedWidthFastPathOverride, DirectWriteProfile,
540 disable_direct_date_fast_path_for_scope, disable_direct_fixed_width_fast_path_for_scope,
541 finish_direct_write_profile, start_direct_write_profile,
542};
543#[cfg(feature = "bench-profile")]
544pub(crate) use enabled::{
545 direct_date_fast_path_disabled, direct_fixed_width_fast_path_disabled, record_accepted_batch,
546 record_append_encode, record_bulk_load_stats, record_measure_batch, record_null_cell,
547 record_nvarchar_utf16_bytes, record_row_range, record_row_range_split, record_send_total,
548 record_varbinary_bytes,
549};
550
551pub(crate) fn record_elapsed<T>(start: std::time::Instant, record: fn(Duration), value: T) -> T {
552 record(start.elapsed());
553 value
554}
555
556#[cfg(all(test, feature = "bench-profile"))]
557mod tests {
558 use std::time::Duration;
559
560 #[test]
561 fn direct_profile_accumulates_and_resets_current_thread_data() {
562 super::start_direct_write_profile();
563 super::record_measure_batch(Duration::from_millis(2));
564 super::record_row_range_split(Duration::from_millis(3));
565 super::record_append_encode(Duration::from_millis(5));
566 super::record_send_total(Duration::from_millis(13));
567 super::record_accepted_batch(7);
568 super::record_row_range(11);
569 super::record_nvarchar_utf16_bytes(17);
570 super::record_varbinary_bytes(19);
571 super::record_null_cell();
572 super::record_bulk_load_stats(tiberius::BulkLoadStats {
573 packet: tiberius::BulkLoadPacketStats {
574 write_packets_calls: 23,
575 packets_written: 29,
576 packet_payload_bytes: 31,
577 max_packet_payload_bytes: 37,
578 max_buffered_bytes_before_write: 41,
579 buffered_bytes_after_last_write: 43,
580 finalized_packet_payload_bytes: 47,
581 },
582 write_timing: tiberius::BulkLoadWriteTimingStats {
583 write_packets_elapsed: Duration::from_millis(53),
584 write_to_wire_calls: 59,
585 write_to_wire_elapsed: Duration::from_millis(61),
586 write_to_wire_payload_bytes: 67,
587 max_write_to_wire_elapsed: Duration::from_millis(71),
588 max_write_to_wire_payload_bytes: 73,
589 flush_calls: 79,
590 flush_elapsed: Duration::from_millis(83),
591 max_flush_elapsed: Duration::from_millis(89),
592 finalize_elapsed: Duration::from_millis(97),
593 finalize_write_to_wire_elapsed: Duration::from_millis(101),
594 finalize_flush_elapsed: Duration::from_millis(103),
595 finalize_result_elapsed: Duration::from_millis(107),
596 connection_write: tiberius::BulkLoadConnectionWriteStats {
597 calls: 109,
598 payload_bytes: 113,
599 ready_elapsed: Duration::from_millis(127),
600 encode_elapsed: Duration::from_millis(131),
601 flush_elapsed: Duration::from_millis(137),
602 max_ready_elapsed: Duration::from_millis(139),
603 max_encode_elapsed: Duration::from_millis(149),
604 max_flush_elapsed: Duration::from_millis(151),
605 max_payload_bytes: 157,
606 },
607 direct_packet_write: tiberius::BulkLoadDirectPacketWriteStats {
608 calls: 163,
609 payload_bytes: 167,
610 header_bytes: 173,
611 max_payload_bytes: 179,
612 final_calls: 181,
613 final_payload_bytes: 191,
614 final_header_bytes: 193,
615 raw_stream_calls: 197,
616 tls_stream_calls: 199,
617 write_calls: 179,
618 write_bytes: 181,
619 max_write_bytes: 191,
620 write_elapsed: Duration::from_millis(193),
621 max_write_elapsed: Duration::from_millis(197),
622 header_write_calls: 211,
623 header_write_bytes: 223,
624 header_max_write_bytes: 227,
625 header_write_elapsed: Duration::from_millis(229),
626 header_max_write_elapsed: Duration::from_millis(233),
627 header_partial_writes: 239,
628 payload_write_calls: 241,
629 payload_write_bytes: 251,
630 payload_max_write_bytes: 257,
631 payload_write_elapsed: Duration::from_millis(263),
632 payload_max_write_elapsed: Duration::from_millis(269),
633 payload_partial_writes: 271,
634 poll_write_polls: 277,
635 poll_write_pending_count: 281,
636 poll_write_pending_elapsed: Duration::from_millis(283),
637 poll_write_max_pending_elapsed: Duration::from_millis(293),
638 poll_write_ready_count: 307,
639 poll_write_ready_elapsed: Duration::from_millis(311),
640 poll_write_max_ready_elapsed: Duration::from_millis(313),
641 flush_calls: 199,
642 flush_elapsed: Duration::from_millis(211),
643 max_flush_elapsed: Duration::from_millis(223),
644 flush_pending_count: 317,
645 flush_pending_elapsed: Duration::from_millis(331),
646 flush_max_pending_elapsed: Duration::from_millis(337),
647 },
648 },
649 });
650
651 let profile = super::finish_direct_write_profile().unwrap();
652
653 assert_eq!(profile.measure_batch, Duration::from_millis(2));
654 assert_eq!(profile.row_range_split, Duration::from_millis(3));
655 assert_eq!(profile.append_encode, Duration::from_millis(5));
656 assert_eq!(profile.send_total, Duration::from_millis(13));
657 assert_eq!(
658 profile.send_without_append_encode(),
659 Duration::from_millis(8)
660 );
661 assert_eq!(profile.rows, 7);
662 assert_eq!(profile.batches, 1);
663 assert_eq!(profile.row_ranges, 1);
664 assert_eq!(profile.encoded_bytes, 11);
665 assert_eq!(profile.max_row_range_bytes, 11);
666 assert_eq!(profile.nvarchar_utf16_bytes, 17);
667 assert_eq!(profile.varbinary_bytes, 19);
668 assert_eq!(profile.null_cells, 1);
669 assert_eq!(profile.packet_write_calls, 23);
670 assert_eq!(profile.packets_written, 29);
671 assert_eq!(profile.packet_payload_bytes, 31);
672 assert_eq!(profile.max_packet_payload_bytes, 37);
673 assert_eq!(profile.max_buffered_bytes_before_write, 41);
674 assert_eq!(profile.buffered_bytes_after_last_write, 43);
675 assert_eq!(profile.finalized_packet_payload_bytes, 47);
676 assert_eq!(
677 profile.bulk_write_packets_elapsed,
678 Duration::from_millis(53)
679 );
680 assert_eq!(profile.bulk_write_to_wire_calls, 59);
681 assert_eq!(
682 profile.bulk_write_to_wire_elapsed,
683 Duration::from_millis(61)
684 );
685 assert_eq!(profile.bulk_write_to_wire_payload_bytes, 67);
686 assert_eq!(
687 profile.bulk_max_write_to_wire_elapsed,
688 Duration::from_millis(71)
689 );
690 assert_eq!(profile.bulk_max_write_to_wire_payload_bytes, 73);
691 assert_eq!(profile.bulk_flush_calls, 79);
692 assert_eq!(profile.bulk_flush_elapsed, Duration::from_millis(83));
693 assert_eq!(profile.bulk_max_flush_elapsed, Duration::from_millis(89));
694 assert_eq!(profile.bulk_finalize_elapsed, Duration::from_millis(97));
695 assert_eq!(
696 profile.bulk_finalize_write_to_wire_elapsed,
697 Duration::from_millis(101)
698 );
699 assert_eq!(
700 profile.bulk_finalize_flush_elapsed,
701 Duration::from_millis(103)
702 );
703 assert_eq!(
704 profile.bulk_finalize_result_elapsed,
705 Duration::from_millis(107)
706 );
707 assert_eq!(profile.bulk_connection_write_calls, 109);
708 assert_eq!(profile.bulk_connection_write_payload_bytes, 113);
709 assert_eq!(
710 profile.bulk_connection_write_ready_elapsed,
711 Duration::from_millis(127)
712 );
713 assert_eq!(
714 profile.bulk_connection_write_encode_elapsed,
715 Duration::from_millis(131)
716 );
717 assert_eq!(
718 profile.bulk_connection_write_flush_elapsed,
719 Duration::from_millis(137)
720 );
721 assert_eq!(
722 profile.bulk_connection_write_max_ready_elapsed,
723 Duration::from_millis(139)
724 );
725 assert_eq!(
726 profile.bulk_connection_write_max_encode_elapsed,
727 Duration::from_millis(149)
728 );
729 assert_eq!(
730 profile.bulk_connection_write_max_flush_elapsed,
731 Duration::from_millis(151)
732 );
733 assert_eq!(profile.bulk_connection_write_max_payload_bytes, 157);
734 assert_eq!(profile.bulk_direct_packet_write_calls, 163);
735 assert_eq!(profile.bulk_direct_packet_payload_bytes, 167);
736 assert_eq!(profile.bulk_direct_packet_header_bytes, 173);
737 assert_eq!(profile.bulk_direct_packet_max_payload_bytes, 179);
738 assert_eq!(profile.bulk_direct_packet_final_calls, 181);
739 assert_eq!(profile.bulk_direct_packet_final_payload_bytes, 191);
740 assert_eq!(profile.bulk_direct_packet_final_header_bytes, 193);
741 assert_eq!(profile.bulk_direct_packet_raw_stream_calls, 197);
742 assert_eq!(profile.bulk_direct_packet_tls_stream_calls, 199);
743 assert_eq!(profile.bulk_direct_packet_low_level_write_calls, 179);
744 assert_eq!(profile.bulk_direct_packet_low_level_write_bytes, 181);
745 assert_eq!(profile.bulk_direct_packet_max_low_level_write_bytes, 191);
746 assert_eq!(
747 profile.bulk_direct_packet_write_elapsed,
748 Duration::from_millis(193)
749 );
750 assert_eq!(
751 profile.bulk_direct_packet_max_write_elapsed,
752 Duration::from_millis(197)
753 );
754 assert_eq!(profile.bulk_direct_packet_header_write_calls, 211);
755 assert_eq!(profile.bulk_direct_packet_header_write_bytes, 223);
756 assert_eq!(profile.bulk_direct_packet_header_max_write_bytes, 227);
757 assert_eq!(
758 profile.bulk_direct_packet_header_write_elapsed,
759 Duration::from_millis(229)
760 );
761 assert_eq!(
762 profile.bulk_direct_packet_header_max_write_elapsed,
763 Duration::from_millis(233)
764 );
765 assert_eq!(profile.bulk_direct_packet_header_partial_writes, 239);
766 assert_eq!(profile.bulk_direct_packet_payload_write_calls, 241);
767 assert_eq!(profile.bulk_direct_packet_payload_write_bytes, 251);
768 assert_eq!(profile.bulk_direct_packet_payload_max_write_bytes, 257);
769 assert_eq!(
770 profile.bulk_direct_packet_payload_write_elapsed,
771 Duration::from_millis(263)
772 );
773 assert_eq!(
774 profile.bulk_direct_packet_payload_max_write_elapsed,
775 Duration::from_millis(269)
776 );
777 assert_eq!(profile.bulk_direct_packet_payload_partial_writes, 271);
778 assert_eq!(profile.bulk_direct_packet_poll_write_polls, 277);
779 assert_eq!(profile.bulk_direct_packet_poll_write_pending_count, 281);
780 assert_eq!(
781 profile.bulk_direct_packet_poll_write_pending_elapsed,
782 Duration::from_millis(283)
783 );
784 assert_eq!(
785 profile.bulk_direct_packet_poll_write_max_pending_elapsed,
786 Duration::from_millis(293)
787 );
788 assert_eq!(profile.bulk_direct_packet_poll_write_ready_count, 307);
789 assert_eq!(
790 profile.bulk_direct_packet_poll_write_ready_elapsed,
791 Duration::from_millis(311)
792 );
793 assert_eq!(
794 profile.bulk_direct_packet_poll_write_max_ready_elapsed,
795 Duration::from_millis(313)
796 );
797 assert_eq!(profile.bulk_direct_packet_flush_calls, 199);
798 assert_eq!(
799 profile.bulk_direct_packet_flush_elapsed,
800 Duration::from_millis(211)
801 );
802 assert_eq!(
803 profile.bulk_direct_packet_max_flush_elapsed,
804 Duration::from_millis(223)
805 );
806 assert_eq!(profile.bulk_direct_packet_flush_pending_count, 317);
807 assert_eq!(
808 profile.bulk_direct_packet_flush_pending_elapsed,
809 Duration::from_millis(331)
810 );
811 assert_eq!(
812 profile.bulk_direct_packet_flush_max_pending_elapsed,
813 Duration::from_millis(337)
814 );
815 assert!(super::finish_direct_write_profile().is_none());
816 }
817}