/src/utils/ptr_sets2.h

https://github.com/SRI-CSL/yices2 · C Header · 186 lines · 39 code · 33 blank · 114 comment · 1 complexity · 64e7fc43dd84f5ddc5e351ee18e7c309 MD5 · raw file

  1. /*
  2. * This file is part of the Yices SMT Solver.
  3. * Copyright (C) 2017 SRI International.
  4. *
  5. * Yices is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * Yices is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with Yices. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /*
  19. * Sets/bags of pointers
  20. * - this supports addition and removal of (void *) pointers.
  21. * All elements in the set must be distinct from NULL and
  22. * DELETED_PTR_ELEM (defined below)
  23. * - the implementation uses an array
  24. * - if the set is small, we just use linear scan of the array
  25. * - when the set becomes large, we switch to a hash table
  26. *
  27. * This is a variant of ptr_sets that uses a hash code provided
  28. * by the caller.
  29. */
  30. #ifndef __PTR_SETS2_H
  31. #define __PTR_SETS2_H
  32. #include <stdint.h>
  33. #include <stdbool.h>
  34. #include <stddef.h>
  35. #include "utils/memalloc.h"
  36. /*
  37. * Descriptor: hash function + aux pointer
  38. * - the hash function for any element p is desc->hash(desc->aux, p)
  39. * - the descriptor must be passed to most functions.
  40. */
  41. typedef uint32_t (*ptr_hash_fun_t)(void *aux, void *p);
  42. typedef struct ptr_set2_hash_s {
  43. ptr_hash_fun_t hash;
  44. void *aux;
  45. } ptr_set2_hash_t;
  46. /*
  47. * Set descriptor:
  48. * - data = array of n elements where n is a power of two
  49. * - size = n
  50. * - nelems = actual number of elements in data
  51. * - ndeleted = number of deleted elements
  52. * - hash function + auxiliary data
  53. */
  54. typedef struct ptr_set2_s {
  55. uint32_t size;
  56. uint32_t nelems;
  57. uint32_t ndeleted;
  58. uint32_t resize_threshold;
  59. void *data[0]; // real size = size
  60. } ptr_set2_t;
  61. #define DEF_PTR_SET2_SIZE 8
  62. #define MAX_PTR_SET2_SIZE ((UINT32_MAX-sizeof(ptr_set2_t))/sizeof(void *))
  63. /*
  64. * Threshold: when size > SMALL_PTR_SET_SIZE, we switch to
  65. * a hash-table representation.
  66. *
  67. * In hash-table mode, the following thresholds are used:
  68. * - when nelems > size * PTR_SET_RESIZE_RATIO: make the table larger
  69. * - when nelems < size * PTR_SET_SHRINK_RATIO: make the table smaller
  70. */
  71. #define SMALL_PTR_SET2_SIZE 32
  72. #define PTR_SET2_RESIZE_RATIO 0.7
  73. #define PTR_SET2_SHRINK_RATIO 0.3
  74. /*
  75. * Marker for deleted elements
  76. */
  77. #define DELETED_PTR_ELEM ((void *) 1)
  78. /*
  79. * Allocate and initialize a set
  80. * - this creates an empty set of default size
  81. */
  82. extern ptr_set2_t *new_ptr_set2(void);
  83. /*
  84. * Delete a set descriptor
  85. */
  86. static inline void free_ptr_set2(ptr_set2_t *s) {
  87. safe_free(s);
  88. }
  89. /*
  90. * Check whether p != NULL && p != DELETED_PTR_ELEM
  91. */
  92. static inline bool live_ptr_elem(void *p) {
  93. return (((uintptr_t) p) >> 1) != (uintptr_t) 0;
  94. }
  95. /*
  96. * Check whether set s contains p
  97. * - d = hash-function descriptor for s
  98. * - s can be NULL here. NULL is interpreted as the empty set.
  99. */
  100. extern bool ptr_set2_member(ptr_set2_t *s, const ptr_set2_hash_t *d, void *p);
  101. /*
  102. * Add p to the set *s.
  103. * - d = hash-function descriptor for s
  104. * - p must be distinct from NULL and from DELETED_PTR_ELEM
  105. * - if *s is NULL, this function creates a new set of
  106. * default size that contains the singleton { p } and stores
  107. * this new set in *s.
  108. * - if *s is non NULL, then p is added to the set pointed
  109. * to by *s. This may cause of new set descriptor to
  110. * be allocated and stored in *s (and the original set
  111. * is freed).
  112. *
  113. * The function does not check whether p is already present.
  114. * It will add an element to *s no-matter what (so *s may
  115. * contain duplicates).
  116. */
  117. extern void ptr_set2_add(ptr_set2_t **s, const ptr_set2_hash_t *d, void *p);
  118. /*
  119. * Remove p from set *s
  120. * - d = hash-function descriptor for s
  121. * - p must be distinct from NULL and from DELETED_PTR_ELEM
  122. * - p must be present in *s (so *s must be non-NULL)
  123. * - *s may be updated to a new set descriptor if the removal
  124. * of p causes a reduction in size.
  125. *
  126. * If s contains p multiple times, then only one occurrence
  127. * of p is removed.
  128. */
  129. extern void ptr_set2_remove(ptr_set2_t **s, const ptr_set2_hash_t *d, void *p);
  130. /*
  131. * Add p to *s if it's not present.
  132. * - d = hash-function descriptor for s
  133. * - updates *s as explained in ptr_set2_add
  134. * - returns true if p is added (i.e., p was not in *s when the function was called)
  135. * - returns false otherwise and leaves *s unchanged.
  136. */
  137. extern bool ptr_set2_add_if_absent(ptr_set2_t **s, const ptr_set2_hash_t *d, void *p);
  138. /*
  139. * Remove p from *s if it's present
  140. * - d = hash-function descriptor for s
  141. * - if p is not present in *s, then *s is unchanged and the function
  142. * returns false.
  143. * - otherwise, one occurrence of p is removed from *s, then *s
  144. * may be updated as in ptr_set2_remove, and the function returns true.
  145. */
  146. extern bool ptr_set2_remove_if_present(ptr_set2_t **s, const ptr_set2_hash_t *d, void *p);
  147. /*
  148. * Iterator: call f(aux, p) for every p stored in s
  149. * - f must not have a side effect on s
  150. */
  151. typedef void (*ptr_set2_iterator_t)(void *aux, void *p);
  152. extern void ptr_set2_iterate(ptr_set2_t *s, void *aux, ptr_set2_iterator_t f);
  153. #endif /* __PTR_SET2S_H */