struct ht_node * ht_values_as_vector(struct ht_ht *ht) { struct ht_node *v = malloc(ht->items*sizeof(struct ht_node)); struct ht_node *n = ht_first(ht); for (int i = 0; i < ht->items; i++) { v[i] = *n; n = ht_next(ht); } return v; }
void write_frequencies (int fl, char *buffer, long buflen) { struct ht_ht *ht; long total, i, j, size; struct ht_node *nd; sorter *s; sorter tmp; ht = generate_frequencies (fl, buffer, buflen); total = 0; size = 0; for (nd = ht_first (ht); nd != NULL; nd = ht_next (ht)) { total = total + nd->val; size++; } s = calloc (size, sizeof (sorter)); i = 0; for (nd = ht_first (ht); nd != NULL; nd = ht_next (ht)) { s[i].string = nd->key; s[i++].num = nd->val; } for (i = 0; i < size - 1; i++) for (j = i + 1; j < size; j++) if (s[i].num < s[j].num) { memcpy (&tmp, &(s[i]), sizeof (sorter)); memcpy (&(s[i]), &(s[j]), sizeof (sorter)); memcpy (&(s[j]), &tmp, sizeof (sorter)); } for (i = 0; i < size; i++) printf ("%s %.3f\n", s[i].string, 100 * (float) s[i].num / total); printf ("\n"); ht_destroy (ht); free (s); }
/* doc: <routine name="ht_put" return_type="void *" export="shared"> doc: <summary>Put value `val' associated with key `key' in table `ht'. If `ht' is not full, we return the address of the associated value in `ht'.</summary> doc: <param name="ht" type="struct htable *">Table to initialize.</param> doc: <param name="key" type="rt_uint_ptr">Key to insert in `ht'.</param> doc: <param name="val" type="void *">Value to insert in `ht'.</param> doc: <return>Address of value in `ht' if inserted, NULL otherwise.</return> doc: <thread_safety>Not Safe</thread_safety> doc: <synchronization>None</synchronization> doc: </routine> */ rt_shared void * ht_put(struct htable *ht, rt_uint_ptr key, void * val) { void *l_val; REQUIRE("ht not null", ht); REQUIRE("key not null", key); l_val = ht_first(ht, key); if (l_val) { /* We found a free position for `key' so let's copy `val' in it. */ memcpy (l_val, val, ht->h_sval); } return l_val; }
/* doc: <routine name="ht_resize" return_type="int" export="shared"> doc: <summary>Resize `ht' to accomodate `new_size' many elements.</summary> doc: <param name="ht" type="struct htable *">Table to resize.</param> doc: <param name="new_size" type="size_t">New size. If smaller than existing size, no resizing is done.</param> doc: <return>0 if resizing was Ok, -1 otherwise.</return> doc: <thread_safety>Not Safe</thread_safety> doc: <synchronization>None</synchronization> doc: </routine> */ rt_shared int ht_resize(struct htable *ht, size_t new_size) { size_t l_capacity; /* Size of old H table */ size_t sval; /* Size of an H table item */ rt_uint_ptr *key; /* To loop over keys */ void * val, *l_value; /* To loop over values */ struct htable new_ht; REQUIRE("ht not null", ht); l_capacity = ht->h_capacity; if (l_capacity >= new_size) { return -1; /* Requested size is no bigger than what we have. */ } sval = ht->h_sval; if (-1 == ht_create(&new_ht, l_capacity * 2, sval)) { return -1; /* Extension of H table failed */ } key = ht->h_keys; /* Start of array of keys */ val = ht->h_values; /* Start of array of values */ /* Now loop over the whole table, inserting each item in the new one */ for (; l_capacity > 0; l_capacity--, key++, val = (char *) val + sval) { if (*key) { l_value = ht_first(&new_ht, *key); CHECK("Item found", l_value); memcpy (l_value, val, sval); } } /* Free old H table and set H table descriptor */ ht_release(ht); memcpy (ht, &new_ht, sizeof(struct htable)); return 0; /* Extension was ok */ }