This is an automated email from the ASF dual-hosted git repository.
olabusayoT pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/daffodil.git
The following commit(s) were added to refs/heads/main by this push:
new d902f9442 Add string-keyed fast path to NS.apply avoiding URI.create
per element
d902f9442 is described below
commit d902f94427ac45796b501586e33ef71134f4ca0b
Author: olabusayoT <[email protected]>
AuthorDate: Tue Aug 18 16:24:24 2026 -0400
Add string-keyed fast path to NS.apply avoiding URI.create per element
NextElementResolver's OnlyOnePossibilityForNextElement and
SeveralPossibilitiesForNextElement both call NS(namespace) on every
element resolution when the infoset source has namespaces. NS.apply(String)
previously ran URI.create plus a ReentrantReadWriteLock-guarded WeakHashMap
lookup on every call, even for a namespace string seen many times before.
NS now extends UniquenessCache[String, NS], keyed directly by the
namespace string instead of URI. A cache hit never touches URI.create;
URI.create only runs in valueFromKey on a genuine cache miss. apply(URI)
delegates to apply(uri.toString).
DAFFODIL-3092
---
.../org/apache/daffodil/lib/xml/Namespaces.scala | 24 ++++++++++++++--------
1 file changed, 15 insertions(+), 9 deletions(-)
diff --git
a/daffodil-core/src/main/scala/org/apache/daffodil/lib/xml/Namespaces.scala
b/daffodil-core/src/main/scala/org/apache/daffodil/lib/xml/Namespaces.scala
index 47498b282..443faffca 100644
--- a/daffodil-core/src/main/scala/org/apache/daffodil/lib/xml/Namespaces.scala
+++ b/daffodil-core/src/main/scala/org/apache/daffodil/lib/xml/Namespaces.scala
@@ -28,7 +28,7 @@ import org.apache.daffodil.lib.util.UniquenessCache
*
* Import this object. I.e., import org.apache.daffodil.lib.xml.NS.*
*/
-object NS extends UniquenessCache[URI, NS] {
+object NS extends UniquenessCache[String, NS] {
/**
* Import these implicit conversions for convenience if you like
@@ -37,25 +37,31 @@ object NS extends UniquenessCache[URI, NS] {
implicit def implicitNStoString(ns: NS): String = ns.toString
implicit def implicitNStoURI(ns: NS): URI = ns.uri
- override def apply(uri: URI): NS = {
+ def apply(uri: URI): NS = {
Assert.usage(uri != null)
- super.apply(uri)
+ apply(uri.toString)
}
- def apply(nsString: String): NS = {
- // NoNamespace and UnspecifiedNamespace do not have a URI, and so they are
- // not retrieved from the uniqueness cache
+ /**
+ * The cache is keyed directly by the namespace string (e.g. resolving
+ * next-elements during unparse, where the same handful of namespace URI
+ * strings recur once per element in a document), not by URI. A cache hit
+ * therefore never parses the string via URI.create, only a cache miss
+ * (the first time a given string is seen) pays that cost, in
+ * valueFromKey below.
+ */
+ override def apply(nsString: String): NS = {
if (nsString == null || nsString == "" || nsString ==
NoNamespace.toString) {
NoNamespace
} else if (nsString == UnspecifiedNamespace.toString) {
UnspecifiedNamespace
} else {
- apply(URI.create(nsString))
+ super.apply(nsString)
}
}
- protected def valueFromKey(uri: URI): NS = new NS(uri)
- protected def keyFromValue(ns: NS): Option[URI] = Some(ns.uri)
+ protected def valueFromKey(nsString: String): NS = new
NS(URI.create(nsString))
+ protected def keyFromValue(ns: NS): Option[String] = Some(ns.uri.toString)
/**
* Finds all prefixes for a given namespace. Used to suggest