Skip to content

Commit

Permalink
Improves performance of http.body.Body.readline()
Browse files Browse the repository at this point in the history
  • Loading branch information
Djoume Salvetti authored and benoitc committed May 10, 2012
1 parent 4b59fc3 commit 9e308e3
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 13 deletions.
22 changes: 9 additions & 13 deletions gunicorn/http/body.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,24 +228,20 @@ def readline(self, size=None):
return ""

line = self.buf.getvalue()
self.buf.truncate(0)
if len(line) < size:
line += self.reader.read(size - len(line))
extra_buf_data = line[size:]
line = line[:size]

idx = line.find("\n")
if idx >= 0:
ret = line[:idx+1]
self.buf.truncate(0)
self.buf.write(line[idx+1:])
self.buf.write(extra_buf_data)
return ret

self.buf.truncate(0)
ch = ""
buf = [line]
lsize = len(line)
while lsize < size and ch != "\n":
ch = self.reader.read(1)
if not len(ch):
break
lsize += 1
buf.append(ch)
return "".join(buf)
self.buf.write(extra_buf_data)
return line

def readlines(self, size=None):
ret = []
Expand Down
61 changes: 61 additions & 0 deletions tests/004-test-http-body.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from StringIO import StringIO

import t
from gunicorn.http.body import Body


def assert_readline(payload, size, expected):
body = Body(StringIO(payload))
t.eq(body.readline(size), expected)


def test_readline_empty_body():
assert_readline("", None, "")
assert_readline("", 1, "")


def test_readline_zero_size():
assert_readline("abc", 0, "")
assert_readline("\n", 0, "")


def test_readline_new_line_before_size():
body = Body(StringIO("abc\ndef"))
t.eq(body.readline(4), "abc\n")
t.eq(body.readline(), "def")


def test_readline_new_line_after_size():
body = Body(StringIO("abc\ndef"))
t.eq(body.readline(2), "ab")
t.eq(body.readline(), "c\n")


def test_readline_no_new_line():
body = Body(StringIO("abcdef"))
t.eq(body.readline(), "abcdef")
body = Body(StringIO("abcdef"))
t.eq(body.readline(2), "ab")
t.eq(body.readline(2), "cd")
t.eq(body.readline(2), "ef")


def test_readline_buffer_loaded():
reader = StringIO("abc\ndef")
body = Body(reader)
body.read(1) # load internal buffer
reader.write("g\nhi")
reader.seek(7)
t.eq(body.readline(), "bc\n")
t.eq(body.readline(), "defg\n")
t.eq(body.readline(), "hi")


def test_readline_buffer_loaded_with_size():
body = Body(StringIO("abc\ndef"))
body.read(1) # load internal buffer
t.eq(body.readline(2), "bc")
t.eq(body.readline(2), "\n")
t.eq(body.readline(2), "de")
t.eq(body.readline(2), "f")

0 comments on commit 9e308e3

Please sign in to comment.