Micro optimizations

This commit is contained in:
Kovid Goyal 2015-05-26 07:56:54 +05:30
parent d4ad8086d2
commit 3e27e0da0f

View File

@ -22,7 +22,9 @@ from calibre.utils.monotonic import monotonic
READ, WRITE, RDWR = 'READ', 'WRITE', 'RDWR' READ, WRITE, RDWR = 'READ', 'WRITE', 'RDWR'
class ReadBuffer(object): class ReadBuffer(object): # {{{
' A ring buffer used to speed up the readline() implementation by minimizing recv() calls '
__slots__ = ('ba', 'buf', 'read_pos', 'write_pos', 'full_state') __slots__ = ('ba', 'buf', 'read_pos', 'write_pos', 'full_state')
@ -78,6 +80,7 @@ class ReadBuffer(object):
def readline(self): def readline(self):
# Return whatever is in the buffer upto (and including) the first \n # Return whatever is in the buffer upto (and including) the first \n
# If no \n is present, returns everything
if self.read_pos == self.write_pos and self.full_state is WRITE: if self.read_pos == self.write_pos and self.full_state is WRITE:
return b'' return b''
if self.read_pos < self.write_pos: if self.read_pos < self.write_pos:
@ -104,6 +107,7 @@ class ReadBuffer(object):
if self.read_pos == self.write_pos: if self.read_pos == self.write_pos:
self.full_state = WRITE self.full_state = WRITE
return ans return ans
# }}}
class Connection(object): class Connection(object):
@ -365,28 +369,30 @@ class ServerLoop(object):
def tick(self): def tick(self):
now = monotonic() now = monotonic()
for s, conn in tuple(self.connection_map.iteritems()): read_needed, write_needed, readable, remove = [], [], [], []
for s, conn in self.connection_map.iteritems():
if now - conn.last_activity > self.opts.timeout: if now - conn.last_activity > self.opts.timeout:
if not conn.handle_timeout(): if not conn.handle_timeout():
self.log.debug('Closing connection because of extended inactivity') remove.append((s, conn))
self.close(s, conn) continue
if conn.wait_for is READ:
read_needed, write_needed, readable = [], [], [] (readable if conn.read_buffer.has_data else read_needed).append(s)
for c in self.connection_map.itervalues(): elif conn.wait_for is WRITE:
if c.wait_for is READ: write_needed.append(s)
(readable if c.read_buffer.has_data else read_needed).append(c.socket)
elif c.wait_for is WRITE:
write_needed.append(c.socket)
else: else:
write_needed.append(c) write_needed.append(s)
(readable if c.read_buffer.has_data else read_needed).append(c.socket) (readable if conn.read_buffer.has_data else read_needed).append(s)
for s, conn in remove:
self.log.debug('Closing connection because of extended inactivity')
self.close(s, conn)
if readable: if readable:
writable = [] writable = []
else: else:
try: try:
readable, writable, _ = select.select([self.socket] + read_needed, write_needed, [], self.opts.timeout) readable, writable, _ = select.select([self.socket] + read_needed, write_needed, [], self.opts.timeout)
except select.error as e: except (select.error, socket.error) as e:
if e.errno in socket_errors_eintr: if e.errno in socket_errors_eintr:
return return
for s, conn in tuple(self.connection_map.iteritems()): for s, conn in tuple(self.connection_map.iteritems()):