@@ -53,8 +53,6 @@ pub mod rhh;
53
53
pub use self :: ord:: OrdValSpine as ValSpine ;
54
54
pub use self :: ord:: OrdKeySpine as KeySpine ;
55
55
56
- use std:: ops:: { Add , Sub } ;
57
- use std:: convert:: { TryInto , TryFrom } ;
58
56
use std:: borrow:: { Borrow , ToOwned } ;
59
57
60
58
use timely:: container:: columnation:: { Columnation , TimelyStack } ;
96
94
pub trait Layout {
97
95
/// The represented update.
98
96
type Target : Update + ?Sized ;
99
- /// Offsets to use from keys into vals.
100
- type KeyOffset : OrdOffset ;
101
- /// Offsets to use from vals into updates.
102
- type ValOffset : OrdOffset ;
103
97
/// Container for update keys.
104
98
type KeyContainer :
105
99
RetainFrom < <Self :: Target as Update >:: Key > +
@@ -114,38 +108,34 @@ pub trait Layout {
114
108
}
115
109
116
110
/// A layout that uses vectors
117
- pub struct Vector < U : Update , O : OrdOffset = usize > {
118
- phantom : std:: marker:: PhantomData < ( U , O ) > ,
111
+ pub struct Vector < U : Update > {
112
+ phantom : std:: marker:: PhantomData < U > ,
119
113
}
120
114
121
- impl < U : Update , O : OrdOffset > Layout for Vector < U , O >
115
+ impl < U : Update > Layout for Vector < U >
122
116
where
123
117
U :: Key : ToOwned < Owned = U :: Key > + Sized + Clone ,
124
118
U :: Val : ToOwned < Owned = U :: Val > + Sized + Clone ,
125
119
{
126
120
type Target = U ;
127
- type KeyOffset = O ;
128
- type ValOffset = O ;
129
121
type KeyContainer = Vec < U :: Key > ;
130
122
type ValContainer = Vec < U :: Val > ;
131
123
type UpdContainer = Vec < ( U :: Time , U :: Diff ) > ;
132
124
}
133
125
134
126
/// A layout based on timely stacks
135
- pub struct TStack < U : Update , O : OrdOffset = usize > {
136
- phantom : std:: marker:: PhantomData < ( U , O ) > ,
127
+ pub struct TStack < U : Update > {
128
+ phantom : std:: marker:: PhantomData < U > ,
137
129
}
138
130
139
- impl < U : Update +Clone , O : OrdOffset > Layout for TStack < U , O >
131
+ impl < U : Update +Clone > Layout for TStack < U >
140
132
where
141
133
U :: Key : Columnation + ToOwned < Owned = U :: Key > ,
142
134
U :: Val : Columnation + ToOwned < Owned = U :: Val > ,
143
135
U :: Time : Columnation ,
144
136
U :: Diff : Columnation ,
145
137
{
146
138
type Target = U ;
147
- type KeyOffset = O ;
148
- type ValOffset = O ;
149
139
type KeyContainer = TimelyStack < U :: Key > ;
150
140
type ValContainer = TimelyStack < U :: Val > ;
151
141
type UpdContainer = TimelyStack < ( U :: Time , U :: Diff ) > ;
@@ -168,19 +158,18 @@ impl<T: Clone> PreferredContainer for [T] {
168
158
}
169
159
170
160
/// An update and layout description based on preferred containers.
171
- pub struct Preferred < K : ?Sized , V : ?Sized , T , D , O : OrdOffset = usize > {
172
- phantom : std:: marker:: PhantomData < ( Box < K > , Box < V > , T , D , O ) > ,
161
+ pub struct Preferred < K : ?Sized , V : ?Sized , T , D > {
162
+ phantom : std:: marker:: PhantomData < ( Box < K > , Box < V > , T , D ) > ,
173
163
}
174
164
175
- impl < K , V , T , R , O > Update for Preferred < K , V , T , R , O >
165
+ impl < K , V , T , R > Update for Preferred < K , V , T , R >
176
166
where
177
167
K : Ord +ToOwned + ?Sized ,
178
168
K :: Owned : Ord +Clone ,
179
169
V : Ord +ToOwned + ?Sized ,
180
170
V :: Owned : Ord +Clone ,
181
171
T : Ord +Lattice +timely:: progress:: Timestamp +Clone ,
182
172
R : Semigroup +Clone ,
183
- O : OrdOffset ,
184
173
{
185
174
type Key = K ;
186
175
type KeyOwned = K :: Owned ;
@@ -190,19 +179,16 @@ where
190
179
type Diff = R ;
191
180
}
192
181
193
- impl < K , V , T , D , O > Layout for Preferred < K , V , T , D , O >
182
+ impl < K , V , T , D > Layout for Preferred < K , V , T , D >
194
183
where
195
184
K : Ord +ToOwned +PreferredContainer + ?Sized ,
196
185
K :: Owned : Ord +Clone ,
197
186
V : Ord +ToOwned +PreferredContainer + ?Sized ,
198
187
V :: Owned : Ord +Clone ,
199
188
T : Ord +Lattice +timely:: progress:: Timestamp +Clone ,
200
189
D : Semigroup +Clone ,
201
- O : OrdOffset ,
202
190
{
203
- type Target = Preferred < K , V , T , D , O > ;
204
- type KeyOffset = O ;
205
- type ValOffset = O ;
191
+ type Target = Preferred < K , V , T , D > ;
206
192
type KeyContainer = K :: Container ;
207
193
type ValContainer = V :: Container ;
208
194
type UpdContainer = Vec < ( T , D ) > ;
@@ -239,16 +225,90 @@ impl<T: Columnation> RetainFrom<T> for TimelyStack<T> {
239
225
}
240
226
}
241
227
242
- /// Trait for types used as offsets into an ordered layer.
243
- /// This is usually `usize`, but `u32` can also be used in applications
244
- /// where huge batches do not occur to reduce metadata size.
245
- pub trait OrdOffset : Copy + PartialEq + Add < Output =Self > + Sub < Output =Self > + TryFrom < usize > + TryInto < usize >
246
- { }
228
+ use std:: convert:: TryInto ;
247
229
248
- impl < O > OrdOffset for O
249
- where
250
- O : Copy + PartialEq + Add < Output =Self > + Sub < Output =Self > + TryFrom < usize > + TryInto < usize > ,
251
- { }
230
+ /// A list of unsigned integers that uses `u32` elements as long as they are small enough, and switches to `u64` once they are not.
231
+ #[ derive( Eq , PartialEq , Ord , PartialOrd , Clone , Debug , Abomonation ) ]
232
+ pub struct OffsetList {
233
+ /// Offsets that fit within a `u32`.
234
+ smol : Vec < u32 > ,
235
+ /// Offsets that either do not fit in a `u32`, or are inserted after some offset that did not fit.
236
+ chonk : Vec < u64 > ,
237
+ }
238
+
239
+ impl OffsetList {
240
+ /// Inserts the offset, as a `u32` if that is still on the table.
241
+ pub fn push ( & mut self , offset : usize ) {
242
+ if self . chonk . is_empty ( ) {
243
+ if let Ok ( smol) = offset. try_into ( ) {
244
+ self . smol . push ( smol) ;
245
+ }
246
+ else {
247
+ self . chonk . push ( offset. try_into ( ) . unwrap ( ) )
248
+ }
249
+ }
250
+ else {
251
+ self . chonk . push ( offset. try_into ( ) . unwrap ( ) )
252
+ }
253
+ }
254
+ /// Like `std::ops::Index`, which we cannot implement as it must return a `&usize`.
255
+ pub fn index ( & self , index : usize ) -> usize {
256
+ if index < self . smol . len ( ) {
257
+ self . smol [ index] . try_into ( ) . unwrap ( )
258
+ }
259
+ else {
260
+ self . chonk [ index - self . smol . len ( ) ] . try_into ( ) . unwrap ( )
261
+ }
262
+ }
263
+ /// Set the offset at location index.
264
+ ///
265
+ /// Complicated if `offset` does not fit into `self.smol`.
266
+ pub fn set ( & mut self , index : usize , offset : usize ) {
267
+ if index < self . smol . len ( ) {
268
+ if let Ok ( off) = offset. try_into ( ) {
269
+ self . smol [ index] = off;
270
+ }
271
+ else {
272
+ // Move all `smol` elements from `index` onward to the front of `chonk`.
273
+ self . chonk . splice ( 0 ..0 , self . smol . drain ( index ..) . map ( |x| x. try_into ( ) . unwrap ( ) ) ) ;
274
+ self . chonk [ index - self . smol . len ( ) ] = offset. try_into ( ) . unwrap ( ) ;
275
+ }
276
+ }
277
+ else {
278
+ self . chonk [ index - self . smol . len ( ) ] = offset. try_into ( ) . unwrap ( ) ;
279
+ }
280
+ }
281
+ /// The last element in the list of offsets, if non-empty.
282
+ pub fn last ( & self ) -> Option < usize > {
283
+ if self . chonk . is_empty ( ) {
284
+ self . smol . last ( ) . map ( |x| ( * x) . try_into ( ) . unwrap ( ) )
285
+ }
286
+ else {
287
+ self . chonk . last ( ) . map ( |x| ( * x) . try_into ( ) . unwrap ( ) )
288
+ }
289
+ }
290
+ /// THe number of offsets in the list.
291
+ pub fn len ( & self ) -> usize {
292
+ self . smol . len ( ) + self . chonk . len ( )
293
+ }
294
+ /// Allocate a new list with a specified capacity.
295
+ pub fn with_capacity ( cap : usize ) -> Self {
296
+ Self {
297
+ smol : Vec :: with_capacity ( cap) ,
298
+ chonk : Vec :: new ( ) ,
299
+ }
300
+ }
301
+ /// Trim all elements at index `length` and greater.
302
+ pub fn truncate ( & mut self , length : usize ) {
303
+ if length > self . smol . len ( ) {
304
+ self . chonk . truncate ( length - self . smol . len ( ) ) ;
305
+ }
306
+ else {
307
+ assert ! ( self . chonk. is_empty( ) ) ;
308
+ self . smol . truncate ( length) ;
309
+ }
310
+ }
311
+ }
252
312
253
313
pub use self :: containers:: { BatchContainer , SliceContainer } ;
254
314
0 commit comments