From e1bf16876708b1c7a18051066b8ee24480046e98 Mon Sep 17 00:00:00 2001 From: "Hongli Lai (Phusion)" Date: Sat, 11 Sep 2010 19:56:21 +0200 Subject: [PATCH] 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. --- lib/mongo/connection.rb | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/lib/mongo/connection.rb b/lib/mongo/connection.rb index 8becb7d..0c7a4e3 100644 --- a/lib/mongo/connection.rb +++ b/lib/mongo/connection.rb @@ -739,7 +739,7 @@ module Mongo end def receive(sock) - receive_header(sock) + receive_and_discard_header(sock) number_received, cursor_id = receive_response_header(sock) read_documents(number_received, cursor_id, sock) end @@ -757,6 +757,15 @@ module Mongo response_to = header.get_int op = header.get_int 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) header_buf = BSON::ByteBuffer.new @@ -873,6 +882,30 @@ module Mongo message 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) BINARY_ENCODING = Encoding.find("binary")