2
0

hashindex.pyx 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  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_clear(HashIndex *index)
  9. void hashindex_close(HashIndex *index)
  10. void hashindex_flush(HashIndex *index)
  11. void *hashindex_get(HashIndex *index, void *key)
  12. void *hashindex_next_key(HashIndex *index, void *key)
  13. void hashindex_delete(HashIndex *index, void *key)
  14. void hashindex_set(HashIndex *index, void *key, void *value)
  15. _NoDefault = object()
  16. cdef class IndexBase:
  17. cdef HashIndex *index
  18. def __cinit__(self, path):
  19. self.index = hashindex_open(path)
  20. if not self.index:
  21. raise Exception('Failed to open %s' % path)
  22. def __dealloc__(self):
  23. hashindex_close(self.index)
  24. def clear(self):
  25. hashindex_clear(self.index)
  26. def flush(self):
  27. hashindex_flush(self.index)
  28. def setdefault(self, key, value):
  29. if not key in self:
  30. self[key] = value
  31. def get(self, key, default=None):
  32. try:
  33. return self[key]
  34. except KeyError:
  35. return default
  36. def pop(self, key, default=_NoDefault):
  37. try:
  38. value = self[key]
  39. del self[key]
  40. return value
  41. except KeyError:
  42. if default != _NoDefault:
  43. return default
  44. raise
  45. def __len__(self):
  46. return hashindex_get_size(self.index)
  47. cdef class NSIndex(IndexBase):
  48. @classmethod
  49. def create(cls, path, capacity=16):
  50. index = hashindex_create(path, capacity, 32, 8)
  51. hashindex_close(index)
  52. return cls(path)
  53. def __getitem__(self, key):
  54. assert len(key) == 32
  55. data = <int *>hashindex_get(self.index, <char *>key)
  56. if not data:
  57. raise KeyError
  58. return data[0], data[1]
  59. def __delitem__(self, key):
  60. assert len(key) == 32
  61. hashindex_delete(self.index, <char *>key)
  62. def __setitem__(self, key, value):
  63. assert len(key) == 32
  64. cdef int[2] data
  65. data[0] = value[0]
  66. data[1] = value[1]
  67. hashindex_set(self.index, <char *>key, data)
  68. def __contains__(self, key):
  69. assert len(key) == 32
  70. data = <int *>hashindex_get(self.index, <char *>key)
  71. return data != NULL
  72. def iteritems(self, marker=None, limit=0):
  73. iter = NSKeyIterator()
  74. iter.index = self.index
  75. return iter
  76. cdef class NSKeyIterator:
  77. cdef HashIndex *index
  78. cdef char *key
  79. def __cinit__(self):
  80. self.key = NULL
  81. def __iter__(self):
  82. return self
  83. def __next__(self):
  84. self.key = <char *>hashindex_next_key(self.index, <char *>self.key)
  85. if not self.key:
  86. raise StopIteration
  87. cdef int *value = <int *>(self.key + 32)
  88. return self.key[:32], (value[0], value[1])
  89. cdef class ChunkIndex(IndexBase):
  90. @classmethod
  91. def create(cls, path, capacity=16):
  92. index = hashindex_create(path, capacity, 32, 12)
  93. hashindex_close(index)
  94. return cls(path)
  95. def __getitem__(self, key):
  96. assert len(key) == 32
  97. data = <int *>hashindex_get(self.index, <char *>key)
  98. if not data:
  99. raise KeyError
  100. return data[0], data[1], data[2]
  101. def __delitem__(self, key):
  102. assert len(key) == 32
  103. hashindex_delete(self.index, <char *>key)
  104. def __setitem__(self, key, value):
  105. assert len(key) == 32
  106. cdef int[3] data
  107. data[0] = value[0]
  108. data[1] = value[1]
  109. data[2] = value[2]
  110. hashindex_set(self.index, <char *>key, data)
  111. def __contains__(self, key):
  112. assert len(key) == 32
  113. data = <int *>hashindex_get(self.index, <char *>key)
  114. return data != NULL
  115. def iteritems(self, marker=None, limit=0):
  116. iter = ChunkKeyIterator()
  117. iter.index = self.index
  118. return iter
  119. cdef class ChunkKeyIterator:
  120. cdef HashIndex *index
  121. cdef char *key
  122. def __cinit__(self):
  123. self.key = NULL
  124. def __iter__(self):
  125. return self
  126. def __next__(self):
  127. self.key = <char *>hashindex_next_key(self.index, <char *>self.key)
  128. if not self.key:
  129. raise StopIteration
  130. cdef int *value = <int *>(self.key + 32)
  131. return self.key[:32], (value[0], value[1], value[2])
  132. cdef class BandIndex(IndexBase):
  133. @classmethod
  134. def create(cls, path, capacity=16):
  135. index = hashindex_create(path, capacity, 4, 4)
  136. hashindex_close(index)
  137. return cls(path)
  138. def __getitem__(self, key):
  139. cdef int k = key
  140. data = <int *>hashindex_get(self.index, &k)
  141. if not data:
  142. raise KeyError
  143. return data[0]
  144. def __delitem__(self, key):
  145. cdef int k = key
  146. hashindex_delete(self.index, &k)
  147. def __setitem__(self, key, value):
  148. cdef int k = key
  149. cdef int v = value
  150. hashindex_set(self.index, &k, &v)
  151. def __contains__(self, key):
  152. cdef int k = key
  153. data = <int *>hashindex_get(self.index, &k)
  154. return data != NULL
  155. def iteritems(self, marker=None, limit=0):
  156. iter = BandKeyIterator()
  157. iter.index = self.index
  158. return iter
  159. cdef class BandKeyIterator:
  160. cdef HashIndex *index
  161. cdef int *key
  162. def __cinit__(self):
  163. self.key = NULL
  164. def __iter__(self):
  165. return self
  166. def __next__(self):
  167. self.key = <int *>hashindex_next_key(self.index, <char *>self.key)
  168. if not self.key:
  169. raise StopIteration
  170. return self.key[0], self.key[1]