Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement bounded iterators for BTree #20082

Merged
merged 1 commit into from
Jan 19, 2015
Merged

Conversation

pczarn
Copy link
Contributor

@pczarn pczarn commented Dec 20, 2014

Part of collections reform v1, #18424
Also, iteration is simplified:

before
test btree::map::bench::iter_1000                          ... bench:     17177 ns/iter (+/- 6302)
test btree::map::bench::iter_100000                        ... bench:   1735731 ns/iter (+/- 23908)
test btree::map::bench::iter_20                            ... bench:       386 ns/iter (+/- 148)
after
test btree::map::bench::iter_1000                          ... bench:     15777 ns/iter (+/- 346)
test btree::map::bench::iter_100000                        ... bench:   1602604 ns/iter (+/- 73629)
test btree::map::bench::iter_20                            ... bench:       339 ns/iter (+/- 91)

cc @gereeter @cgaebel
r? @gankro

@@ -1376,7 +1381,7 @@ struct AbsTraversal<Impl> {

/// A single atomic step in a traversal. Either an element is visited, or an edge is followed
pub enum TraversalItem<K, V, E> {
Elem(K, V),
Elem((K, V)),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just for convenient interop with iterators?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the obscure opt.map(Elem). Ah, I should add a comment there.

@cgaebel
Copy link
Contributor

cgaebel commented Dec 20, 2014

Can I see tests that look like the iter tests, but bounded? Just make sure they iterate over the same number of elements. I suspect it'd be an interesting comparison. Specifically, I'm looking to see what the cost of creating the iterator looks like.

}

/// An endpoint of a range of keys.
pub enum Bound<T> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like this shouldn't live in this file. Maybe it should go in libcore? I don't know. It just doesn't seem specific to BTrees.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed. I recommend moving it to the root of libcollections (and std::collections as a re-export).

@Gankra
Copy link
Contributor

Gankra commented Dec 21, 2014

Quick skim: interesting approach! Excited to dig into this. Sad to see macros. :(

Will review monday if no one else does first.

@cgaebel
Copy link
Contributor

cgaebel commented Dec 21, 2014

Haha "sad to see macros" is pretty much exactly what I thought when scrolling through this.

@pczarn
Copy link
Contributor Author

pczarn commented Dec 21, 2014

Should we provide RangedKeys, RangedValues, RangedValuesMut for map, as well as RangedItems RangedKeys for BTreeSet?

interesting approach!

Can you think of some other approach?

Unfortunately, the code is quadrupled for both ends and mut/immutable. Macros deal with the latter duplication.

@pczarn pczarn force-pushed the btree-bounded-iter branch from b3496c9 to d199ddb Compare December 21, 2014 15:38
@Gankra
Copy link
Contributor

Gankra commented Dec 22, 2014

I was assuming you were going to replace the Two RingBufs with two Vecs, which should better optimize for the "average" case. In fact you've kind've done that. Two stacks and a deque are famously "equivalent", although normally I see that used to implement a deque using two stacks, not the other way around :P

The code complexity benefits probably make it worth it, though.

Push(item) => { self.left.push_back(item); },
Pop => { self.left.pop_back(); },
Push(item) => { self.traversals.push_back(item); },
Pop => { self.traversals.pop_back(); },
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

;_; so elegant

@pczarn pczarn force-pushed the btree-bounded-iter branch 4 times, most recently from 4402b6a to d4e6d3d Compare December 23, 2014 22:43
self.head_is_edge = true;
self.inner.next_kv().map(Elem)
})
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Smooth. 💖

@Gankra
Copy link
Contributor

Gankra commented Dec 30, 2014

Just need to fully parse the macro madness...

loop {
let slice = lca.slice_from(min_key).slice_to(max_key);
match slice.edges {
[ref $($m)* edge] => lca = edge.$as_slices_internal(),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trying to understand this: basically you make a subslice, and if it contains a single edge you conclude that you must descend deeper? Otherwise (including the case where it's empty?), this must be the LCA?

As always: would love some more docs as to what's going on here.

@Gankra
Copy link
Contributor

Gankra commented Jan 4, 2015

Basically r=me (feel free to squash), but this is complex enough that I'd appreciate a secondary review from @huonw or @gereeter (or anyone else, really).

Also needs another rebase :(

@pczarn pczarn force-pushed the btree-bounded-iter branch 2 times, most recently from 7168297 to 31531c6 Compare January 4, 2015 23:54
@pczarn
Copy link
Contributor Author

pczarn commented Jan 4, 2015

@gankro, done. The comment "for ranges such as..." is irrelevant for the main example.

@pczarn pczarn force-pushed the btree-bounded-iter branch from 31531c6 to 1f62517 Compare January 5, 2015 00:20
// lca represents the Lowest Common Ancestor, above which we never
// walk, since everything else is outside the range to iterate.
// ___________________
// |__0_|_80_|_85_|_90_| (root)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose you wouldn't like to have that irrelevant part. Removed.

@emberian
Copy link
Member

emberian commented Jan 5, 2015

Needs another rebase :(

@pczarn pczarn force-pushed the btree-bounded-iter branch 3 times, most recently from c91326e to 3ee4dc0 Compare January 7, 2015 22:08
@pczarn
Copy link
Contributor Author

pczarn commented Jan 7, 2015

@gankro Tested, rebased (in this order 😅 )

@Gankra
Copy link
Contributor

Gankra commented Jan 9, 2015

@pczarn needs some changes for old_impl_check stuff, I guess?

@pczarn pczarn force-pushed the btree-bounded-iter branch from 3ee4dc0 to fe6cca3 Compare January 14, 2015 15:25
@pczarn
Copy link
Contributor Author

pczarn commented Jan 14, 2015

Updated for old_impl_check

@Gankra
Copy link
Contributor

Gankra commented Jan 19, 2015

Seems this didn't satisfy all the impl check issues.

@pczarn pczarn force-pushed the btree-bounded-iter branch from fe6cca3 to cf2a2ab Compare January 19, 2015 16:48
Simplify BTree's iterators, too.
@pczarn pczarn force-pushed the btree-bounded-iter branch from cf2a2ab to 429c23d Compare January 19, 2015 16:49
@pczarn
Copy link
Contributor Author

pczarn commented Jan 19, 2015

@gankro Updated

@Gankra
Copy link
Contributor

Gankra commented Jan 19, 2015

@bors r+ 429c

@Gankra
Copy link
Contributor

Gankra commented Jan 19, 2015

Actually this is some pretty hairy stuff.

@bors p=0

?

@Gankra
Copy link
Contributor

Gankra commented Jan 19, 2015

Aha.

@bors rollup-

@bors
Copy link
Contributor

bors commented Jan 19, 2015

⌛ Testing commit 429c23d with merge 54c9a46...

bors added a commit that referenced this pull request Jan 19, 2015
Part of collections reform v1, #18424
Also, iteration is simplified:
```
before
test btree::map::bench::iter_1000                          ... bench:     17177 ns/iter (+/- 6302)
test btree::map::bench::iter_100000                        ... bench:   1735731 ns/iter (+/- 23908)
test btree::map::bench::iter_20                            ... bench:       386 ns/iter (+/- 148)
after
test btree::map::bench::iter_1000                          ... bench:     15777 ns/iter (+/- 346)
test btree::map::bench::iter_100000                        ... bench:   1602604 ns/iter (+/- 73629)
test btree::map::bench::iter_20                            ... bench:       339 ns/iter (+/- 91)
```
cc @gereeter @cgaebel
r? @gankro
@bors bors merged commit 429c23d into rust-lang:master Jan 19, 2015
@pczarn pczarn deleted the btree-bounded-iter branch January 24, 2015 09:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants