PageRenderTime 40ms CodeModel.GetById 11ms RepoModel.GetById 1ms app.codeStats 0ms

/rpython/rlib/rweaklist.py

https://bitbucket.org/halgari/pypy
Python | 60 lines | 41 code | 10 blank | 9 comment | 8 complexity | f51e180c94cbfdf9c2889a3de2376e8f MD5 | raw file
Possible License(s): BSD-3-Clause, Apache-2.0, AGPL-3.0
  1. import weakref
  2. from rpython.rlib.rweakref import dead_ref
  3. def _reduced_value(s):
  4. while True:
  5. divide = s & 1
  6. s >>= 1
  7. if not divide:
  8. return s
  9. class RWeakListMixin(object):
  10. _mixin_ = True
  11. def initialize(self):
  12. self.handles = []
  13. self.look_distance = 0
  14. def get_all_handles(self):
  15. return self.handles
  16. def reserve_next_handle_index(self):
  17. # The reservation ordering done here is tweaked for pypy's
  18. # memory allocator. We look from index 'look_distance'.
  19. # Look_distance increases from 0. But we also look at
  20. # "look_distance/2" or "/4" or "/8", etc. If we find that one
  21. # of these secondary locations is free, we assume it's because
  22. # there was recently a minor collection; so we reset
  23. # look_distance to 0 and start again from the lowest locations.
  24. length = len(self.handles)
  25. for d in range(self.look_distance, length):
  26. if self.handles[d]() is None:
  27. self.look_distance = d + 1
  28. return d
  29. s = _reduced_value(d)
  30. if self.handles[s]() is None:
  31. break
  32. # restart from the beginning
  33. for d in range(0, length):
  34. if self.handles[d]() is None:
  35. self.look_distance = d + 1
  36. return d
  37. # full! extend, but don't use '+=' here
  38. self.handles = self.handles + [dead_ref] * (length // 3 + 5)
  39. self.look_distance = length + 1
  40. return length
  41. def add_handle(self, content):
  42. index = self.reserve_next_handle_index()
  43. self.store_handle(index, content)
  44. return index
  45. def store_handle(self, index, content):
  46. self.handles[index] = weakref.ref(content)
  47. def fetch_handle(self, index):
  48. if 0 <= index < len(self.handles):
  49. return self.handles[index]()
  50. return None