mirror of
https://github.com/johnkerl/miller.git
synced 2026-07-21 10:29:02 +00:00
free-flags for lhmss
This commit is contained in:
parent
52460b7445
commit
16ccc58649
8 changed files with 69 additions and 63 deletions
|
|
@ -61,22 +61,22 @@ static lhmss_t* singleton_pdesc_to_chars_map = NULL;
|
|||
static lhmss_t* get_desc_to_chars_map() {
|
||||
if (singleton_pdesc_to_chars_map == NULL) {
|
||||
singleton_pdesc_to_chars_map = lhmss_alloc();
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "cr", "\r");
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "crcr", "\r\r");
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "newline", "\n");
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "lf", "\n");
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "lflf", "\n\n");
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "crlf", "\r\n");
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "crlfcrlf", "\r\n\r\n");
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "tab", "\t");
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "space", " ");
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "comma", ",");
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "newline", "\n");
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "pipe", "|");
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "slash", "/");
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "colon", ":");
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "semicolon", ";");
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "equals", "=");
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "cr", "\r", NO_FREE);
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "crcr", "\r\r", NO_FREE);
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "newline", "\n", NO_FREE);
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "lf", "\n", NO_FREE);
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "lflf", "\n\n", NO_FREE);
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "crlf", "\r\n", NO_FREE);
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "crlfcrlf", "\r\n\r\n", NO_FREE);
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "tab", "\t", NO_FREE);
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "space", " ", NO_FREE);
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "comma", ",", NO_FREE);
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "newline", "\n", NO_FREE);
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "pipe", "|", NO_FREE);
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "slash", "/", NO_FREE);
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "colon", ":", NO_FREE);
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "semicolon", ";", NO_FREE);
|
||||
lhmss_put(singleton_pdesc_to_chars_map, "equals", "=", NO_FREE);
|
||||
}
|
||||
return singleton_pdesc_to_chars_map;
|
||||
}
|
||||
|
|
@ -98,12 +98,12 @@ static lhmsi_t* singleton_default_repeat_ipses = NULL;
|
|||
static lhmss_t* get_default_rses() {
|
||||
if (singleton_default_rses == NULL) {
|
||||
singleton_default_rses = lhmss_alloc();
|
||||
lhmss_put(singleton_default_rses, "dkvp", "\n");
|
||||
lhmss_put(singleton_default_rses, "nidx", "\n");
|
||||
lhmss_put(singleton_default_rses, "csv", "\r\n");
|
||||
lhmss_put(singleton_default_rses, "csvlite", "\n");
|
||||
lhmss_put(singleton_default_rses, "pprint", "\n");
|
||||
lhmss_put(singleton_default_rses, "xtab", "(N/A)");
|
||||
lhmss_put(singleton_default_rses, "dkvp", "\n", NO_FREE);
|
||||
lhmss_put(singleton_default_rses, "nidx", "\n", NO_FREE);
|
||||
lhmss_put(singleton_default_rses, "csv", "\r\n", NO_FREE);
|
||||
lhmss_put(singleton_default_rses, "csvlite", "\n", NO_FREE);
|
||||
lhmss_put(singleton_default_rses, "pprint", "\n", NO_FREE);
|
||||
lhmss_put(singleton_default_rses, "xtab", "(N/A)", NO_FREE);
|
||||
}
|
||||
return singleton_default_rses;
|
||||
}
|
||||
|
|
@ -111,12 +111,12 @@ static lhmss_t* get_default_rses() {
|
|||
static lhmss_t* get_default_fses() {
|
||||
if (singleton_default_fses == NULL) {
|
||||
singleton_default_fses = lhmss_alloc();
|
||||
lhmss_put(singleton_default_fses, "dkvp", ",");
|
||||
lhmss_put(singleton_default_fses, "nidx", " ");
|
||||
lhmss_put(singleton_default_fses, "csv", ",");
|
||||
lhmss_put(singleton_default_fses, "csvlite", ",");
|
||||
lhmss_put(singleton_default_fses, "pprint", " ");
|
||||
lhmss_put(singleton_default_fses, "xtab", "\n");
|
||||
lhmss_put(singleton_default_fses, "dkvp", ",", NO_FREE);
|
||||
lhmss_put(singleton_default_fses, "nidx", " ", NO_FREE);
|
||||
lhmss_put(singleton_default_fses, "csv", ",", NO_FREE);
|
||||
lhmss_put(singleton_default_fses, "csvlite", ",", NO_FREE);
|
||||
lhmss_put(singleton_default_fses, "pprint", " ", NO_FREE);
|
||||
lhmss_put(singleton_default_fses, "xtab", "\n", NO_FREE);
|
||||
}
|
||||
return singleton_default_fses;
|
||||
}
|
||||
|
|
@ -124,12 +124,12 @@ static lhmss_t* get_default_fses() {
|
|||
static lhmss_t* get_default_pses() {
|
||||
if (singleton_default_pses == NULL) {
|
||||
singleton_default_pses = lhmss_alloc();
|
||||
lhmss_put(singleton_default_pses, "dkvp", "=");
|
||||
lhmss_put(singleton_default_pses, "nidx", "(N/A)");
|
||||
lhmss_put(singleton_default_pses, "csv", "(N/A)");
|
||||
lhmss_put(singleton_default_pses, "csvlite", "(N/A)");
|
||||
lhmss_put(singleton_default_pses, "pprint", "(N/A)");
|
||||
lhmss_put(singleton_default_pses, "xtab", " ");
|
||||
lhmss_put(singleton_default_pses, "dkvp", "=", NO_FREE);
|
||||
lhmss_put(singleton_default_pses, "nidx", "(N/A)", NO_FREE);
|
||||
lhmss_put(singleton_default_pses, "csv", "(N/A)", NO_FREE);
|
||||
lhmss_put(singleton_default_pses, "csvlite", "(N/A)", NO_FREE);
|
||||
lhmss_put(singleton_default_pses, "pprint", "(N/A)", NO_FREE);
|
||||
lhmss_put(singleton_default_pses, "xtab", " ", NO_FREE);
|
||||
}
|
||||
return singleton_default_pses;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
// Array-only (open addressing) string-to-string linked hash map with linear
|
||||
// probing for collisions.
|
||||
//
|
||||
// Keys and values are strduped.
|
||||
// Keys and values are not strduped.
|
||||
//
|
||||
// John Kerl 2012-08-13
|
||||
//
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
#include "lib/mlr_globals.h"
|
||||
#include "lib/mlrutil.h"
|
||||
#include "containers/lhmss.h"
|
||||
#include "containers/free_flags.h"
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
// Allow compile-time override, e.g using gcc -D.
|
||||
|
|
@ -43,7 +44,7 @@
|
|||
#define EMPTY 0xce
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
static void lhmss_put_no_enlarge(lhmss_t* pmap, char* key, char* value);
|
||||
static void lhmss_put_no_enlarge(lhmss_t* pmap, char* key, char* value, char free_flags);
|
||||
static void lhmss_enlarge(lhmss_t* pmap);
|
||||
|
||||
static void lhmss_init(lhmss_t *pmap, int length) {
|
||||
|
|
@ -76,7 +77,7 @@ lhmss_t* lhmss_alloc() {
|
|||
lhmss_t* lhmss_copy(lhmss_t* pmap) {
|
||||
lhmss_t* pnew = lhmss_alloc();
|
||||
for (lhmsse_t* pe = pmap->phead; pe != NULL; pe = pe->pnext)
|
||||
lhmss_put(pnew, pe->key, pe->value);
|
||||
lhmss_put(pnew, mlr_strdup_or_die(pe->key), mlr_strdup_or_die(pe->value), FREE_ENTRY_KEY|FREE_ENTRY_VALUE);
|
||||
return pnew;
|
||||
}
|
||||
|
||||
|
|
@ -84,8 +85,10 @@ void lhmss_free(lhmss_t* pmap) {
|
|||
if (pmap == NULL)
|
||||
return;
|
||||
for (lhmsse_t* pe = pmap->phead; pe != NULL; pe = pe->pnext) {
|
||||
free(pe->key);
|
||||
free(pe->value);
|
||||
if (pe->free_flags & FREE_ENTRY_KEY)
|
||||
free(pe->key);
|
||||
if (pe->free_flags & FREE_ENTRY_VALUE)
|
||||
free(pe->value);
|
||||
}
|
||||
free(pmap->entries);
|
||||
free(pmap->states);
|
||||
|
|
@ -135,27 +138,33 @@ static int lhmss_find_index_for_key(lhmss_t* pmap, char* key) {
|
|||
}
|
||||
|
||||
// ----------------------------------------------------------------
|
||||
void lhmss_put(lhmss_t* pmap, char* key, char* value) {
|
||||
void lhmss_put(lhmss_t* pmap, char* key, char* value, char free_flags) {
|
||||
if ((pmap->num_occupied + pmap->num_freed) >= (pmap->array_length*LOAD_FACTOR))
|
||||
lhmss_enlarge(pmap);
|
||||
lhmss_put_no_enlarge(pmap, key, value);
|
||||
lhmss_put_no_enlarge(pmap, key, value, free_flags);
|
||||
}
|
||||
|
||||
static void lhmss_put_no_enlarge(lhmss_t* pmap, char* key, char* value) {
|
||||
static void lhmss_put_no_enlarge(lhmss_t* pmap, char* key, char* value, char free_flags) {
|
||||
int index = lhmss_find_index_for_key(pmap, key);
|
||||
lhmsse_t* pe = &pmap->entries[index];
|
||||
|
||||
if (pmap->states[index] == OCCUPIED) {
|
||||
// Existing key found in chain; put value.
|
||||
if (streq(pe->key, key)) {
|
||||
free(pe->value);
|
||||
pe->value = mlr_strdup_or_die(value);
|
||||
if (pe->free_flags & FREE_ENTRY_VALUE)
|
||||
free(pe->value);
|
||||
pe->value = value;
|
||||
if (free_flags & FREE_ENTRY_VALUE)
|
||||
pe->free_flags |= FREE_ENTRY_VALUE;
|
||||
else
|
||||
pe->free_flags &= ~FREE_ENTRY_VALUE;
|
||||
}
|
||||
} else if (pmap->states[index] == EMPTY) {
|
||||
// End of chain.
|
||||
pe->ideal_index = mlr_canonical_mod(mlr_string_hash_func(key), pmap->array_length);
|
||||
pe->key = mlr_strdup_or_die(key);
|
||||
pe->value = mlr_strdup_or_die(value);
|
||||
pe->key = key;
|
||||
pe->value = value;
|
||||
pe->free_flags = free_flags;
|
||||
pmap->states[index] = OCCUPIED;
|
||||
|
||||
if (pmap->phead == NULL) {
|
||||
|
|
@ -254,10 +263,7 @@ static void lhmss_enlarge(lhmss_t* pmap) {
|
|||
lhmss_init(pmap, pmap->array_length*ENLARGEMENT_FACTOR);
|
||||
|
||||
for (lhmsse_t* pe = old_head; pe != NULL; pe = pe->pnext) {
|
||||
// xxx implement free-flags here so we can do this without the redundant strdups
|
||||
lhmss_put_no_enlarge(pmap, pe->key, pe->value);
|
||||
free(pe->key);
|
||||
free(pe->value);
|
||||
lhmss_put_no_enlarge(pmap, pe->key, pe->value, pe->free_flags);
|
||||
}
|
||||
free(old_entries);
|
||||
free(old_states);
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
// ----------------------------------------------------------------
|
||||
typedef struct _lhmsse_t {
|
||||
int ideal_index;
|
||||
char free_flags;
|
||||
char* key;
|
||||
char* value;
|
||||
struct _lhmsse_t *pprev;
|
||||
|
|
@ -43,7 +44,7 @@ typedef struct _lhmss_t {
|
|||
lhmss_t* lhmss_alloc();
|
||||
lhmss_t* lhmss_copy(lhmss_t* pmap);
|
||||
void lhmss_free(lhmss_t* pmap);
|
||||
void lhmss_put(lhmss_t* pmap, char* key, char* value);
|
||||
void lhmss_put(lhmss_t* pmap, char* key, char* value, char free_flags);
|
||||
char* lhmss_get(lhmss_t* pmap, char* key);
|
||||
int lhmss_has_key(lhmss_t* pmap, char* key);
|
||||
void lhmss_remove(lhmss_t* pmap, char* key);
|
||||
|
|
|
|||
|
|
@ -74,9 +74,10 @@ void lrec_put(lrec_t* prec, char* key, char* value, char free_flags) {
|
|||
free(pe->value);
|
||||
}
|
||||
pe->value = value;
|
||||
pe->free_flags &= ~FREE_ENTRY_VALUE;
|
||||
if (free_flags & FREE_ENTRY_VALUE)
|
||||
pe->free_flags |= FREE_ENTRY_VALUE;
|
||||
else
|
||||
pe->free_flags &= ~FREE_ENTRY_VALUE;
|
||||
} else {
|
||||
pe = mlr_malloc_or_die(sizeof(lrece_t));
|
||||
pe->key = key;
|
||||
|
|
|
|||
|
|
@ -197,8 +197,8 @@ static sllv_t* mapper_histogram_emit(mapper_histogram_state_t* pstate) {
|
|||
for (sllse_t* pe = pstate->value_field_names->phead; pe != NULL; pe = pe->pnext) {
|
||||
char* value_field_name = pe->value;
|
||||
char* count_field_name = mlr_paste_3_strings(value_field_name, "_", "count");
|
||||
lhmss_put(pcount_field_names, value_field_name, count_field_name);
|
||||
free(count_field_name);
|
||||
lhmss_put(pcount_field_names, mlr_strdup_or_die(value_field_name), count_field_name,
|
||||
FREE_ENTRY_KEY|FREE_ENTRY_VALUE);
|
||||
}
|
||||
|
||||
for (int i = 0; i < pstate->nbins; i++) {
|
||||
|
|
@ -304,9 +304,7 @@ static sllv_t* mapper_histogram_emit_auto(mapper_histogram_state_t* pstate) {
|
|||
for (sllse_t* pe = pstate->value_field_names->phead; pe != NULL; pe = pe->pnext) {
|
||||
char* value_field_name = pe->value;
|
||||
char* count_field_name = mlr_paste_3_strings(value_field_name, "_", "count");
|
||||
// xxx make a transfer-ownership option for lhmss (which currently is strdup-only)
|
||||
lhmss_put(pcount_field_names, value_field_name, count_field_name);
|
||||
free(count_field_name);
|
||||
lhmss_put(pcount_field_names, mlr_strdup_or_die(value_field_name), count_field_name, FREE_ENTRY_KEY|FREE_ENTRY_VALUE);
|
||||
}
|
||||
|
||||
for (int i = 0; i < nbins; i++) {
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ static mapper_t* mapper_rename_parse_cli(int* pargi, int argc, char** argv) {
|
|||
}
|
||||
lhmss_t* pold_to_new = lhmss_alloc();
|
||||
for (sllse_t* pe = pnames->phead; pe != NULL; pe = pe->pnext->pnext) {
|
||||
lhmss_put(pold_to_new, pe->value, pe->pnext->value);
|
||||
lhmss_put(pold_to_new, mlr_strdup_or_die(pe->value), mlr_strdup_or_die(pe->pnext->value), FREE_ENTRY_KEY|FREE_ENTRY_VALUE);
|
||||
}
|
||||
slls_free(pnames);
|
||||
|
||||
|
|
|
|||
|
|
@ -555,7 +555,7 @@ static void stats1_percentile_emit(void* pvstate, char* value_field_name, char*
|
|||
char* output_field_name = lhmss_get(pstate->poutput_field_names, stats1_acc_name);
|
||||
if (output_field_name == NULL) {
|
||||
output_field_name = mlr_paste_3_strings(value_field_name, "_", stats1_acc_name);
|
||||
lhmss_put(pstate->poutput_field_names, stats1_acc_name, output_field_name);
|
||||
lhmss_put(pstate->poutput_field_names, mlr_strdup_or_die(stats1_acc_name), mlr_strdup_or_die(output_field_name), FREE_ENTRY_KEY|FREE_ENTRY_VALUE);
|
||||
}
|
||||
lrec_put(poutrec, output_field_name, s, FREE_ENTRY_KEY|FREE_ENTRY_VALUE);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -331,7 +331,7 @@ static char* test_lhmss() {
|
|||
mu_assert_lf(!lhmss_has_key(pmap, "z")); mu_assert_lf(lhmss_get(pmap, "z") == NULL);
|
||||
mu_assert_lf(lhmss_check_counts(pmap));
|
||||
|
||||
lhmss_put(pmap, "x", "3");
|
||||
lhmss_put(pmap, "x", "3", NO_FREE);
|
||||
mu_assert_lf(pmap->num_occupied == 1);
|
||||
mu_assert_lf(!lhmss_has_key(pmap, "w")); mu_assert_lf(lhmss_get(pmap, "w") == NULL);
|
||||
mu_assert_lf( lhmss_has_key(pmap, "x")); mu_assert_lf(streq(lhmss_get(pmap, "x"), "3"));
|
||||
|
|
@ -339,7 +339,7 @@ static char* test_lhmss() {
|
|||
mu_assert_lf(!lhmss_has_key(pmap, "z")); mu_assert_lf(lhmss_get(pmap, "z") == NULL);
|
||||
mu_assert_lf(lhmss_check_counts(pmap));
|
||||
|
||||
lhmss_put(pmap, "y", "5");
|
||||
lhmss_put(pmap, "y", "5", NO_FREE);
|
||||
mu_assert_lf(pmap->num_occupied == 2);
|
||||
mu_assert_lf(!lhmss_has_key(pmap, "w")); mu_assert_lf(lhmss_get(pmap, "w") == NULL);
|
||||
mu_assert_lf( lhmss_has_key(pmap, "x")); mu_assert_lf(streq(lhmss_get(pmap, "x"), "3"));
|
||||
|
|
@ -347,7 +347,7 @@ static char* test_lhmss() {
|
|||
mu_assert_lf(!lhmss_has_key(pmap, "z")); mu_assert_lf(lhmss_get(pmap, "z") == NULL);
|
||||
mu_assert_lf(lhmss_check_counts(pmap));
|
||||
|
||||
lhmss_put(pmap, "x", "4");
|
||||
lhmss_put(pmap, "x", "4", NO_FREE);
|
||||
mu_assert_lf(pmap->num_occupied == 2);
|
||||
mu_assert_lf(!lhmss_has_key(pmap, "w")); mu_assert_lf(lhmss_get(pmap, "w") == NULL);
|
||||
mu_assert_lf( lhmss_has_key(pmap, "x")); mu_assert_lf(streq(lhmss_get(pmap, "x"), "4"));
|
||||
|
|
@ -355,7 +355,7 @@ static char* test_lhmss() {
|
|||
mu_assert_lf(!lhmss_has_key(pmap, "z")); mu_assert_lf(lhmss_get(pmap, "z") == NULL);
|
||||
mu_assert_lf(lhmss_check_counts(pmap));
|
||||
|
||||
lhmss_put(pmap, "z", "7");
|
||||
lhmss_put(pmap, "z", "7", NO_FREE);
|
||||
mu_assert_lf(pmap->num_occupied == 3);
|
||||
mu_assert_lf(!lhmss_has_key(pmap, "w")); mu_assert_lf(lhmss_get(pmap, "w") == NULL);
|
||||
mu_assert_lf( lhmss_has_key(pmap, "x")); mu_assert_lf(streq(lhmss_get(pmap, "x"), "4"));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue