/src/utils/int_queues.c

https://github.com/SRI-CSL/yices2 · C · 169 lines · 83 code · 32 blank · 54 comment · 21 complexity · 9985bee68fdb9d5b07adf5fca8e0119c 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. * QUEUES OF 32BIT SIGNED INTEGERS
  20. */
  21. #include <assert.h>
  22. #include "utils/int_queues.h"
  23. #include "utils/memalloc.h"
  24. /*
  25. * Initialize a queue of size n
  26. */
  27. void init_int_queue(int_queue_t *q, uint32_t n) {
  28. if (n == 0) {
  29. n = DEFAULT_INT_QUEUE_INITIAL_SIZE;
  30. } else if (n > MAX_INT_QUEUE_SIZE) {
  31. out_of_memory();
  32. }
  33. q->data = (int32_t *) safe_malloc(n * sizeof(int32_t));
  34. q->size = n;
  35. q->head = 0;
  36. q->tail = 0;
  37. }
  38. /*
  39. * Delete: free data array
  40. */
  41. void delete_int_queue(int_queue_t *q) {
  42. safe_free(q->data);
  43. q->data = NULL;
  44. }
  45. /*
  46. * Resize the queue. make data array 50% larger.
  47. * content of data array is unchanged
  48. */
  49. static void resize_queue(int_queue_t *q) {
  50. uint32_t n;
  51. n = q->size + 1;
  52. n += n >> 1;
  53. if (n > MAX_INT_QUEUE_SIZE) {
  54. out_of_memory();
  55. }
  56. q->data = (int32_t *) safe_realloc(q->data, n * sizeof(int32_t));
  57. q->size = n;
  58. }
  59. /*
  60. * Push element x at the end of the queue
  61. */
  62. void int_queue_push(int_queue_t *q, int32_t x) {
  63. uint32_t i, n, j;
  64. i = q->tail;
  65. q->data[i] = x;
  66. i ++;
  67. q->tail = i;
  68. if (i == q->size) {
  69. if (q->head == 0) {
  70. /*
  71. * full queue, stored in data[0...size-1],
  72. * just increase the size
  73. */
  74. resize_queue(q);
  75. } else {
  76. q->tail = 0;
  77. }
  78. } else if (i == q->head) {
  79. /*
  80. * full queue, stored in data[0..i-1][head .. size-1]
  81. * increase the size and shift data[head .. size - 1] to the end
  82. * of the new data array.
  83. */
  84. n = q->size;
  85. resize_queue(q);
  86. j = q->size;
  87. do {
  88. n --;
  89. j --;
  90. q->data[j] = q->data[n];
  91. } while (n > i);
  92. q->head = j;
  93. }
  94. }
  95. /*
  96. * Push a[0 ... n-1] in the queue (in this order)
  97. */
  98. void int_queue_push_array(int_queue_t *q, int32_t *a, uint32_t n) {
  99. uint32_t i;
  100. for (i=0; i<n; i++) {
  101. int_queue_push(q, a[i]);
  102. }
  103. }
  104. /*
  105. * Return first element and remove it
  106. */
  107. int32_t int_queue_pop(int_queue_t *q) {
  108. uint32_t h;
  109. int32_t x;
  110. assert(q->head != q->tail);
  111. h = q->head;
  112. x = q->data[h];
  113. h ++;
  114. if (h >= q->size) h = 0;
  115. q->head = h;
  116. return x;
  117. }
  118. /*
  119. * Get the first element (don't remove it).
  120. */
  121. int32_t int_queue_first(int_queue_t *q) {
  122. assert(q->head != q->tail);
  123. return q->data[q->head];
  124. }
  125. /*
  126. * Get the last element (don't remove it)
  127. */
  128. int32_t int_queue_last(int_queue_t *q) {
  129. uint32_t i;
  130. assert(q->head != q->tail);
  131. i = q->tail;
  132. if (i == 0) {
  133. i = q->size;
  134. }
  135. assert(i > 0);
  136. return q->data[i-1];
  137. }