Skip to content

Commit 2bc00e3

Browse files
committed
Implement Extend for WriteHandle
Add a impl for Extend<Op> to WriteHandle, to append multiple operations from an iterator from the oplog at once. In addition to convenience, this has the potential to be more efficient by avoiding reallocating the vector for the oplog multiple times.
1 parent 9821e18 commit 2bc00e3

File tree

1 file changed

+29
-12
lines changed

1 file changed

+29
-12
lines changed

left-right/src/write.rs

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -299,18 +299,7 @@ where
299299
///
300300
/// Its effects will not be exposed to readers until you call [`publish`](Self::publish).
301301
pub fn append(&mut self, op: O) -> &mut Self {
302-
if self.first {
303-
// Safety: we know there are no outstanding w_handle readers, since we haven't
304-
// refreshed ever before, so we can modify it directly!
305-
let mut w_inner = self.raw_write_handle();
306-
let w_inner = unsafe { w_inner.as_mut() };
307-
let r_handle = self.enter().expect("map has not yet been destroyed");
308-
// Because we are operating directly on the map, and nothing is aliased, we do want
309-
// to perform drops, so we invoke absorb_second.
310-
Absorb::absorb_second(w_inner, op, &*r_handle);
311-
} else {
312-
self.oplog.push_back(op);
313-
}
302+
self.extend(std::iter::once(op));
314303
self
315304
}
316305

@@ -340,6 +329,34 @@ where
340329
}
341330
}
342331

332+
impl<T, O> Extend<O> for WriteHandle<T, O>
333+
where
334+
T: Absorb<O>,
335+
{
336+
/// Add multiple operations to the operational log.
337+
///
338+
/// Their effects will not be exposed to readers until you call [`publish`](Self::publish)
339+
fn extend<I>(&mut self, ops: I)
340+
where
341+
I: IntoIterator<Item = O>,
342+
{
343+
if self.first {
344+
// Safety: we know there are no outstanding w_handle readers, since we haven't
345+
// refreshed ever before, so we can modify it directly!
346+
let mut w_inner = self.raw_write_handle();
347+
let w_inner = unsafe { w_inner.as_mut() };
348+
let r_handle = self.enter().expect("map has not yet been destroyed");
349+
// Because we are operating directly on the map, and nothing is aliased, we do want
350+
// to perform drops, so we invoke absorb_second.
351+
for op in ops {
352+
Absorb::absorb_second(w_inner, op, &*r_handle);
353+
}
354+
} else {
355+
self.oplog.extend(ops);
356+
}
357+
}
358+
}
359+
343360
/// `WriteHandle` can be sent across thread boundaries:
344361
///
345362
/// ```

0 commit comments

Comments
 (0)