rb: Buffer the slice!s in MemoryBuffer for a significant performance increase [THRIFT-63]
Author: Kevin Ballard <kevin@rapleaf.com>
Currently it buffers up to 4kB before throwing away the data.
Tests with 1MB shows the exact same performance characteristics.
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@675049 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/rb/lib/thrift/transport.rb b/lib/rb/lib/thrift/transport.rb
index d55adf0..6b1152e 100644
--- a/lib/rb/lib/thrift/transport.rb
+++ b/lib/rb/lib/thrift/transport.rb
@@ -217,12 +217,16 @@
deprecate_class! :TFramedTransportFactory => FramedTransportFactory
class MemoryBuffer < Transport
+ GARBAGE_BUFFER_SIZE = 4*(2**10) # 4kB
+
# If you pass a string to this, you should #dup that string
# unless you want it to be modified by #read and #write
#--
- # yes this behavior is intentional
+ # this behavior is no longer required. If you wish to change it
+ # go ahead, just make sure the specs pass
def initialize(buffer = nil)
@buf = buffer || ''
+ @index = 0
end
def open?
@@ -236,20 +240,28 @@
end
def peek
- not @buf.empty?
+ @index < @buf.size
end
# this method does not use the passed object directly but copies it
def reset_buffer(new_buf = '')
@buf.replace new_buf
+ @index = 0
end
def available
- @buf.length
+ @buf.length - @index
end
def read(len)
- @buf.slice!(0, len)
+ data = @buf.slice(@index, len)
+ @index += len
+ @index = @buf.size if @index > @buf.size
+ if @index >= GARBAGE_BUFFER_SIZE
+ @buf = @buf.slice(@index..-1)
+ @index = 0
+ end
+ data
end
def write(wbuf)
@@ -262,19 +274,17 @@
# For fast binary protocol access
def borrow(size = nil)
if size.nil?
- @buf[0..-1]
+ @buf[@index..-1]
else
- if size > @buf.length
+ if size > available
raise EOFError # Memory buffers only get one shot.
else
- @buf[0..size]
+ @buf[@index, size]
end
end
end
- def consume!(size)
- @buf.slice!(0, size)
- end
+ alias_method :consume!, :read
end
deprecate_class! :TMemoryBuffer => MemoryBuffer
diff --git a/lib/rb/spec/transport_spec.rb b/lib/rb/spec/transport_spec.rb
index 1fe8600..972e984 100644
--- a/lib/rb/spec/transport_spec.rb
+++ b/lib/rb/spec/transport_spec.rb
@@ -240,7 +240,8 @@
s = "this is a test"
@buffer = MemoryBuffer.new(s)
@buffer.read(4).should == "this"
- s.should == " is a test"
+ s.slice!(-4..-1)
+ @buffer.read(@buffer.available).should == " is a "
end
it "should always remain open" do