You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by co...@apache.org on 2026/10/16 15:53:02 UTC
(cxf) branch main updated: CXF-7641: Reduce allocations in CachingXmlEventWriter (#3592)
This is an automated email from the ASF dual-hosted git repository.
coheigea pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cxf.git
The following commit(s) were added to refs/heads/main by this push:
new 5354732d878 CXF-7641: Reduce allocations in CachingXmlEventWriter (#3592)
5354732d878 is described below
commit 5354732d878ecae81391e049701e518084b0873d
Author: Colm O hEigeartaigh <co...@users.noreply.github.com>
AuthorDate: Fri Oct 16 16:52:55 2026 +0100
CXF-7641: Reduce allocations in CachingXmlEventWriter (#3592)
---
.../cxf/staxutils/CachingXmlEventWriter.java | 25 ++++++++++++++++------
.../org/apache/cxf/staxutils/StaxUtilsTest.java | 23 ++++++++++++++++++++
2 files changed, 41 insertions(+), 7 deletions(-)
diff --git a/core/src/main/java/org/apache/cxf/staxutils/CachingXmlEventWriter.java b/core/src/main/java/org/apache/cxf/staxutils/CachingXmlEventWriter.java
index 9900ee0308f..de4d7b02672 100644
--- a/core/src/main/java/org/apache/cxf/staxutils/CachingXmlEventWriter.java
+++ b/core/src/main/java/org/apache/cxf/staxutils/CachingXmlEventWriter.java
@@ -157,12 +157,12 @@ public class CachingXmlEventWriter implements XMLStreamWriter {
}
public void setDefaultNamespace(String ns) throws XMLStreamException {
- curContext.addNs("", ns);
+ addNs("", ns);
}
public void writeNamespace(String pfx, String ns) throws XMLStreamException {
- curContext.addNs(pfx, ns);
+ addNs(pfx, ns);
if (StringUtils.isEmpty(pfx)) {
addEvent(factory.createNamespace(ns));
} else {
@@ -179,7 +179,18 @@ public class CachingXmlEventWriter implements XMLStreamWriter {
}
}
public void setPrefix(String pfx, String uri) throws XMLStreamException {
- curContext.addNs(pfx, uri);
+ addNs(pfx, uri);
+ }
+
+ /**
+ * Elements share their parent's namespace context until they declare a namespace,
+ * to avoid allocating a context per element when buffering large documents.
+ */
+ private void addNs(String pfx, String ns) {
+ if (!contexts.isEmpty() && curContext == contexts.peek()) {
+ curContext = new NSContext(curContext);
+ }
+ curContext.addNs(pfx, ns);
}
@@ -211,7 +222,6 @@ public class CachingXmlEventWriter implements XMLStreamWriter {
public void writeStartElement(String name) throws XMLStreamException {
elNames.push(lastStart);
contexts.push(curContext);
- curContext = new NSContext(curContext);
lastStart = new QName(name);
Set<javax.xml.stream.events.Attribute> atSet = Collections.emptySet();
Set<javax.xml.stream.events.Namespace> nsSet = Collections.emptySet();
@@ -220,7 +230,6 @@ public class CachingXmlEventWriter implements XMLStreamWriter {
public void writeStartElement(String name, String ns) throws XMLStreamException {
elNames.push(lastStart);
contexts.push(curContext);
- curContext = new NSContext(curContext);
lastStart = new QName(ns, name);
Set<javax.xml.stream.events.Attribute> atSet = Collections.emptySet();
Set<javax.xml.stream.events.Namespace> nsSet = Collections.emptySet();
@@ -229,7 +238,6 @@ public class CachingXmlEventWriter implements XMLStreamWriter {
public void writeStartElement(String pfx, String name, String ns) throws XMLStreamException {
elNames.push(lastStart);
contexts.push(curContext);
- curContext = new NSContext(curContext);
lastStart = new QName(ns, name, pfx);
Set<javax.xml.stream.events.Attribute> atSet = Collections.emptySet();
Set<javax.xml.stream.events.Namespace> nsSet = Collections.emptySet();
@@ -238,12 +246,15 @@ public class CachingXmlEventWriter implements XMLStreamWriter {
public static class NSContext implements NamespaceContext {
NamespaceContext parent;
- Map<String, String> map = new HashMap<>();
+ Map<String, String> map = Collections.emptyMap();
public NSContext(NamespaceContext p) {
parent = p;
}
public void addNs(String pfx, String ns) {
+ if (map.isEmpty()) {
+ map = new HashMap<>();
+ }
map.put(pfx, ns);
}
diff --git a/core/src/test/java/org/apache/cxf/staxutils/StaxUtilsTest.java b/core/src/test/java/org/apache/cxf/staxutils/StaxUtilsTest.java
index 54b1c0ba657..ac0a54c98af 100644
--- a/core/src/test/java/org/apache/cxf/staxutils/StaxUtilsTest.java
+++ b/core/src/test/java/org/apache/cxf/staxutils/StaxUtilsTest.java
@@ -61,6 +61,7 @@ import static org.hamcrest.core.IsEqual.equalTo;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -443,6 +444,28 @@ public class StaxUtilsTest {
assertEquals(-1, idx);
}
+ @Test
+ public void testCachingXmlEventWriterNamespaceScope() throws Exception {
+ CachingXmlEventWriter writer = new CachingXmlEventWriter();
+ writer.writeStartElement("root");
+ writer.writeStartElement("a", "first", "urn:a");
+ writer.writeNamespace("a", "urn:a");
+ writer.writeStartElement("child");
+ assertEquals("urn:a", writer.getNamespaceContext().getNamespaceURI("a"));
+ assertEquals("a", writer.getPrefix("urn:a"));
+ writer.writeEndElement();
+ writer.writeEndElement();
+ assertNull(writer.getNamespaceContext().getNamespaceURI("a"));
+ writer.writeStartElement("second");
+ assertNull(writer.getNamespaceContext().getNamespaceURI("a"));
+ assertNull(writer.getPrefix("urn:a"));
+ writer.setPrefix("b", "urn:b");
+ assertEquals("urn:b", writer.getNamespaceContext().getNamespaceURI("b"));
+ writer.writeEndElement();
+ assertNull(writer.getNamespaceContext().getNamespaceURI("b"));
+ writer.writeEndElement();
+ }
+
@Test
public void testCopyWithEmptyNamespace() throws Exception {
StringBuilder in = new StringBuilder(128);