Optimize MongoDB::Cursor#construct_query_message.

This commit is contained in:
Hongli Lai (Phusion) 2010-09-11 23:48:15 +02:00 committed by Kyle Banker
parent bde53f1e20
commit c8726ca150
4 changed files with 35 additions and 7 deletions

View File

@ -47,22 +47,29 @@ module BSON
end end
if RUBY_VERSION >= '1.9' if RUBY_VERSION >= '1.9'
def self.to_utf8(str) NULL_BYTE = "\0".force_encoding('binary').freeze
str.encode("utf-8") UTF8_ENCODING = Encoding.find('utf-8')
BINARY_ENCODING = Encoding.find('binary')
def self.to_utf8_binary(str)
str.encode(UTF8_ENCODING).force_encoding(BINARY_ENCODING)
end end
else else
def self.to_utf8(str) NULL_BYTE = "\0"
def self.to_utf8_binary(str)
begin begin
str.unpack("U*") str.unpack("U*")
rescue => ex rescue => ex
raise InvalidStringEncoding, "String not valid utf-8: #{str}" raise InvalidStringEncoding, "String not valid utf-8: #{str.inspect}"
end end
str str
end end
end end
def self.serialize_cstr(buf, val) def self.serialize_cstr(buf, val)
buf.put_array(to_utf8(val.to_s).unpack("C*") << 0) buf.put_binary(to_utf8_binary(val.to_s))
buf.put_binary(NULL_BYTE)
end end
def self.serialize_key(buf, key) def self.serialize_key(buf, key)

View File

@ -117,6 +117,20 @@ module BSON
@cursor += 1 @cursor += 1
end end
def put_binary(data, offset=nil)
@cursor = offset if offset
if defined?(BINARY_ENCODING)
data = data.dup.force_encoding(BINARY_ENCODING)
end
if more?
@str[@cursor, data.length] = data
else
ensure_length(@cursor)
@str << data
end
@cursor += data.length
end
def put_array(array, offset=nil) def put_array(array, offset=nil)
@cursor = offset if offset @cursor = offset if offset
if more? if more?

View File

@ -404,8 +404,8 @@ module Mongo
message.put_int(@skip) message.put_int(@skip)
message.put_int(@limit) message.put_int(@limit)
spec = query_contains_special_fields? ? construct_query_spec : @selector spec = query_contains_special_fields? ? construct_query_spec : @selector
message.put_array(BSON::BSON_CODER.serialize(spec, false).to_a) message.put_binary(BSON::BSON_CODER.serialize(spec, false).to_s)
message.put_array(BSON::BSON_CODER.serialize(@fields, false).to_a) if @fields message.put_binary(BSON::BSON_CODER.serialize(@fields, false).to_s) if @fields
message message
end end

View File

@ -125,6 +125,13 @@ class ByteBufferTest < Test::Unit::TestCase
@buf.to_s) @buf.to_s)
end end
def test_put_binary
@buf.put(1)
@buf.put_binary("\x02\x03", 0)
@buf.put_binary("\x04\x05", 4)
assert_equal "\x02\x03\x00\x00\x04\x05", @buf.to_s
end
def test_rewrite def test_rewrite
@buf.put_int(0) @buf.put_int(0)
@buf.rewind @buf.rewind