FrontISTR  6.0.0
Large-scale structural analysis program with finit element method
hecmw_map_int.c
Go to the documentation of this file.
1 /*****************************************************************************
2  * Copyright (c) 2019 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_map_int.h"
15 
16 enum { MAP_MAX_VAL_INIT = 1024, MAP_MAX_VAL_GROW = 2 };
17 
18 int HECMW_map_int_init(struct hecmw_map_int *map, void (*free_fnc)(void *)) {
19  HECMW_assert(map);
20 
21  map->n_val = 0;
22  map->max_val = 0;
23 
24  map->vals = NULL;
25  map->pairs = NULL;
26 
27  map->checked = 1;
28  map->sorted = 1;
29 
30  map->mark = NULL;
31 
32  map->in_iter = 0;
33  map->iter = 0;
34 
35  map->free_fnc = free_fnc;
36 
37  return HECMW_SUCCESS;
38 }
39 
41  HECMW_assert(map);
42 
43  if (map->max_val == 0) {
44  HECMW_assert(map->n_val == 0);
45  return;
46  }
47 
48  if (map->free_fnc != NULL) {
49  size_t i;
50 
51  for (i = 0; i < map->n_val; i++) map->free_fnc(map->vals[i].val);
52  }
53 
54  HECMW_free(map->vals);
55  HECMW_free(map->pairs);
56 
57  if (map->mark != NULL) {
58  HECMW_bit_array_finalize(map->mark);
59  HECMW_free(map->mark);
60  }
61 
62  return;
63 }
64 
65 size_t HECMW_map_int_nval(const struct hecmw_map_int *map) {
66  HECMW_assert(map);
67 
68  return map->n_val;
69 }
70 
71 static int map_resize(struct hecmw_map_int *map, size_t new_max_val) {
72  HECMW_assert(map);
73  HECMW_assert(map->n_val <= new_max_val);
74 
75  if (map->max_val == new_max_val) return HECMW_SUCCESS;
76 
77  if (map->mark) {
78  HECMW_bit_array_finalize(map->mark);
79  HECMW_free(map->mark);
80  map->mark = NULL;
81  }
82 
83  if (new_max_val == 0) {
84  HECMW_assert(map->vals != NULL && map->pairs != NULL);
85 
86  free(map->vals);
87  map->vals = NULL;
88  free(map->pairs);
89  map->pairs = NULL;
90  } else {
91  struct hecmw_map_int_value *new_vals;
92  struct hecmw_map_int_pair *new_pairs;
93 
94  new_vals = (struct hecmw_map_int_value *)HECMW_realloc(
95  map->vals, sizeof(struct hecmw_map_int_value) * new_max_val);
96  if (new_vals == NULL) return HECMW_ERROR;
97  map->vals = new_vals;
98 
99  new_pairs = (struct hecmw_map_int_pair *)HECMW_realloc(
100  map->pairs, sizeof(struct hecmw_map_int_pair) * new_max_val);
101  if (new_pairs == NULL) return HECMW_ERROR;
102  map->pairs = new_pairs;
103  }
104 
105  map->max_val = new_max_val;
106  return HECMW_SUCCESS;
107 }
108 
109 static int map_grow(struct hecmw_map_int *map) {
110  size_t new_max_val;
111 
112  HECMW_assert(map);
113 
114  if (map->max_val == 0)
115  new_max_val = MAP_MAX_VAL_INIT;
116  else
117  new_max_val = map->max_val * MAP_MAX_VAL_GROW;
118 
119  return map_resize(map, new_max_val);
120 }
121 
122 int HECMW_map_int_add(struct hecmw_map_int *map, int key, void *value) {
123  HECMW_assert(map);
124 
125  if (map->n_val == map->max_val)
126  if (map_grow(map) != HECMW_SUCCESS) return HECMW_ERROR;
127 
128  map->vals[map->n_val].key = key;
129  map->vals[map->n_val].val = value;
130 
131  map->pairs[map->n_val].key = key;
132  map->pairs[map->n_val].local = map->n_val;
133 
134  if (map->n_val > 0 && map->sorted) {
135  int key_prev = map->vals[map->n_val - 1].key;
136 
137  if (key_prev > key) map->sorted = map->checked = 0;
138 
139  if (map->checked && key_prev == key) map->checked = 0;
140  }
141 
142  map->n_val++;
143 
144  return HECMW_SUCCESS;
145 }
146 
147 static int pair_cmp(const void *v1, const void *v2) {
148  const struct hecmw_map_int_pair *p1, *p2;
149 
150  p1 = (const struct hecmw_map_int_pair *)v1;
151  p2 = (const struct hecmw_map_int_pair *)v2;
152 
153  if (p1->key < p2->key) return -1;
154  if (p1->key > p2->key) return 1;
155  return 0;
156 }
157 
159  size_t i, n_dup = 0, n = 1;
160 
161  HECMW_assert(map);
162 
163  if (map->checked) return 0;
164 
165  if (!map->sorted) {
166  qsort(map->pairs, map->n_val, sizeof(struct hecmw_map_int_pair), pair_cmp);
167  map->sorted = 1;
168  }
169 
171  HECMW_bit_array_set_all(map->mark);
172 
173  for (i = 1; i < map->n_val; i++) {
174  if (map->pairs[i - n].key == map->pairs[i].key) {
175  n_dup++;
176  if (map->pairs[i - n].local < map->pairs[i].local) {
177  HECMW_bit_array_unset(map->mark, map->pairs[i - n].local);
178  n = 1;
179  } else {
180  HECMW_bit_array_unset(map->mark, map->pairs[i].local);
181  n++;
182  }
183  } else {
184  n = 1;
185  }
186  }
187 
189 
190  map->checked = 1;
191 
192  map_resize(map, map->n_val); /* reduce memory usage */
193 
194  return n_dup;
195 }
196 
197 static int map_search(const struct hecmw_map_int *map, int key, size_t *index) {
198  size_t left, right, center;
199  int ckey;
200 
201  HECMW_assert(map && index);
202 
203  /* binary search */
204 
205  left = 0;
206  right = map->n_val - 1;
207 
208  while (left <= right) {
209  center = (left + right) / 2;
210  ckey = map->pairs[center].key;
211 
212  if (ckey < key)
213  left = center + 1;
214  else if (ckey > key)
215  right = center - 1;
216  else { /* ckey == key */
217  *index = map->pairs[center].local;
218  return HECMW_SUCCESS;
219  }
220  }
221 
222  /* not found */
223  *index = left;
224  return HECMW_ERROR;
225 }
226 
227 int HECMW_map_int_key2local(const struct hecmw_map_int *map, int key,
228  size_t *local) {
229  HECMW_assert(map);
230  HECMW_assert(map->checked);
231 
232  if (map_search(map, key, local) != HECMW_SUCCESS) return HECMW_ERROR;
233 
234  HECMW_assert(0 <= *local && *local < map->n_val);
235  HECMW_assert(map->vals[*local].key == key);
236 
237  return HECMW_SUCCESS;
238 }
239 
240 void *HECMW_map_int_get(const struct hecmw_map_int *map, int key) {
241  size_t local;
242 
243  HECMW_assert(map);
244  HECMW_assert(map->checked);
245 
246  if (HECMW_map_int_key2local(map, key, &local) != HECMW_SUCCESS) return NULL;
247 
248  return map->vals[local].val;
249 }
250 
252  HECMW_assert(map);
253  HECMW_assert(map->checked);
254 
255  map->in_iter = 1;
256  map->iter = 0;
257  return;
258 }
259 
260 int HECMW_map_int_iter_next(struct hecmw_map_int *map, int *key, void **value) {
261  HECMW_assert(map && key);
262  HECMW_assert(map->in_iter);
263  HECMW_assert(map->iter <= map->n_val);
264 
265  if (map->iter == map->n_val) {
266  map->in_iter = 0;
267  map->iter = 0;
268  return 0;
269  }
270 
271  *key = map->vals[map->iter].key;
272  if (value != NULL) *value = map->vals[map->iter].val;
273 
274  map->iter++;
275 
276  return 1;
277 }
278 
280  HECMW_assert(map);
281 
282  if (map->mark != NULL) {
283  HECMW_bit_array_finalize(map->mark);
284  HECMW_free(map->mark);
285  }
286  map->mark =
287  (struct hecmw_bit_array *)HECMW_malloc(sizeof(struct hecmw_bit_array));
288  if (map->mark == NULL) {
289  return HECMW_ERROR;
290  }
291 
292  if (HECMW_bit_array_init(map->mark, map->n_val) != HECMW_SUCCESS)
293  return HECMW_ERROR;
294 
295  return HECMW_SUCCESS;
296 }
297 
298 int HECMW_map_int_mark(struct hecmw_map_int *map, int key) {
299  size_t local;
300 
301  HECMW_assert(map);
302  HECMW_assert(map->mark);
303 
304  if (HECMW_map_int_key2local(map, key, &local) != HECMW_SUCCESS)
305  return HECMW_ERROR;
306 
307  HECMW_bit_array_set(map->mark, local);
308 
309  return HECMW_SUCCESS;
310 }
311 
313  void **value) {
314  HECMW_assert(map);
315  HECMW_assert(0 <= map->iter && map->iter <= map->n_val);
316  HECMW_assert(map->mark);
317 
318  while (map->iter < map->n_val && HECMW_bit_array_get(map->mark, map->iter))
319  map->iter++;
320 
321  return HECMW_map_int_iter_next(map, key, value);
322 }
323 
324 static void rebuild_pairs(struct hecmw_map_int *map) {
325  size_t i;
326  int sorted = 1;
327 
328  HECMW_assert(map);
329 
330  for (i = 0; i < map->n_val; i++) {
331  map->pairs[i].key = map->vals[i].key;
332  map->pairs[i].local = i;
333  if (i > 0 && map->vals[i].key < map->vals[i - 1].key) sorted = 0;
334  }
335 
336  if (!sorted) {
337  qsort(map->pairs, map->n_val, sizeof(struct hecmw_map_int_pair), pair_cmp);
338  }
339 }
340 
342  size_t i, n_del = 0;
343 
344  HECMW_assert(map);
345  HECMW_assert(map->mark);
346 
347  for (i = 0; i < map->n_val; i++) {
348  if (HECMW_bit_array_get(map->mark, i)) { /* marked */
349  if (n_del > 0) map->vals[i - n_del] = map->vals[i];
350  } else { /* not marked */
351  if (map->free_fnc != NULL) map->free_fnc(map->vals[i].val);
352  n_del++;
353  }
354  }
355 
356  if (n_del > 0) {
357  map->n_val -= n_del;
358  rebuild_pairs(map);
359  }
360 
361  HECMW_bit_array_finalize(map->mark);
362  HECMW_free(map->mark);
363  map->mark = NULL;
364 
365  return n_del;
366 }
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_unset(struct hecmw_bit_array *ba, size_t index)
void HECMW_bit_array_set_all(struct hecmw_bit_array *ba)
void HECMW_bit_array_finalize(struct hecmw_bit_array *ba)
#define HECMW_ERROR
Definition: hecmw_config.h:81
#define HECMW_SUCCESS
Definition: hecmw_config.h:79
#define NULL
#define HECMW_realloc(ptr, size)
Definition: hecmw_malloc.h:22
#define HECMW_free(ptr)
Definition: hecmw_malloc.h:24
#define HECMW_malloc(size)
Definition: hecmw_malloc.h:20
size_t HECMW_map_int_nval(const struct hecmw_map_int *map)
Definition: hecmw_map_int.c:65
int HECMW_map_int_add(struct hecmw_map_int *map, int key, void *value)
int HECMW_map_int_iter_next(struct hecmw_map_int *map, int *key, void **value)
int HECMW_map_int_mark_init(struct hecmw_map_int *map)
int HECMW_map_int_mark(struct hecmw_map_int *map, int key)
int HECMW_map_int_iter_next_unmarked(struct hecmw_map_int *map, int *key, void **value)
@ MAP_MAX_VAL_INIT
Definition: hecmw_map_int.c:16
@ MAP_MAX_VAL_GROW
Definition: hecmw_map_int.c:16
int HECMW_map_int_del_unmarked(struct hecmw_map_int *map)
void * HECMW_map_int_get(const struct hecmw_map_int *map, int key)
size_t HECMW_map_int_check_dup(struct hecmw_map_int *map)
void HECMW_map_int_iter_init(struct hecmw_map_int *map)
void HECMW_map_int_finalize(struct hecmw_map_int *map)
Definition: hecmw_map_int.c:40
int HECMW_map_int_key2local(const struct hecmw_map_int *map, int key, size_t *local)
int HECMW_map_int_init(struct hecmw_map_int *map, void(*free_fnc)(void *))
Definition: hecmw_map_int.c:18
#define HECMW_assert(cond)
Definition: hecmw_util.h:40