summaryrefslogtreecommitdiffstats
path: root/lib.c
diff options
context:
space:
mode:
authorKaz Kylheku <kaz@kylheku.com>2016-01-09 20:22:21 -0800
committerKaz Kylheku <kaz@kylheku.com>2016-01-09 20:22:21 -0800
commit41e5183c51e48cd2854099159a173da10eb30b8b (patch)
treeb7b9e43817b220348b8df581a78195461ec2303d /lib.c
parent1020794b7ff51a4f168a73343f0674e71b0b279b (diff)
downloadtxr-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.c36
1 files 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);
}