@@ -26,58 +26,68 @@ impl<C: Cursor> CursorList<C> {
26
26
result
27
27
}
28
28
29
- // Initialize min_key with the indices of cursors with the minimum key.
30
- //
31
- // This method scans the current keys of each cursor, and tracks the indices
32
- // of cursors whose key equals the minimum valid key seen so far. As it goes,
33
- // if it observes an improved key it clears the current list, updates the
34
- // minimum key, and continues.
35
- //
36
- // Once finished, it invokes `minimize_vals()` to ensure the value cursor is
37
- // in a consistent state as well.
29
+ /// Initialize min_key with the indices of cursors with the minimum key.
30
+ ///
31
+ /// This method scans the current keys of each cursor, and tracks the indices
32
+ /// of cursors whose key equals the minimum valid key seen so far. As it goes,
33
+ /// if it observes an improved key it clears the current list, updates the
34
+ /// minimum key, and continues.
35
+ ///
36
+ /// Once finished, it invokes `minimize_vals()` to ensure the value cursor is
37
+ /// in a consistent state as well.
38
38
fn minimize_keys ( & mut self , storage : & [ C :: Storage ] ) {
39
39
40
40
self . min_key . clear ( ) ;
41
41
42
- // Determine the index of the cursor with minimum key.
43
- let mut min_key_opt = None ;
44
- for ( index, cursor) in self . cursors . iter ( ) . enumerate ( ) {
45
- let key = cursor. get_key ( & storage[ index] ) ;
46
- if key. is_some ( ) {
47
- if min_key_opt. is_none ( ) || key. lt ( & min_key_opt) {
48
- min_key_opt = key;
49
- self . min_key . clear ( ) ;
50
- }
51
- if key. eq ( & min_key_opt) {
52
- self . min_key . push ( index) ;
42
+ // We'll visit each non-`None` key, maintaining the indexes of the least keys in `self.min_key`.
43
+ let mut iter = self . cursors . iter ( ) . enumerate ( ) . flat_map ( |( idx, cur) | cur. get_key ( & storage[ idx] ) . map ( |key| ( idx, key) ) ) ;
44
+ if let Some ( ( idx, key) ) = iter. next ( ) {
45
+ let mut min_key = key;
46
+ self . min_key . push ( idx) ;
47
+ for ( idx, key) in iter {
48
+ match key. cmp ( & min_key) {
49
+ std:: cmp:: Ordering :: Less => {
50
+ self . min_key . clear ( ) ;
51
+ self . min_key . push ( idx) ;
52
+ min_key = key;
53
+ }
54
+ std:: cmp:: Ordering :: Equal => {
55
+ self . min_key . push ( idx) ;
56
+ }
57
+ std:: cmp:: Ordering :: Greater => { }
53
58
}
54
59
}
55
60
}
56
61
57
62
self . minimize_vals ( storage) ;
58
63
}
59
64
60
- // Initialize min_val with the indices of minimum key cursors with the minimum value.
61
- //
62
- // This method scans the current values of cursor with minimum keys, and tracks the
63
- // indices of cursors whose value equals the minimum valid value seen so far. As it
64
- // goes, if it observes an improved value it clears the current list, updates the minimum
65
- // value, and continues.
65
+ /// Initialize min_val with the indices of minimum key cursors with the minimum value.
66
+ ///
67
+ /// This method scans the current values of cursor with minimum keys, and tracks the
68
+ /// indices of cursors whose value equals the minimum valid value seen so far. As it
69
+ /// goes, if it observes an improved value it clears the current list, updates the minimum
70
+ /// value, and continues.
66
71
fn minimize_vals ( & mut self , storage : & [ C :: Storage ] ) {
67
72
68
73
self . min_val . clear ( ) ;
69
74
70
- // Determine the index of the cursor with minimum value.
71
- let mut min_val = None ;
72
- for & index in self . min_key . iter ( ) {
73
- let val = self . cursors [ index] . get_val ( & storage[ index] ) ;
74
- if val. is_some ( ) {
75
- if min_val. is_none ( ) || val. lt ( & min_val) {
76
- min_val = val;
77
- self . min_val . clear ( ) ;
78
- }
79
- if val. eq ( & min_val) {
80
- self . min_val . push ( index) ;
75
+ // We'll visit each non-`None` value, maintaining the indexes of the least values in `self.min_val`.
76
+ let mut iter = self . min_key . iter ( ) . cloned ( ) . flat_map ( |idx| self . cursors [ idx] . get_val ( & storage[ idx] ) . map ( |val| ( idx, val) ) ) ;
77
+ if let Some ( ( idx, val) ) = iter. next ( ) {
78
+ let mut min_val = val;
79
+ self . min_val . push ( idx) ;
80
+ for ( idx, val) in iter {
81
+ match val. cmp ( & min_val) {
82
+ std:: cmp:: Ordering :: Less => {
83
+ self . min_val . clear ( ) ;
84
+ self . min_val . push ( idx) ;
85
+ min_val = val;
86
+ }
87
+ std:: cmp:: Ordering :: Equal => {
88
+ self . min_val . push ( idx) ;
89
+ }
90
+ std:: cmp:: Ordering :: Greater => { }
81
91
}
82
92
}
83
93
}
@@ -114,6 +124,15 @@ impl<C: Cursor> Cursor for CursorList<C> {
114
124
debug_assert ! ( self . cursors[ self . min_val[ 0 ] ] . val_valid( & storage[ self . min_val[ 0 ] ] ) ) ;
115
125
self . cursors [ self . min_val [ 0 ] ] . val ( & storage[ self . min_val [ 0 ] ] )
116
126
}
127
+ #[ inline]
128
+ fn get_key < ' a > ( & self , storage : & ' a Vec < C :: Storage > ) -> Option < Self :: Key < ' a > > {
129
+ self . min_key . get ( 0 ) . map ( |idx| self . cursors [ * idx] . key ( & storage[ * idx] ) )
130
+ }
131
+ #[ inline]
132
+ fn get_val < ' a > ( & self , storage : & ' a Vec < C :: Storage > ) -> Option < Self :: Val < ' a > > {
133
+ self . min_val . get ( 0 ) . map ( |idx| self . cursors [ * idx] . val ( & storage[ * idx] ) )
134
+ }
135
+
117
136
#[ inline]
118
137
fn map_times < L : FnMut ( Self :: TimeGat < ' _ > , Self :: DiffGat < ' _ > ) > ( & mut self , storage : & Vec < C :: Storage > , mut logic : L ) {
119
138
for & index in self . min_val . iter ( ) {
0 commit comments