Skip to content

Commit f4a951e

Browse files
remove deref bound from containers (#417)
* remove deref bound from containers * Reformatting
1 parent abad1b4 commit f4a951e

File tree

3 files changed

+93
-65
lines changed

3 files changed

+93
-65
lines changed

src/trace/layers/mod.rs

Lines changed: 71 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -119,12 +119,63 @@ pub trait BatchContainer: Default {
119119
fn copy(&mut self, item: &Self::Item);
120120
/// Extends from a slice of items.
121121
fn copy_slice(&mut self, slice: &[Self::Item]);
122+
/// Extends from a range of items in another`Self`.
123+
fn copy_range(&mut self, other: &Self, start: usize, end: usize);
122124
/// Creates a new container with sufficient capacity.
123125
fn with_capacity(size: usize) -> Self;
124126
/// Reserves additional capacity.
125127
fn reserve(&mut self, additional: usize);
126128
/// Creates a new container with sufficient capacity.
127129
fn merge_capacity(cont1: &Self, cont2: &Self) -> Self;
130+
131+
/// Reference to the element at this position.
132+
fn index(&self, index: usize) -> &Self::Item;
133+
/// Number of contained elements
134+
fn len(&self) -> usize;
135+
136+
/// Reports the number of elements satisfing the predicate.
137+
///
138+
/// This methods *relies strongly* on the assumption that the predicate
139+
/// stays false once it becomes false, a joint property of the predicate
140+
/// and the layout of `Self. This allows `advance` to use exponential search to
141+
/// count the number of elements in time logarithmic in the result.
142+
fn advance<F: Fn(&Self::Item)->bool>(&self, start: usize, end: usize, function: F) -> usize {
143+
144+
let small_limit = 8;
145+
146+
// Exponential seach if the answer isn't within `small_limit`.
147+
if end > start + small_limit && function(self.index(start + small_limit)) {
148+
149+
// start with no advance
150+
let mut index = small_limit + 1;
151+
if start + index < end && function(self.index(start + index)) {
152+
153+
// advance in exponentially growing steps.
154+
let mut step = 1;
155+
while start + index + step < end && function(self.index(start + index + step)) {
156+
index += step;
157+
step = step << 1;
158+
}
159+
160+
// advance in exponentially shrinking steps.
161+
step = step >> 1;
162+
while step > 0 {
163+
if start + index + step < end && function(self.index(start + index + step)) {
164+
index += step;
165+
}
166+
step = step >> 1;
167+
}
168+
169+
index += 1;
170+
}
171+
172+
index
173+
}
174+
else {
175+
let limit = std::cmp::min(end, start + small_limit);
176+
(start .. limit).filter(|x| function(self.index(*x))).count()
177+
}
178+
}
128179
}
129180

130181
impl<T: Clone> BatchContainer for Vec<T> {
@@ -138,6 +189,9 @@ impl<T: Clone> BatchContainer for Vec<T> {
138189
fn copy_slice(&mut self, slice: &[T]) {
139190
self.extend_from_slice(slice);
140191
}
192+
fn copy_range(&mut self, other: &Self, start: usize, end: usize) {
193+
self.extend_from_slice(&other[start .. end]);
194+
}
141195
fn with_capacity(size: usize) -> Self {
142196
Vec::with_capacity(size)
143197
}
@@ -147,6 +201,12 @@ impl<T: Clone> BatchContainer for Vec<T> {
147201
fn merge_capacity(cont1: &Self, cont2: &Self) -> Self {
148202
Vec::with_capacity(cont1.len() + cont2.len())
149203
}
204+
fn index(&self, index: usize) -> &Self::Item {
205+
&self[index]
206+
}
207+
fn len(&self) -> usize {
208+
self[..].len()
209+
}
150210
}
151211

152212
impl<T: Columnation> BatchContainer for TimelyStack<T> {
@@ -163,6 +223,13 @@ impl<T: Columnation> BatchContainer for TimelyStack<T> {
163223
self.copy(item);
164224
}
165225
}
226+
fn copy_range(&mut self, other: &Self, start: usize, end: usize) {
227+
let slice = &other[start .. end];
228+
self.reserve_items(slice.iter());
229+
for item in slice.iter() {
230+
self.copy(item);
231+
}
232+
}
166233
fn with_capacity(size: usize) -> Self {
167234
Self::with_capacity(size)
168235
}
@@ -173,49 +240,10 @@ impl<T: Columnation> BatchContainer for TimelyStack<T> {
173240
new.reserve_regions(std::iter::once(cont1).chain(std::iter::once(cont2)));
174241
new
175242
}
176-
}
177-
178-
179-
/// Reports the number of elements satisfing the predicate.
180-
///
181-
/// This methods *relies strongly* on the assumption that the predicate
182-
/// stays false once it becomes false, a joint property of the predicate
183-
/// and the slice. This allows `advance` to use exponential search to
184-
/// count the number of elements in time logarithmic in the result.
185-
pub fn advance<T, F: Fn(&T)->bool>(slice: &[T], function: F) -> usize {
186-
187-
let small_limit = 8;
188-
189-
// Exponential seach if the answer isn't within `small_limit`.
190-
if slice.len() > small_limit && function(&slice[small_limit]) {
191-
192-
// start with no advance
193-
let mut index = small_limit + 1;
194-
if index < slice.len() && function(&slice[index]) {
195-
196-
// advance in exponentially growing steps.
197-
let mut step = 1;
198-
while index + step < slice.len() && function(&slice[index + step]) {
199-
index += step;
200-
step = step << 1;
201-
}
202-
203-
// advance in exponentially shrinking steps.
204-
step = step >> 1;
205-
while step > 0 {
206-
if index + step < slice.len() && function(&slice[index + step]) {
207-
index += step;
208-
}
209-
step = step >> 1;
210-
}
211-
212-
index += 1;
213-
}
214-
215-
index
243+
fn index(&self, index: usize) -> &Self::Item {
244+
&self[index]
216245
}
217-
else {
218-
let limit = std::cmp::min(slice.len(), small_limit);
219-
slice[..limit].iter().filter(|x| function(*x)).count()
246+
fn len(&self) -> usize {
247+
self[..].len()
220248
}
221249
}

src/trace/layers/ordered.rs

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
//! Implementation using ordered keys and exponential search.
22
3-
use super::{Trie, Cursor, Builder, MergeBuilder, TupleBuilder, BatchContainer, advance};
3+
use super::{Trie, Cursor, Builder, MergeBuilder, TupleBuilder, BatchContainer};
44
use std::convert::{TryFrom, TryInto};
55
use std::fmt::Debug;
6-
use std::ops::{Sub,Add,Deref};
6+
use std::ops::{Sub,Add};
77

88
/// Trait for types used as offsets into an ordered layer.
99
/// This is usually `usize`, but `u32` can also be used in applications
@@ -23,7 +23,7 @@ where
2323
pub struct OrderedLayer<K, L, O=usize, C=Vec<K>>
2424
where
2525
K: Ord,
26-
C: BatchContainer<Item=K>+Deref<Target=[K]>,
26+
C: BatchContainer<Item=K>,
2727
O: OrdOffset
2828
{
2929
/// The keys of the layer.
@@ -40,7 +40,7 @@ where
4040
impl<K, L, O, C> Trie for OrderedLayer<K, L, O, C>
4141
where
4242
K: Ord,
43-
C: BatchContainer<Item=K>+Deref<Target=[K]>,
43+
C: BatchContainer<Item=K>,
4444
L: Trie,
4545
O: OrdOffset
4646
{
@@ -77,7 +77,7 @@ where
7777
pub struct OrderedBuilder<K, L, O=usize, C=Vec<K>>
7878
where
7979
K: Ord,
80-
C: BatchContainer<Item=K>+Deref<Target=[K]>,
80+
C: BatchContainer<Item=K>,
8181
O: OrdOffset
8282
{
8383
/// Keys
@@ -91,7 +91,7 @@ where
9191
impl<K, L, O, C> Builder for OrderedBuilder<K, L, O, C>
9292
where
9393
K: Ord,
94-
C: BatchContainer<Item=K>+Deref<Target=[K]>,
94+
C: BatchContainer<Item=K>,
9595
L: Builder,
9696
O: OrdOffset
9797
{
@@ -115,7 +115,7 @@ where
115115
impl<K, L, O, C> MergeBuilder for OrderedBuilder<K, L, O, C>
116116
where
117117
K: Ord,
118-
C: BatchContainer<Item=K>+Deref<Target=[K]>,
118+
C: BatchContainer<Item=K>,
119119
L: MergeBuilder,
120120
O: OrdOffset
121121
{
@@ -134,7 +134,7 @@ where
134134
let other_basis = other.offs[lower];
135135
let self_basis = self.offs.last().map(|&x| x).unwrap_or(O::try_from(0).ok().unwrap());
136136

137-
self.keys.copy_slice(&other.keys[lower .. upper]);
137+
self.keys.copy_range(&other.keys, lower, upper);
138138
for index in lower .. upper {
139139
self.offs.push((other.offs[index + 1] + self_basis) - other_basis);
140140
}
@@ -162,7 +162,7 @@ where
162162
impl<K, L, O, C> OrderedBuilder<K, L, O, C>
163163
where
164164
K: Ord,
165-
C: BatchContainer<Item=K>+Deref<Target=[K]>,
165+
C: BatchContainer<Item=K>,
166166
L: MergeBuilder,
167167
O: OrdOffset
168168
{
@@ -173,10 +173,10 @@ where
173173
let (trie1, lower1, upper1) = other1;
174174
let (trie2, lower2, upper2) = other2;
175175

176-
match trie1.keys[*lower1].cmp(&trie2.keys[*lower2]) {
176+
match trie1.keys.index(*lower1).cmp(&trie2.keys.index(*lower2)) {
177177
::std::cmp::Ordering::Less => {
178178
// determine how far we can advance lower1 until we reach/pass lower2
179-
let step = 1 + advance(&trie1.keys[(1 + *lower1)..upper1], |x| x < &trie2.keys[*lower2]);
179+
let step = 1 + trie1.keys.advance(1 + *lower1, upper1, |x| x < &trie2.keys.index(*lower2));
180180
let step = std::cmp::min(step, 1_000);
181181
self.copy_range(trie1, *lower1, *lower1 + step);
182182
*lower1 += step;
@@ -189,7 +189,7 @@ where
189189
(&trie2.vals, trie2.offs[*lower2].try_into().ok().unwrap(), trie2.offs[*lower2 + 1].try_into().ok().unwrap())
190190
);
191191
if upper > lower {
192-
self.keys.copy(&trie1.keys[*lower1]);
192+
self.keys.copy(&trie1.keys.index(*lower1));
193193
self.offs.push(O::try_from(upper).ok().unwrap());
194194
}
195195

@@ -198,7 +198,7 @@ where
198198
},
199199
::std::cmp::Ordering::Greater => {
200200
// determine how far we can advance lower2 until we reach/pass lower1
201-
let step = 1 + advance(&trie2.keys[(1 + *lower2)..upper2], |x| x < &trie1.keys[*lower1]);
201+
let step = 1 + trie2.keys.advance(1 + *lower2, upper2, |x| x < &trie1.keys.index(*lower1));
202202
let step = std::cmp::min(step, 1_000);
203203
self.copy_range(trie2, *lower2, *lower2 + step);
204204
*lower2 += step;
@@ -210,7 +210,7 @@ where
210210
impl<K, L, O, C> TupleBuilder for OrderedBuilder<K, L, O, C>
211211
where
212212
K: Ord,
213-
C: BatchContainer<Item=K>+Deref<Target=[K]>,
213+
C: BatchContainer<Item=K>,
214214
L: TupleBuilder,
215215
O: OrdOffset
216216
{
@@ -229,7 +229,7 @@ where
229229
fn push_tuple(&mut self, (key, val): (K, L::Item)) {
230230

231231
// if first element, prior element finish, or different element, need to push and maybe punctuate.
232-
if self.keys.len() == 0 || self.offs[self.keys.len()].try_into().ok().unwrap() != 0 || self.keys[self.keys.len()-1] != key {
232+
if self.keys.len() == 0 || self.offs[self.keys.len()].try_into().ok().unwrap() != 0 || self.keys.index(self.keys.len()-1) != &key {
233233
if self.keys.len() > 0 && self.offs[self.keys.len()].try_into().ok().unwrap() == 0 {
234234
self.offs[self.keys.len()] = O::try_from(self.vals.boundary()).ok().unwrap();
235235
}
@@ -252,12 +252,12 @@ pub struct OrderedCursor<L: Trie> {
252252
impl<K, L, O, C> Cursor<OrderedLayer<K, L, O, C>> for OrderedCursor<L>
253253
where
254254
K: Ord,
255-
C: BatchContainer<Item=K>+Deref<Target=[K]>,
255+
C: BatchContainer<Item=K>,
256256
L: Trie,
257257
O: OrdOffset
258258
{
259259
type Key = K;
260-
fn key<'a>(&self, storage: &'a OrderedLayer<K, L, O, C>) -> &'a Self::Key { &storage.keys[self.pos] }
260+
fn key<'a>(&self, storage: &'a OrderedLayer<K, L, O, C>) -> &'a Self::Key { &storage.keys.index(self.pos) }
261261
fn step(&mut self, storage: &OrderedLayer<K, L, O, C>) {
262262
self.pos += 1;
263263
if self.valid(storage) {
@@ -268,7 +268,7 @@ where
268268
}
269269
}
270270
fn seek(&mut self, storage: &OrderedLayer<K, L, O, C>, key: &Self::Key) {
271-
self.pos += advance(&storage.keys[self.pos .. self.bounds.1], |k| k.lt(key));
271+
self.pos += storage.keys.advance(self.pos, self.bounds.1, |k| k.lt(key));
272272
if self.valid(storage) {
273273
self.child.reposition(&storage.vals, storage.offs[self.pos].try_into().ok().unwrap(), storage.offs[self.pos + 1].try_into().ok().unwrap());
274274
}

src/trace/layers/ordered_leaf.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
use ::difference::Semigroup;
44

5-
use super::{Trie, Cursor, Builder, MergeBuilder, TupleBuilder, BatchContainer, advance};
5+
use super::{Trie, Cursor, Builder, MergeBuilder, TupleBuilder, BatchContainer};
66
use std::ops::Deref;
77

88
/// A layer of unordered values.
@@ -62,7 +62,7 @@ where
6262
}
6363
#[inline]
6464
fn copy_range(&mut self, other: &Self::Trie, lower: usize, upper: usize) {
65-
self.vals.copy_slice(&other.vals[lower .. upper]);
65+
self.vals.copy_range(&other.vals, lower, upper);
6666
}
6767
fn push_merge(&mut self, other1: (&Self::Trie, usize, usize), other2: (&Self::Trie, usize, usize)) -> usize {
6868

@@ -77,7 +77,7 @@ where
7777
match trie1.vals[lower1].0.cmp(&trie2.vals[lower2].0) {
7878
::std::cmp::Ordering::Less => {
7979
// determine how far we can advance lower1 until we reach/pass lower2
80-
let step = 1 + advance(&trie1.vals[(1+lower1)..upper1], |x| x.0 < trie2.vals[lower2].0);
80+
let step = 1 + trie1.vals.advance(1+lower1, upper1, |x| x.0 < trie2.vals[lower2].0);
8181
let step = std::cmp::min(step, 1000);
8282
<OrderedLeafBuilder<K, R, C> as MergeBuilder>::copy_range(self, trie1, lower1, lower1 + step);
8383
lower1 += step;
@@ -95,7 +95,7 @@ where
9595
}
9696
::std::cmp::Ordering::Greater => {
9797
// determine how far we can advance lower2 until we reach/pass lower1
98-
let step = 1 + advance(&trie2.vals[(1+lower2)..upper2], |x| x.0 < trie1.vals[lower1].0);
98+
let step = 1 + trie2.vals.advance(1+lower2, upper2, |x| x.0 < trie1.vals[lower1].0);
9999
let step = std::cmp::min(step, 1000);
100100
<OrderedLeafBuilder<K, R, C> as MergeBuilder>::copy_range(self, trie2, lower2, lower2 + step);
101101
lower2 += step;

0 commit comments

Comments
 (0)