From 41e5183c51e48cd2854099159a173da10eb30b8b Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sat, 9 Jan 2016 20:22:21 -0800 Subject: 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. --- lib.c | 36 ++++++++++-------------------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/lib.c b/lib.c index 1d034edf..cdc7ec1f 100644 --- a/lib.c +++ b/lib.c @@ -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); } -- cgit v1.2.3