aboutsummaryrefslogtreecommitdiffstats
path: root/python/gevent/_ident.py
diff options
context:
space:
mode:
authorJames Taylor <user234683@users.noreply.github.com>2018-09-14 19:32:27 -0700
committerJames Taylor <user234683@users.noreply.github.com>2018-09-14 19:32:27 -0700
commit4212164e91ba2f49583cf44ad623a29b36db8f77 (patch)
tree47aefe3c0162f03e0c823b43873356f69c1cd636 /python/gevent/_ident.py
parent6ca20ff7010f2bafc7fefcb8cad982be27a8aeae (diff)
downloadyt-local-4212164e91ba2f49583cf44ad623a29b36db8f77.tar.lz
yt-local-4212164e91ba2f49583cf44ad623a29b36db8f77.tar.xz
yt-local-4212164e91ba2f49583cf44ad623a29b36db8f77.zip
Windows: Use 32-bit distribution of python
Diffstat (limited to 'python/gevent/_ident.py')
-rw-r--r--python/gevent/_ident.py84
1 files changed, 84 insertions, 0 deletions
diff --git a/python/gevent/_ident.py b/python/gevent/_ident.py
new file mode 100644
index 0000000..56a28df
--- /dev/null
+++ b/python/gevent/_ident.py
@@ -0,0 +1,84 @@
+# -*- coding: utf-8 -*-
+# Copyright 2018 gevent contributors. See LICENSE for details.
+# cython: auto_pickle=False,embedsignature=True,always_allow_keywords=False
+
+from __future__ import absolute_import
+from __future__ import division
+from __future__ import print_function
+
+
+from weakref import WeakKeyDictionary
+from weakref import ref
+
+from heapq import heappop
+from heapq import heappush
+
+__all__ = [
+ 'IdentRegistry',
+]
+
+class ValuedWeakRef(ref):
+ """
+ A weak ref with an associated value.
+ """
+ # This seems entirely spurious; even on Python 2.7
+ # weakref.ref descends from object
+ # pylint: disable=slots-on-old-class
+ __slots__ = ('value',)
+
+
+class IdentRegistry(object):
+ """
+ Maintains a unique mapping of (small) positive integer identifiers
+ to objects that can be weakly referenced.
+
+ It is guaranteed that no two objects will have the the same
+ identifier at the same time, as long as those objects are
+ also uniquely hashable.
+ """
+
+ def __init__(self):
+ # {obj -> (ident, wref(obj))}
+ self._registry = WeakKeyDictionary()
+
+ # A heap of numbers that have been used and returned
+ self._available_idents = []
+
+ def get_ident(self, obj):
+ """
+ Retrieve the identifier for *obj*, creating one
+ if necessary.
+ """
+
+ try:
+ return self._registry[obj][0]
+ except KeyError:
+ pass
+
+ if self._available_idents:
+ # Take the smallest free number
+ ident = heappop(self._available_idents)
+ else:
+ # Allocate a bigger one
+ ident = len(self._registry)
+
+ vref = ValuedWeakRef(obj, self._return_ident)
+ vref.value = ident # pylint:disable=assigning-non-slot,attribute-defined-outside-init
+ self._registry[obj] = (ident, vref)
+ return ident
+
+ def _return_ident(self, vref):
+ # By the time this is called, self._registry has been
+ # updated
+ if heappush is not None:
+ # Under some circumstances we can get called
+ # when the interpreter is shutting down, and globals
+ # aren't available any more.
+ heappush(self._available_idents, vref.value)
+
+ def __len__(self):
+ return len(self._registry)
+
+
+from gevent._util import import_c_accel
+import_c_accel(globals(), 'gevent.__ident')