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

Reply via email to