stream == range ? [Sliding window]

Dragos Carp via Digitalmars-d digitalmars-d at puremagic.com
Sun May 31 16:54:18 PDT 2015


>>> Hardly. In fact, I've spent quite some time trying to figure 
>>> this out.
>>>
>>> Doing bulk read to some array is the pushing burden of 
>>> maintaining
>>> some buffer on the user and adding the overhead of extra copy 
>>> on
>>> buffered streams. Not to mention that the more methods we put 
>>> in range
>>> API the more if/else forests we produce in our algorithms.
>>
>> LinearBuffer tries to address this problem in:
>> https://github.com/D-Programming-Language/phobos/pull/2928
>> This simply extends the existing std.array.Appender with 
>> popFrontN
>> operations.
>>
>> The use case would be like this:
>> 1. accumulate data in the LiniearBuffer by appending to the 
>> buffer
>> 2. try to identify the next token
>> 3. if a token is identified popFontN the length of the token
>> 4. otherwise acumulate some more (go to 1.)
>>
>
> Yes, that's the pattern. Thoughts:
> 1. popFrontN is just confusing - this is not a range, let's not 
> pretend it is.

LinearBuffer is not meant as replacement of streams or such. It 
is a low level data structure, that maybe could be used in the 
implementation of the streams.
Considering the FIFO style of usage, I found popFrontN 
appropriate. But it would be no problem to rename it.

> 2. As it stands it would require first copying into appender 
> which is slow. The opposite direction is usually a better match 
> - assume appender (or rather buffer) is filled to its capacity 
> with data from the file and keeping this invariant true.

This would function differently if the data comes over the 
socket, usually you cannot fill the buffer.

>
> Otherwise it looks quite similar to the sliding window 
> interface and that is great.
>
> data --> window
> popFrontN --> skip
> put ~~> extend (probably should be just called 'more')

Sometimes (socket recv) you don't know how much extend.

>
> Actually I've dig up my original code for buffer, amended and 
> integrated in one of Steven's Schveighoffer I/O package forks:
>
> https://github.com/DmitryOlshansky/phobos/blob/new-io3/std/io/textbuf.d#L68
> Now I recall it's not quite sliding window as it shrinks on 
> reads...
> Anyhow the same pattern goes with: data, discard and extend.
>
>> I was also thinking about adding a new method:
>> ptrdiff_t putFrom(ptrdiff_t delegate(T[]) read);
>> meant to be used together with file read or socket receive 
>> functions. In
>> this way the read/recv system functions can write directly 
>> into the
>> input buffer without intermediate copies.
>
> Yes, that is the missing piece in the current setup, something 
> got to fill the buffer directly.
>
> Parser or any other component down the line shouldn't concern 
> itself with reading, just using some "more" primitive to 
> auto-magically extend the window by at least X bytes. That 
> would shrink-extend buffer  and load it behind the scenes.

As I sad, LinearBuffer is meant to be used "behind the scenes".

I find Andrei's bulkRead, maybe combined with a matcher a la 
boost::asio read_until, the simplest high level interface.


More information about the Digitalmars-d mailing list