keyset.pyx 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. from libc.string cimport memcmp
  2. from libc.mem cimport free
  3. from lakesuperior.cy_include cimport collections as cc
  4. from lakesuperior.model.base cimport (
  5. KeyIdx, Key, DoubleKey, TripleKey, Buffer
  6. )
  7. cdef class Keyset:
  8. """
  9. Pre-allocated result set.
  10. """
  11. def __cinit__(self, size_t ct=0):
  12. """
  13. Initialize and allocate memory for the data set.
  14. :param size_t ct: Number of elements to be accounted for.
  15. """
  16. self.itemsize = TRP_KLEN
  17. cc.array_conf_init(&self.conf)
  18. self.conf.capacity = ct
  19. self.conf.exp_factor = .5
  20. cc.array_init_conf(&self.conf, &self.data)
  21. if not self.data:
  22. raise MemoryError()
  23. def __dealloc__(self):
  24. """
  25. Free the memory.
  26. This is called when the Python instance is garbage collected, which
  27. makes it handy to safely pass a Keyset instance across functions.
  28. """
  29. if self.data:
  30. free(self.data)
  31. # Access methods.
  32. cdef Keyset lookup(
  33. self, const KeyIdx* sk, const KeyIdx* pk, const KeyIdx* ok
  34. ):
  35. """
  36. Look up triple keys.
  37. This works in a similar way that the ``SimpleGraph`` and ``LmdbStore``
  38. methods work.
  39. Any and all the terms may be NULL. A NULL term is treated as unbound.
  40. :param const KeyIdx* sk: s key pointer.
  41. :param const KeyIdx* pk: p key pointer.
  42. :param const KeyIdx* ok: o key pointer.
  43. """
  44. cdef:
  45. void* cur
  46. cc.ArrayIter it
  47. TripleKey spok
  48. Keyset ret
  49. KeyIdx k1 = NULL, k2 = NULL
  50. cc.array_iter_init(&it, self.data)
  51. if sk and pk and ok: # s p o
  52. pass # TODO
  53. elif sk:
  54. k1 = sk[0]
  55. if pk: # s p ?
  56. k2 = pk[0]
  57. cmp_fn = cb.lookup_skpk_cmp_fn
  58. elif ok: # s ? o
  59. k2 = ok[0]
  60. cmp_fn = cb.lookup_skok_cmp_fn
  61. else: # s ? ?
  62. cmp_fn = cb.lookup_sk_cmp_fn
  63. elif pk:
  64. k1 = pk[0]
  65. if ok: # ? p o
  66. k2 = ok[0]
  67. cmp_fn = cb.lookup_pkok_cmp_fn
  68. else: # ? p ?
  69. cmp_fn = cb.lookup_pk_cmp_fn
  70. elif ok: # ? ? o
  71. k1 = ok[0]
  72. cmp_fn = cb.lookup_ok_cmp_fn
  73. else: # ? ? ?
  74. return self # TODO Placeholder. This should actually return a copy.
  75. ret = Keyset(256) # TODO Totally arbitrary.
  76. while cc.array_iter_next(&it, &cur) != cc.CC_ITER_END:
  77. if cmp_fn(<TripleKey*>spok, k1, k2):
  78. if cc.array_add(ret.data, spok) != cc.CC_OK:
  79. raise RuntimeError('Error adding triple key.')
  80. return ret