FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
hecmw_varray_idx.c
Go to the documentation of this file.
1 /*****************************************************************************
2  * Copyright (c) 2026 FrontISTR Commons
3  * This software is released under the MIT License, see LICENSE.txt
4  *****************************************************************************/
5 
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <errno.h>
10 #include "hecmw_util.h"
11 #include "hecmw_malloc.h"
12 #include "hecmw_config.h"
13 #include "hecmw_bit_array.h"
14 #include "hecmw_varray_idx.h"
15 
17 
19  HECMW_assert(varray);
20 
21  varray->n_val = 0;
22  varray->max_val = 0;
23 
24  varray->vals = NULL;
25 
26  return HECMW_SUCCESS;
27 }
28 
30  HECMW_assert(varray);
31 
32  if (varray->max_val == 0) {
33  HECMW_assert(varray->n_val == 0);
34  return;
35  }
36 
37  HECMW_free(varray->vals);
38  return;
39 }
40 
41 size_t HECMW_varray_idx_nval(const struct hecmw_varray_idx *varray) {
42  HECMW_assert(varray);
43 
44  return varray->n_val;
45 }
46 
47 static int varray_resize(struct hecmw_varray_idx *varray, size_t new_max_val) {
48  idx_t *new_vals;
49 
50  HECMW_assert(varray);
51  HECMW_assert(varray->n_val <= new_max_val);
52 
53  if (varray->max_val == new_max_val) return HECMW_SUCCESS;
54 
55  if (new_max_val == 0) {
56  HECMW_assert(varray->vals);
57 
58  HECMW_free(varray->vals);
59  varray->vals = NULL;
60  varray->max_val = 0;
61 
62  return HECMW_SUCCESS;
63  }
64 
65  new_vals = (idx_t *)HECMW_realloc(varray->vals, sizeof(idx_t) * new_max_val);
66  if (new_vals == NULL) {
67  return HECMW_ERROR;
68  }
69 
70  varray->vals = new_vals;
71  varray->max_val = new_max_val;
72 
73  return HECMW_SUCCESS;
74 }
75 
76 static int varray_grow(struct hecmw_varray_idx *varray) {
77  size_t new_max_val;
78 
79  HECMW_assert(varray);
80 
81  if (varray->max_val == 0)
82  new_max_val = VARRAY_MAX_VAL_INIT;
83  else
84  new_max_val = varray->max_val * VARRAY_MAX_VAL_GROW;
85 
86  return varray_resize(varray, new_max_val);
87 }
88 
89 int HECMW_varray_idx_append(struct hecmw_varray_idx *varray, idx_t value) {
90  HECMW_assert(varray);
91 
92  if (varray->n_val == varray->max_val)
93  if (varray_grow(varray) != HECMW_SUCCESS) return HECMW_ERROR;
94 
95  varray->vals[varray->n_val] = value;
96  varray->n_val++;
97 
98  return HECMW_SUCCESS;
99 }
100 
102  size_t index) {
103  HECMW_assert(varray);
104  HECMW_assert(0 <= index && index < varray->n_val);
105 
106  return varray->vals[index];
107 }
108 
110  const struct hecmw_varray_idx *varray2) {
111  size_t i;
112 
113  HECMW_assert(varray);
114  HECMW_assert(varray2);
115 
116  while (varray->n_val + varray2->n_val > varray->max_val) {
117  if (varray_grow(varray) != HECMW_SUCCESS) return HECMW_ERROR;
118  }
119  for (i = 0; i < varray2->n_val; i++) {
120  varray->vals[varray->n_val] = varray2->vals[i];
121  varray->n_val++;
122  }
123  return HECMW_SUCCESS;
124 }
125 
126 static int idx_cmp(const void *v1, const void *v2) {
127  const idx_t *i1, *i2;
128 
129  i1 = (const idx_t *)v1;
130  i2 = (const idx_t *)v2;
131 
132  if (*i1 < *i2) return -1;
133  if (*i1 > *i2) return 1;
134  return 0;
135 }
136 
138  HECMW_assert(varray);
139  qsort(varray->vals, varray->n_val, sizeof(idx_t), idx_cmp);
140 }
141 
143  size_t *index) {
144  idx_t *p;
145  p = bsearch(&value, varray->vals, varray->n_val, sizeof(idx_t), idx_cmp);
146  if (p == NULL) return HECMW_ERROR;
147  *index = p - varray->vals;
148  return HECMW_SUCCESS;
149 }
150 
151 size_t HECMW_varray_idx_uniq(struct hecmw_varray_idx *varray) {
152  size_t i, n_dup = 0;
153 
154  HECMW_assert(varray);
155 
156  for (i = 1; i < varray->n_val; i++) {
157  if (varray->vals[i - 1] == varray->vals[i]) {
158  n_dup++;
159  } else {
160  if (n_dup > 0) {
161  varray->vals[i - n_dup] = varray->vals[i];
162  }
163  }
164  }
165 
166  varray->n_val -= n_dup;
167 
168  if (varray->n_val * 2 < varray->max_val)
169  varray_resize(varray, varray->n_val); /* reduce memory usage */
170 
171  return n_dup;
172 }
173 
174 int HECMW_varray_idx_resize(struct hecmw_varray_idx *varray, size_t len) {
175  HECMW_assert(varray);
176 
177  if (varray->max_val < len) {
178  if (varray_resize(varray, len) != HECMW_SUCCESS) return HECMW_ERROR;
179  }
180  varray->n_val = len;
181  return HECMW_SUCCESS;
182 }
183 
185  HECMW_assert(varray);
186  return varray->vals;
187 }
188 
189 const idx_t *HECMW_varray_idx_get_cv(const struct hecmw_varray_idx *varray) {
190  HECMW_assert(varray);
191  return varray->vals;
192 }
193 
194 int HECMW_varray_idx_copy(const struct hecmw_varray_idx *varray,
195  struct hecmw_varray_idx *varray2) {
196  size_t i;
197 
198  HECMW_assert(varray);
199 
200  if (HECMW_varray_idx_resize(varray2, varray->n_val) != HECMW_SUCCESS)
201  return HECMW_ERROR;
202 
203  for (i = 0; i < varray->n_val; i++) varray2->vals[i] = varray->vals[i];
204 
205  return HECMW_SUCCESS;
206 }
207 
209  struct hecmw_varray_idx tmp_array;
210 
211  HECMW_assert(varray);
212 
213  if (HECMW_varray_idx_init(&tmp_array) != HECMW_SUCCESS) {
214  return HECMW_ERROR;
215  }
216  if (HECMW_varray_idx_copy(varray, &tmp_array) != HECMW_SUCCESS) {
217  return HECMW_ERROR;
218  }
219  HECMW_varray_idx_sort(&tmp_array);
220 
221  if (HECMW_varray_idx_uniq(&tmp_array) != 0) {
222  struct hecmw_bit_array ba;
223  size_t i, n_dup = 0;
224 
225  HECMW_bit_array_init(&ba, tmp_array.n_val);
226  for (i = 0; i < varray->n_val; i++) {
227  idx_t *key = varray->vals + i;
228  idx_t *res =
229  bsearch(key, tmp_array.vals, tmp_array.n_val, sizeof(idx_t), idx_cmp);
230  size_t idx;
231 
232  HECMW_assert(res != NULL);
233 
234  idx = res - tmp_array.vals;
235 
236  if (HECMW_bit_array_get(&ba, idx)) {
237  n_dup++;
238  } else {
239  HECMW_bit_array_set(&ba, idx);
240  varray->vals[i - n_dup] = varray->vals[i];
241  }
242  }
243  varray->n_val -= n_dup;
245 
246  HECMW_assert(varray->n_val == tmp_array.n_val);
247  }
248  HECMW_varray_idx_finalize(&tmp_array);
249  return HECMW_SUCCESS;
250 }
251 
252 int HECMW_varray_idx_assign(struct hecmw_varray_idx *varray, size_t begin,
253  size_t end, idx_t val) {
254  size_t i;
255 
256  HECMW_assert(varray);
257  HECMW_assert(0 <= begin);
258  HECMW_assert(end <= varray->n_val);
259 
260  for (i = begin; i < end; i++) {
261  varray->vals[i] = val;
262  }
263  return HECMW_SUCCESS;
264 }
265 
266 int HECMW_varray_idx_insert(struct hecmw_varray_idx *varray, size_t index,
267  idx_t val) {
268  HECMW_assert(varray);
269  HECMW_assert(0 <= index && index <= varray->n_val);
270 
271  if (varray->n_val == varray->max_val)
272  if (varray_grow(varray) != HECMW_SUCCESS) return HECMW_ERROR;
273 
274  memmove(varray->vals + index + 1, varray->vals + index,
275  sizeof(idx_t) * (varray->n_val - index));
276 
277  varray->vals[index] = val;
278  varray->n_val++;
279 
280  return HECMW_SUCCESS;
281 }
282 
283 int HECMW_varray_idx_delete(struct hecmw_varray_idx *varray, size_t index) {
284  HECMW_assert(varray);
285  HECMW_assert(0 <= index && index <= varray->n_val);
286 
287  memmove(varray->vals + index, varray->vals + index + 1,
288  sizeof(idx_t) * (varray->n_val - index - 1));
289 
290  varray->n_val--;
291 
292  return HECMW_SUCCESS;
293 }
int HECMW_bit_array_init(struct hecmw_bit_array *ba, size_t len)
int HECMW_bit_array_get(struct hecmw_bit_array *ba, size_t index)
void HECMW_bit_array_set(struct hecmw_bit_array *ba, size_t index)
void HECMW_bit_array_finalize(struct hecmw_bit_array *ba)
#define HECMW_ERROR
Definition: hecmw_config.h:68
#define HECMW_SUCCESS
Definition: hecmw_config.h:66
#define NULL
#define HECMW_realloc(ptr, size)
Definition: hecmw_malloc.h:22
#define HECMW_free(ptr)
Definition: hecmw_malloc.h:24
#define HECMW_assert(cond)
Definition: hecmw_util.h:40
int HECMW_varray_idx_append(struct hecmw_varray_idx *varray, idx_t value)
void HECMW_varray_idx_finalize(struct hecmw_varray_idx *varray)
@ VARRAY_MAX_VAL_INIT
@ VARRAY_MAX_VAL_GROW
idx_t * HECMW_varray_idx_get_v(struct hecmw_varray_idx *varray)
int HECMW_varray_idx_search(struct hecmw_varray_idx *varray, idx_t value, size_t *index)
size_t HECMW_varray_idx_uniq(struct hecmw_varray_idx *varray)
size_t HECMW_varray_idx_nval(const struct hecmw_varray_idx *varray)
int HECMW_varray_idx_assign(struct hecmw_varray_idx *varray, size_t begin, size_t end, idx_t val)
int HECMW_varray_idx_delete(struct hecmw_varray_idx *varray, size_t index)
void HECMW_varray_idx_sort(struct hecmw_varray_idx *varray)
idx_t HECMW_varray_idx_get(const struct hecmw_varray_idx *varray, size_t index)
int HECMW_varray_idx_copy(const struct hecmw_varray_idx *varray, struct hecmw_varray_idx *varray2)
int HECMW_varray_idx_cat(struct hecmw_varray_idx *varray, const struct hecmw_varray_idx *varray2)
int HECMW_varray_idx_insert(struct hecmw_varray_idx *varray, size_t index, idx_t val)
int HECMW_varray_idx_resize(struct hecmw_varray_idx *varray, size_t len)
int HECMW_varray_idx_init(struct hecmw_varray_idx *varray)
int HECMW_varray_idx_rmdup(struct hecmw_varray_idx *varray)
const idx_t * HECMW_varray_idx_get_cv(const struct hecmw_varray_idx *varray)
long long idx_t