Simplified BSON serialization calls for performance.

This commit is contained in:
Kyle Banker 2009-11-12 14:48:49 -05:00
parent db1f382150
commit 3362fb5be6
6 changed files with 39 additions and 10 deletions

View File

@ -18,6 +18,13 @@ require 'mongo/cursor'
require 'mongo/collection'
require 'mongo/admin'
begin
require 'mongo_ext/cbson'
BSON_SERIALIZER = CBson
rescue LoadError
BSON_SERIALIZER = BSON
end
module Mongo
ASCENDING = 1
DESCENDING = -1

View File

@ -221,7 +221,7 @@ module Mongo
message.put_int(0)
BSON.serialize_cstr(message, "#{@db.name}.#{@name}")
message.put_int(0)
message.put_array(BSON.new.serialize(selector, false).to_a)
message.put_array(BSON_SERIALIZER.serialize(selector, false).unpack("C*"))
@db.send_message_with_operation(Mongo::Constants::OP_DELETE, message,
"db.#{@db.name}.remove(#{selector.inspect})")
end
@ -258,8 +258,8 @@ module Mongo
update_options += 1 if options[:upsert]
update_options += 2 if options[:multi]
message.put_int(update_options)
message.put_array(BSON.new.serialize(selector, false).to_a)
message.put_array(BSON.new.serialize(document, false).to_a)
message.put_array(BSON_SERIALIZER.serialize(selector, false).unpack("C*"))
message.put_array(BSON_SERIALIZER.serialize(document, false).unpack("C*"))
if options[:safe]
@db.send_message_with_safe_check(Mongo::Constants::OP_UPDATE, message,
"db.#{@name}.update(#{selector.inspect}, #{document.inspect})")
@ -486,7 +486,7 @@ EOS
message = ByteBuffer.new
message.put_int(0)
BSON.serialize_cstr(message, "#{@db.name}.#{collection_name}")
documents.each { |doc| message.put_array(BSON.new.serialize(doc, check_keys).to_a) }
documents.each { |doc| message.put_array(BSON_SERIALIZER.serialize(doc, check_keys).unpack("C*")) }
if safe
@db.send_message_with_safe_check(Mongo::Constants::OP_INSERT, message,
"db.#{collection_name}.insert(#{documents.inspect})")

View File

@ -322,8 +322,8 @@ module Mongo
if query_contains_special_fields?
selector = selector_with_special_query_fields
end
message.put_array(BSON.new.serialize(selector).to_a)
message.put_array(BSON.new.serialize(@fields).to_a) if @fields
message.put_array(BSON_SERIALIZER.serialize(selector, false).unpack("C*"))
message.put_array(BSON_SERIALIZER.serialize(@fields, false).unpack("C*")) if @fields
message
end

View File

@ -450,6 +450,14 @@ module Mongo
end
end
def send_message_with_operation_raw(operation, message, log_message=nil)
message_with_headers = add_message_headers_raw(operation, message)
@logger.debug(" MONGODB #{log_message || message}") if @logger
@semaphore.synchronize do
send_message_on_socket(message_with_headers)
end
end
# Sends a message to the database, waits for a response, and raises
# and exception if the operation has failed.
def send_message_with_safe_check(operation, message, log_message=nil)
@ -641,7 +649,7 @@ module Mongo
BSON.serialize_cstr(message, "#{@name}.$cmd")
message.put_int(0)
message.put_int(-1)
message.put_array(BSON.new.serialize({:getlasterror => 1}).to_a)
message.put_array(BSON_SERIALIZER.serialize({:getlasterror => 1}, false).unpack("C*"))
add_message_headers(Mongo::Constants::OP_QUERY, message)
end
@ -655,7 +663,7 @@ module Mongo
BSON.serialize_cstr(message, "#{@name}.$cmd")
message.put_int(0)
message.put_int(-1)
message.put_array(BSON.new.serialize({:reseterror => 1}).to_a)
message.put_array(BSON_SERIALIZER.serialize({:reseterror => 1}, false).unpack("C*"))
add_message_headers(Mongo::Constants::OP_QUERY, message)
end

View File

@ -71,6 +71,12 @@ class BSON
@buf.to_a
end
# Serializes an object.
# Implemented to ensure an API compatible with BSON extension.
def self.serialize(obj, check_keys)
new.serialize(obj, check_keys)
end
begin
require 'mongo_ext/cbson'
def serialize(obj, check_keys=false)
@ -99,6 +105,12 @@ class BSON
end
end
# Returns the array stored in the buffer.
# Implemented to ensure an API compatible with BSON extension.
def unpack(arg)
@buf.to_a
end
def serialize_key_value(k, v, check_keys)
k = k.to_s
if check_keys

View File

@ -20,9 +20,11 @@ class ByteBuffer
attr_reader :order
def initialize(initial_data=[])
@buf = initial_data
@buf = initial_data
@cursor = 0
self.order = :little_endian
@order = :little_endian
@int_pack_order = 'V'
@double_pack_order = 'E'
end
# +endianness+ should be :little_endian or :big_endian. Default is :little_endian