Mercurial > public > mercurial-scm > hg-stable
view mercurial/revlogutils/revlogv0.py @ 52009:609700e5d8df
head-revs: add a native implementation of the `stop_rev` parameter
This does not add too much complexity to the native code and help with
branchmap v3 performance.
Note that the final conversion of the heads from native-code to Python is still
too costly, especially in Rust. In addition the current caching around headrevs
is too simple and fragile. However these are an unrelated problem.
### benchmark.name = hg.command.unbundle
# bin-env-vars.hg.py-re2-module = default
# benchmark.variants.issue6528 = disabled
# benchmark.variants.resource-usage = default
# benchmark.variants.reuse-external-delta-parent = yes
# benchmark.variants.revs = any-1-extra-rev
# benchmark.variants.source = unbundle
# benchmark.variants.validate = default
# benchmark.variants.verbosity = quiet
## data-env-vars.name = netbeans-2018-08-01-zstd-sparse-revlog
# bin-env-vars.hg.flavor = default
branch-v2: 0.233711 ~~~~~
branch-v3 before: 0.239857 (+2.63%, +0.01)
branch-v3 after: 0.239558 (+2.50%, +0.01)
# bin-env-vars.hg.flavor = rust
branch-v2: 0.235230 ~~~~~
branch-v3 before: 0.240972 (+2.44%, +0.01)
branch-v3 after: 0.239917 (+1.99%, +0.00)
## data-env-vars.name = netbeans-2018-08-01-ds2-pnm
# bin-env-vars.hg.flavor = rust
branch-v2: 0.255586 ~~~~~
branch-v3 before: 0.268560 (+5.08%, +0.01)
branch-v3 after: 0.262261 (+2.61%, +0.01)
## data-env-vars.name = mozilla-central-2024-03-22-zstd-sparse-revlog
# bin-env-vars.hg.flavor = default
branch-v2: 0.339010 ~~~~~
branch-v3 before: 0.349389 (+3.06%, +0.01)
branch-v3 after: 0.348247 (+2.72%, +0.01)
# bin-env-vars.hg.flavor = rust
branch-v2: 0.346525 ~~~~~
branch-v3 before: 0.355661 (+2.64%, +0.01)
branch-v3 after: 0.350906 (+1.26%, +0.00)
## data-env-vars.name = mozilla-central-2024-03-22-ds2-pnm
# bin-env-vars.hg.flavor = rust
branch-v2: 0.380202 ~~~~~
branch-v3 before: 0.408851 (+7.54%, +0.03)
branch-v3 after: 0.406511 (+6.92%, +0.03)
## data-env-vars.name = mozilla-unified-2024-03-22-zstd-sparse-revlog
# bin-env-vars.hg.flavor = default
branch-v2: 0.412165 ~~~~~
branch-v3 before: 0.427782 (+3.79%, +0.02)
branch-v3 after: 0.422595 (+2.53%, +0.01)
# bin-env-vars.hg.flavor = rust
branch-v2: 0.412397 ~~~~~
branch-v3 before: 0.422354 (+2.41%, +0.01)
branch-v3 after: 0.421079 (+2.11%, +0.01)
## data-env-vars.name = mozilla-unified-2024-03-22-ds2-pnm
# bin-env-vars.hg.flavor = rust
branch-v2: 0.429501 ~~~~~
branch-v3 before: 0.443197 (+3.19%, +0.01)
branch-v3 after: 0.449432 (+4.64%, +0.02)
## data-env-vars.name = mozilla-try-2024-03-26-zstd-sparse-revlog
# bin-env-vars.hg.flavor = default
branch-v2: 3.403171 ~~~~~
branch-v3 before: 3.819477 (+12.23%, +0.42)
branch-v3 after: 3.658482 (+7.50%, +0.26)
# bin-env-vars.hg.flavor = rust
branch-v2: 3.454876 ~~~~~
branch-v3 before: 3.590284 (+3.92%, +0.14)
branch-v3 after: 3.545843 (+2.63%, +0.09)
## data-env-vars.name = mozilla-try-2024-03-26-ds2-pnm
# bin-env-vars.hg.flavor = rust
branch-v2: 3.465435 ~~~~~
branch-v3 before: 3.633278 (+4.84%, +0.17)
branch-v3 after: 3.556074 (+2.62%, +0.09)
author | Pierre-Yves David <pierre-yves.david@octobus.net> |
---|---|
date | Fri, 27 Sep 2024 03:55:40 +0200 |
parents | 22da1dc97281 |
children | 5cc8deb96b48 |
line wrap: on
line source
# revlogv0 - code related to revlog format "V0" # # Copyright 2005-2007 Olivia Mackall <olivia@selenic.com> # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. from __future__ import annotations from ..node import sha1nodeconstants from .constants import ( INDEX_ENTRY_V0, ) from ..i18n import _ from .. import ( error, node, revlogutils, util, ) from . import ( nodemap as nodemaputil, ) def getoffset(q): return int(q >> 16) def gettype(q): return int(q & 0xFFFF) class revlogoldindex(list): rust_ext_compat = 0 entry_size = INDEX_ENTRY_V0.size null_item = revlogutils.entry( data_offset=0, data_compressed_length=0, data_delta_base=node.nullrev, link_rev=node.nullrev, parent_rev_1=node.nullrev, parent_rev_2=node.nullrev, node_id=sha1nodeconstants.nullid, ) @util.propertycache def _nodemap(self): nodemap = nodemaputil.NodeMap({sha1nodeconstants.nullid: node.nullrev}) for r in range(0, len(self)): n = self[r][7] nodemap[n] = r return nodemap def has_node(self, node): """return True if the node exist in the index""" return node in self._nodemap def rev(self, node): """return a revision for a node If the node is unknown, raise a RevlogError""" return self._nodemap[node] def get_rev(self, node): """return a revision for a node If the node is unknown, return None""" return self._nodemap.get(node) def append(self, tup): self._nodemap[tup[7]] = len(self) super(revlogoldindex, self).append(tup) def __delitem__(self, i): if not isinstance(i, slice) or not i.stop == -1 or i.step is not None: raise ValueError(b"deleting slices only supports a:-1 with step 1") for r in range(i.start, len(self)): del self._nodemap[self[r][7]] super(revlogoldindex, self).__delitem__(i) def clearcaches(self): self.__dict__.pop('_nodemap', None) def __getitem__(self, i): if i == -1: return self.null_item return list.__getitem__(self, i) def pack_header(self, header): """pack header information in binary""" return b'' def entry_binary(self, rev): """return the raw binary string representing a revision""" entry = self[rev] if gettype(entry[0]): raise error.RevlogError( _(b'index entry flags need revlog version 1') ) e2 = ( getoffset(entry[0]), entry[1], entry[3], entry[4], self[entry[5]][7], self[entry[6]][7], entry[7], ) return INDEX_ENTRY_V0.pack(*e2) def headrevs(self, excluded_revs=None, stop_rev=None): count = len(self) if stop_rev is not None: count = min(count, stop_rev) if not count: return [node.nullrev] # we won't iter over filtered rev so nobody is a head at start ishead = [0] * (count + 1) revs = range(count) if excluded_revs is not None: revs = (r for r in revs if r not in excluded_revs) for r in revs: ishead[r] = 1 # I may be an head e = self[r] ishead[e[5]] = ishead[e[6]] = 0 # my parent are not return [r for r, val in enumerate(ishead) if val] def parse_index_v0(data, inline): s = INDEX_ENTRY_V0.size index = [] nodemap = nodemaputil.NodeMap({node.nullid: node.nullrev}) n = off = 0 l = len(data) while off + s <= l: cur = data[off : off + s] off += s e = INDEX_ENTRY_V0.unpack(cur) # transform to revlogv1 format e2 = revlogutils.entry( data_offset=e[0], data_compressed_length=e[1], data_delta_base=e[2], link_rev=e[3], parent_rev_1=nodemap.get(e[4], node.nullrev), parent_rev_2=nodemap.get(e[5], node.nullrev), node_id=e[6], ) index.append(e2) nodemap[e[6]] = n n += 1 index = revlogoldindex(index) return index, None