Optimize MongoDB::Connection#receive.

It doesn't do anything with the header. So instead of parsing the header,
just read the header data and discard it.
This commit is contained in:
Hongli Lai (Phusion) 2010-09-11 19:56:21 +02:00 committed by Kyle Banker
parent 2291a59fcc
commit e1bf168767
1 changed files with 34 additions and 1 deletions

View File

@ -739,7 +739,7 @@ module Mongo
end end
def receive(sock) def receive(sock)
receive_header(sock) receive_and_discard_header(sock)
number_received, cursor_id = receive_response_header(sock) number_received, cursor_id = receive_response_header(sock)
read_documents(number_received, cursor_id, sock) read_documents(number_received, cursor_id, sock)
end end
@ -758,6 +758,15 @@ module Mongo
op = header.get_int op = header.get_int
end end
def receive_and_discard_header(sock)
bytes_read = receive_and_discard_message_on_socket(16, sock)
unless bytes_read == STANDARD_HEADER_SIZE
raise "Short read for DB response header: " +
"expected #{STANDARD_HEADER_SIZE} bytes, saw #{bytes_read}"
end
nil
end
def receive_response_header(sock) def receive_response_header(sock)
header_buf = BSON::ByteBuffer.new header_buf = BSON::ByteBuffer.new
header_buf.put_array(receive_message_on_socket(RESPONSE_HEADER_SIZE, sock).unpack("C*")) header_buf.put_array(receive_message_on_socket(RESPONSE_HEADER_SIZE, sock).unpack("C*"))
@ -873,6 +882,30 @@ module Mongo
message message
end end
# Low-level data for receiving data from socket.
# Unlike #receive_message_on_socket, this method immediately discards the data
# and only returns the number of bytes read.
def receive_and_discard_message_on_socket(length, socket)
chunk = new_binary_string
bytes_read = 0
begin
socket.read(length, chunk)
bytes_read = chunk.length
raise ConnectionFailure, "connection closed" unless bytes_read > 0
if bytes_read < length
while bytes_read < length
socket.read(length - bytes_read, chunk)
raise ConnectionFailure, "connection closed" unless chunk.length > 0
bytes_read += chunk.length
end
end
rescue => ex
close
raise ConnectionFailure, "Operation failed with the following exception: #{ex}"
end
bytes_read
end
if defined?(Encoding) if defined?(Encoding)
BINARY_ENCODING = Encoding.find("binary") BINARY_ENCODING = Encoding.find("binary")