From bf2ff249b97b31822cb02c4850dae15966b70a6f Mon Sep 17 00:00:00 2001 From: Kevin Clark Date: Tue, 8 Jul 2008 23:20:15 +0000 Subject: [PATCH] rb: Buffer the slice!s in MemoryBuffer for a significant performance increase [THRIFT-63] Author: Kevin Ballard 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 --- lib/rb/lib/thrift/transport.rb | 30 ++++++++++++++++++++---------- lib/rb/spec/transport_spec.rb | 3 ++- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/lib/rb/lib/thrift/transport.rb b/lib/rb/lib/thrift/transport.rb index d55adf0d..6b1152e3 100644 --- a/lib/rb/lib/thrift/transport.rb +++ b/lib/rb/lib/thrift/transport.rb @@ -217,12 +217,16 @@ module Thrift 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 @@ module Thrift 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 @@ module Thrift # 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 1fe8600f..972e9846 100644 --- a/lib/rb/spec/transport_spec.rb +++ b/lib/rb/spec/transport_spec.rb @@ -240,7 +240,8 @@ class ThriftTransportSpec < Spec::ExampleGroup 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 -- 2.17.1