Transient ranges

Alex Parrill via Digitalmars-d digitalmars-d at puremagic.com
Mon May 30 11:32:53 PDT 2016


On Monday, 30 May 2016 at 12:53:07 UTC, Steven Schveighoffer 
wrote:
> On 5/30/16 5:35 AM, Dicebot wrote:
>> On Sunday, 29 May 2016 at 17:25:47 UTC, Steven Schveighoffer 
>> wrote:
>>> What problems are solvable only by not caching the front 
>>> element? I
>>> can't think of any.
>>
>> As far as I know, currently it is done mostly for performance 
>> reasons -
>> if result is fitting in the register there is no need to 
>> allocate stack
>> space for the cache, or something like that. One of most 
>> annoying
>> examples is map which calls lambda on each `front` call :
>> https://github.com/dlang/phobos/blob/master/std/algorithm/iteration.d#L587-L590
>
> Maybe my understanding of your post is incorrect. You said "It 
> is impossible to correctly define input range without caching 
> front which may not be always possible and may have negative 
> performance impact."
>
> I'm trying to figure out which cases caching makes the solution 
> impossible.

One case is wrapping a network stream: a TCP input range that 
yields ubyte[] chunks of data as they are read from the socket, a 
joiner to join the blocks together, a map that converts the bytes 
to characters, and take to consume each message.

The issue is that, in a naive implementation, creating the TCP 
range requires reading a chunk from the socket to populate front. 
Since I usually set up my stream objects, before using them, the 
receiver range will try to receive a chunk, but I haven't sent a 
request to the server yet, so it would block indefinitely.

Same issue with popFront: I need to pop the bytes I've already 
used for the previous request, but calling popFront would mean 
waiting for the response for the next request which I haven't 
sent out yet.

The solution I used was to delay actually receiving the chunk 
until front was called, which complicates the implementation a 
bit.


More information about the Digitalmars-d mailing list