@@ -122,19 +122,41 @@ impl<'a, K: Ord + Clone, V> VacantEntry<'a, K, V> {
122122 }
123123 }
124124
125- /// Inserts the key into the `MarkMap`.
126- ///
127- /// If you want to insert a value into the `MarkMap` use `insert` or `insert_entry` instead.
128- /// This function can be used if you want to mark a vacant key as `required` or `used`.
129- pub fn occupied_entry ( self ) -> OccupiedEntry < ' a , K , V > {
125+ /// Marks the key associated with this entry as required.
126+ pub fn mark_required ( & mut self ) {
130127 match self . pos {
131128 Ok ( pos) => {
132- self . map . contents [ pos] . 2 = None ;
133- OccupiedEntry { pos , map : self . map }
129+ let repr = self . map . contents [ pos] . 1 ;
130+ self . map . contents [ pos ] . 1 = repr | Mark :: Required . repr ( ) ;
134131 }
135132 Err ( pos) => {
136- self . map . contents . insert ( pos, ( self . key , 0 , None ) ) ;
137- OccupiedEntry { pos, map : self . map }
133+ self . map
134+ . contents
135+ . insert ( pos, ( self . key . clone ( ) , Mark :: Required . repr ( ) , None ) ) ;
136+ self . pos = Ok ( pos)
137+ }
138+ }
139+ }
140+
141+ /// Sets the merge behavior for the key associated with this entry.
142+ pub fn set_merge_behavior ( & mut self , mb : MergeBehavior ) {
143+ match self . pos {
144+ Ok ( pos) => {
145+ let merge_reprs = Mark :: MergeBehavior ( MergeBehavior :: MutuallyExclusive ) . repr ( )
146+ | Mark :: MergeBehavior ( MergeBehavior :: Ours ) . repr ( )
147+ | Mark :: MergeBehavior ( MergeBehavior :: Theirs ) . repr ( ) ;
148+ let mut repr = self . map . contents [ pos] . 1 ;
149+ // Zap just the MergeBehavior bits.
150+ repr ^= repr & merge_reprs;
151+ repr |= Mark :: MergeBehavior ( mb) . repr ( ) ;
152+ self . map . contents [ pos] . 1 = repr;
153+ }
154+ Err ( pos) => {
155+ self . map . contents . insert (
156+ pos,
157+ ( self . key . clone ( ) , Mark :: MergeBehavior ( mb) . repr ( ) , None ) ,
158+ ) ;
159+ self . pos = Ok ( pos)
138160 }
139161 }
140162 }
@@ -208,6 +230,9 @@ pub struct OccupiedEntry<'a, K, V> {
208230/// A view into a vacant entry in a `MarkMap`. It is part of the `Entry` enum.
209231#[ doc( hidden) ]
210232pub struct VacantEntry < ' a , K , V > {
233+ // The values of the `pos` result imply:
234+ // * When `Ok(pos)` the key was found at `pos`, and it's value was `None`.
235+ // * When `Err(pos)` the key was not found at `pos`.
211236 pos : Result < usize , usize > ,
212237 key : K ,
213238 map : & ' a mut MarkMap < K , V > ,
@@ -905,4 +930,68 @@ mod test {
905930 vec![ ( & "a" , & "mm" ) , ( & "b" , & "mm2" ) , ( & "x" , & "mm2" ) ]
906931 ) ;
907932 }
933+
934+ #[ test]
935+ fn test_vacant_entry_required ( ) {
936+ let mut mm = MarkMap :: new ( ) ;
937+ // To test the first case we want a marked key with no value associated to it.
938+ mm. mark_used ( & "a" ) ;
939+ let e = mm. entry ( "a" ) ;
940+ match e {
941+ Entry :: Occupied ( _) => panic ! ( "Expected unoccupied entry" ) ,
942+ Entry :: Vacant ( mut e) => {
943+ e. mark_required ( ) ;
944+ e. insert_entry ( "a" ) ;
945+ }
946+ }
947+ assert ! ( mm. is_required( & "a" ) ) ;
948+ assert ! ( mm. is_used( & "a" ) ) ;
949+ // For the second case we want an unmarked key with another key in it's binary search pos.
950+ mm. insert ( "c" , "c" ) ;
951+ let e = mm. entry ( "b" ) ;
952+ match e {
953+ Entry :: Occupied ( _) => panic ! ( "Expected unoccupied entry" ) ,
954+ Entry :: Vacant ( mut e) => {
955+ e. mark_required ( ) ;
956+ }
957+ }
958+ assert ! ( mm. is_required( & "b" ) ) ;
959+ assert ! ( !mm. is_required( & "c" ) ) ;
960+ }
961+
962+ #[ test]
963+ fn test_vacant_entry_merge_behavior ( ) {
964+ let mut mm = MarkMap :: new ( ) ;
965+ // To test the first case we want a marked key with no value associated to it.
966+ mm. mark_used ( & "a" ) ;
967+ let mut mm2 = MarkMap :: new ( ) ;
968+ mm2. insert ( "a" , "a2" ) ;
969+ mm2. insert ( "a" , "c2" ) ;
970+ let e = mm. entry ( "a" ) ;
971+ match e {
972+ Entry :: Occupied ( _) => panic ! ( "Expected unoccupied entry" ) ,
973+ Entry :: Vacant ( mut e) => {
974+ e. set_merge_behavior ( MergeBehavior :: Ours ) ;
975+ e. insert_entry ( "a1" ) ;
976+ }
977+ }
978+ assert_eq ! (
979+ mm. get_mark( & "a" ) ,
980+ Some ( Mark :: MergeBehavior ( MergeBehavior :: Ours ) . repr( ) | Mark :: Used . repr( ) )
981+ ) ;
982+ // For the second case we want an unmarked key with another key in it's binary search pos.
983+ mm. insert ( "c" , "c" ) ;
984+ let e = mm. entry ( "b" ) ;
985+ match e {
986+ Entry :: Occupied ( _) => panic ! ( "Expected unoccupied entry" ) ,
987+ Entry :: Vacant ( mut e) => {
988+ e. set_merge_behavior ( MergeBehavior :: Theirs ) ;
989+ }
990+ }
991+ assert_eq ! (
992+ mm. get_mark( & "b" ) ,
993+ Some ( Mark :: MergeBehavior ( MergeBehavior :: Theirs ) . repr( ) )
994+ ) ;
995+ assert_eq ! ( mm. get_mark( & "c" ) , Some ( 0 ) ) ;
996+ }
908997}
0 commit comments