You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

py.py 1.7KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. from __future__ import absolute_import, division, unicode_literals
  2. from pip._vendor.six import text_type
  3. from bisect import bisect_left
  4. from ._base import Trie as ABCTrie
  5. class Trie(ABCTrie):
  6. def __init__(self, data):
  7. if not all(isinstance(x, text_type) for x in data.keys()):
  8. raise TypeError("All keys must be strings")
  9. self._data = data
  10. self._keys = sorted(data.keys())
  11. self._cachestr = ""
  12. self._cachepoints = (0, len(data))
  13. def __contains__(self, key):
  14. return key in self._data
  15. def __len__(self):
  16. return len(self._data)
  17. def __iter__(self):
  18. return iter(self._data)
  19. def __getitem__(self, key):
  20. return self._data[key]
  21. def keys(self, prefix=None):
  22. if prefix is None or prefix == "" or not self._keys:
  23. return set(self._keys)
  24. if prefix.startswith(self._cachestr):
  25. lo, hi = self._cachepoints
  26. start = i = bisect_left(self._keys, prefix, lo, hi)
  27. else:
  28. start = i = bisect_left(self._keys, prefix)
  29. keys = set()
  30. if start == len(self._keys):
  31. return keys
  32. while self._keys[i].startswith(prefix):
  33. keys.add(self._keys[i])
  34. i += 1
  35. self._cachestr = prefix
  36. self._cachepoints = (start, i)
  37. return keys
  38. def has_keys_with_prefix(self, prefix):
  39. if prefix in self._data:
  40. return True
  41. if prefix.startswith(self._cachestr):
  42. lo, hi = self._cachepoints
  43. i = bisect_left(self._keys, prefix, lo, hi)
  44. else:
  45. i = bisect_left(self._keys, prefix)
  46. if i == len(self._keys):
  47. return False
  48. return self._keys[i].startswith(prefix)