keyset.pyx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. from libc.string cimport memcmp
  2. from libc.stdlib cimport free
  3. cimport lakesuperior.cy_include.collections as cc
  4. cimport lakesuperior.model.structures.callbacks as cb
  5. from lakesuperior.model.base cimport (
  6. TRP_KLEN, KeyIdx, Key, DoubleKey, TripleKey, Buffer
  7. )
  8. cdef class Keyset:
  9. """
  10. Pre-allocated result set.
  11. """
  12. def __cinit__(self, size_t ct=1):
  13. """
  14. Initialize and allocate memory for the data set.
  15. :param size_t ct: Number of elements to be accounted for.
  16. """
  17. cc.array_conf_init(&self.conf)
  18. self.conf.capacity = ct or 1
  19. self.conf.exp_factor = .5
  20. cc.array_new_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
  50. KeyIdx* k2 = NULL
  51. key_cmp_fn_t cmp_fn
  52. cc.array_iter_init(&it, self.data)
  53. if sk and pk and ok: # s p o
  54. pass # TODO
  55. elif sk:
  56. k1 = sk
  57. if pk: # s p ?
  58. k2 = pk
  59. cmp_fn = cb.lookup_skpk_cmp_fn
  60. elif ok: # s ? o
  61. k2 = ok
  62. cmp_fn = cb.lookup_skok_cmp_fn
  63. else: # s ? ?
  64. cmp_fn = cb.lookup_sk_cmp_fn
  65. elif pk:
  66. k1 = pk
  67. if ok: # ? p o
  68. k2 = ok
  69. cmp_fn = cb.lookup_pkok_cmp_fn
  70. else: # ? p ?
  71. cmp_fn = cb.lookup_pk_cmp_fn
  72. elif ok: # ? ? o
  73. k1 = ok
  74. cmp_fn = cb.lookup_ok_cmp_fn
  75. else: # ? ? ?
  76. return self # TODO Placeholder. This should actually return a copy.
  77. ret = Keyset(256) # TODO Totally arbitrary.
  78. while cc.array_iter_next(&it, &cur) != cc.CC_ITER_END:
  79. if cmp_fn(<TripleKey*>spok, k1, k2):
  80. if cc.array_add(ret.data, spok) != cc.CC_OK:
  81. raise RuntimeError('Error adding triple key.')
  82. return ret