kgraph.h 2.7 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. #ifndef AC_KGRAPH_H
  2. #define AC_KGRAPH_H
  3. #include <stdint.h>
  4. #include <stdlib.h>
  5. #include "khash.h"
  6. #include "kbtree.h"
  7. typedef unsigned kgint_t;
  8. #define kgraph_t(name) kh_##name##_t
  9. #define __KG_BASIC(name, SCOPE, vertex_t, arc_t, ehn) \
  10. SCOPE kgraph_t(name) *kg_init_##name(void) { return kh_init(name); } \
  11. SCOPE void kg_destroy_##name(kgraph_t(name) *g) { \
  12. khint_t k; \
  13. if (g == 0) return; \
  14. for (k = kh_begin(g); k != kh_end(g); ++k) \
  15. if (kh_exist(g, k)) kh_destroy(ehn, kh_val(g, k)._arc); \
  16. kh_destroy(name, g); \
  17. } \
  18. SCOPE vertex_t *kg_get_v_##name(kgraph_t(name) *g, kgint_t v) { \
  19. khint_t k = kh_get(name, g, v); \
  20. return k == kh_end(g)? 0 : &kh_val(g, k); \
  21. } \
  22. SCOPE vertex_t *kg_put_v_##name(kgraph_t(name) *g, kgint_t v, int *absent) { \
  23. khint_t k; \
  24. k = kh_put(name, g, v, absent); \
  25. if (*absent) kh_val(g, k)._arc = kh_init(ehn); \
  26. return &kh_val(g, k); \
  27. } \
  28. SCOPE void kg_put_a_##name(kgraph_t(name) *g, kgint_t vbeg, kgint_t vend, int dir, arc_t **pb, arc_t **pe) { \
  29. vertex_t *p; \
  30. khint_t k; \
  31. int absent; \
  32. p = kg_put_v_##name(g, vbeg, &absent); \
  33. k = kh_put(ehn, p->_arc, vend<<2|dir, &absent); \
  34. *pb = &kh_val(p->_arc, k); \
  35. p = kg_put_v_##name(g, vend, &absent); \
  36. k = kh_put(ehn, p->_arc, vbeg<<2|(~dir&3), &absent); \
  37. *pe = &kh_val(p->_arc, k); \
  38. } \
  39. SCOPE vertex_t *kg_del_v_##name(kgraph_t(name) *g, kgint_t v) { \
  40. khint_t k, k0, k2, k3; \
  41. khash_t(ehn) *h; \
  42. k0 = k = kh_get(name, g, v); \
  43. if (k == kh_end(g)) return 0; /* not present in the graph */ \
  44. h = kh_val(g, k)._arc; \
  45. for (k = kh_begin(h); k != kh_end(h); ++k) /* remove v from its neighbors */ \
  46. if (kh_exist(h, k)) { \
  47. k2 = kh_get(name, g, kh_key(h, k)>>2); \
  48. /* assert(k2 != kh_end(g)); */ \
  49. k3 = kh_get(ehn, kh_val(g, k2)._arc, v<<2|(~kh_key(h, k)&3)); \
  50. /* assert(k3 != kh_end(kh_val(g, k2)._arc)); */ \
  51. kh_del(ehn, kh_val(g, k2)._arc, k3); \
  52. } \
  53. kh_destroy(ehn, h); \
  54. kh_del(name, g, k0); \
  55. return &kh_val(g, k0); \
  56. }
  57. #define KGRAPH_PRINT(name, SCOPE) \
  58. SCOPE void kg_print_##name(kgraph_t(name) *g) { \
  59. khint_t k, k2; \
  60. for (k = kh_begin(g); k != kh_end(g); ++k) \
  61. if (kh_exist(g, k)) { \
  62. printf("v %u\n", kh_key(g, k)); \
  63. for (k2 = kh_begin(kh_val(g, k)._arc); k2 != kh_end(kh_val(g, k)._arc); ++k2) \
  64. if (kh_exist(kh_val(g, k)._arc, k2) && kh_key(g, k) < kh_key(kh_val(g, k)._arc, k2)>>2) \
  65. printf("a %u%c%c%u\n", kh_key(g, k), "><"[kh_key(kh_val(g, k)._arc, k2)>>1&1], \
  66. "><"[kh_key(kh_val(g, k)._arc, k2)&1], kh_key(kh_val(g, k)._arc, k2)>>2); \
  67. } \
  68. }
  69. #define KGRAPH_INIT(name, SCOPE, vertex_t, arc_t, ehn) \
  70. KHASH_INIT2(name, SCOPE, kgint_t, vertex_t, 1, kh_int_hash_func, kh_int_hash_equal) \
  71. __KG_BASIC(name, SCOPE, vertex_t, arc_t, ehn)
  72. #endif