diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2016-01-09 20:22:21 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2016-01-09 20:22:21 -0800 |
commit | 41e5183c51e48cd2854099159a173da10eb30b8b (patch) | |
tree | b7b9e43817b220348b8df581a78195461ec2303d /lib.c | |
parent | 1020794b7ff51a4f168a73343f0674e71b0b279b (diff) | |
download | txr-41e5183c51e48cd2854099159a173da10eb30b8b.tar.gz txr-41e5183c51e48cd2854099159a173da10eb30b8b.tar.bz2 txr-41e5183c51e48cd2854099159a173da10eb30b8b.zip |
Rework lazy string optimization done in TXR 118.
This is also a bugfix. Padding up the index to be at least
1024 characters longer than the existing prefix was dumb
and wrong; it changes the semantics of code which restores the
list from the lazy string, like the @(freeform) directive.
How much of the string is forced is visible to the caller!
* lib.c (lazy_str_force, lazy_str_force_upto): Don't
collect pieces from the lazy list and then catenate them
in one pass. Instead, use the existing function string_extend,
which grows the string exponentially.
Diffstat (limited to 'lib.c')
-rw-r--r-- | lib.c | 36 |
1 files changed, 10 insertions, 26 deletions
@@ -6146,18 +6146,18 @@ static val copy_lazy_str(val lstr) val lazy_str_force(val lstr) { - val lim, term; - list_collect_decl (strlist, ptail); + val lim, term, pfx; type_check(lstr, LSTR); lim = lstr->ls.props->limit; term = lstr->ls.props->term; + pfx = lstr->ls.prefix; while ((!lim || gt(lim, zero)) && lstr->ls.list) { val next = pop(&lstr->ls.list); if (!next) break; - ptail = list_collect(ptail, next); - ptail = list_collect(ptail, term); + string_extend(pfx, next); + string_extend(pfx, term); if (lim) lim = minus(lim, one); } @@ -6165,11 +6165,6 @@ val lazy_str_force(val lstr) if (lim) set(mkloc(lstr->ls.props->limit, lstr), lim); - if (strlist) { - push(lstr->ls.prefix, &strlist); - set(mkloc(lstr->ls.prefix, lstr), cat_str(strlist, nil)); - } - return lstr->ls.prefix; } @@ -6198,28 +6193,22 @@ val lazy_str_put(val lstr, val stream) val lazy_str_force_upto(val lstr, val index) { uses_or2; - val lim, term, ltrm, len, effidx = index; - list_collect_decl (strlist, ptail); + val lim, term, ltrm, pfx, len; type_check(lstr, LSTR); lim = lstr->ls.props->limit; term = lstr->ls.props->term; ltrm = length_str(term); - len = length_str(lstr->ls.prefix); - - if (lt(effidx, len)) - return t; + pfx = lstr->ls.prefix; + len = length_str(pfx); - if (minus(effidx, len) < num_fast(1024)) - effidx = plus(len, num_fast(1024)); - - while (ge(effidx, len) && lstr->ls.list && + while (ge(index, len) && lstr->ls.list && or2(null(lim),gt(lim,zero))) { val next = pop(&lstr->ls.list); if (!next) break; - ptail = list_collect(ptail, next); - ptail = list_collect(ptail, term); + string_extend(pfx, next); + string_extend(pfx, term); if (lim) lim = minus(lim, one); len = plus(len, length_str(next)); @@ -6229,11 +6218,6 @@ val lazy_str_force_upto(val lstr, val index) if (lim) set(mkloc(lstr->ls.props->limit, lstr), lim); - if (strlist) { - push(lstr->ls.prefix, &strlist); - set(mkloc(lstr->ls.prefix, lstr), cat_str(strlist, nil)); - } - return lt(index, len); } |