1
1
//! Like `Count` but with the value type specialized to `()`.
2
2
3
- use std:: fmt:: Debug ;
4
-
5
- use collection:: { close_under_lub, LeastUpperBound , Lookup } ;
3
+ use :: Data ;
4
+ use collection:: { LeastUpperBound , Lookup } ;
6
5
use collection:: compact:: Compact ;
6
+ use collection:: trace:: { Traceable , TraceRef } ;
7
7
8
- #[ derive( Copy , Clone , Debug ) ]
9
- pub struct Offset {
10
- dataz : u32 ,
11
- }
12
-
13
- impl Offset {
14
- #[ inline( always) ]
15
- fn new ( offset : usize ) -> Offset {
16
- assert ! ( offset < ( ( !0u32 ) as usize ) ) ; // note strict inequality
17
- Offset { dataz : ( !0u32 ) - offset as u32 }
18
- }
19
- #[ inline( always) ]
20
- fn val ( & self ) -> usize { ( ( !0u32 ) - self . dataz ) as usize }
21
- }
22
-
23
- struct ListEntry {
24
- time : u32 ,
25
- wgts : i32 ,
26
- next : Option < Offset > ,
27
- }
28
-
29
- pub struct Count < K , T , L > {
30
- phantom : :: std:: marker:: PhantomData < K > ,
31
- links : Vec < ListEntry > ,
32
- times : Vec < T > ,
33
- pub keys : L ,
34
- temp : Vec < T > ,
35
- }
36
-
37
- impl < K , L , T > Count < K , T , L > where K : Ord , L : Lookup < K , Offset > , T : LeastUpperBound +Debug {
38
-
8
+ impl < K , L , T > Traceable for Count < K , T , L > where K : Data +Ord +' static , L : Lookup < K , Offset > +' static , T : LeastUpperBound +' static {
9
+ type Key = K ;
10
+ type Index = T ;
11
+ type Value = ( ) ;
12
+
39
13
/// Installs a supplied set of keys and values as the differences for `time`.
40
- pub fn set_difference ( & mut self , time : T , accumulation : Compact < K , ( ) > ) {
14
+ fn set_difference ( & mut self , time : T , accumulation : Compact < K , ( ) > ) {
41
15
42
16
// extract the relevant fields
43
17
let keys = accumulation. keys ;
@@ -78,52 +52,59 @@ impl<K, L, T> Count<K, T, L> where K: Ord, L: Lookup<K, Offset>, T: LeastUpperBo
78
52
79
53
self . times . push ( time) ;
80
54
}
55
+ }
56
+
57
+ impl < ' a , K , L , T > TraceRef < ' a , K , T , ( ) > for & ' a Count < K , T , L > where K : Ord +' a , L : Lookup < K , Offset > +' a , T : LeastUpperBound +' a {
58
+ type VIterator = WeightIterator < ' a > ;
59
+ type TIterator = CountIterator < ' a , K , T , L > ;
60
+ fn trace ( self , key : & K ) -> Self :: TIterator {
61
+ CountIterator {
62
+ trace : self ,
63
+ next0 : self . keys . get_ref ( key) . map ( |& x|x) ,
64
+ // silly: (),
65
+ }
66
+ }
67
+ }
68
+
69
+ #[ derive( Copy , Clone , Debug ) ]
70
+ pub struct Offset {
71
+ dataz : u32 ,
72
+ }
81
73
82
- /// Enumerates the differences for `key` at `time`.
83
- pub fn get_diff ( & self , key : & K , time : & T ) -> i32 {
84
- self . trace ( key)
85
- . filter ( |x| x. 0 == time)
86
- . map ( |x| x. 1 )
87
- . next ( )
88
- . unwrap_or ( 0 )
74
+ impl Offset {
75
+ #[ inline( always) ]
76
+ fn new ( offset : usize ) -> Offset {
77
+ assert ! ( offset < ( ( !0u32 ) as usize ) ) ; // note strict inequality
78
+ Offset { dataz : ( !0u32 ) - offset as u32 }
89
79
}
80
+ #[ inline( always) ]
81
+ fn val ( & self ) -> usize { ( ( !0u32 ) - self . dataz ) as usize }
82
+ }
83
+
84
+ struct ListEntry {
85
+ time : u32 ,
86
+ wgts : i32 ,
87
+ next : Option < Offset > ,
88
+ }
89
+
90
+ pub struct Count < K , T , L > {
91
+ phantom : :: std:: marker:: PhantomData < K > ,
92
+ links : Vec < ListEntry > ,
93
+ times : Vec < T > ,
94
+ pub keys : L ,
95
+ // temp: Vec<T>,
96
+ silly : ( ) ,
97
+ }
98
+
99
+ impl < K , L , T > Count < K , T , L > where K : Data +Ord +' static , L : Lookup < K , Offset > +' static , T : LeastUpperBound +' static {
90
100
91
101
pub fn get_count ( & self , key : & K , time : & T ) -> i32 {
92
102
let mut sum = 0 ;
93
- for wgt in self . trace ( key) . filter ( |x| x. 0 <= time) . map ( |x| x. 1 ) {
103
+ for wgt in Traceable :: trace ( self , key) . filter ( |x| x. 0 <= time) . map ( |mut x| x. 1 . next ( ) . unwrap ( ) . 1 ) {
94
104
sum += wgt;
95
105
}
96
106
sum
97
107
}
98
-
99
- // TODO : this could do a better job of returning newly interesting times: those times that are
100
- // TODO : now in the least upper bound, but were not previously so. The main risk is that the
101
- // TODO : easy way to do this computes the LUB before and after, but this can be expensive:
102
- // TODO : the LUB with `index` is often likely to be smaller than the LUB without it.
103
- /// Lists times that are the least upper bound of `time` and any subset of existing times.
104
- pub fn interesting_times < ' a > ( & ' a mut self , key : & K , index : T ) -> & ' a [ T ] {
105
- // panic!();
106
- let mut temp = :: std:: mem:: replace ( & mut self . temp , Vec :: new ( ) ) ;
107
- temp. clear ( ) ;
108
- temp. push ( index) ;
109
- for ( time, _) in self . trace ( key) {
110
- let lub = time. least_upper_bound ( & temp[ 0 ] ) ;
111
- if !temp. contains ( & lub) {
112
- temp. push ( lub) ;
113
- }
114
- }
115
- close_under_lub ( & mut temp) ;
116
- :: std:: mem:: replace ( & mut self . temp , temp) ;
117
- & self . temp [ ..]
118
- }
119
-
120
- /// Enumerates pairs of time `&T` and differences `DifferenceIterator<V>` for `key`.
121
- pub fn trace < ' a > ( & ' a self , key : & K ) -> CountIterator < ' a , K , T , L > {
122
- CountIterator {
123
- trace : self ,
124
- next0 : self . keys . get_ref ( key) . map ( |& x|x) ,
125
- }
126
- }
127
108
}
128
109
129
110
impl < K : Eq , L : Lookup < K , Offset > , T > Count < K , T , L > {
@@ -133,7 +114,8 @@ impl<K: Eq, L: Lookup<K, Offset>, T> Count<K, T, L> {
133
114
links : Vec :: new ( ) ,
134
115
times : Vec :: new ( ) ,
135
116
keys : l,
136
- temp : Vec :: new ( ) ,
117
+ // temp: Vec::new(),
118
+ silly : ( ) ,
137
119
}
138
120
}
139
121
}
@@ -146,18 +128,35 @@ pub struct CountIterator<'a, K: Eq+'a, T: 'a, L: Lookup<K, Offset>+'a> {
146
128
}
147
129
148
130
impl < ' a , K : Eq , T , L > Iterator for CountIterator < ' a , K , T , L >
149
- where K : Ord +' a ,
150
- T : LeastUpperBound +Debug + ' a ,
131
+ where K : Ord +' a ,
132
+ T : LeastUpperBound +' a ,
151
133
L : Lookup < K , Offset > +' a {
152
- type Item = ( & ' a T , i32 ) ;
134
+ type Item = ( & ' a T , WeightIterator < ' a > ) ;
153
135
154
136
#[ inline]
155
137
fn next ( & mut self ) -> Option < Self :: Item > {
156
138
self . next0 . map ( |position| {
157
139
let time_index = self . trace . links [ position. val ( ) ] . time as usize ;
158
- let result = ( & self . trace . times [ time_index] , self . trace . links [ position. val ( ) ] . wgts ) ;
140
+ let result = ( & self . trace . times [ time_index] , WeightIterator { weight : self . trace . links [ position. val ( ) ] . wgts , silly : & self . trace . silly } ) ;
159
141
self . next0 = self . trace . links [ position. val ( ) ] . next ;
160
142
result
161
143
} )
162
144
}
163
145
}
146
+
147
+ pub struct WeightIterator < ' a > {
148
+ weight : i32 ,
149
+ silly : & ' a ( ) ,
150
+ }
151
+
152
+ impl < ' a > Iterator for WeightIterator < ' a > {
153
+ type Item = ( & ' a ( ) , i32 ) ;
154
+ fn next ( & mut self ) -> Option < ( & ' a ( ) , i32 ) > {
155
+ if self . weight == 0 { None }
156
+ else {
157
+ let result = self . weight ;
158
+ self . weight = 0 ;
159
+ Some ( ( self . silly , result) )
160
+ }
161
+ }
162
+ }
0 commit comments