vector.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /* Generic vector interface routine
  2. * Copyright (C) 1997 Kunihiro Ishiguro
  3. *
  4. * This file is part of GNU Zebra.
  5. *
  6. * GNU Zebra is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation; either version 2, or (at your option) any
  9. * later version.
  10. *
  11. * GNU Zebra is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with GNU Zebra; see the file COPYING. If not, write to the Free
  18. * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  19. * 02111-1307, USA.
  20. */
  21. #include <zebra.h>
  22. #include "vector.h"
  23. #include "memory.h"
  24. /* Initialize vector : allocate memory and return vector. */
  25. vector
  26. vector_init (unsigned int size)
  27. {
  28. vector v = XCALLOC (MTYPE_VECTOR, sizeof (struct _vector));
  29. /* allocate at least one slot */
  30. if (size == 0)
  31. size = 1;
  32. v->alloced = size;
  33. v->active = 0;
  34. v->index = XCALLOC (MTYPE_VECTOR_INDEX, sizeof (void *) * size);
  35. return v;
  36. }
  37. void
  38. vector_only_wrapper_free (vector v)
  39. {
  40. XFREE (MTYPE_VECTOR, v);
  41. }
  42. void
  43. vector_only_index_free (void *index)
  44. {
  45. XFREE (MTYPE_VECTOR_INDEX, index);
  46. }
  47. void
  48. vector_free (vector v)
  49. {
  50. XFREE (MTYPE_VECTOR_INDEX, v->index);
  51. XFREE (MTYPE_VECTOR, v);
  52. }
  53. vector
  54. vector_copy (vector v)
  55. {
  56. unsigned int size;
  57. vector new = XCALLOC (MTYPE_VECTOR, sizeof (struct _vector));
  58. new->active = v->active;
  59. new->alloced = v->alloced;
  60. size = sizeof (void *) * (v->alloced);
  61. new->index = XCALLOC (MTYPE_VECTOR_INDEX, size);
  62. memcpy (new->index, v->index, size);
  63. return new;
  64. }
  65. /* Check assigned index, and if it runs short double index pointer */
  66. void
  67. vector_ensure (vector v, unsigned int num)
  68. {
  69. if (v->alloced > num)
  70. return;
  71. v->index = XREALLOC (MTYPE_VECTOR_INDEX,
  72. v->index, sizeof (void *) * (v->alloced * 2));
  73. memset (&v->index[v->alloced], 0, sizeof (void *) * v->alloced);
  74. v->alloced *= 2;
  75. if (v->alloced <= num)
  76. vector_ensure (v, num);
  77. }
  78. /* This function only returns next empty slot index. It dose not mean
  79. the slot's index memory is assigned, please call vector_ensure()
  80. after calling this function. */
  81. int
  82. vector_empty_slot (vector v)
  83. {
  84. unsigned int i;
  85. if (v->active == 0)
  86. return 0;
  87. for (i = 0; i < v->active; i++)
  88. if (v->index[i] == 0)
  89. return i;
  90. return i;
  91. }
  92. /* Set value to the smallest empty slot. */
  93. int
  94. vector_set (vector v, void *val)
  95. {
  96. unsigned int i;
  97. i = vector_empty_slot (v);
  98. vector_ensure (v, i);
  99. v->index[i] = val;
  100. if (v->active <= i)
  101. v->active = i + 1;
  102. return i;
  103. }
  104. /* Set value to specified index slot. */
  105. int
  106. vector_set_index (vector v, unsigned int i, void *val)
  107. {
  108. vector_ensure (v, i);
  109. v->index[i] = val;
  110. if (v->active <= i)
  111. v->active = i + 1;
  112. return i;
  113. }
  114. /* Look up vector. */
  115. void *
  116. vector_lookup (vector v, unsigned int i)
  117. {
  118. if (i >= v->active)
  119. return NULL;
  120. return v->index[i];
  121. }
  122. /* Lookup vector, ensure it. */
  123. void *
  124. vector_lookup_ensure (vector v, unsigned int i)
  125. {
  126. vector_ensure (v, i);
  127. return v->index[i];
  128. }
  129. /* Unset value at specified index slot. */
  130. void
  131. vector_unset (vector v, unsigned int i)
  132. {
  133. if (i >= v->alloced)
  134. return;
  135. v->index[i] = NULL;
  136. if (i + 1 == v->active)
  137. {
  138. v->active--;
  139. while (i && v->index[--i] == NULL && v->active--)
  140. ; /* Is this ugly ? */
  141. }
  142. }
  143. /* Count the number of not emplty slot. */
  144. unsigned int
  145. vector_count (vector v)
  146. {
  147. unsigned int i;
  148. unsigned count = 0;
  149. for (i = 0; i < v->active; i++)
  150. if (v->index[i] != NULL)
  151. count++;
  152. return count;
  153. }