You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by rp...@apache.org on 2016/09/02 15:13:51 UTC
logging-log4j2 git commit: LOG4J2-1349 make new ThreadContextMap
implementations package-private and introduce factory to instantiate them in
ThreadContext
Repository: logging-log4j2
Updated Branches:
refs/heads/LOG4J2-1349-gcfree-threadcontext e6cf7c909 -> 7aac69c81
LOG4J2-1349 make new ThreadContextMap implementations package-private and introduce factory to instantiate them in ThreadContext
Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/7aac69c8
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/7aac69c8
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/7aac69c8
Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext
Commit: 7aac69c81b2a8cbb8267424c1c6604b08f6009f5
Parents: e6cf7c9
Author: rpopma <rp...@apache.org>
Authored: Sat Sep 3 00:13:43 2016 +0900
Committer: rpopma <rp...@apache.org>
Committed: Sat Sep 3 00:13:43 2016 +0900
----------------------------------------------------------------------
.../org/apache/logging/log4j/ThreadContext.java | 60 ++-----------
.../CopyOnWriteSortedArrayThreadContextMap.java | 4 +-
.../GarbageFreeSortedArrayThreadContextMap.java | 2 +-
.../log4j/spi/ThreadContextMapFactory.java | 91 ++++++++++++++++++++
.../log4j/perf/jmh/ThreadContextBenchmark.java | 14 ++-
.../CopyOnWriteOpenHashMapThreadContextMap.java | 42 ---------
.../GarbageFreeOpenHashMapThreadContextMap.java | 45 ----------
.../CopyOnWriteOpenHashMapThreadContextMap.java | 44 ++++++++++
.../GarbageFreeOpenHashMapThreadContextMap.java | 47 ++++++++++
9 files changed, 196 insertions(+), 153 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7aac69c8/log4j-api/src/main/java/org/apache/logging/log4j/ThreadContext.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/ThreadContext.java b/log4j-api/src/main/java/org/apache/logging/log4j/ThreadContext.java
index bc01bf8..4636469 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/ThreadContext.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/ThreadContext.java
@@ -27,19 +27,14 @@ import java.util.Map;
import java.util.NoSuchElementException;
import org.apache.logging.log4j.message.ParameterizedMessage;
-import org.apache.logging.log4j.spi.CopyOnWriteSortedArrayThreadContextMap;
-import org.apache.logging.log4j.spi.DefaultThreadContextMap;
import org.apache.logging.log4j.spi.DefaultThreadContextStack;
-import org.apache.logging.log4j.spi.GarbageFreeSortedArrayThreadContextMap;
import org.apache.logging.log4j.spi.NoOpThreadContextMap;
-import org.apache.logging.log4j.spi.Provider;
import org.apache.logging.log4j.spi.ThreadContextMap;
import org.apache.logging.log4j.spi.ThreadContextMap2;
+import org.apache.logging.log4j.spi.ThreadContextMapFactory;
import org.apache.logging.log4j.spi.ThreadContextStack;
import org.apache.logging.log4j.status.StatusLogger;
-import org.apache.logging.log4j.util.Constants;
import org.apache.logging.log4j.util.PropertiesUtil;
-import org.apache.logging.log4j.util.ProviderUtil;
/**
* The ThreadContext allows applications to store information either in a Map or a Stack.
@@ -193,8 +188,6 @@ public final class ThreadContext {
private static final String DISABLE_MAP = "disableThreadContextMap";
private static final String DISABLE_STACK = "disableThreadContextStack";
private static final String DISABLE_ALL = "disableThreadContext";
- private static final String THREAD_CONTEXT_KEY = "log4j2.threadContextMap";
- private static final String GC_FREE_THREAD_CONTEXT_KEY = "log4j2.garbagefree.threadContextMap";
private static boolean disableAll;
private static boolean useMap;
@@ -222,54 +215,11 @@ public final class ThreadContext {
useMap = !(managerProps.getBooleanProperty(DISABLE_MAP) || disableAll);
contextStack = new DefaultThreadContextStack(useStack);
- final String threadContextMapName = managerProps.getStringProperty(THREAD_CONTEXT_KEY);
- final ClassLoader cl = ProviderUtil.findClassLoader();
- if (threadContextMapName != null) {
- try {
- final Class<?> clazz = cl.loadClass(threadContextMapName);
- if (ThreadContextMap.class.isAssignableFrom(clazz)) {
- contextMap = (ThreadContextMap) clazz.newInstance();
- }
- } catch (final ClassNotFoundException cnfe) {
- LOGGER.error("Unable to locate configured ThreadContextMap {}", threadContextMapName);
- } catch (final Exception ex) {
- LOGGER.error("Unable to create configured ThreadContextMap {}", threadContextMapName, ex);
- }
- }
- if (contextMap == null && ProviderUtil.hasProviders()) {
- final String factoryClassName = LogManager.getFactory().getClass().getName();
- for (final Provider provider : ProviderUtil.getProviders()) {
- if (factoryClassName.equals(provider.getClassName())) {
- final Class<? extends ThreadContextMap> clazz = provider.loadThreadContextMap();
- if (clazz != null) {
- try {
- contextMap = clazz.newInstance();
- break;
- } catch (final Exception e) {
- LOGGER.error("Unable to locate or load configured ThreadContextMap {}",
- provider.getThreadContextMap(), e);
- contextMap = createThreadContextMap(useMap);
- }
- }
- }
- }
- }
- if (contextMap == null) {
- contextMap = createThreadContextMap(useMap);
- }
- }
-
- private static ThreadContextMap createThreadContextMap(final boolean doUseMap) {
- if (!doUseMap) {
- return new NoOpThreadContextMap();
- }
- if (Constants.ENABLE_THREADLOCALS) {
- if (PropertiesUtil.getProperties().getBooleanProperty(GC_FREE_THREAD_CONTEXT_KEY)) {
- return new GarbageFreeSortedArrayThreadContextMap();
- }
- return new CopyOnWriteSortedArrayThreadContextMap();
+ if (!useMap) {
+ contextMap = new NoOpThreadContextMap();
+ } else {
+ contextMap = ThreadContextMapFactory.createThreadContextMap();
}
- return new DefaultThreadContextMap(doUseMap);
}
/**
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7aac69c8/log4j-api/src/main/java/org/apache/logging/log4j/spi/CopyOnWriteSortedArrayThreadContextMap.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/CopyOnWriteSortedArrayThreadContextMap.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/CopyOnWriteSortedArrayThreadContextMap.java
index 80c0e4d..81c69d5 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/CopyOnWriteSortedArrayThreadContextMap.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/CopyOnWriteSortedArrayThreadContextMap.java
@@ -32,8 +32,8 @@ import org.apache.logging.log4j.util.PropertiesUtil;
*
* @since 2.7
*/
-public class CopyOnWriteSortedArrayThreadContextMap implements ThreadContextMap, ThreadContextMap2,
- CopyOnWrite, MutableContextDataSupplier {
+class CopyOnWriteSortedArrayThreadContextMap implements ThreadContextMap, ThreadContextMap2, CopyOnWrite,
+ MutableContextDataSupplier {
/**
* The default initial capacity.
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7aac69c8/log4j-api/src/main/java/org/apache/logging/log4j/spi/GarbageFreeSortedArrayThreadContextMap.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/GarbageFreeSortedArrayThreadContextMap.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/GarbageFreeSortedArrayThreadContextMap.java
index 04705dd..cf93367 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/spi/GarbageFreeSortedArrayThreadContextMap.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/GarbageFreeSortedArrayThreadContextMap.java
@@ -32,7 +32,7 @@ import org.apache.logging.log4j.util.PropertiesUtil;
* </p>
* @since 2.7
*/
-public class GarbageFreeSortedArrayThreadContextMap implements ThreadContextMap, ThreadContextMap2,
+class GarbageFreeSortedArrayThreadContextMap implements ThreadContextMap, ThreadContextMap2,
MutableContextDataSupplier {
/**
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7aac69c8/log4j-api/src/main/java/org/apache/logging/log4j/spi/ThreadContextMapFactory.java
----------------------------------------------------------------------
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/spi/ThreadContextMapFactory.java b/log4j-api/src/main/java/org/apache/logging/log4j/spi/ThreadContextMapFactory.java
new file mode 100644
index 0000000..b44f883
--- /dev/null
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/spi/ThreadContextMapFactory.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.spi;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.status.StatusLogger;
+import org.apache.logging.log4j.util.Constants;
+import org.apache.logging.log4j.util.PropertiesUtil;
+import org.apache.logging.log4j.util.ProviderUtil;
+
+/**
+ * Creates the ThreadContextMap instance used by the ThreadContext.
+ *
+ * @see ThreadContextMap
+ * @see org.apache.logging.log4j.ThreadContext
+ * @since 2.7
+ */
+public final class ThreadContextMapFactory {
+ private static final Logger LOGGER = StatusLogger.getLogger();
+ private static final String THREAD_CONTEXT_KEY = "log4j2.threadContextMap";
+ private static final String GC_FREE_THREAD_CONTEXT_KEY = "log4j2.garbagefree.threadContextMap";
+
+ private ThreadContextMapFactory() {
+ }
+
+ public static ThreadContextMap createThreadContextMap() {
+ final PropertiesUtil managerProps = PropertiesUtil.getProperties();
+ final String threadContextMapName = managerProps.getStringProperty(THREAD_CONTEXT_KEY);
+ final ClassLoader cl = ProviderUtil.findClassLoader();
+ ThreadContextMap result = null;
+ if (threadContextMapName != null) {
+ try {
+ final Class<?> clazz = cl.loadClass(threadContextMapName);
+ if (ThreadContextMap.class.isAssignableFrom(clazz)) {
+ result = (ThreadContextMap) clazz.newInstance();
+ }
+ } catch (final ClassNotFoundException cnfe) {
+ LOGGER.error("Unable to locate configured ThreadContextMap {}", threadContextMapName);
+ } catch (final Exception ex) {
+ LOGGER.error("Unable to create configured ThreadContextMap {}", threadContextMapName, ex);
+ }
+ }
+ if (result == null && ProviderUtil.hasProviders()) {
+ final String factoryClassName = LogManager.getFactory().getClass().getName();
+ for (final Provider provider : ProviderUtil.getProviders()) {
+ if (factoryClassName.equals(provider.getClassName())) {
+ final Class<? extends ThreadContextMap> clazz = provider.loadThreadContextMap();
+ if (clazz != null) {
+ try {
+ result = clazz.newInstance();
+ break;
+ } catch (final Exception e) {
+ LOGGER.error("Unable to locate or load configured ThreadContextMap {}",
+ provider.getThreadContextMap(), e);
+ result = createDefaultThreadContextMap();
+ }
+ }
+ }
+ }
+ }
+ if (result == null) {
+ result = createDefaultThreadContextMap();
+ }
+ return result;
+ }
+
+ private static ThreadContextMap createDefaultThreadContextMap() {
+ if (Constants.ENABLE_THREADLOCALS) {
+ if (PropertiesUtil.getProperties().getBooleanProperty(GC_FREE_THREAD_CONTEXT_KEY)) {
+ return new GarbageFreeSortedArrayThreadContextMap();
+ }
+ return new CopyOnWriteSortedArrayThreadContextMap();
+ }
+ return new DefaultThreadContextMap(true);
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7aac69c8/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/ThreadContextBenchmark.java
----------------------------------------------------------------------
diff --git a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/ThreadContextBenchmark.java b/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/ThreadContextBenchmark.java
index 6e07abb..c45f4c6 100644
--- a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/ThreadContextBenchmark.java
+++ b/log4j-perf/src/main/java/org/apache/logging/log4j/perf/jmh/ThreadContextBenchmark.java
@@ -30,15 +30,13 @@ import org.apache.logging.log4j.ThreadContextBenchmarkAccess;
import org.apache.logging.log4j.core.config.Property;
import org.apache.logging.log4j.core.impl.ContextDataInjector;
import org.apache.logging.log4j.core.impl.ContextDataInjectorFactory;
-import org.apache.logging.log4j.util.ArrayContextData;
-import org.apache.logging.log4j.perf.nogc.CopyOnWriteOpenHashMapThreadContextMap;
-import org.apache.logging.log4j.spi.CopyOnWriteSortedArrayThreadContextMap;
+import org.apache.logging.log4j.perf.nogc.OpenHashMapContextData;
+import org.apache.logging.log4j.spi.CopyOnWriteOpenHashMapThreadContextMap;
import org.apache.logging.log4j.spi.DefaultThreadContextMap;
-import org.apache.logging.log4j.perf.nogc.GarbageFreeOpenHashMapThreadContextMap;
-import org.apache.logging.log4j.spi.GarbageFreeSortedArrayThreadContextMap;
+import org.apache.logging.log4j.spi.GarbageFreeOpenHashMapThreadContextMap;
import org.apache.logging.log4j.spi.MutableContextData;
-import org.apache.logging.log4j.perf.nogc.OpenHashMapContextData;
import org.apache.logging.log4j.spi.ThreadContextMap;
+import org.apache.logging.log4j.util.ArrayContextData;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
@@ -83,9 +81,9 @@ public class ThreadContextBenchmark {
static {
IMPLEMENTATIONS.put(DEFAULT_CONTEXT_MAP, DefaultThreadContextMap.class);
IMPLEMENTATIONS.put(COPY_OPENHASH_MAP, CopyOnWriteOpenHashMapThreadContextMap.class);
- IMPLEMENTATIONS.put(COPY_ARRAY_MAP, CopyOnWriteSortedArrayThreadContextMap.class);
+ IMPLEMENTATIONS.put(COPY_ARRAY_MAP, CopyOnWriteOpenHashMapThreadContextMap.SUPER); //CopyOnWriteSortedArrayThreadContextMap.class);
IMPLEMENTATIONS.put(NO_GC_OPENHASH_MAP, GarbageFreeOpenHashMapThreadContextMap.class);
- IMPLEMENTATIONS.put(NO_GC_ARRAY_MAP, GarbageFreeSortedArrayThreadContextMap.class);
+ IMPLEMENTATIONS.put(NO_GC_ARRAY_MAP, GarbageFreeOpenHashMapThreadContextMap.SUPER); //GarbageFreeSortedArrayThreadContextMap.class);
}
@Param({ "Default", "CopyOpenHash", "CopySortedArray", "NoGcOpenHash", "NoGcSortedArray"})
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7aac69c8/log4j-perf/src/main/java/org/apache/logging/log4j/perf/nogc/CopyOnWriteOpenHashMapThreadContextMap.java
----------------------------------------------------------------------
diff --git a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/nogc/CopyOnWriteOpenHashMapThreadContextMap.java b/log4j-perf/src/main/java/org/apache/logging/log4j/perf/nogc/CopyOnWriteOpenHashMapThreadContextMap.java
deleted file mode 100644
index e34c031..0000000
--- a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/nogc/CopyOnWriteOpenHashMapThreadContextMap.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.perf.nogc;
-
-import org.apache.logging.log4j.spi.CopyOnWriteSortedArrayThreadContextMap;
-import org.apache.logging.log4j.spi.ContextData;
-import org.apache.logging.log4j.spi.MutableContextData;
-import org.apache.logging.log4j.util.PropertiesUtil;
-
-/**
- * {@code OpenHashMapContextData}-based implementation of the {@code ThreadContextMap} interface that creates a copy of
- * the data structure on every modification. Any particular instance of the data structure is a snapshot of the
- * ThreadContext at some point in time and can safely be passed off to other threads
- *
- * @since 2.7
- */
-public class CopyOnWriteOpenHashMapThreadContextMap extends CopyOnWriteSortedArrayThreadContextMap {
- @Override
- protected MutableContextData createMutableContextData() {
- return new OpenHashMapContextData<>(PropertiesUtil.getProperties().getIntegerProperty(
- PROPERTY_NAME_INITIAL_CAPACITY, DEFAULT_INITIAL_CAPACITY));
- }
-
- @Override
- protected MutableContextData createMutableContextData(final ContextData original) {
- return new OpenHashMapContextData<>(original);
- }
-}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7aac69c8/log4j-perf/src/main/java/org/apache/logging/log4j/perf/nogc/GarbageFreeOpenHashMapThreadContextMap.java
----------------------------------------------------------------------
diff --git a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/nogc/GarbageFreeOpenHashMapThreadContextMap.java b/log4j-perf/src/main/java/org/apache/logging/log4j/perf/nogc/GarbageFreeOpenHashMapThreadContextMap.java
deleted file mode 100644
index cb97936..0000000
--- a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/nogc/GarbageFreeOpenHashMapThreadContextMap.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache license, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the license for the specific language governing permissions and
- * limitations under the license.
- */
-package org.apache.logging.log4j.perf.nogc;
-
-import org.apache.logging.log4j.spi.GarbageFreeSortedArrayThreadContextMap;
-import org.apache.logging.log4j.spi.ContextData;
-import org.apache.logging.log4j.spi.MutableContextData;
-import org.apache.logging.log4j.util.PropertiesUtil;
-
-/**
- * {@code OpenHashMapContextData}-based implementation of the {@code ThreadContextMap} interface that attempts not to
- * create temporary objects. Adding and removing key-value pairs will not create temporary objects.
- * <p>
- * Since the underlying data structure is modified directly it is not suitable for passing by reference to other
- * threads. Instead, client code needs to copy the contents when interacting with another thread.
- * </p>
- *
- * @since 2.7
- */
-public class GarbageFreeOpenHashMapThreadContextMap extends GarbageFreeSortedArrayThreadContextMap {
- @Override
- protected MutableContextData createMutableContextData() {
- return new OpenHashMapContextData<>(PropertiesUtil.getProperties().getIntegerProperty(
- PROPERTY_NAME_INITIAL_CAPACITY, DEFAULT_INITIAL_CAPACITY));
- }
-
- @Override
- protected MutableContextData createMutableContextData(final ContextData original) {
- return new OpenHashMapContextData<>(original);
- }
-}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7aac69c8/log4j-perf/src/main/java/org/apache/logging/log4j/spi/CopyOnWriteOpenHashMapThreadContextMap.java
----------------------------------------------------------------------
diff --git a/log4j-perf/src/main/java/org/apache/logging/log4j/spi/CopyOnWriteOpenHashMapThreadContextMap.java b/log4j-perf/src/main/java/org/apache/logging/log4j/spi/CopyOnWriteOpenHashMapThreadContextMap.java
new file mode 100644
index 0000000..463e3ed
--- /dev/null
+++ b/log4j-perf/src/main/java/org/apache/logging/log4j/spi/CopyOnWriteOpenHashMapThreadContextMap.java
@@ -0,0 +1,44 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.spi;
+
+import org.apache.logging.log4j.perf.nogc.OpenHashMapContextData;
+import org.apache.logging.log4j.util.PropertiesUtil;
+
+/**
+ * {@code OpenHashMapContextData}-based implementation of the {@code ThreadContextMap} interface that creates a copy of
+ * the data structure on every modification. Any particular instance of the data structure is a snapshot of the
+ * ThreadContext at some point in time and can safely be passed off to other threads
+ *
+ * @since 2.7
+ */
+public class CopyOnWriteOpenHashMapThreadContextMap extends CopyOnWriteSortedArrayThreadContextMap {
+
+ /** Constant used in benchmark code */
+ public static final Class<? extends ThreadContextMap> SUPER = CopyOnWriteSortedArrayThreadContextMap.class;
+
+ @Override
+ protected MutableContextData createMutableContextData() {
+ return new OpenHashMapContextData<>(PropertiesUtil.getProperties().getIntegerProperty(
+ PROPERTY_NAME_INITIAL_CAPACITY, DEFAULT_INITIAL_CAPACITY));
+ }
+
+ @Override
+ protected MutableContextData createMutableContextData(final ContextData original) {
+ return new OpenHashMapContextData<>(original);
+ }
+}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7aac69c8/log4j-perf/src/main/java/org/apache/logging/log4j/spi/GarbageFreeOpenHashMapThreadContextMap.java
----------------------------------------------------------------------
diff --git a/log4j-perf/src/main/java/org/apache/logging/log4j/spi/GarbageFreeOpenHashMapThreadContextMap.java b/log4j-perf/src/main/java/org/apache/logging/log4j/spi/GarbageFreeOpenHashMapThreadContextMap.java
new file mode 100644
index 0000000..5df5dda
--- /dev/null
+++ b/log4j-perf/src/main/java/org/apache/logging/log4j/spi/GarbageFreeOpenHashMapThreadContextMap.java
@@ -0,0 +1,47 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache license, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the license for the specific language governing permissions and
+ * limitations under the license.
+ */
+package org.apache.logging.log4j.spi;
+
+import org.apache.logging.log4j.perf.nogc.OpenHashMapContextData;
+import org.apache.logging.log4j.util.PropertiesUtil;
+
+/**
+ * {@code OpenHashMapContextData}-based implementation of the {@code ThreadContextMap} interface that attempts not to
+ * create temporary objects. Adding and removing key-value pairs will not create temporary objects.
+ * <p>
+ * Since the underlying data structure is modified directly it is not suitable for passing by reference to other
+ * threads. Instead, client code needs to copy the contents when interacting with another thread.
+ * </p>
+ *
+ * @since 2.7
+ */
+public class GarbageFreeOpenHashMapThreadContextMap extends GarbageFreeSortedArrayThreadContextMap {
+
+ /** Constant used in benchmark code */
+ public static final Class<? extends ThreadContextMap> SUPER = GarbageFreeSortedArrayThreadContextMap.class;
+
+ @Override
+ protected MutableContextData createMutableContextData() {
+ return new OpenHashMapContextData<>(PropertiesUtil.getProperties().getIntegerProperty(
+ PROPERTY_NAME_INITIAL_CAPACITY, DEFAULT_INITIAL_CAPACITY));
+ }
+
+ @Override
+ protected MutableContextData createMutableContextData(final ContextData original) {
+ return new OpenHashMapContextData<>(original);
+ }
+}