5454{
5555 handle : left_right:: WriteHandle < Inner < K , V , M , S > , Operation < K , V , M > > ,
5656 r_handle : ReadHandle < K , V , M , S > ,
57-
58- /// If Some, write directly to the write handle map, since no publish has happened.
59- /// Some(false) indicates that the necessary `Operation::JustCloneRHandle` has not
60- /// yet been appended to the oplog for when a publish does happen.
61- direct_write : Option < bool > ,
6257}
6358
6459impl < K , V , M , S > fmt:: Debug for WriteHandle < K , V , M , S >
7166 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
7267 f. debug_struct ( "WriteHandle" )
7368 . field ( "handle" , & self . handle )
74- . field ( "direct_write" , & self . direct_write )
7569 . finish ( )
7670 }
7771}
8781 handle : left_right:: WriteHandle < Inner < K , V , M , S > , Operation < K , V , M > > ,
8882 ) -> Self {
8983 let r_handle = ReadHandle :: new ( left_right:: ReadHandle :: clone ( & * handle) ) ;
90- Self {
91- handle,
92- r_handle,
93- direct_write : Some ( false ) ,
94- }
84+ Self { handle, r_handle }
9585 }
9686
9787 /// Publish all changes since the last call to `publish` to make them visible to readers.
10090 /// are many of them.
10191 pub fn publish ( & mut self ) -> & mut Self {
10292 self . handle . publish ( ) ;
103- self . direct_write = None ;
10493 self
10594 }
10695
@@ -117,26 +106,7 @@ where
117106 }
118107
119108 fn add_op ( & mut self , op : Operation < K , V , M > ) -> & mut Self {
120- if let Some ( ref mut queued_clone) = self . direct_write {
121- {
122- // Safety: we know there are no outstanding w_handle readers, since we haven't
123- // refreshed ever before, so we can modify it directly!
124- let mut w_inner = self . handle . raw_write_handle ( ) ;
125- let w_inner = unsafe { w_inner. as_mut ( ) } ;
126- let r_handle = self . handle . enter ( ) . expect ( "map has not yet been destroyed" ) ;
127- // Because we are operating directly on the map, and nothing is aliased, we do want
128- // to perform drops, so we invoke absorb_second.
129- Absorb :: absorb_second ( w_inner, op, & * r_handle) ;
130- }
131-
132- if !* queued_clone {
133- // NOTE: since we didn't record this in the oplog, r_handle *must* clone w_handle
134- self . handle . append ( Operation :: JustCloneRHandle ) ;
135- * queued_clone = true ;
136- }
137- } else {
138- self . handle . append ( op) ;
139- }
109+ self . handle . append ( op) ;
140110 self
141111 }
142112
@@ -426,10 +396,6 @@ where
426396 Operation :: SetMeta ( ref m) => {
427397 self . meta = m. clone ( ) ;
428398 }
429- Operation :: JustCloneRHandle => {
430- // This is applying the operation to the original write handle,
431- // which we already applied the first batch of operations to.
432- }
433399 }
434400 }
435401
@@ -541,33 +507,6 @@ where
541507 Operation :: SetMeta ( m) => {
542508 inner. meta = m;
543509 }
544- Operation :: JustCloneRHandle => {
545- // This is applying the operation to the original read handle,
546- // which is empty, and needs to copy over all data from the
547- // write handle that we wrote to directly.
548-
549- // XXX: it really is too bad that we can't just .clone() the data here and save
550- // ourselves a lot of re-hashing, re-bucketization, etc.
551- inner. data . extend ( other. data . iter ( ) . map ( |( k, vs) | {
552- // # Safety (for aliasing):
553- //
554- // We are aliasing every value in the read map, and the oplog has no other
555- // pending operations (by the semantics of JustCloneRHandle). For any of the
556- // values we alias to be dropped, the operation that drops it must first be
557- // enqueued to the oplog, at which point it will _first_ go through
558- // absorb_first, which will remove the alias and leave only one alias left.
559- // Only after that, when that operation eventually goes through absorb_second,
560- // will the alias be dropped, and by that time it is the only value.
561- //
562- // # Safety (for NoDrop -> DoDrop):
563- //
564- // The oplog has only this one operation in it for the first call to `publish`,
565- // so we are about to turn the alias back into NoDrop.
566- ( k. clone ( ) , unsafe {
567- ValuesInner :: alias ( vs, other. data . hasher ( ) )
568- } )
569- } ) ) ;
570- }
571510 }
572511 }
573512
@@ -588,6 +527,37 @@ where
588527 unsafe { Box :: from_raw ( Box :: into_raw ( self ) as * mut _ as * mut _ ) } ;
589528 drop ( inner) ;
590529 }
530+
531+ fn sync_with ( & mut self , first : & Self ) {
532+ let inner: & mut Inner < K , V , M , S , crate :: aliasing:: DoDrop > =
533+ unsafe { & mut * ( self as * mut _ as * mut _ ) } ;
534+ inner. data . extend ( first. data . iter ( ) . map ( |( k, vs) | {
535+ // # Safety (for aliasing):
536+ //
537+ // We are aliasing every value in the read map, and the oplog has no other
538+ // pending operations (by the semantics of JustCloneRHandle). For any of the
539+ // values we alias to be dropped, the operation that drops it must first be
540+ // enqueued to the oplog, at which point it will _first_ go through
541+ // absorb_first, which will remove the alias and leave only one alias left.
542+ // Only after that, when that operation eventually goes through absorb_second,
543+ // will the alias be dropped, and by that time it is the only value.
544+ //
545+ // # Safety (for hashing):
546+ //
547+ // Due to `RandomState` there can be subtle differences between the iteration order
548+ // of two `HashMap` instances. We prevent this by using `left_right::new_with_empty`,
549+ // which `clone`s the first map, making them use the same hasher.
550+ //
551+ // # Safety (for NoDrop -> DoDrop):
552+ //
553+ // The oplog has only this one operation in it for the first call to `publish`,
554+ // so we are about to turn the alias back into NoDrop.
555+ ( k. clone ( ) , unsafe {
556+ ValuesInner :: alias ( vs, first. data . hasher ( ) )
557+ } )
558+ } ) ) ;
559+ self . ready = true ;
560+ }
591561}
592562
593563impl < K , V , M , S > Extend < ( K , V ) > for WriteHandle < K , V , M , S >
@@ -658,8 +628,6 @@ pub(super) enum Operation<K, V, M> {
658628 MarkReady ,
659629 /// Set the value of the map meta.
660630 SetMeta ( M ) ,
661- /// Copy over the contents of the read map wholesale as the write map is empty.
662- JustCloneRHandle ,
663631}
664632
665633impl < K , V , M > fmt:: Debug for Operation < K , V , M >
@@ -685,7 +653,6 @@ where
685653 Operation :: Reserve ( ref a, ref b) => f. debug_tuple ( "Reserve" ) . field ( a) . field ( b) . finish ( ) ,
686654 Operation :: MarkReady => f. debug_tuple ( "MarkReady" ) . finish ( ) ,
687655 Operation :: SetMeta ( ref a) => f. debug_tuple ( "SetMeta" ) . field ( a) . finish ( ) ,
688- Operation :: JustCloneRHandle => f. debug_tuple ( "JustCloneRHandle" ) . finish ( ) ,
689656 }
690657 }
691658}
0 commit comments