Skip to content

Commit

Permalink
Fix ByteBuffer#index for read-write boundary match
Browse files Browse the repository at this point in the history
The previous implementation searched the buffers individually, which
will only work correctly for search substrings of length 1.

This instead implements the continued search by folding the write buffer
into the read buffer unless a match was found in the initial segment.

An alternative that doesn't fold the two buffers could naturally be
implemented, but that would be much more complicated.

In principle, the old implementation could be retained for one character
substrings, but I did not think it would be a common enough case to be
worth the extra effort.
  • Loading branch information
grddev committed Oct 27, 2015
1 parent 6c51254 commit d7426ed
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 3 deletions.
14 changes: 11 additions & 3 deletions lib/ione/byte_buffer.rb
Expand Up @@ -179,10 +179,12 @@ def index(substring, start_index=0)
swap_buffers
end
read_buffer_length = @read_buffer.bytesize
if start_index < read_buffer_length - @offset && (index = @read_buffer.index(substring, @offset + start_index))
if start_index + substring.bytesize <= read_buffer_length - @offset && (index = @read_buffer.index(substring, @offset + start_index))
index - @offset
elsif (index = @write_buffer.index(substring, start_index - read_buffer_length + @offset))
index + read_buffer_length - @offset
elsif start_index + substring.bytesize <= read_buffer_length - @offset + @write_buffer.bytesize
merge_read_buffer
start_index = read_buffer_length - substring.bytesize if read_buffer_length - substring.bytesize > start_index
@read_buffer.index(substring, start_index)
else
nil
end
Expand Down Expand Up @@ -298,5 +300,11 @@ def swap_buffers
@read_buffer = @write_buffer
@write_buffer = ''
end

def merge_read_buffer
@read_buffer = @read_buffer[@offset, @read_buffer.length - @offset] << @write_buffer
@write_buffer = ''
@offset = 0
end
end
end
14 changes: 14 additions & 0 deletions spec/ione/byte_buffer_spec.rb
Expand Up @@ -354,6 +354,20 @@ module Ione
buffer.append(' baz baz')
buffer.index('baz', 8).should == 11
end

it 'returns the first index when the matching substring spans the read and write buffer' do
buffer.append('foo bar')
buffer.read(1)
buffer.append('bar barbar')
buffer.index('barbar', 0).should == 3
end

it 'returns nil when the substring does not fit in the search space' do
buffer.append('foo')
buffer.read(1)
buffer.append('bar')
buffer.index('bar', 3).should be_nil
end
end

context 'when reading and appending' do
Expand Down

0 comments on commit d7426ed

Please sign in to comment.