##// END OF EJS Templates
changelog: add class to represent parsed changelog revisions...
changelog: add class to represent parsed changelog revisions Currently, changelog entries are parsed into their respective components at read time. Many operations are only interested in a subset of fields of a changelog entry. The parsing and storing of all the fields adds avoidable overhead. This patch introduces the "changelogrevision" class. It takes changelog raw text and exposes the parsed results as attributes. The code for parsing changelog entries has been moved into its construction function. changelog.read() has been modified to use the new class internally while maintaining its existing API. Future patches will make revision parsing lazy. We implement the construction function of the new class with __new__ instead of __init__ so we can use a named tuple to represent the empty revision. This saves overhead and complexity of coercing later versions of this class to represent an empty instance. While we are here, we add a method on changelog to obtain an instance of the new type. The overhead of constructing the new class regresses performance of revsets accessing this data: author(mpm) 0.896565 0.929984 desc(bug) 0.887169 0.935642 105% date(2015) 0.878797 0.908094 extra(rebase_source) 0.865446 0.922624 106% author(mpm) or author(greg) 1.801832 1.902112 105% author(mpm) or desc(bug) 1.812438 1.860977 date(2015) or branch(default) 0.968276 1.005824 author(mpm) or desc(bug) or date(2015) or extra(rebase_source) 3.656193 3.743381 Once lazy parsing is implemented, these revsets will all be faster than before. There is no performance change on revsets that do not access this data. There /could/ be a performance regression on operations that perform several changelog reads. However, I can't think of anything outside of revsets and `hg log` (basically the same as a revset) that would be impacted.

File last commit:

r27046:37fcfe52 default
r28487:98d98a64 default
Show More
protocol.py
110 lines | 3.2 KiB | text/x-python | PythonLexer
Dirkjan Ochtman
separate the wire protocol commands from the user interface commands
r5598 #
# Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
# Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
#
Martin Geisler
updated license to be explicit about GPL version 2
r8225 # This software may be used and distributed according to the terms of the
Matt Mackall
Update license to GPLv2+
r10263 # GNU General Public License version 2 or any later version.
Dirkjan Ochtman
separate the wire protocol commands from the user interface commands
r5598
Yuya Nishihara
hgweb: use absolute_import
r27046 from __future__ import absolute_import
import cStringIO
import cgi
import urllib
import zlib
from .common import (
HTTP_OK,
)
from .. import (
util,
wireproto,
)
Dirkjan Ochtman
hgweb: explicitly check if requested command exists
r5963
Dirkjan Ochtman
hgweb: explicit response status
r5993 HGTYPE = 'application/mercurial-0.1'
Andrew Pritchard
wireproto: add out-of-band error class to allow remote repo to report errors...
r15017 HGERRTYPE = 'application/hg-error'
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595
Pierre-Yves David
wireproto: introduce an abstractserverproto class...
r20903 class webproto(wireproto.abstractserverproto):
Idan Kamara
ui: use I/O descriptors internally...
r14614 def __init__(self, req, ui):
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 self.req = req
self.response = ''
Idan Kamara
ui: use I/O descriptors internally...
r14614 self.ui = ui
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 def getargs(self, args):
Steven Brown
httprepo: long arguments support (issue2126)...
r14093 knownargs = self._args()
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 data = {}
keys = args.split()
for k in keys:
if k == '*':
star = {}
Steven Brown
httprepo: long arguments support (issue2126)...
r14093 for key in knownargs.keys():
Peter Arrenbrecht
wireproto: fix handling of '*' args for HTTP and SSH
r13721 if key != 'cmd' and key not in keys:
Steven Brown
httprepo: long arguments support (issue2126)...
r14093 star[key] = knownargs[key][0]
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 data['*'] = star
else:
Steven Brown
httprepo: long arguments support (issue2126)...
r14093 data[k] = knownargs[k][0]
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 return [data[k] for k in keys]
Steven Brown
httprepo: long arguments support (issue2126)...
r14093 def _args(self):
args = self.req.form.copy()
chunks = []
Matt Mackall
http: minor tweaks to long arg handling...
r14094 i = 1
Martin Geisler
check-code: flag 0/1 used as constant Boolean expression
r14494 while True:
Matt Mackall
http: minor tweaks to long arg handling...
r14094 h = self.req.env.get('HTTP_X_HGARG_' + str(i))
Steven Brown
httprepo: long arguments support (issue2126)...
r14093 if h is None:
break
chunks += [h]
Matt Mackall
http: minor tweaks to long arg handling...
r14094 i += 1
Steven Brown
httprepo: long arguments support (issue2126)...
r14093 args.update(cgi.parse_qs(''.join(chunks), keep_blank_values=True))
return args
Dirkjan Ochtman
protocol: shuffle server methods to group send methods
r11621 def getfile(self, fp):
length = int(self.req.env['CONTENT_LENGTH'])
for s in util.filechunkiter(self.req, limit=length):
fp.write(s)
def redirect(self):
Idan Kamara
ui: use I/O descriptors internally...
r14614 self.oldio = self.ui.fout, self.ui.ferr
self.ui.ferr = self.ui.fout = cStringIO.StringIO()
def restore(self):
val = self.ui.fout.getvalue()
self.ui.ferr, self.ui.fout = self.oldio
return val
Dirkjan Ochtman
protocol: extract compression from streaming mechanics
r11623 def groupchunks(self, cg):
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 z = zlib.compressobj()
Martin Geisler
check-code: flag 0/1 used as constant Boolean expression
r14494 while True:
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 chunk = cg.read(4096)
if not chunk:
break
Dirkjan Ochtman
protocol: extract compression from streaming mechanics
r11623 yield z.compress(chunk)
yield z.flush()
Matt Mackall
protocol: move hgweb protocol support back into protocol.py...
r11595 def _client(self):
return 'remote:%s:%s:%s' % (
self.req.env.get('wsgi.url_scheme') or 'http',
urllib.quote(self.req.env.get('REMOTE_HOST', '')),
urllib.quote(self.req.env.get('REMOTE_USER', '')))
def iscmd(cmd):
return cmd in wireproto.commands
def call(repo, req, cmd):
Idan Kamara
ui: use I/O descriptors internally...
r14614 p = webproto(req, repo.ui)
Dirkjan Ochtman
protocol: wrap non-string protocol responses in classes
r11625 rsp = wireproto.dispatch(repo, p, cmd)
Dirkjan Ochtman
protocol: use generators instead of req.write() for hgweb stream responses
r11626 if isinstance(rsp, str):
Mads Kiilerich
hgweb: pass the actual response body to request.response, not just the length...
r18352 req.respond(HTTP_OK, HGTYPE, body=rsp)
return []
Dirkjan Ochtman
protocol: use generators instead of req.write() for hgweb stream responses
r11626 elif isinstance(rsp, wireproto.streamres):
req.respond(HTTP_OK, HGTYPE)
return rsp.gen
elif isinstance(rsp, wireproto.pushres):
Idan Kamara
ui: use I/O descriptors internally...
r14614 val = p.restore()
Mads Kiilerich
hgweb: use Content-Length for pushres...
r18346 rsp = '%d\n%s' % (rsp.res, val)
Mads Kiilerich
hgweb: pass the actual response body to request.response, not just the length...
r18352 req.respond(HTTP_OK, HGTYPE, body=rsp)
return []
Benoit Boissinot
wireproto: introduce pusherr() to deal with "unsynced changes" error...
r12703 elif isinstance(rsp, wireproto.pusherr):
Benoit Boissinot
wireproto/http: drain the incoming bundle in case of errors
r12704 # drain the incoming bundle
req.drain()
Idan Kamara
ui: use I/O descriptors internally...
r14614 p.restore()
Benoit Boissinot
wireproto: introduce pusherr() to deal with "unsynced changes" error...
r12703 rsp = '0\n%s\n' % rsp.res
Mads Kiilerich
hgweb: pass the actual response body to request.response, not just the length...
r18352 req.respond(HTTP_OK, HGTYPE, body=rsp)
return []
Andrew Pritchard
wireproto: add out-of-band error class to allow remote repo to report errors...
r15017 elif isinstance(rsp, wireproto.ooberror):
rsp = rsp.message
Mads Kiilerich
hgweb: pass the actual response body to request.response, not just the length...
r18352 req.respond(HTTP_OK, HGERRTYPE, body=rsp)
return []