hashindex.pyx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. # -*- coding: utf-8 -*-
  2. cdef extern from "hashindex.h":
  3. ctypedef struct HashIndex:
  4. pass
  5. HashIndex *hashindex_open(char *path)
  6. HashIndex *hashindex_create(char *path, int capacity, int key_size, int value_size)
  7. int hashindex_get_size(HashIndex *index)
  8. void hashindex_close(HashIndex *index)
  9. void hashindex_flush(HashIndex *index)
  10. void *hashindex_get(HashIndex *index, void *key)
  11. void *hashindex_next_key(HashIndex *index, void *key)
  12. void hashindex_delete(HashIndex *index, void *key)
  13. void hashindex_set(HashIndex *index, void *key, void *value)
  14. cdef class IndexBase:
  15. cdef HashIndex *index
  16. def __cinit__(self, path):
  17. self.index = hashindex_open(path)
  18. if not self.index:
  19. raise Exception('Failed to open %s' % path)
  20. def __dealloc__(self):
  21. hashindex_close(self.index)
  22. def flush(self):
  23. hashindex_flush(self.index)
  24. def setdefault(self, key, value):
  25. if not key in self:
  26. self[key] = value
  27. def pop(self, key):
  28. value = self[key]
  29. del self[key]
  30. return value
  31. def __len__(self):
  32. return hashindex_get_size(self.index)
  33. cdef class NSIndex(IndexBase):
  34. @classmethod
  35. def create(cls, path, capacity=16):
  36. index = hashindex_create(path, capacity, 32, 8)
  37. hashindex_close(index)
  38. return cls(path)
  39. def __getitem__(self, key):
  40. assert len(key) == 32
  41. data = <int *>hashindex_get(self.index, <char *>key)
  42. if not data:
  43. raise KeyError
  44. return data[0], data[1]
  45. def __delitem__(self, key):
  46. assert len(key) == 32
  47. hashindex_delete(self.index, <char *>key)
  48. def __setitem__(self, key, value):
  49. assert len(key) == 32
  50. cdef int[2] data
  51. data[0] = value[0]
  52. data[1] = value[1]
  53. hashindex_set(self.index, <char *>key, data)
  54. def __contains__(self, key):
  55. assert len(key) == 32
  56. data = <int *>hashindex_get(self.index, <char *>key)
  57. return data != NULL
  58. def iteritems(self, marker=None, limit=0):
  59. iter = NSKeyIterator()
  60. iter.index = self.index
  61. return iter
  62. cdef class NSKeyIterator:
  63. cdef HashIndex *index
  64. cdef char *key
  65. def __cinit__(self):
  66. self.key = NULL
  67. def __iter__(self):
  68. return self
  69. def __next__(self):
  70. self.key = <char *>hashindex_next_key(self.index, <char *>self.key)
  71. if not self.key:
  72. raise StopIteration
  73. cdef int *value = <int *>(self.key + 32)
  74. return self.key[:32], (value[0], value[1])
  75. cdef class BandIndex(IndexBase):
  76. @classmethod
  77. def create(cls, path, capacity=16):
  78. index = hashindex_create(path, capacity, 4, 4)
  79. hashindex_close(index)
  80. return cls(path)
  81. def __getitem__(self, key):
  82. cdef int k = key
  83. data = <int *>hashindex_get(self.index, &k)
  84. if not data:
  85. raise KeyError
  86. return data[0]
  87. def __delitem__(self, key):
  88. cdef int k = key
  89. hashindex_delete(self.index, &k)
  90. def __setitem__(self, key, value):
  91. cdef int k = key
  92. cdef int v = value
  93. hashindex_set(self.index, &k, &v)
  94. def __contains__(self, key):
  95. cdef int k = key
  96. data = <int *>hashindex_get(self.index, &k)
  97. return data != NULL
  98. def iteritems(self, marker=None, limit=0):
  99. iter = BandKeyIterator()
  100. iter.index = self.index
  101. return iter
  102. cdef class BandKeyIterator:
  103. cdef HashIndex *index
  104. cdef int *key
  105. def __cinit__(self):
  106. self.key = NULL
  107. def __iter__(self):
  108. return self
  109. def __next__(self):
  110. self.key = <int *>hashindex_next_key(self.index, <char *>self.key)
  111. if not self.key:
  112. raise StopIteration
  113. return self.key[0], self.key[1]