-
Notifications
You must be signed in to change notification settings - Fork 33
[WIP] mergesorted #63
base: master
Are you sure you want to change the base?
Conversation
Hmm, I now have doubts regarding type stability of this solution as well. Although I never use
Note that Do we have a chance to fix it? If not, does it make sense to introduce |
I like the idea of a prefetching iterator. I was going to call it You should be able to make it type-stable if you know the type of the state and value of the two inner iterators. You know these types if you call This might work: immutable PeekIterator{C}
c::C # wrapped collection (inner iterator)
end
immutable PeekIteratorState{S,V}
s::S # inner iterator state
valid::Bool # whether v is valid
v::V # cached value
PeekIteratorState(s, v) = new(s, true, v)
PeekIteratorState(s) = new(s, false) # v remains uninitialized
end
function start{C}(p::PeekIterator{C})
s = start(p.c)
d = done(p.c, s)
if !d
v, s = next(p.c, s)
end
# Due to Julia's weird scoping rules, v remains known to the compiler, but might not be defined
# Note: if the "if" block above contains a "return" statement, this doesn't work any more
S = typeof(s)
V = typeof(v)
if !d
PeekIteratorState{S,V}(s, v)
else
PeekIteratorState{S,V}(s)
end
end
function done{C,S,V}(p::PeekIterator{C}, s::PeekIteratorState{S,V})
!s.valid # this implies done(p.c, s.s)
end
function next{C,S,V}(p::PeekIterator{C}, s::PeekIteratorState{S,V})
@assert s.valid
if done(p.c, s.s)
# inner iterator is done; return one more value
s.v, PeekIteratorState{S,V}(s.s)
else
v, s = next(p.c, s.s)
s.v, PeekIteratorState{S,V}(s, v)
end
end |
Here you are:
|
As topping, for iterators which have the next element in their state already (so nothing is really to be done), define e.g.
|
I think we should avoid throwing exceptions in
I thought about using |
Here's a version that is both - type stable and allows wrapping empty iterators (I renamed
And some test for demonstration:
|
@dfdx You can change the implementation of This |
I think |
PS:
|
@dfdx It kind of "worked" because you provided the right "length" and julia's comprehension does not call "done" in that particular case |
Oops, my tests wrongly convinced me that the transformation was correct. As a useful output (mostly for myself): don't use
Yep, realized it just after I'd posted the comment :)
Not sure I got you right, but the following code removes
|
That's what I meant. This iterator is actually quite neat. |
I've made a separate PR for |
Done (though tests will fail for now since this PR relies on #65 which is not merged yet). |
Alternative version of #62. The main difference is that function
safenext()
andcomplete()
are replaced with one another iteratorPrefetchIterator
which constantly keeps 1 element in cache, making it available for comparison without actually moving an iterator pointer (see this comment for details why it is needed at all). Compared with #62, this version:PrefetchIterator
reads 1 element during construction)