1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
use Debug;
use BytesView;
use ;
/// Allowing for writing of bytes.
///
/// Only supports asynchronous access. Accepts the byte sequences to be written as `bytesbuf::BytesView` instances.
///
/// # Ownership
///
/// The methods on this trait accept `&mut self` and take an exclusive reference to the object for
/// the duration of the operation. This implies that only one write operation can be concurrently
/// executed on the object.
///
/// # Memory management for efficient I/O
///
/// For optimal efficiency when performing I/O, writes should be performed from memory optimized
/// for the underlying I/O endpoint. This is achieved by reserving memory from the implementation's
/// memory provider and generating your bytes into the returned memory buffer before performing the
/// write operation.
///
/// To be clear, the expectation is that whatever data you want to write is placed into the implementation's
/// provided memory buffers right from the start. If your data starts "somewhere else"
/// and must be copied, optimal I/O efficiency cannot be achieved as copying by definition
/// is a form of inefficiency. The data must be born in the memory buffers used for the write operation.
///
/// There are two ways to ensure you are using memory suitable for optimally efficient I/O:
///
/// 1. You may call [`Memory::reserve()`][2] on the implementing type to reserve memory from its memory provider.
/// 2. You may sometimes want to call `reserve()` at certain times when Rust borrowing rules do
/// not allow you to call it directly on the implementation because it has already been borrowed.
/// In this case, you can obtain an independent reference to the memory provider first via
/// [`HasMemory::memory()`][1], which allows you to bypass the need to borrow the implementing object itself.
///
/// Some implementations do not perform real I/O and only move data around in memory. Such
/// implementations typically do not have any special memory requirements and will operate
/// with the same efficiency regardless of which buffers the data is in. Any relaxed behaviors
/// like this will typically be described in the implementation's API documentation.
///
/// # Thread safety
///
/// This trait requires `Send` from both the implementation and any returned futures.
///
/// [1]: bytesbuf::mem::HasMemory::memory
/// [2]: bytesbuf::mem::Memory::reserve