mesonlib: Reimplement version comparison for speed

This commit is contained in:
Dylan Baker 2019-04-23 10:41:23 -07:00
parent c30ccae0b6
commit cbdf9d0647
1 changed files with 25 additions and 14 deletions

View File

@ -15,7 +15,6 @@
"""A library of random helper functionality.""" """A library of random helper functionality."""
from pathlib import Path from pathlib import Path
from typing import List from typing import List
import functools
import sys import sys
import stat import stat
import time import time
@ -506,7 +505,6 @@ def detect_vcs(source_dir):
return None return None
# a helper class which implements the same version ordering as RPM # a helper class which implements the same version ordering as RPM
@functools.total_ordering
class Version: class Version:
def __init__(self, s): def __init__(self, s):
self._s = s self._s = s
@ -527,7 +525,24 @@ class Version:
return '<Version: {}>'.format(self._s) return '<Version: {}>'.format(self._s)
def __lt__(self, other): def __lt__(self, other):
return self.__cmp__(other) == -1 if isinstance(other, Version):
return self.__cmp(other, operator.lt)
return NotImplemented
def __gt__(self, other):
if isinstance(other, Version):
return self.__cmp(other, operator.gt)
return NotImplemented
def __le__(self, other):
if isinstance(other, Version):
return self.__cmp(other, operator.le)
return NotImplemented
def __ge__(self, other):
if isinstance(other, Version):
return self.__cmp(other, operator.ge)
return NotImplemented
def __eq__(self, other): def __eq__(self, other):
if isinstance(other, Version): if isinstance(other, Version):
@ -539,25 +554,21 @@ class Version:
return self._v != other._v return self._v != other._v
return NotImplemented return NotImplemented
def __cmp__(self, other): def __cmp(self, other, comparator):
def cmp(a, b):
return (a > b) - (a < b)
# compare each sequence in order # compare each sequence in order
for ours, theirs in zip(self._v, other._v): for ours, theirs in zip(self._v, other._v):
# sort a non-digit sequence before a digit sequence # sort a non-digit sequence before a digit sequence
ours_is_int = isinstance(ours, int) ours_is_int = isinstance(ours, int)
if ours_is_int != isinstance(theirs, int): theirs_is_int = isinstance(theirs, int)
return 1 if ours_is_int else -1 if ours_is_int != theirs_is_int:
return comparator(ours_is_int, theirs_is_int)
# compare lexicographically if ours != theirs:
c = cmp(ours, theirs) return comparator(ours, theirs)
if c != 0:
return c
# if equal length, all components have matched, so equal # if equal length, all components have matched, so equal
# otherwise, the version with a suffix remaining is greater # otherwise, the version with a suffix remaining is greater
return cmp(len(self._v), len(other._v)) return comparator(len(self._v), len(other._v))
def _version_extract_cmpop(vstr2): def _version_extract_cmpop(vstr2):
if vstr2.startswith('>='): if vstr2.startswith('>='):