keyset.h 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. #ifndef LSUP_KEYSET_H
  2. #define LSUP_KEYSET_H
  3. #include "core.h"
  4. typedef enum LSUP_KSFlag {
  5. LSUP_KS_CHECK_CAP = 1 << 0,
  6. LSUP_KS_CHECK_DUP = 1 << 1
  7. } LSUP_KSFlag;
  8. typedef struct keyset {
  9. LSUP_TripleKey *data;
  10. size_t capacity;
  11. size_t cur;
  12. size_t free_i;
  13. float expand_ratio;
  14. } LSUP_Keyset;
  15. int LSUP_keyset_init(LSUP_Keyset *ks, size_t capacity, float expand_ratio);
  16. LSUP_Keyset *LSUP_keyset_new(size_t capacity, float expand_ratio);
  17. /**
  18. * Move cursor to a non-empty position.
  19. */
  20. inline bool LSUP_keyset_seek(LSUP_Keyset* ks, size_t idx)
  21. {
  22. if (idx >= ks->free_i) return false;
  23. ks->cur = idx;
  24. return true;
  25. }
  26. inline size_t LSUP_keyset_size(LSUP_Keyset* ks)
  27. {
  28. return(ks->free_i);
  29. }
  30. inline size_t LSUP_keyset_tell(LSUP_Keyset* ks)
  31. {
  32. return(ks->cur);
  33. }
  34. inline const LSUP_TripleKey *LSUP_keyset_peek(LSUP_Keyset *ks) {
  35. return (const LSUP_TripleKey *)(ks->data + ks->cur);
  36. }
  37. inline bool LSUP_keyset_contains(
  38. const LSUP_Keyset *ks, const LSUP_TripleKey *val) {
  39. for (size_t i = 0; i < ks->free_i; i++) {
  40. // scan from the least to the most probable to match.
  41. if (
  42. (*val)[2] == ks->data[i][2] &&
  43. (*val)[0] == ks->data[i][0] &&
  44. (*val)[1] == ks->data[i][1]) {
  45. return true;
  46. }
  47. }
  48. return false;
  49. }
  50. inline bool LSUP_keyset_next(LSUP_Keyset *ks)
  51. {
  52. if (ks->free_i > 0 && ks->cur < ks->free_i - 1) {
  53. ks->cur ++;
  54. return true;
  55. }
  56. return false;
  57. }
  58. /**
  59. * Resize the keyset capacity.
  60. *
  61. * Size cannot be smaller than `free_i`. Therefore, specifying a size of 0 will
  62. * always compact the keyset to the current occupied space.
  63. */
  64. int LSUP_keyset_resize(LSUP_Keyset *ks, size_t new_size);
  65. /**
  66. * Add a single key.
  67. */
  68. int LSUP_keyset_add(
  69. LSUP_Keyset *ks, const LSUP_TripleKey *val, LSUP_KSFlag flags);
  70. int LSUP_keyset_remove(LSUP_Keyset *ks, const LSUP_TripleKey *val);
  71. int LSUP_keyset_copy(const LSUP_Keyset *src, LSUP_Keyset *dest);
  72. int LSUP_keyset_sparse_copy(LSUP_Keyset *src, LSUP_Keyset *dest);
  73. int LSUP_keyset_lookup(
  74. LSUP_Keyset *ks, LSUP_Keyset *res,
  75. const LSUP_Key sk, const LSUP_Key pk, const LSUP_Key ok);
  76. /**
  77. * Set-theoretical union (ks1 ∪ ks2).
  78. *
  79. * The resulting Keyset is initialized beforehand and is not compacted.
  80. */
  81. int LSUP_keyset_join(LSUP_Keyset *ks1, LSUP_Keyset *ks2, LSUP_Keyset *res);
  82. /**
  83. * Set-theoretical complement (ks1 \ ks2).
  84. *
  85. * The resulting Keyset is initialized beforehand and is not compacted.
  86. */
  87. int LSUP_keyset_subtract(LSUP_Keyset *ks1, LSUP_Keyset *ks2, LSUP_Keyset *res);
  88. /**
  89. * Set-theoretical intersection (ks1 ∩ ks2).
  90. *
  91. * The resulting Keyset is initialized beforehand and is not compacted.
  92. */
  93. int LSUP_keyset_intersect(LSUP_Keyset *ks1, LSUP_Keyset *ks2, LSUP_Keyset *res);
  94. /**
  95. * Disjunctive union (XOR) (ks1 ⊕ ks2).
  96. *
  97. * The resulting Keyset is initialized beforehand and is not compacted.
  98. */
  99. int LSUP_keyset_xor(LSUP_Keyset *ks1, LSUP_Keyset *ks2, LSUP_Keyset *res);
  100. void LSUP_keyset_done(LSUP_Keyset *ks);
  101. void LSUP_keyset_free(LSUP_Keyset *ks);
  102. #endif