diff options
-rw-r--r-- | ChangeLog | 19 | ||||
-rw-r--r-- | awk.h | 6 | ||||
-rw-r--r-- | str_array.c | 28 |
3 files changed, 37 insertions, 16 deletions
@@ -209,6 +209,25 @@ Add RED_NON_FATAL to flags. (in_PROCINFO): Make smarter and more general. +2014-12-13 Andrew J. Schorr <aschorr@telemetry-investments.com> + + * awk.h (bucket_item): Remove 'struct exp_node *name'. The string index + will be held directly in the bucket instead of via a pointer to a + NODE. This saves memory when the NODE is not referenced elsewhere, + but costs memory if the NODE is still required due to other references. + (ahname): Remove define, since hs.name is gone. + (ahname_str, ahname_len): Update comments. + * str_array.c (str_lookup): Instead of holding a pointer to the + subscript NODE, make a copy of the string and call DEREF to release + the NODE. + (str_clear, str_remove): Free the allocated string subscript memory + instead of decreasing the reference count on the node. + (str_copy): Instead of calling dupnode, use estrdup to copy the + subscript string. + (str_list): Must call make_string to create a new string node instead + of calling dupnode. + (str_dump): Must create a string NODE to pass to assoc_info. + 2014-12-12 Stephen Davies <sdavies@sdc.com.au> Improve comment handling in pretty printing. @@ -309,7 +309,6 @@ typedef union bucket_item { char *str; size_t len; size_t code; - struct exp_node *name; struct exp_node *val; } hs; struct { @@ -322,9 +321,8 @@ typedef union bucket_item { /* string hash table */ #define ahnext hs.next -#define ahname hs.name /* a string index node */ -#define ahname_str hs.str /* shallow copy; = ahname->stptr */ -#define ahname_len hs.len /* = ahname->stlen */ +#define ahname_str hs.str /* private memory */ +#define ahname_len hs.len /* length of subscript string */ #define ahvalue hs.val #define ahcode hs.code diff --git a/str_array.c b/str_array.c index 33c9ddcc..4e3b0566 100644 --- a/str_array.c +++ b/str_array.c @@ -190,9 +190,9 @@ str_lookup(NODE *symbol, NODE *subs) getbucket(b); b->ahnext = symbol->buckets[hash1]; symbol->buckets[hash1] = b; - b->ahname = subs; - b->ahname_str = subs->stptr; + b->ahname_str = estrdup(subs->stptr, subs->stlen); b->ahname_len = subs->stlen; + DEREF(subs); b->ahvalue = dupnode(Nnull_string); b->ahcode = code1; return & (b->ahvalue); @@ -235,7 +235,7 @@ str_clear(NODE *symbol, NODE *subs ATTRIBUTE_UNUSED) freenode(r); } else unref(r); - unref(b->ahname); + free(b->ahname_str); freebucket(b); } symbol->buckets[i] = NULL; @@ -276,7 +276,7 @@ str_remove(NODE *symbol, NODE *subs) || memcmp(b->ahname_str, s2->stptr, s1_len) == 0) { /* item found */ - unref(b->ahname); + free(b->ahname_str); if (prev != NULL) prev->ahnext = b->ahnext; else @@ -324,7 +324,7 @@ str_copy(NODE *symbol, NODE *newsymb) for (chain = old[i], pnew = & new[i]; chain != NULL; chain = chain->ahnext ) { - NODE *oldval, *newsubs; + NODE *oldval; getbucket(newchain); @@ -333,9 +333,8 @@ str_copy(NODE *symbol, NODE *newsymb) * value from the original input list */ - newsubs = newchain->ahname = dupnode(chain->ahname); - newchain->ahname_str = newsubs->stptr; - newchain->ahname_len = newsubs->stlen; + newchain->ahname_str = estrdup(chain->ahname_str, chain->ahname_len); + newchain->ahname_len = chain->ahname_len; oldval = chain->ahvalue; if (oldval->type == Node_val) @@ -396,10 +395,10 @@ str_list(NODE *symbol, NODE *t) for (i = 0; i < symbol->array_size; i++) { for (b = symbol->buckets[i]; b != NULL; b = b->ahnext) { /* index */ - subs = b->ahname; + subs = make_string(b->ahname_str, b->ahname_len); if ((assoc_kind & AINUM) != 0) (void) force_number(subs); - list[k++] = dupnode(subs); + list[k++] = subs; /* value */ if ((assoc_kind & AVALUE) != 0) { @@ -511,8 +510,13 @@ str_dump(NODE *symbol, NODE *ndump) fprintf(output_fp, "\n"); aname = make_aname(symbol); for (i = 0; i < symbol->array_size; i++) { - for (b = symbol->buckets[i]; b != NULL; b = b->ahnext) - assoc_info(b->ahname, b->ahvalue, ndump, aname); + for (b = symbol->buckets[i]; b != NULL; b = b->ahnext) { + NODE *tmp; + + tmp = make_string(b->ahname_str, b->ahname_len); + assoc_info(tmp, b->ahvalue, ndump, aname); + DEREF(tmp); + } } } |