sapling/mercurial
Yuya Nishihara 44aa43c0dc revset: add depth limit to descendants() (issue5374)
This is naive implementation using two-pass scanning. Tracking descendants
isn't an easy problem if both start and stop depths are specified. It's
impractical to remember all possible depths of each node while scanning from
roots to descendants because the number of depths explodes. Instead, we could
cache (min, max) depths as a good approximation and track ancestors back when
needed, but that's likely to have off-by-one bug.

Since this implementation appears not significantly slower, and is quite
straightforward, I think it's good enough for practical use cases. The time
and space complexity is O(n) ish.

  revisions:
  0) 1-pass scanning with (min, max)-depth cache (worst-case quadratic)
  1) 2-pass scanning (this version)

  repository:
  mozilla-central

  # descendants(0) (for reference)
  *) 0.430353

  # descendants(0, depth=1000)
  0) 0.264889
  1) 0.398289

  # descendants(limit(tip:0, 1, offset=10000), depth=1000)
  0) 0.025478
  1) 0.029099

  # descendants(0, depth=2000, startdepth=1000)
  0) painfully slow (due to quadratic backtracking of ancestors)
  1) 1.531138
2017-06-24 23:05:57 +09:00
..
cext cext: mark constant variables 2017-05-21 13:41:01 +09:00
cffi cffi: remove superfluous "if True" blocks 2017-05-02 21:45:10 +09:00
default.d mergetools.rc: find OSX FileMerge in the new location inside Xcode 4.3 2015-10-16 11:37:34 +02:00
help formatter: add support for parts map of [templates] section 2017-04-22 21:29:00 +09:00
hgweb hgweb: plug followlines action in annotate view 2017-06-21 17:17:17 +02:00
httpclient httpclient: update to 54868ef054d2 of httpplus 2016-06-27 11:53:50 -04:00
pure cffi: split modules from pure 2017-05-02 21:15:31 +09:00
templates show: show all namespaces in "work" view 2017-06-24 15:11:05 -07:00
__init__.py py3: add pycompat.unicode and add it to importer 2017-04-07 23:35:51 +05:30
ancestor.py cleanup: use set literals 2017-02-10 16:56:29 -08:00
archival.py py3: remove use of *L syntax 2016-09-01 02:29:46 +05:30
bdiff.c bdiff: split bdiff into cpy-aware and cpy-agnostic part 2016-07-13 10:46:26 +02:00
bdiff.h bdiff: split bdiff into cpy-aware and cpy-agnostic part 2016-07-13 10:46:26 +02:00
bitmanipulation.h bitmanipulation: add missing include of string.h 2017-06-02 10:32:39 -07:00
bookmarks.py bookmarks: factor method _printer out of for loop in printbookmarks 2017-06-20 17:18:20 -07:00
branchmap.py branchmap: remove use of buffer() to support Python 2.6 2017-05-13 11:58:08 -07:00
bundle2.py bundle: inline applybundle1() 2017-06-22 21:45:32 -07:00
bundlerepo.py bundlerepo: fix raw handling in revision() 2017-04-06 17:45:47 -07:00
byterange.py pycompat: switch to util.urlreq/util.urlerr for py3 compat 2016-04-06 23:22:12 +00:00
changegroup.py bundle: move combineresults() from changegroup to bundle2 2017-06-22 13:58:20 -07:00
changelog.py revlog: make 'storedeltachains' a "public" attribute 2016-10-14 02:25:08 +02:00
chgserver.py pager: set some environment variables if they're not set 2017-04-13 08:27:19 -07:00
cmdutil.py cmdutil: use named arguments for changeset_templater.__init__ 2017-06-24 11:47:26 -07:00
color.py color: special case 'always' in 'ui.color' 2017-05-02 20:19:09 +02:00
commands.py identify: rename 'changed' keyword -> 'dirty' 2017-06-25 17:46:35 -04:00
commandserver.py commandserver: move printbanner logic to bindsocket 2017-04-30 11:21:05 -07:00
compat.h compat: define ssize_t as int on 32bit Windows, silences C4142 warning 2016-07-15 23:54:56 +09:00
config.py config: make config.items() return a copy 2017-05-18 13:38:37 -07:00
configitems.py configitems: register 'ui.interactive' 2017-06-23 17:19:29 +02:00
context.py py3: add utility to forward __str__() to __bytes__() 2017-06-24 13:48:04 +09:00
copies.py py3: use dict.update() instead of constructing lists and adding them 2017-06-01 01:14:02 +05:30
crecord.py patch: rewrite reversehunks (issue5337) 2017-06-20 23:22:38 -07:00
dagop.py revset: add depth limit to descendants() (issue5374) 2017-06-24 23:05:57 +09:00
dagparser.py error: get Abort from 'error' instead of 'util' 2015-10-08 12:55:45 -07:00
dagutil.py dagutil: use absolute_import 2015-08-08 19:04:09 -07:00
debugcommands.py debugrevlog: align chain length, reach, and compression ratio 2017-06-26 22:27:34 +09:00
destutil.py update: show the commit to which we updated in case of multiple heads (BC) 2017-06-06 22:17:39 +05:30
dirstate.py filestat: move __init__ to frompath constructor 2017-06-10 14:09:54 -07:00
dirstateguard.py dirstateguard: move to new module so I can break some layering violations 2016-11-21 21:29:32 -05:00
discovery.py checkheads: use a "lazyancestors" object for allfuturecommon 2017-06-05 13:44:15 +01:00
dispatch.py dispatch: remove unused _loaded 2017-06-24 02:39:21 +09:00
dummycert.pem ssl: on OS X, use a dummy cert to trick Python/OpenSSL to use system CA certs 2014-09-26 02:19:48 +02:00
encoding.py py3: add utility to forward __str__() to __bytes__() 2017-06-24 13:48:04 +09:00
error.py error: rename RichIOError to PeerTransportError 2017-04-16 11:12:37 -07:00
exchange.py bundle: make applybundle() delegate v1 bundles to applybundle1() 2017-06-22 15:00:19 -07:00
exewrapper.c exewrapper: add .dll to LoadLibrary() argument 2016-04-27 09:23:39 -07:00
extensions.py extensions: register functions always at loading extension (issue5601) 2017-06-24 02:39:20 +09:00
fancyopts.py cleanup: use set literals 2017-02-10 16:56:29 -08:00
filelog.py filelog: fix parsemeta docstring 2017-05-02 22:39:14 -07:00
filemerge.py templater: add simple interface for unnamed template (API) 2017-04-22 19:56:47 +09:00
fileset.py py3: use pycompat.bytestr so that we don't get ascii values 2017-05-29 16:21:15 +05:30
formatter.py formatter: add support for parts map of [templates] section 2017-04-22 21:29:00 +09:00
graphmod.py dagop: split module hosting DAG-related algorithms from revset 2016-10-16 18:03:24 +09:00
hbisect.py bisect: move check_state into the bisect module 2016-08-24 04:25:20 +02:00
help.py help: explain how to access subtopics in internals 2017-04-19 17:04:22 -07:00
hg.py py3: check for bytes instead of str in isinstance 2017-06-22 03:20:11 +05:30
hook.py py3: convert keys of kwargs back to bytes using pycompat.byteskwargs() 2017-06-17 15:29:26 +05:30
httpconnection.py httpconnection: allow a global auth.cookiefile config entry 2017-03-09 22:35:10 -08:00
httppeer.py httppeer: unify hint message for PeerTransportError 2017-05-01 05:52:36 +09:00
i18n.py i18n: make the locale directory name the same string type as the datapath 2016-10-08 05:26:18 -04:00
keepalive.py keepalive: send HTTP request headers in a deterministic order 2017-04-13 18:04:38 -07:00
localrepo.py py3: use '%d' instead of '%s' for integers 2017-06-17 14:53:25 +05:30
lock.py lock: avoid unintentional lock acquisition at failure of readlock 2017-05-01 19:59:13 +09:00
lsprof.py lsprof: use print function 2016-01-02 11:40:53 -08:00
lsprofcalltree.py lsprofcalltree: use print function 2016-01-02 11:45:29 -08:00
mail.py mail: handle renamed email.Header 2016-10-07 17:30:11 +02:00
manifest.py treemanifest: add walksubtrees api 2017-04-10 13:07:47 -07:00
match.py match: allow pats to be None 2017-06-08 22:18:17 -07:00
mdiff.py mdiff: add a hunkinrange helper function 2017-04-01 12:24:59 +02:00
merge.py py3: replace dict.iterkeys() with iter(dict) 2017-06-16 01:46:47 +05:30
mergeutil.py checkunresolved: move to new package to help avoid import cycles 2016-11-21 21:31:45 -05:00
minirst.py minirst: look for column delimiters using slices instead of indicies 2017-05-28 15:47:43 -04:00
mpatch.c internals: move the bitmanipulation routines into its own file 2016-06-06 13:08:13 +02:00
mpatch.h mpatch: raise MemoryError instead of mpatchError if lalloc() failed 2016-08-07 10:06:56 +09:00
namespaces.py namespaces: record and expose whether namespace is built-in 2017-06-24 14:52:15 -07:00
node.py revlog: add support for partial matching of wdir node id 2016-08-19 18:26:04 +09:00
obsolete.py obsolete: use ProgrammingError over assert for volatile set registration 2017-05-01 05:57:36 +02:00
obsutil.py template: add predecessors template 2017-06-15 13:02:58 +02:00
parser.py parser: preserve order of keyword arguments 2017-04-09 11:58:27 +09:00
patch.py configitems: register 'patch.fuzz' as first example for 'configint' 2017-06-17 13:17:10 +02:00
pathutil.py util: rename checkcase() to fscasesensitive() (API) 2016-08-30 09:22:53 -07:00
peer.py py3: convert to next() function 2016-05-16 21:30:53 +00:00
phases.py bundle: add config option to include phases 2017-06-22 10:10:02 -07:00
policy.py policy: remove unused policynoc and policynocffi constants 2017-05-02 21:45:48 +09:00
posix.py chmod: create a new file when flags are set on a hardlinked file 2017-04-26 16:05:22 +02:00
profiling.py profiling: cope with configwith default value handling changes 2017-06-21 10:46:18 +02:00
progress.py progress: retry ferr.flush() and .write() on EINTR (issue5532) 2017-04-13 22:31:17 +09:00
pushkey.py pushkey: use absolute_import 2015-08-08 19:57:27 -07:00
pvec.py base85: proxy through util module 2017-04-26 21:56:47 +09:00
pycompat.py pycompat: move the queue related definitions below queue import 2017-06-16 03:01:22 +05:30
rcutil.py pager: use less as a fallback on Unix 2017-04-28 20:51:14 +09:00
registrar.py registrar: unindent superfluous "if True" block 2017-05-08 22:14:56 +09:00
repair.py bundle: transpose transaction scope with bundle type switch 2017-06-22 21:27:57 -07:00
repoview.py repoview: remove special casing of "requirements" 2017-06-08 20:28:13 -07:00
revlog.py py3: catch binascii.Error raised from binascii.unhexlify 2017-06-20 22:11:46 +05:30
revset.py revset: add depth limit to descendants() (issue5374) 2017-06-24 23:05:57 +09:00
revsetlang.py revsetlang: check arguments passed to ancestors() before optimizing to only() 2017-06-18 11:57:28 +09:00
scmposix.py pager: use less as a fallback on Unix 2017-04-28 20:51:14 +09:00
scmutil.py lock: avoid unintentional lock acquisition at failure of readlock 2017-05-01 19:59:13 +09:00
scmwindows.py pager: use less as a fallback on Unix 2017-04-28 20:51:14 +09:00
server.py serve: add support for Mercurial subrepositories 2017-04-15 18:05:40 -04:00
setdiscovery.py setdiscovery: improves logged message 2017-06-10 18:47:09 +01:00
similar.py similar: remove caching from the module level 2017-01-13 11:42:36 -08:00
simplemerge.py py3: convert kwargs' keys' to str using pycompat.strkwargs() 2017-06-22 03:16:16 +05:30
smartset.py smartset: fix default value of abstractsmartset.sort() 2017-06-25 00:14:48 +09:00
sshpeer.py sshpeer: try harder to snag stderr when stdout closes unexpectedly 2017-04-13 16:09:40 -04:00
sshserver.py wireproto: compress data from a generator 2016-10-16 11:10:21 -07:00
sslutil.py sslutil: reference fingerprints config option properly (issue5559) 2017-05-08 09:30:26 -07:00
statichttprepo.py localrepo: move filtername to __init__ 2017-06-08 23:23:37 -07:00
statprof.py statprof: require input file 2017-01-18 22:45:07 -08:00
store.py store: py26 compat, don't use a dict comprehension 2016-10-09 12:58:22 +02:00
streamclone.py streamclone: consider secret changesets (BC) (issue5589) 2017-06-09 10:41:13 -07:00
subrepo.py subrepo: move prompts out of the if (issue5505) 2017-03-20 04:36:55 -07:00
tagmerge.py tagmerge: use 'wvfs' instead of 'wfile' 2017-03-15 00:28:58 -07:00
tags.py track-tags: write all tag changes to a file 2017-03-28 10:15:02 +02:00
templatefilters.py json: pass formatting options recursively 2017-06-09 21:33:15 +09:00
templatekw.py namespaces: record and expose whether namespace is built-in 2017-06-24 14:52:15 -07:00
templater.py py3: convert kwargs' keys' to str using pycompat.strkwargs() 2017-06-22 03:16:16 +05:30
transaction.py rebase: clean up rebasestate from active transaction 2017-06-24 21:13:48 -07:00
treediscovery.py error: get Abort from 'error' instead of 'util' 2015-10-08 12:55:45 -07:00
txnutil.py txnutil: factor out the logic to read file in according to HG_PENDING 2017-02-21 01:20:59 +09:00
ui.py config: use '_config' within 'configbytes' 2017-06-25 14:41:12 +02:00
unionrepo.py revlog: add 'raw' argument to revision and _addrevision 2017-01-05 17:16:07 +00:00
upgrade.py upgrade: register all format variants in a list 2017-04-12 16:48:13 +02:00
url.py url: support auth.cookiesfile for adding cookies to HTTP requests 2017-03-09 22:40:52 -08:00
util.py py3: add utility to forward __str__() to __bytes__() 2017-06-24 13:48:04 +09:00
verify.py verify: add a config option to skip certain flag processors 2017-05-14 09:38:06 -07:00
vfs.py filestat: move __init__ to frompath constructor 2017-06-10 14:09:54 -07:00
win32.py win32: add a method to enable ANSI color code processing on Windows 10 2017-05-22 22:00:56 -04:00
windows.py windows: do not close stdout on flush() failure 2017-06-05 23:36:35 +09:00
wireproto.py wireproto: update reference to deleted addchangegroup() 2017-06-16 09:37:22 -07:00
worker.py worker: propagate exit code to main process 2017-04-15 13:27:44 +09:00