summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog19
-rw-r--r--awk.h6
-rw-r--r--str_array.c28
3 files changed, 37 insertions, 16 deletions
diff --git a/ChangeLog b/ChangeLog
index 21e90e4b..a59d243d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -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.
diff --git a/awk.h b/awk.h
index 7a44c1d0..bc762c28 100644
--- a/awk.h
+++ b/awk.h
@@ -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);
+ }
}
}