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

Update in chunks #992

Merged
merged 2 commits into from May 27, 2013
Merged

Update in chunks #992

merged 2 commits into from May 27, 2013

Conversation

monarchdodra
Copy link
Collaborator

Basically the old if(isInputRange!Source && hasSlicing!Source && hasLength!Source) was pretty much the same as "finite RA".

This implementation only requires ForwardRange. This means chunks can now be used with "simple" ranges, such as byLine (to read blocks of lines at once), or filter, or infinite ranges, both non-ra (Fib by blocks), or with RA and slicing (Sequence).

AFAIK, chunks requires at least forward: I don't think it could work on a input only.

Implementation wise, there is not much: slicing was basically just changed for take, and everything works just as well. I re-organized a bit so as to document what functions require what traits from Source. Finally, I improved on the implementations of Back/popBack/Length, simply by using more accurate arithmetics.

This pull currently works, but would require #854 to fully unlock the slicing functionality of infinite ranges, and requires #991 so as to test said functionality.

/// Length. Only if $(D hasLength!Source) is $(D_PARAM true)
@property size_t length()
{
return cast(size_t)((_source.length + _chunkSize - 1UL) / _chunkSize);
Copy link
Member

Choose a reason for hiding this comment

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

no need for UL

Copy link
Member

Choose a reason for hiding this comment

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

Oh, and the cast isn't needed either - it's all size_ts. No?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The ˋULˋ is a trick to force promotion to ulong, in case of overflow, before doing the division. Then the cast is to downcast back to size_t. I should have definitly commented it, and used a clearer upcast, too. Sorry about that.

Come to think about it, the upcast would probably be too late here anyways... I'll just change it to a straight up:

ˋcast(ulong)_source.length + ...ˋ

Copy link
Member

Choose a reason for hiding this comment

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

Definitely comment it if you're trying to do anything like that, and yes, any overflow would have already occurred when 1UL was reached.

@andralex
Copy link
Member

andralex commented Dec 8, 2012

lgtm modulo nits

static if (isInfinite!Source)
// undocumented
enum empty = false;
else
/// Ditto
Copy link
Member

Choose a reason for hiding this comment

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

This comment isn't going to show up in the docs. It's the first static if which wins inside of a template. So, you should move the finite version above the infinite one.

@monarchdodra
Copy link
Collaborator Author

Ok. I reviewed and addressed all the above comments. I also fixed an issue with the slicing operator that failed on operations such as chunks[$ .. $] (This is a tricky situation where the "low" bound can actually exceed the underlying _source's length). I added more tests to cover slicing.


The second commit contains something which (IMO) is a very interesting mechanic: I defined opDollar to return a typed dollartoken. This means that even when chunks is finite, you can still bypass a ton of code by statically telling it you want to slice to end. This is especially interesting when combined with drop/popFrontN.


I think it might be better to review commits individually. The first commit is the "meat" commit. The second is really just cherry on the cake. If it is deemed overkill, we can remove it.

EDIT: I had to makes changes that merged the two commits. Sorry :(

@monarchdodra
Copy link
Collaborator Author

OK: Everything is done, and all prerequired commits have been pulled, and I've rebased after them.

Primary objective: Make chunks work with an input range: Done.

Also, chunks is now able to correctly wrap an infinite sliceable range, and provide efficient slicing and slice to end of said range! How cool is that?

Non-infinite ranges can now also efficently slice to $, using a static dollar type. This is important because in the case of chunks, there is a fair amount of computation to calculate length, and then to re-transform an index the the source's index.

Fixed issues where chunks[$ .. $] used to crash.

So, just to say this is done and ready for review.

@alexrp
Copy link
Member

alexrp commented Feb 10, 2013

Fails the auto tester.

@monarchdodra
Copy link
Collaborator Author

Just a quick question. Was "alias this = Something;" made illegal? I know there was talks about it, and I'm getting compiler complaints around it.

@alexrp
Copy link
Member

alexrp commented Feb 10, 2013

Yes. Use alias foo this; for now.

@monarchdodra
Copy link
Collaborator Author

Hum, I'm getting a weird bug. May or may not be my fault, but I'm getting some real erratic behavior: basically, a null this error, which is strange (and new).

In particular, it is produced by one of (line aprox 6700):

    assert (chunks1[$ .. 5].equal(empy)); //Semiquick
    assert (chunks2[$ .. 5].equal(empty)); //Semiquick

But if I comment either of them, than neither individually produces the bug. Also, if I change the order of the "equal" args, then it doesn't produce the bug:

    assert (empty.equal(chunks1[$ .. 5])); //Semiquick
    assert (empty.equal(chunks2[$ .. 5])); //Semiquick

I'm still investigating on the grounds that it is probably my fault, but I'm reporting it in case it smells stinky to anyone... That and I have no idea how an opDollar could produce a null this :/

@monarchdodra
Copy link
Collaborator Author

Well, I think I'm hitting a codegen/compiler bug or something. I'll reduce the test case and submit it.

@monarchdodra
Copy link
Collaborator Author

Yeah, it is a brand new regression. From the 8th. Somebody should look into it while it is fresh:

http://d.puremagic.com/issues/show_bug.cgi?id=9496

}
else
{
return _source[len - remainder..len];
//Dollar token caries a static type, with no extra information.
//It can lazilly transform into _source.length on algorithmic
Copy link
Member

Choose a reason for hiding this comment

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

Typos: »caries«, »lazilly«. Not that it would matter much in a comment.

reduces requirements to ForwardRange
@dnadlinger
Copy link
Member

Are we good to go?

@monarchdodra
Copy link
Collaborator Author

Appart from an outstanding typo in a comment that I just fixed, it should be ready to go, yes.

dnadlinger added a commit that referenced this pull request May 27, 2013
@dnadlinger dnadlinger merged commit dc4fe37 into dlang:master May 27, 2013
@monarchdodra
Copy link
Collaborator Author

Yay! Thanks :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants