Mike Gerwitz

Activist for User Freedom

aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMike Gerwitz <mike.gerwitz@rtspecialty.com>2019-02-20 01:35:52 -0500
committerMike Gerwitz <mike.gerwitz@rtspecialty.com>2019-02-20 02:03:20 -0500
commit5714bfb96b3dc1cc6fe688a5c24a3c2cb6cbcf21 (patch)
tree5815acc90e3b4acd2db9ac7cf519a423fab2195a /src
parent16749a9a45cbd9c4e93b6635e1983a927ffd6711 (diff)
downloadtame-5714bfb96b3dc1cc6fe688a5c24a3c2cb6cbcf21.tar.gz
tame-5714bfb96b3dc1cc6fe688a5c24a3c2cb6cbcf21.tar.bz2
tame-5714bfb96b3dc1cc6fe688a5c24a3c2cb6cbcf21.zip
symtable: Substantial performance improvement in processing
This further improves performance of the symbol table processing. The next step will be to address how symbols are handled on a more intimate level, since it's a huge mess atm. But I'll save that for later, after the low-hanging fruit has been resolved. * src/current/include/preproc/symtable.xsl (preproc:sym-discover): Use `for-each-group' in place of `preceding-sibling'. Aggressive use of maps for geneating the `dedup' sequence, which is a mess. (preproc:symtable-process-symbols): Additional maps to avoid preceding-sibling and following-sibling selectors (O(n²)=>O(n)).
Diffstat (limited to 'src')
-rw-r--r--src/current/include/preproc/symtable.xsl71
1 files changed, 52 insertions, 19 deletions
diff --git a/src/current/include/preproc/symtable.xsl b/src/current/include/preproc/symtable.xsl
index b3002f7..d24301b 100644
--- a/src/current/include/preproc/symtable.xsl
+++ b/src/current/include/preproc/symtable.xsl
@@ -248,12 +248,12 @@
</variable>
<!-- remove duplicates (if any) -->
- <sequence select="
- $extresults/preproc:sym[
- not( @name=preceding-sibling::preproc:sym/@name )
- ]
- , $extresults//preproc:error
- " />
+ <for-each-group select="$extresults/preproc:sym"
+ group-by="@name">
+ <sequence select="current-group()[ 1 ]" />
+ </for-each-group>
+
+ <sequence select="$extresults//preproc:error" />
<!-- process symbols (except imported externs) -->
<variable name="newresult" as="element( preproc:syms )">
@@ -264,6 +264,24 @@
</call-template>
</variable>
+ <!-- contains duplicates -->
+ <variable name="new-seq-map" as="map( xs:string, element( preproc:sym )+ )"
+ select="map:merge(
+ for $sym in $newresult/preproc:sym
+ return map{ string( $sym/@name ) : $sym },
+ map{ 'duplicates' : 'combine' } )" />
+
+ <variable name="new-typed-map" as="map( xs:string, element( preproc:sym ) )"
+ select="map:merge(
+ for $sym in $newresult/preproc:sym[ @type ]
+ return map{ string( $sym/@name ) : $sym } )" />
+
+ <variable name="nonlocals-map" as="map( xs:string, element( preproc:sym ) )"
+ select="map:merge(
+ for $sym in $newresult/preproc:sym[ not( @local = 'true' ) ]
+ return map{ string( $sym/@name ) : $sym } )" />
+
+ <!-- TODO: revisit this logic -->
<variable name="dedup" as="element( preproc:sym )*"
select="$newresult/preproc:sym[
not(
@@ -271,29 +289,27 @@
@pollute='true'
and not( @type )
and (
- @name=preceding-sibling::preproc:sym/@name
- or @name=$newresult/preproc:sym[ @type ]/@name
+ (
+ ( count( $new-seq-map( @name ) ) gt 1 )
+ and @name=preceding-sibling::preproc:sym/@name
+ )
+ or exists( $new-typed-map( @name ) )
)
)
or (
@local = 'true'
- and @name = following-sibling::preproc:sym[
- not( @local = 'true' )
- ]/@name
+ and exists( $nonlocals-map( @name ) )
)
)
]" />
-
<apply-templates mode="preproc:symtable-complete"
select="$dedup">
<with-param name="syms" select="$dedup" />
</apply-templates>
</preproc:symtable>
- <message>
- <text>[preproc/symtable] done.</text>
- </message>
+ <message select="'[preproc/symtable] done.'" />
<!-- copy all of the original elements after the symbol table; we're not
outputting them as we go, so we need to make sure that we don't get
@@ -434,6 +450,7 @@
</function>
+<!-- TODO: revisit this mess -->
<template name="preproc:symtable-process-symbols">
<param name="extresults" as="element( preproc:syms )" />
<param name="new" as="element( preproc:syms )" />
@@ -457,6 +474,18 @@
for $sym in $extresults/preproc:sym
return map{ string( $sym/@name ) : $sym } )" />
+ <!-- contains duplicates -->
+ <variable name="new-seq-map" as="map( xs:string, element( preproc:sym )+ )"
+ select="map:merge(
+ for $sym in $new/preproc:sym
+ return map{ string( $sym/@name ) : $sym },
+ map{ 'duplicates' : 'combine' } )" />
+
+ <variable name="new-overrides-map" as="map( xs:string, element( preproc:sym ) )"
+ select="map:merge(
+ for $sym in $new/preproc:sym[ @override = 'true' ]
+ return map{ string( $sym/@name ) : $sym } )" />
+
<preproc:syms>
<sequence select="$cursym" />
@@ -467,7 +496,13 @@
<variable name="dupall" as="element( preproc:sym )*"
select="$cursym-map( $name ),
$extresults-map( $name ),
- preceding-sibling::preproc:sym[ @name = $name ]" />
+ if ( count( $new-seq-map( $name ) ) gt 1 ) then
+ preceding-sibling::preproc:sym[ @name = $name ]
+ else
+ ()" />
+
+ <variable name="override" as="element( preproc:sym )?"
+ select="$new-overrides-map( @name )" />
<choose>
<when test="@pollute='true' and not( @type )">
@@ -475,9 +510,7 @@
<sequence select="." />
</when>
- <!-- note that dupall uses preceding-sibling, which will catch
- duplicates in that case even if @override is not set -->
- <when test="following-sibling::preproc:sym[ @name=$name and @override='true' ]">
+ <when test="exists( $override ) and not( $override is . )">
<!-- overridden; we're obsolete :( -->
</when>