Skip to content

Commit 3aaa169

Browse files
committed
Optimize simulated read/write
1 parent 4d9e58b commit 3aaa169

File tree

1 file changed

+17
-12
lines changed

1 file changed

+17
-12
lines changed

lambda/src/simulated.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,7 @@ impl BufferState {
111111
}
112112
/// Writes data to the front of the deque byte buffer
113113
fn write(&mut self, buf: &[u8]) {
114-
for b in buf {
115-
self.buffer.push_front(*b)
116-
}
114+
self.buffer.extend(buf);
117115

118116
// If somebody is waiting on this data, wake them up.
119117
if let Some(waker) = self.read_waker.take() {
@@ -122,14 +120,22 @@ impl BufferState {
122120
}
123121

124122
/// Read data from the end of the deque byte buffer
125-
fn read(&mut self, to_buf: &mut ReadBuf<'_>) -> usize {
123+
fn read(&mut self, to_buf: &mut ReadBuf<'_>) {
126124
// Read no more bytes than we have available, and no more bytes than we were asked for
127125
let bytes_to_read = min(to_buf.remaining(), self.buffer.len());
128-
for _ in 0..bytes_to_read {
129-
to_buf.put_slice(&[self.buffer.pop_back().unwrap()]);
130-
}
126+
// a VecDeque isn't contiguous, so we have 2 slices we need to account for
127+
let (buf_l, buf_r) = self.buffer.as_slices();
128+
if let Some(buf) = buf_l.get(..bytes_to_read) {
129+
// if buf_l has enough to satisfy bytes_to_read, just take from it
130+
to_buf.put_slice(buf);
131+
} else {
132+
// otherwise, use up all of buf_l and take the remaining from buf_r
133+
to_buf.put_slice(buf_l);
134+
to_buf.put_slice(&buf_r[..bytes_to_read - buf_l.len()]);
135+
};
131136

132-
bytes_to_read
137+
// cut off what we've read from the start of the buffer
138+
self.buffer.drain(..bytes_to_read);
133139
}
134140
}
135141

@@ -179,17 +185,16 @@ impl AsyncRead for ReadHalf {
179185
.lock()
180186
.expect("Lock was poisoned when acquiring buffer lock for ReadHalf");
181187

182-
let bytes_read = read_from.read(buf);
183-
184188
// Returning Poll::Ready(Ok(0)) would indicate that there is nothing more to read, which
185189
// means that someone trying to read from a VecDeque that hasn't been written to yet
186190
// would get an Eof error (as I learned the hard way). Instead we should return Poll:Pending
187191
// to indicate that there could be more to read in the future.
188-
if bytes_read == 0 {
192+
if read_from.buffer.is_empty() && buf.remaining() != 0 {
193+
// the user wanted to read something, but we don't have it
189194
read_from.read_waker = Some(cx.waker().clone());
190195
Poll::Pending
191196
} else {
192-
//read_from.read_waker = Some(cx.waker().clone());
197+
read_from.read(buf);
193198
Poll::Ready(Ok(()))
194199
}
195200
}

0 commit comments

Comments
 (0)