diff mercurial/util.py @ 23495:b25f07cb5399

util: add a 'nogc' decorator to disable the garbage collection Garbage collection behave pathologically when creating a lot of containers. As we do that more than once it become sensible to have a decorator for it. See inline documentation for details.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Thu, 04 Dec 2014 05:43:40 -0800
parents 46265d0f0c7b
children 4dd8a6a1240d
line wrap: on
line diff
--- a/mercurial/util.py	Fri Dec 05 22:58:02 2014 -0500
+++ b/mercurial/util.py	Thu Dec 04 05:43:40 2014 -0800
@@ -20,6 +20,7 @@
 import re as remod
 import os, time, datetime, calendar, textwrap, signal, collections
 import imp, socket, urllib
+import gc
 
 if os.name == 'nt':
     import windows as platform
@@ -544,6 +545,28 @@
 def never(fn):
     return False
 
+def nogc(func):
+    """disable garbage collector
+
+    Python's garbage collector triggers a GC each time a certain number of
+    container objects (the number being defined by gc.get_threshold()) are
+    allocated even when marked not to be tracked by the collector. Tracking has
+    no effect on when GCs are triggered, only on what objects the GC looks
+    into. As a workaround, disable GC while building complexe (huge)
+    containers.
+
+    This garbage collector issue have been fixed in 2.7.
+    """
+    def wrapper(*args, **kwargs):
+        gcenabled = gc.isenabled()
+        gc.disable()
+        try:
+            return func(*args, **kwargs)
+        finally:
+            if gcenabled:
+                gc.enable()
+    return wrapper
+
 def pathto(root, n1, n2):
     '''return the relative path from one place to another.
     root should use os.sep to separate directories