comparison mercurial/revset.py @ 22692:78c916f24dd9

revset: introduce an abstractsmartset class This class documents all methods required by a smartset. This makes it easier for people to respect the API and ensure we fail loudly when something does not. It will later also contain common default implementations for multiple methods, making it easier to have smartset classes with minimal work.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Wed, 01 Oct 2014 15:14:36 -0500
parents d8a08b68f754
children 093df3b77f27
comparison
equal deleted inserted replaced
22691:d8a08b68f754 22692:78c916f24dd9
2193 funcs |= funcsused(s) 2193 funcs |= funcsused(s)
2194 if tree[0] == 'func': 2194 if tree[0] == 'func':
2195 funcs.add(tree[1][1]) 2195 funcs.add(tree[1][1])
2196 return funcs 2196 return funcs
2197 2197
2198 class baseset(list): 2198 class abstractsmartset(object):
2199
2200 def __nonzero__(self):
2201 """True if the smartset is not empty"""
2202 raise NotImplementedError()
2203
2204 def __contains__(self, rev):
2205 """provide fast membership testing"""
2206 raise NotImplementedError()
2207
2208 def __set__(self):
2209 """Returns a set or a smartset containing all the elements.
2210
2211 The returned structure should be the fastest option for membership
2212 testing.
2213
2214 This is part of the mandatory API for smartset."""
2215 raise NotImplementedError()
2216
2217 def __iter__(self):
2218 """iterate the set in the order it is supposed to be iterated"""
2219 raise NotImplementedError()
2220
2221 def isascending(self):
2222 """True if the set will iterate in ascending order"""
2223 raise NotImplementedError()
2224
2225 def ascending(self):
2226 """Sorts the set in ascending order (in place).
2227
2228 This is part of the mandatory API for smartset."""
2229 raise NotImplementedError()
2230
2231 def isdescending(self):
2232 """True if the set will iterate in descending order"""
2233 raise NotImplementedError()
2234
2235 def descending(self):
2236 """Sorts the set in descending order (in place).
2237
2238 This is part of the mandatory API for smartset."""
2239 raise NotImplementedError()
2240
2241 def min(self):
2242 """return the minimum element in the set"""
2243 raise NotImplementedError()
2244
2245 def max(self):
2246 """return the maximum element in the set"""
2247 raise NotImplementedError()
2248
2249 def reverse(self):
2250 """reverse the expected iteration order"""
2251 raise NotImplementedError()
2252
2253 def sort(self, reverse=True):
2254 """get the set to iterate in an ascending or descending order"""
2255 raise NotImplementedError()
2256
2257 def __and__(self, other):
2258 """Returns a new object with the intersection of the two collections.
2259
2260 This is part of the mandatory API for smartset."""
2261 raise NotImplementedError()
2262
2263 def __add__(self, other):
2264 """Returns a new object with the union of the two collections.
2265
2266 This is part of the mandatory API for smartset."""
2267 raise NotImplementedError()
2268
2269 def __sub__(self, other):
2270 """Returns a new object with the substraction of the two collections.
2271
2272 This is part of the mandatory API for smartset."""
2273 raise NotImplementedError()
2274
2275 def filter(self, condition):
2276 """Returns this smartset filtered by condition as a new smartset.
2277
2278 `condition` is a callable which takes a revision number and returns a
2279 boolean.
2280
2281 This is part of the mandatory API for smartset."""
2282 raise NotImplementedError()
2283
2284 class baseset(list, abstractsmartset):
2199 """Basic data structure that represents a revset and contains the basic 2285 """Basic data structure that represents a revset and contains the basic
2200 operation that it should be able to perform. 2286 operation that it should be able to perform.
2201 2287
2202 Every method in this class should be implemented by any smartset class. 2288 Every method in this class should be implemented by any smartset class.
2203 """ 2289 """
2318 """return the largest element in the set""" 2404 """return the largest element in the set"""
2319 if self.isascending(): 2405 if self.isascending():
2320 return self._last() 2406 return self._last()
2321 return self._first() 2407 return self._first()
2322 2408
2323 class lazyset(object): 2409 class lazyset(abstractsmartset):
2324 """Duck type for baseset class which iterates lazily over the revisions in 2410 """Duck type for baseset class which iterates lazily over the revisions in
2325 the subset and contains a function which tests for membership in the 2411 the subset and contains a function which tests for membership in the
2326 revset 2412 revset
2327 """ 2413 """
2328 def __init__(self, subset, condition=lambda x: True): 2414 def __init__(self, subset, condition=lambda x: True):
2752 if start is None and end is None: 2838 if start is None and end is None:
2753 return fullreposet(repo) 2839 return fullreposet(repo)
2754 return _spanset(repo, start, end) 2840 return _spanset(repo, start, end)
2755 2841
2756 2842
2757 class _spanset(_orderedsetmixin): 2843 class _spanset(_orderedsetmixin, abstractsmartset):
2758 """Duck type for baseset class which represents a range of revisions and 2844 """Duck type for baseset class which represents a range of revisions and
2759 can work lazily and without having all the range in memory 2845 can work lazily and without having all the range in memory
2760 2846
2761 Note that spanset(x, y) behave almost like xrange(x, y) except for two 2847 Note that spanset(x, y) behave almost like xrange(x, y) except for two
2762 notable points: 2848 notable points: