localrepo: cache types for filtered repos (issue5043)
Python introduces a reference cycle on dynamically created types
via __mro__, making them very easy to leak. See
https://bugs.python.org/issue17950.
Previously, repo.filtered() created a type on every invocation.
Long-running processes (like `hg convert`) could call this
function thousands of times, leading to a steady memory leak.
Since we're Unable to stop the leak because this is a bug in
Python, the next best thing is to contain it.
This patch adds a cache of of the dynamically generated repoview/filter
types on the localrepo object. Since we only generate each type
once, we cap the amount of memory that can leak to something
reasonable.
After this change, `hg convert` no longer leaks memory on every
revision. The process will likely grow memory usage over time due
to e.g. larger manifests. But there are no leaks.
Our full contribution guidelines are in our wiki, please see:
https://www.mercurial-scm.org/wiki/ContributingChanges
If you just want a checklist to follow, you can go straight to
https://www.mercurial-scm.org/wiki/ContributingChanges#Submission_checklist
If you can't run the entire testsuite for some reason (it can be
difficult on Windows), please at least run `contrib/check-code.py` on
any files you've modified and run `python contrib/check-commit` on any
commits you've made (for example, `python contrib/check-commit
273ce12ad8f1` will report some style violations on a very old commit).