OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
phash.c
Go to the documentation of this file.
1 
2 #include <phash.h>
3 
4 #include <check.h>
5 #include <stdbool.h>
6 #include <stdint.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <unistd.h>
11 
12 START_TEST(set_1){
14  char k1[] = "key1";
15  char k2[] = "key2";
16  char v1_in[] = "value1";
17  char v1_2_in[] = "value1.2";
18  char v2_in[] = "value2";
19  char v2_const_in[] = "value3";
20 
21  ck_assert(phash_set(p1, k1, v1_in) == 0);
22  char *v1_out = phash_get(p1, k1);
23  ck_assert(v1_in == v1_out);
24 
25  ck_assert(phash_set(p1, k1, v1_2_in) == 1);
26  char *v1_2_out = phash_get(p1, k1);
27  ck_assert(v1_2_in == v1_2_out);
28 
29  ck_assert(phash_set(p1, k2, v2_in) == 0);
30  char *v2_out = phash_get(p1, k2);
31  ck_assert(v2_in == v2_out);
32 
33  ck_assert(phash_set(p1, "key2", v2_const_in) == 1);
34  char *v2_const_out = phash_get(p1, "key2");
35  ck_assert(v2_const_in == v2_const_out);
37 }
38 END_TEST
39 
40 START_TEST(get_out_of_scope){
42  char *v2_const_out = phash_get(p1, "key2");
43  ck_assert(v2_const_out == NULL);
45 }
46 END_TEST
47 
48 START_TEST(set_out_of_scope){
50  int ret;
51  ret = phash_set(p1, "key2", "value3");
52  ck_assert(ret == 0);
53  ck_assert_str_eq(phash_get(p1, "key2"), "value3");
55 }
56 END_TEST
57 
58 START_TEST(iterating){
60  int key_count;
61  char *keys[] = {"key1", "key2", "key3"};
62  char *values[] = {"value1", "value2", "value3"};
63 
64  for (key_count = 0; key_count < 3; key_count++){
65  ck_assert(phash_set(p1, keys[key_count], values[key_count]) == 0);
66  }
67 
68  int replace_value = 0;
69  for (replace_value = 0; replace_value < 2; replace_value++){
70  const char *key;
71  void *value;
72  int rewind_count = 0;
73  for (rewind_count = 0; rewind_count < 3; rewind_count++){
74  key = value = NULL;
75  int found[key_count];
76  int k;
77  for (k=0;k<key_count;k++){
78  found[k] = 0;
79  }
80 
81 // phash_rewind(p1); //auto-rewind
82  while (!phash_next(p1, &key, &value)){
83  ck_assert(key != NULL && value != NULL);
84  for (k=0;k<key_count;k++){
85  if (!strcmp(keys[k], key) && !strcmp(values[k], value)){
86  found[k]++;
87  }
88  }
89  }
90 
91  for (k=0;k<key_count;k++){
92  ck_assert_int_eq(found[k], 1);
93  }
94  }
95  values[0] = "value4";
96  ck_assert_int_eq(phash_set(p1, keys[0], values[0]), 1);
97  }
99 }
100 END_TEST
101 
102 START_TEST(iterating_one_value){
104  int key_count;
105  char *keys[] = {"key1"};
106  char *values[] = {"value1"};
107 
108  for (key_count = 0; key_count < 1; key_count++){
109  ck_assert(phash_set(p1, keys[key_count], values[key_count]) == 0);
110  }
111 
112  int replace_value = 0;
113  for (replace_value = 0; replace_value < 2; replace_value++){
114  const char *key;
115  void *value;
116  int rewind_count = 0;
117  for (rewind_count = 0; rewind_count < 3; rewind_count++){
118  key = value = NULL;
119  int found[key_count];
120  int k;
121  for (k=0;k<key_count;k++){
122  found[k] = 0;
123  }
124 
125  phash_rewind(p1);
126  while (!phash_next(p1, &key, &value)){
127  ck_assert(key != NULL && value != NULL);
128  for (k=0;k<key_count;k++){
129  if (!strcmp(keys[k], key) && !strcmp(values[k], value)){
130  found[k]++;
131  }
132  }
133  }
134 
135  for (k=0;k<key_count;k++){
136  ck_assert_int_eq(found[k], 1);
137  }
138  }
139  values[0] = "value4";
140  ck_assert_int_eq(phash_set(p1, keys[0], values[0]), 1);
141  }
142  phash_destroy(p1);
143 }
144 END_TEST
145 
146 START_TEST(remove_1){
148  int key_count;
149  char *keys[] = {"key1", "key2", "key3"};
150  char *values[] = {"value1", "value2", "value3"};
151 
152  for (key_count = 0; key_count < 3; key_count++){
153  ck_assert_int_eq(phash_set(p1, keys[key_count], values[key_count]), 0);
154  }
155 
156  int remove_value = 0;
157  for (remove_value = 0; remove_value < key_count-1; remove_value++){
158  const char *key;
159  void *value;
160  key = value = NULL;
161  int found[key_count];
162  int k;
163  for (k=0;k<key_count;k++){
164  found[k] = 0;
165  }
166 
167  phash_rewind(p1);
168  while (!phash_next(p1, &key, &value)){
169  ck_assert(key != NULL && value != NULL);
170  for (k=0;k<key_count;k++){
171  if (!strcmp(keys[k], key) && !strcmp(values[k], value)){
172  found[k]++;
173  }
174  }
175  }
176  k = remove_value;
177  for (;k<key_count;k++){
178  ck_assert_int_eq(found[k], 1);
179  }
180  ck_assert_int_eq(phash_remove(p1, keys[remove_value]), 0);
181  }
182  ck_assert_ptr_eq(phash_get(p1, keys[remove_value-1]), NULL);
183  ck_assert_ptr_ne(phash_get(p1, keys[remove_value]), NULL);
184  phash_destroy(p1);
185 }
186 END_TEST
187 
188 
189 static const char characters[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
190 static void random_string(char *buffer, int length){
191  int i=0;
192  for (i=0;i<length;i++){
193  buffer[i] = characters[rand() % (sizeof(characters)-1)];
194  }
195 }
196 
197 START_TEST(stress_test){
199  int i, j, contains_dupes, count = 1000, length = 8;
200  char keys[count][length+1];
201  char values[count][length+1];
202 
203  for (i=0;i<count;i++){
204  random_string(keys[i], length);
205  random_string(values[i], length);
206  keys[i][length] = '\0';
207  values[i][length] = '\0';
208  }
209  do {
210  contains_dupes = 0;
211  for (i=0;i<count;i++){
212  for (j=i+1;j<count;j++){
213  if (!strcmp(keys[i], keys[j])){
214  contains_dupes = 1;
215  random_string(keys[j], length);
216  }
217  }
218  }
219  } while (contains_dupes);
220 
221  for (i=0;i<count;i++){
222  ck_assert_int_eq(phash_set(p1, keys[i], values[i]), 0);
223  }
224 
225  for (i=0;i<count;i++){
226  ck_assert_str_eq(values[i], phash_get(p1, keys[i]));
227  }
228  phash_destroy(p1);
229 }
230 END_TEST
231 
232 START_TEST(copy_keys){
233  char *test_key = malloc(strlen("key1") + 1);
234  strncpy(test_key, "key1", strlen("key1") + 1);
235 
236  phash *p2 = phash_create(0);
237  ck_assert_int_eq(phash_set(p2, test_key, "testval"), 0);
238  free(test_key);
239  ck_assert_str_eq(phash_get(p2, "key1"), "testval");
240  phash_destroy(p2);
241 }
242 END_TEST
243 
244 Suite* stub_suite(void){
245  Suite *s = suite_create("Stub");
246 
247  TCase *tc_core = tcase_create("Core");
248  tcase_add_test(tc_core, set_1);
249  tcase_add_test(tc_core, remove_1);
250  tcase_add_test(tc_core, iterating);
251  tcase_add_test(tc_core, iterating_one_value);
252  tcase_add_test(tc_core, stress_test);
253  tcase_add_test(tc_core, copy_keys);
254  suite_add_tcase(s, tc_core);
255 
256  TCase *tc_segfaults = tcase_create("Segfaults");
257  tcase_add_test(tc_segfaults, set_1);
258  tcase_add_test(tc_segfaults, get_out_of_scope);
259  tcase_add_test(tc_segfaults, set_out_of_scope);
260  suite_add_tcase(s, tc_segfaults);
261 
262  return s;
263 }
264 
265 int main(int argc, char **argv){
266  int number_failed;
267 
268  Suite *s = stub_suite();
269  SRunner *sr = srunner_create(s);
270 
271  srunner_run_all(sr, CK_VERBOSE);
272  number_failed = srunner_ntests_failed(sr);
273  srunner_free(sr);
274  return (number_failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
275 }
int main(int argc, char **argv)
Definition: phash.c:265
int32 value
Definition: Granule.c:1235
START_TEST(set_1)
Definition: phash.c:12
#define EXIT_SUCCESS
Definition: GEO_basic.h:72
int j
Definition: decode_rs.h:73
#define PHASH_NO_COPY_KEYS
Definition: phash.h:30
#define NULL
Definition: decode_rs.h:63
A simple dictionary library for storing pointers.
phash * phash_create(uint32_t options)
Initialize a phash object.
Definition: phash.c:107
int phash_remove(phash *h, const char *key)
Remove a pointer associated with the given string.
Definition: phash.c:146
Implementation-specific, generic type to store the phash object.
Definition: phash.c:40
int phash_set(phash *h, const char *key, void *value)
Add or overwrite a pointer, associating it with the given key.
Definition: phash.c:224
END_TEST Suite * stub_suite(void)
Definition: phash.c:244
void * phash_get(phash *h, const char *key)
Find a pointer associated with the given string.
Definition: phash.c:205
HISTORY txt for MOD_PR01(step one of PGE01) History follows the following convention needed due to new Aqua ReprocessingActual and the expected LUT revision number from PCF Changed to use PGE version for ProductionHistory Added Archive including ProcessingEnvironment Corrected handling of bad to resovle GSFcd02514 Changed to check staged LUT revision number versus the expected LUT revision number from thereby resolving defect report MODxl02056 This change also avoids the memory access violation reported in MODur00039 Changed the way output arrays were initialized with fill values
Definition: HISTORY.txt:162
PARAM_TYPE_NONE Default value No parameter is buried in the product name name_prefix is case insensitive string compared to the product name PARAM_TYPE_VIS_WAVE The visible wavelength bands from the sensor are buried in the product name The product name is compared by appending and name_suffix ie aph_412_giop where prod_ix will be set to PARAM_TYPE_IR_WAVE same search method as PARAM_TYPE_VIS_WAVE except only wavelength above are looped through but prod_ix is still based ie aph_2_giop for the second and prod_ix set to PARAM_TYPE_INT name_prefix is compared with the beginning of the product name If name_suffix is not empty the it must match the end of the product name The characters right after the prefix are read as an integer and prod_ix is set to that number strncpy(l2prod->name_prefix, "myprod", UNITLEN)
data_t s[NROOTS]
Definition: decode_rs.h:75
int phash_next(phash *h, const char **key, void **value)
Retrieves the next key-value pair in the phash. The order in which the pointers are returned shall be...
Definition: phash.c:275
int phash_destroy(phash *h)
Destroy a phash object, free'ing the memory used.
Definition: phash.c:136
int phash_rewind(phash *h)
Rewind iterator for traversing all the keys and values.
Definition: phash.c:269
int i
Definition: decode_rs.h:71
int k
Definition: decode_rs.h:73
int count
Definition: decode_rs.h:79