* terms of the Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*/
-
package org.opendaylight.netconf.nettyutil.handler;
import static java.util.Objects.requireNonNull;
import org.opendaylight.netconf.shaded.exificient.core.EXIFactory;
import org.opendaylight.netconf.shaded.exificient.core.exceptions.EXIException;
import org.opendaylight.netconf.shaded.exificient.main.api.sax.SAXEncoder;
-import org.opendaylight.netconf.shaded.exificient.main.api.sax.SAXFactory;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
-import org.xml.sax.XMLReader;
public final class NetconfEXICodec {
/**
}
});
- private final SAXFactory exiFactory;
+ private final ThreadLocalSAXFactory exiFactory;
private NetconfEXICodec(final EXIFactory exiFactory) {
- this.exiFactory = new SAXFactory(requireNonNull(exiFactory));
+ this.exiFactory = new ThreadLocalSAXFactory(requireNonNull(exiFactory));
}
public static NetconfEXICodec forParameters(final EXIParameters parameters) {
return CODECS.getUnchecked(parameters);
}
- XMLReader getReader() throws EXIException {
- final XMLReader reader = exiFactory.createEXIReader();
+ ThreadLocalSAXDecoder getReader() throws EXIException {
+ final ThreadLocalSAXDecoder reader = exiFactory.createEXIReader();
reader.setEntityResolver(ENTITY_RESOLVER);
return reader;
}
SAXEncoder getWriter() throws EXIException {
- final SAXEncoder writer = exiFactory.createEXIWriter();
- return writer;
+ return exiFactory.createEXIWriter();
}
}
import org.w3c.dom.Document;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
-import org.xml.sax.XMLReader;
public final class NetconfEXIToMessageDecoder extends ByteToMessageDecoder {
* which means that {@link #decode(ChannelHandlerContext, ByteBuf, List)}
* cannot be invoked concurrently. Hence we can reuse the reader.
*/
- private final XMLReader reader;
+ private final ThreadLocalSAXDecoder reader;
private final DocumentBuilder documentBuilder;
- private NetconfEXIToMessageDecoder(final XMLReader reader) {
+ private NetconfEXIToMessageDecoder(final ThreadLocalSAXDecoder reader) {
this.reader = requireNonNull(reader);
this.documentBuilder = UntrustedXML.newDocumentBuilder();
}
--- /dev/null
+/*
+ * Copyright (c) 2019 Pantheon Technologies, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.nettyutil.handler;
+
+import java.io.IOException;
+import org.opendaylight.netconf.shaded.exificient.core.EXIFactory;
+import org.opendaylight.netconf.shaded.exificient.core.exceptions.EXIException;
+import org.opendaylight.netconf.shaded.exificient.main.api.sax.SAXDecoder;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+/**
+ * Utility SAXDecoder, which reuses a thread-local buffer during parse operations.
+ */
+final class ThreadLocalSAXDecoder extends SAXDecoder {
+ // Note these limits are number of chars, i.e. 2 bytes
+ private static final int INITIAL_SIZE = 4096;
+ private static final int CACHE_MAX_SIZE = 32768;
+ private static final ThreadLocal<char[]> CBUFFER_CACHE = ThreadLocal.withInitial(() -> new char[INITIAL_SIZE]);
+
+ ThreadLocalSAXDecoder(final EXIFactory noOptionsFactory) throws EXIException {
+ super(noOptionsFactory, null);
+ }
+
+ @Override
+ public void parse(final InputSource source) throws IOException, SAXException {
+ cbuffer = CBUFFER_CACHE.get();
+ final int startSize = cbuffer.length;
+ try {
+ super.parse(source);
+ } finally {
+ char[] toCache = cbuffer;
+ cbuffer = null;
+ if (toCache.length > CACHE_MAX_SIZE && startSize < CACHE_MAX_SIZE) {
+ // The buffer grew to large for caching, but make sure we enlarge our cached buffer to prevent
+ // some amount of reallocations in future.
+ toCache = new char[CACHE_MAX_SIZE];
+ }
+ CBUFFER_CACHE.set(toCache);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2019 Pantheon Technologies, s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.netconf.nettyutil.handler;
+
+import org.opendaylight.netconf.shaded.exificient.core.EXIFactory;
+import org.opendaylight.netconf.shaded.exificient.core.exceptions.EXIException;
+import org.opendaylight.netconf.shaded.exificient.main.api.sax.SAXFactory;
+
+/**
+ * A SAXFactory which hands out {@link ThreadLocalSAXDecoder}s.
+ */
+final class ThreadLocalSAXFactory extends SAXFactory {
+ ThreadLocalSAXFactory(final EXIFactory exiFactory) {
+ super(exiFactory);
+ }
+
+ @Override
+ public ThreadLocalSAXDecoder createEXIReader() throws EXIException {
+ return new ThreadLocalSAXDecoder(exiFactory);
+ }
+}