This is an archive of the discontinued Mercurial Phabricator instance.

smartset: split generatorset classes to avoid cycle
ClosedPublic

Authored by indygreg on Dec 27 2017, 1:25 PM.

Details

Summary

I uncovered a cycle manifesting in a memory leak by running
hgperfrevset '::tip'. The cycle was due to generatorset.init
assigning a bound method to self.contains. Internet sleuthing
revealed that assigning a bound method to an instance attribute
always creates a cycle.

This commit creates two new variants of generatorset for the special
cases of ascending and descending generators. The special
implementations of contains have been extracted to these classes
where they are defined as contains.

generatorset now implements new and changes the spawned type to
one of the new classes if needed.

Diff Detail

Repository
rHG Mercurial
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

indygreg created this revision.Dec 27 2017, 1:25 PM
quark accepted this revision.Dec 27 2017, 2:13 PM
quark added a subscriber: quark.
quark added inline comments.
mercurial/smartset.py
817

@staticmethod could be a simpler way to break cycles.

yuja accepted this revision.Dec 28 2017, 7:24 AM
yuja added a subscriber: yuja.

Queued, thanks. I've made asc/desc classes private as their constructor
behavior is weird.

@staticmethod could be a simpler way to break cycles.

Subclassing is a better tool in this case since we want to override __contains__,
which can't be replaced by __dict__['__contains__'].

This revision is now accepted and ready to land.Dec 28 2017, 7:24 AM
This revision was automatically updated to reflect the committed changes.