http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/OpenHashMapContextData.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/OpenHashMapContextData.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/OpenHashMapContextData.java deleted file mode 100644 index e1c0e13..0000000 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/OpenHashMapContextData.java +++ /dev/null @@ -1,887 +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.core.impl; - -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.util.Arrays; -import java.util.Collections; -import java.util.ConcurrentModificationException; -import java.util.HashMap; -import java.util.Map; -import java.util.Objects; - -import org.apache.logging.log4j.core.ContextData; -import org.apache.logging.log4j.core.util.BiConsumer; -import org.apache.logging.log4j.core.util.Integers; -import org.apache.logging.log4j.core.util.TriConsumer; -import org.apache.logging.log4j.spi.ThreadContextMap; - -/** - * Open hash map-based implementation of the {@code ContextData} interface. - * Implementation based on <a href="http://fastutil.di.unimi.it/">fastutil</a>'s - * <a href="http://fastutil.di.unimi.it/docs/it/unimi/dsi/fastutil/objects/Object2ObjectOpenHashMap.html">Object2ObjectOpenHashMap</a>. - * <p> - * A type-specific hash map with a fast, small-footprint implementation. - * - * <P> - * Instances of this class use a hash table to represent a map. The table is - * filled up to a specified <em>load factor</em>, and then doubled in size to - * accommodate new entries. If the table is emptied below <em>one fourth</em> of - * the load factor, it is halved in size. However, halving is not performed when - * deleting entries from an iterator, as it would interfere with the iteration - * process. - * - * <p> - * Note that {@link #clear()} does not modify the hash table size. Rather, the - * {@link #trim(int)} method lets you control the size of - * the table; this is particularly useful if you reuse instances of this class. - * <p> - * <ul> - * <li>Garbage-free iteration over key-value pairs with {@code BiConsumer} and {@code TriConsumer}.</li> - * <li>Fast copy. If the ThreadContextMap is also an instance of {@code OpenHashMapContextData}, - * the full thread context data can be transferred with two array copies and five field updates.</li> - * </ul> - * - * @see ThreadContextDataInjector - * @since 2.7 - */ -public class OpenHashMapContextData<K, V> implements MutableContextData, ThreadContextMap { - /** The initial default size of a hash table. */ - public static final int DEFAULT_INITIAL_SIZE = 16; - - /** The default load factor of a hash table. */ - public static final float DEFAULT_LOAD_FACTOR = .75f; - - private static final long serialVersionUID = -1486744623338827187L; - - /** The array of keys. */ - protected transient K[] keys; - /** The array of values. */ - protected transient V[] values; - /** The mask for wrapping a position counter. */ - protected transient int mask; - /** Whether this set contains the key zero. */ - protected transient boolean containsNullKey; - /** The current table size. */ - protected transient int arraySize; - /** - * Threshold after which we rehash. It must be the table size times {@link #loadFactor}. - */ - protected transient int maxFill; - /** Number of entries in the set (including the key zero, if present). */ - protected int size; - /** The acceptable load factor. */ - protected final float loadFactor; - - private V defRetValue = null; - - /** - * Creates a new hash map with initial expected - * {@link #DEFAULT_INITIAL_SIZE} entries and - * {@link #DEFAULT_LOAD_FACTOR} as load factor. - */ - public OpenHashMapContextData() { - this(DEFAULT_INITIAL_SIZE, DEFAULT_LOAD_FACTOR); - } - /** - * Creates a new hash map with {@link #DEFAULT_LOAD_FACTOR} as load factor. - * - * @param expected - * the expected number of elements in the hash map. - */ - public OpenHashMapContextData(final int expected) { - this(expected, DEFAULT_LOAD_FACTOR); - } - /** - * Creates a new hash map. - * - * <p> - * The actual table size will be the least power of two greater than - * <code>expected</code>/<code>f</code>. - * - * @param expected - * the expected number of elements in the hash set. - * @param f - * the load factor. - */ - @SuppressWarnings("unchecked") - public OpenHashMapContextData(final int expected, final float f) { - if (f <= 0 || f > 1) { - throw new IllegalArgumentException( - "Load factor must be greater than 0 and smaller than or equal to 1"); - } - if (expected < 0){ - throw new IllegalArgumentException( - "The expected number of elements must be nonnegative"); - } - this.loadFactor = f; - arraySize = HashCommon.arraySize(expected, f); - mask = arraySize - 1; - maxFill = HashCommon.maxFill(arraySize, f); - keys = (K[]) new Object[arraySize + 1]; - values = (V[]) new Object[arraySize + 1]; - } - /** - * Creates a new hash map with {@link #DEFAULT_LOAD_FACTOR} as load - * factor copying a given one. - * - * @param map - * a {@link Map} to be copied into the new hash map. - */ - public OpenHashMapContextData(final Map<? extends K, ? extends V> map) { - this(map, DEFAULT_LOAD_FACTOR); - } - /** - * Creates a new hash map copying a given one. - * - * @param map - * a {@link Map} to be copied into the new hash map. - * @param f - * the load factor. - */ - public OpenHashMapContextData(final Map<? extends K, ? extends V> map, final float f) { - this(map.size(), f); - putAll(map); - } - - /** - * Creates a new hash map with {@link #DEFAULT_LOAD_FACTOR} as load - * factor copying a given type-specific one. - * - * @param contextData - * a type-specific map to be copied into the new hash map. - */ - public OpenHashMapContextData(final ContextData contextData) { - this(contextData, DEFAULT_LOAD_FACTOR); - } - /** - * Creates a new hash map copying a given type-specific one. - * - * @param contextData - * a type-specific map to be copied into the new hash map. - * @param f - * the load factor. - */ - public OpenHashMapContextData(final ContextData contextData, final float f) { - this(contextData.size(), f); - if (contextData instanceof OpenHashMapContextData) { - initFrom0((OpenHashMapContextData) contextData); - } else { - contextData.forEach(PUT_ALL, this); - } - } - private static final TriConsumer<String, Object, MutableContextData> PUT_ALL = - new TriConsumer<String, Object, MutableContextData>() { - @Override - public void accept(final String key, final Object value, final MutableContextData contextData) { - contextData.putValue(key, value); - } - }; - - @SuppressWarnings("unchecked") - private void initFrom0(final OpenHashMapContextData other) { - // this.loadFactor = other.loadFactor; // final field - this.arraySize = other.arraySize; - this.size = other.size; - this.containsNullKey = other.containsNullKey; - this.mask = other.mask; - this.maxFill = other.maxFill; - keys = (K[]) Arrays.copyOf(other.keys, arraySize + 1); - values = (V[]) Arrays.copyOf(other.values, arraySize + 1); - } - - private int realSize() { - return containsNullKey ? size - 1 : size; - } - - private void ensureCapacity(final int capacity) { - final int needed = HashCommon.arraySize(capacity, loadFactor); - if (needed > arraySize) { - rehash(needed); - } - } - - private void tryCapacity(final long capacity) { - final int needed = (int) Math.min( - 1 << 30, Math.max(2, Integers.ceilingNextPowerOfTwo((int) Math.ceil(capacity / loadFactor)))); - if (needed > arraySize) { - rehash(needed); - } - } - - /** {@inheritDoc} */ - public void putAll(Map<? extends K, ? extends V> map) { - if (loadFactor <= .5) { - // The resulting map will be sized for m.size() elements - ensureCapacity(map.size()); - } else { - // The resulting map will be tentatively sized for size() + m.size() elements - tryCapacity(size() + map.size()); - } - for (Map.Entry<? extends K, ? extends V> entry : map.entrySet()) { - putObjectValue(entry.getKey(), entry.getValue()); - } - } - - @Override - public Map<String, String> asMap() { - final Map<String, String> result = new HashMap<>(size); - forEach(COPY_INTO_MAP, result); - return result; - } - - private static final TriConsumer<String, Object, Map<String, String>> COPY_INTO_MAP = - new TriConsumer<String, Object, Map<String, String>>() { - @Override - public void accept(final String k, final Object v, final Map<String, String> map) { - map.put(k, v == null ? null : v.toString()); - } - }; - - /* - * Removes all elements from this map. - * - * <P>To increase object reuse, this method does not change the table size. - * If you want to reduce the table size, you must use {@link #trim()}. - */ - @Override - public void clear() { - if (size == 0) { - return; - } - size = 0; - containsNullKey = false; - Arrays.fill(keys, (null)); - Arrays.fill(values, null); - } - - @Override - public boolean containsKey(final String key) { - return containsObjectKey((Object) key); - } - - @SuppressWarnings("unchecked") - private boolean containsObjectKey(final Object k) { - if (k == null) { - return containsNullKey; - } - K curr; - final K[] key = this.keys; - int pos; - // The starting point. - if ((curr = key[pos = HashCommon.mix(k.hashCode()) & mask]) == null) { - return false; - } - if (k.equals(curr)) { - return true; - } - // There's always an unused entry. - while (true) { - if ((curr = key[pos = (pos + 1) & mask]) == null) { - return false; - } - if (k.equals(curr)) { - return true; - } - } - } - - public boolean equals(final Object obj) { - if (obj == this) { - return true; - } - if (!(obj instanceof ContextData)) { - return false; - } - final ContextData other = (ContextData) obj; - if (other.size() != size()) { - return false; - } - int pos = arraySize; - if (containsNullKey) { - if (!Objects.equals(getObjectValue(null), other.getValue(null))) { - return false; - } - } - --pos; - final K myKeys[] = this.keys; - for (; pos >= 0; pos--) { - K k; - if ((k = myKeys[pos]) != null) { - if (!Objects.equals(values[pos], other.getValue((String) k))) { - return false; - } - } - } - return true; - } - - @Override - @SuppressWarnings("unchecked") - public <VAL> void forEach(final BiConsumer<String, ? super VAL> action) { - final int startSize = size; - final K myKeys[] = this.keys; - int pos = arraySize; - if (containsNullKey) { - action.accept((String) myKeys[pos], (VAL) values[pos]); - if (size != startSize) { - throw new ConcurrentModificationException(); - } - } - --pos; - for (; pos >= 0; pos--) { - if (myKeys[pos] != null) { - action.accept((String) myKeys[pos], (VAL) values[pos]); - if (size != startSize) { - throw new ConcurrentModificationException(); - } - } - } - } - - @Override - @SuppressWarnings("unchecked") - public <VAL, STATE> void forEach(final TriConsumer<String, ? super VAL, STATE> action, final STATE state) { - final int startSize = size; - final K myKeys[] = this.keys; - int pos = arraySize; - if (containsNullKey) { - action.accept((String) myKeys[pos], (VAL) values[pos], state); - if (size != startSize) { - throw new ConcurrentModificationException(); - } - } - --pos; - for (; pos >= 0; pos--) { - if (myKeys[pos] != null) { - action.accept((String) myKeys[pos], (VAL) values[pos], state); - if (size != startSize) { - throw new ConcurrentModificationException(); - } - } - } - } - - @Override - public String get(final String key) { - return (String) getObjectValue(key); - } - - @SuppressWarnings("unchecked") - private V getObjectValue(final Object k) { - if (k == null) { - return containsNullKey ? values[arraySize] : defRetValue; - } - K curr; - final K[] key = this.keys; - int pos; - // The starting point. - if ((curr = key[pos = HashCommon.mix(k.hashCode()) & mask]) == null) { - return defRetValue; - } - if (k.equals(curr)) { - return values[pos]; - } - // There's always an unused entry. - while (true) { - if (((curr = key[pos = (pos + 1) & mask]) == null)) { - return defRetValue; - } - if (k.equals(curr)) { - return values[pos]; - } - } - } - - @Override - public Map<String, String> getCopy() { - return asMap(); - } - - @Override - public Map<String, String> getImmutableMapOrNull() { - return isEmpty() ? null : Collections.unmodifiableMap(asMap()); - } - - @Override - public <VAL> VAL getValue(final String key) { - return (VAL) getObjectValue((Object) key); - } - - @Override - public boolean isEmpty() { - return size == 0; - } - - @Override - @SuppressWarnings("unchecked") - public void put(final String key, final String value) { - putObjectValue((K) key, (V) value); - } - - private int insert(final K k, final V v) { - int pos; - if (k == null) { - if (containsNullKey) { - return arraySize; - } - containsNullKey = true; - pos = arraySize; - } else { - K curr; - final K[] key = this.keys; - // The starting point. - if (!((curr = key[pos = HashCommon.mix(k.hashCode()) & mask]) == null)) { - if (curr.equals(k)) { - return pos; - } - while (!((curr = key[pos = (pos + 1) & mask]) == null)) { - if (curr.equals(k)) { - return pos; - } - } - } - } - keys[pos] = k; - values[pos] = v; - if (size++ >= maxFill) { - rehash(HashCommon.arraySize(size + 1, loadFactor)); - } - return -1; - } - - @Override - public void putAll(final ContextData source) { - if (size() == 0 && source instanceof OpenHashMapContextData) { - initFrom0((OpenHashMapContextData) source); - } else if (source != null) { - source.forEach(PUT_ALL, this); - } - } - - private V putObjectValue(final K k, final V v) { - final int pos = insert(k, v); - if (pos < 0) { - return defRetValue; - } - final V oldValue = values[pos]; - values[pos] = v; - return oldValue; - } - - @Override - @SuppressWarnings("unchecked") - public void putValue(final String key, final Object value) { - putObjectValue((K) key, (V) value); - } - - @Override - public void remove(final String key) { - removeObjectKey((Object) key); - } - - @SuppressWarnings("unchecked") - private V removeObjectKey(final Object k) { - if (k == null) { - if (containsNullKey) { - return removeNullEntry(); - } - return defRetValue; - } - final K[] key = this.keys; - int pos = HashCommon.mix(k.hashCode()) & mask; - K curr = key[pos & mask]; - // The starting point. - if (curr == null) { - return defRetValue; - } - if (k.equals(curr)) { - return removeEntry(pos); - } - while (true) { - if ((curr = key[pos = (pos + 1) & mask]) == null) { - return defRetValue; - } - if (k.equals(curr)) { - return removeEntry(pos); - } - } - } - private V removeEntry(final int pos) { - final V oldValue = values[pos]; - values[pos] = null; - size--; - shiftKeys(pos); - if (size < maxFill / 4 && arraySize > DEFAULT_INITIAL_SIZE) { - rehash(arraySize / 2); - } - return oldValue; - } - private V removeNullEntry() { - containsNullKey = false; - keys[arraySize] = null; - final V oldValue = values[arraySize]; - values[arraySize] = null; - size--; - if (size < maxFill / 4 && arraySize > DEFAULT_INITIAL_SIZE) { - rehash(arraySize / 2); - } - return oldValue; - } - /** - * Shifts left entries with the specified hash code, starting at the - * specified position, and empties the resulting free entry. - * - * @param pos - * a starting position. - */ - private void shiftKeys(int pos) { - // Shift entries with the same hash. - int last, slot; - K curr; - final K[] myKeys = this.keys; - for (;;) { - pos = ((last = pos) + 1) & mask; - for (;;) { - if (((curr = myKeys[pos]) == null)) { - myKeys[last] = (null); - values[last] = null; - return; - } - slot = HashCommon.mix(curr.hashCode()) & mask; - if (last <= pos ? (last >= slot || slot > pos) : (last >= slot && slot > pos)) { - break; - } - pos = (pos + 1) & mask; - } - myKeys[last] = curr; - values[last] = values[pos]; - } - } - - @Override - public int size() { - return size; - } - - /** - * Rehashes this map if the table is too large. - * - * <P> - * Let <var>N</var> be the smallest table size that can hold - * <code>max(n,{@link #size()})</code> entries, still satisfying the load - * factor. If the current table size is smaller than or equal to - * <var>N</var>, this method does nothing. Otherwise, it rehashes this map - * in a table of size <var>N</var>. - * - * <P> - * This method is useful when reusing maps. {@linkplain #clear() Clearing a - * map} leaves the table size untouched. If you are reusing a map many times, - * you can call this method with a typical size to avoid keeping around a - * very large table just because of a few large transient maps. - * - * @param n - * the threshold for the trimming. - * @return true if there was enough memory to trim the map. - */ - public boolean trim(final int n) { - final int l = HashCommon.nextPowerOfTwo((int) Math.ceil(n / loadFactor)); - if (l >= n || size > HashCommon.maxFill(l, loadFactor)) - return true; - try { - rehash(l); - } catch (OutOfMemoryError cantDoIt) { // unusual to catch OOME but in this case appropriate - return false; - } - return true; - } - /** - * Rehashes the map. - * - * <P> - * This method implements the basic rehashing strategy, and may be overriden - * by subclasses implementing different rehashing strategies (e.g., - * disk-based rehashing). However, you should not override this method - * unless you understand the internal workings of this class. - * - * @param newN - * the new size - */ - @SuppressWarnings("unchecked") - protected void rehash(final int newN) { - final K myKeys[] = this.keys; - final V myValues[] = this.values; - final int mask = newN - 1; // Note that this is used by the hashing - // macro - final K newKey[] = (K[]) new Object[newN + 1]; - final V newValue[] = (V[]) new Object[newN + 1]; - int i = arraySize, pos; - for (int j = realSize(); j-- != 0;) { - while (myKeys[--i] == null) { - // advance i until we find an existing key - } - if (newKey[pos = HashCommon.mix(myKeys[i].hashCode()) & mask] != null) { // rehash & check slot availability - while (newKey[pos = (pos + 1) & mask] != null) { - // find available slot at (or immediately following) pos - } - } - newKey[pos] = myKeys[i]; - newValue[pos] = myValues[i]; - } - newValue[newN] = myValues[arraySize]; - arraySize = newN; - this.mask = mask; - maxFill = HashCommon.maxFill(arraySize, loadFactor); - this.keys = newKey; - this.values = newValue; - } - - /** - * Returns a hash code for this map. - * - * @return a hash code for this map. - */ - public int hashCode() { - int result = 0; - for (int j = realSize(), i = 0, t = 0; j-- != 0;) { - while (keys[i] == null) { - i++; - } - if (this != keys[i]) { - t = keys[i].hashCode(); - } - if (this != values[i]) { - t ^= (values[i] == null ? 0 : values[i].hashCode()); - } - result += t; - i++; - } - // Zero / null keys have hash zero. - if (containsNullKey) { - result += (values[arraySize] == null ? 0 : values[arraySize].hashCode()); - } - return result; - } - - @SuppressWarnings("unchecked") - private void readObject(final ObjectInputStream s) throws IOException, ClassNotFoundException { - s.defaultReadObject(); - arraySize = HashCommon.arraySize(size, loadFactor); - maxFill = HashCommon.maxFill(arraySize, loadFactor); - mask = arraySize - 1; - final K key[] = this.keys = (K[]) new Object[arraySize + 1]; - final V value[] = this.values = (V[]) new Object[arraySize + 1]; - K k; - V v; - for (int i = size, pos; i-- != 0;) { - k = (K) s.readObject(); - v = (V) s.readObject(); - if (k == null) { - pos = arraySize; - containsNullKey = true; - } else { - pos = HashCommon.mix(k.hashCode()) & mask; - while (key[pos] != null) { - pos = (pos + 1) & mask; - } - } - key[pos] = k; - value[pos] = v; - } - } - - private void writeObject(final ObjectOutputStream s) throws IOException { - s.defaultWriteObject(); - try { - forEach(SERIALIZER, s); - } catch (final RuntimeException runex) { - if (runex.getCause() instanceof IOException) { - throw (IOException) runex.getCause(); - } - throw runex; - } - } - - private static final TriConsumer<String, Object, ObjectOutputStream> SERIALIZER = - new TriConsumer<String, Object, ObjectOutputStream>() { - @Override - public void accept(final String k, final Object v, final ObjectOutputStream objectOutputStream) { - try { - objectOutputStream.writeObject(k); - objectOutputStream.writeObject(v); - } catch (final IOException ioex) { - throw new IllegalStateException(ioex); - } - } - }; - - @Override - public String toString() { - final StringBuilder sb = new StringBuilder(256); - sb.append('{'); - final K myKeys[] = this.keys; - int pos = arraySize; - boolean first = true; - if (containsNullKey) { - sb.append(myKeys[pos] == this ? "(this map)" : myKeys[pos]); - sb.append('='); - sb.append(values[pos] == this ? "(this map)" : values[pos]); - first = false; - } - --pos; - for (; pos >= 0; pos--) { - if (myKeys[pos] != null) { - if (first) { - first = false; - } else { - sb.append(", "); - } - sb.append(myKeys[pos] == this ? "(this map)" : myKeys[pos]); - sb.append('='); - sb.append(values[pos] == this ? "(this map)" : values[pos]); - } - } - sb.append('}'); - return sb.toString(); - } - - private static class HashCommon { - private HashCommon() {} - - /** 2<sup>32</sup> · φ, φ = (√5 − 1)/2. */ - private static final int INT_PHI = 0x9E3779B9; - - /** The reciprocal of {@link #INT_PHI} modulo 2<sup>32</sup>. */ - private static final int INV_INT_PHI = 0x144cbc89; - - /** Avalanches the bits of an integer by applying the finalisation step of MurmurHash3. - * - * <p>This method implements the finalisation step of Austin Appleby's - * <a href="http://code.google.com/p/smhasher/">MurmurHash3</a>. - * Its purpose is to avalanche the bits of the argument to within 0.25% bias. - * - * @param x an integer. - * @return a hash value with good avalanching properties. - */ - public static int murmurHash3(int x) { - x ^= x >>> 16; - x *= 0x85ebca6b; - x ^= x >>> 13; - x *= 0xc2b2ae35; - x ^= x >>> 16; - return x; - } - - /** - * Quickly mixes the bits of an integer. - * - * <p>This method mixes the bits of the argument by multiplying by the golden ratio and - * xorshifting the result. It is borrowed from <a href="https://github.com/OpenHFT/Koloboke">Koloboke</a>, and - * it has slightly worse behaviour than {@link #murmurHash3(int)} (in open-addressing hash tables the average - * number of probes is slightly larger), but it's much faster. - * - * @param x an integer. - * @return a hash value obtained by mixing the bits of {@code x}. - * @see #invMix(int) - */ - public static int mix(final int x) { - final int h = x * INT_PHI; - return h ^ (h >>> 16); - } - - /** The inverse of {@link #mix(int)}. This method is mainly useful to create unit tests. - * - * @param x an integer. - * @return a value that passed through {@link #mix(int)} would give {@code x}. - */ - public static int invMix(final int x) { - return (x ^ x >>> 16) * INV_INT_PHI; - } - - /** Return the least power of two greater than or equal to the specified value. - * - * <p>Note that this function will return 1 when the argument is 0. - * - * @param x an integer smaller than or equal to 2<sup>30</sup>. - * @return the least power of two greater than or equal to the specified value. - */ - public static int nextPowerOfTwo(int x) { - if (x == 0) { - return 1; - } - x--; - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - return (x | x >> 16) + 1; - } - - /** Return the least power of two greater than or equal to the specified value. - * - * <p>Note that this function will return 1 when the argument is 0. - * - * @param x a long integer smaller than or equal to 2<sup>62</sup>. - * @return the least power of two greater than or equal to the specified value. - */ - public static long nextPowerOfTwo(long x) { - if (x == 0) { - return 1; - } - x--; - x |= x >> 1; - x |= x >> 2; - x |= x >> 4; - x |= x >> 8; - x |= x >> 16; - return (x | x >> 32) + 1; - } - - - /** Returns the maximum number of entries that can be filled before rehashing. - * - * @param n the size of the backing array. - * @param f the load factor. - * @return the maximum number of entries before rehashing. - */ - public static int maxFill(final int n, final float f) { - /* We must guarantee that there is always at least - * one free entry (even with pathological load factors). */ - return Math.min((int) Math.ceil(n * f), n - 1); - } - - /** - * Returns the least power of two smaller than or equal to 2<sup>30</sup> and larger than or equal to - * <code>Math.ceil( expected / f )</code>. - * - * @param expected the expected number of elements in a hash table. - * @param f the load factor. - * @return the minimum possible size for a backing array. - * @throws IllegalArgumentException if the necessary size is larger than 2<sup>30</sup>. - */ - public static int arraySize(final int expected, final float f) { - final long result = Math.max(2, nextPowerOfTwo((long) Math.ceil(expected / f))); - if (result > (1 << 30)) { - throw new IllegalArgumentException("Too large (" + expected + - " expected elements with load factor " + f + ")"); - } - return (int) result; - } - } -}
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ReusableLogEventFactory.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ReusableLogEventFactory.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ReusableLogEventFactory.java index 93a160e..62608a5 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ReusableLogEventFactory.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ReusableLogEventFactory.java @@ -28,6 +28,7 @@ import org.apache.logging.log4j.core.util.Clock; import org.apache.logging.log4j.core.util.ClockFactory; import org.apache.logging.log4j.message.Message; import org.apache.logging.log4j.message.TimestampMessage; +import org.apache.logging.log4j.spi.MutableContextData; /** * Garbage-free LogEventFactory that reuses a single mutable log event. http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjector.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjector.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjector.java index af534fb..786d23f 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjector.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/impl/ThreadContextDataInjector.java @@ -20,8 +20,10 @@ import java.util.List; import java.util.Map; import org.apache.logging.log4j.ThreadContext; -import org.apache.logging.log4j.core.ContextData; +import org.apache.logging.log4j.spi.ContextData; import org.apache.logging.log4j.core.config.Property; +import org.apache.logging.log4j.spi.MutableContextData; +import org.apache.logging.log4j.spi.ThreadContextMap; /** * {@code ThreadContextDataInjector} contains a number of strategies for copying key-value pairs from the various http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataAsEntryListDeserializer.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataAsEntryListDeserializer.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataAsEntryListDeserializer.java index 4b83fc7..c6d5245 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataAsEntryListDeserializer.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataAsEntryListDeserializer.java @@ -21,7 +21,7 @@ import java.util.List; import java.util.Map; import org.apache.logging.log4j.core.impl.ContextDataFactory; -import org.apache.logging.log4j.core.impl.MutableContextData; +import org.apache.logging.log4j.spi.MutableContextData; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataAsEntryListSerializer.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataAsEntryListSerializer.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataAsEntryListSerializer.java index 8fbffdf..329c6fa 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataAsEntryListSerializer.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataAsEntryListSerializer.java @@ -19,8 +19,8 @@ package org.apache.logging.log4j.core.jackson; import java.io.IOException; import java.util.Map; -import org.apache.logging.log4j.core.ContextData; -import org.apache.logging.log4j.core.util.BiConsumer; +import org.apache.logging.log4j.spi.ContextData; +import org.apache.logging.log4j.util.BiConsumer; import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.core.JsonGenerator; http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataDeserializer.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataDeserializer.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataDeserializer.java index 0988a98..c3dc827 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataDeserializer.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataDeserializer.java @@ -21,7 +21,7 @@ import java.io.IOException; import java.util.Map; import org.apache.logging.log4j.core.impl.ContextDataFactory; -import org.apache.logging.log4j.core.impl.MutableContextData; +import org.apache.logging.log4j.spi.MutableContextData; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataSerializer.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataSerializer.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataSerializer.java index 8868c0d..67d6c8b 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataSerializer.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/ContextDataSerializer.java @@ -19,8 +19,8 @@ package org.apache.logging.log4j.core.jackson; import java.io.IOException; import java.util.Map; -import org.apache.logging.log4j.core.ContextData; -import org.apache.logging.log4j.core.util.TriConsumer; +import org.apache.logging.log4j.spi.ContextData; +import org.apache.logging.log4j.util.TriConsumer; import com.fasterxml.jackson.core.JsonGenerationException; import com.fasterxml.jackson.core.JsonGenerator; http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/LogEventJsonMixIn.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/LogEventJsonMixIn.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/LogEventJsonMixIn.java index 2338cb0..30b01a8 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/LogEventJsonMixIn.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/LogEventJsonMixIn.java @@ -21,7 +21,7 @@ import java.util.Map; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.ThreadContext.ContextStack; -import org.apache.logging.log4j.core.ContextData; +import org.apache.logging.log4j.spi.ContextData; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.impl.ThrowableProxy; import org.apache.logging.log4j.message.Message; http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/LogEventWithContextListMixIn.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/LogEventWithContextListMixIn.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/LogEventWithContextListMixIn.java index e40c65a..c195001 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/LogEventWithContextListMixIn.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/jackson/LogEventWithContextListMixIn.java @@ -21,7 +21,7 @@ import java.util.Map; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.ThreadContext.ContextStack; -import org.apache.logging.log4j.core.ContextData; +import org.apache.logging.log4j.spi.ContextData; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.impl.ThrowableProxy; import org.apache.logging.log4j.message.Message; http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/GelfLayout.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/GelfLayout.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/GelfLayout.java index 9edd36b..2f4853c 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/GelfLayout.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/layout/GelfLayout.java @@ -38,7 +38,7 @@ import org.apache.logging.log4j.core.config.plugins.PluginFactory; import org.apache.logging.log4j.core.net.Severity; import org.apache.logging.log4j.core.util.JsonUtils; import org.apache.logging.log4j.core.util.KeyValuePair; -import org.apache.logging.log4j.core.util.TriConsumer; +import org.apache.logging.log4j.util.TriConsumer; import org.apache.logging.log4j.message.Message; import org.apache.logging.log4j.status.StatusLogger; import org.apache.logging.log4j.util.StringBuilderFormattable; http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MdcPatternConverter.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MdcPatternConverter.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MdcPatternConverter.java index bcbdbd8..1fc0512 100644 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MdcPatternConverter.java +++ b/log4j-core/src/main/java/org/apache/logging/log4j/core/pattern/MdcPatternConverter.java @@ -16,11 +16,11 @@ */ package org.apache.logging.log4j.core.pattern; -import org.apache.logging.log4j.core.ContextData; +import org.apache.logging.log4j.spi.ContextData; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.config.plugins.Plugin; import org.apache.logging.log4j.core.util.Constants; -import org.apache.logging.log4j.core.util.TriConsumer; +import org.apache.logging.log4j.util.TriConsumer; import org.apache.logging.log4j.util.StringBuilders; /** http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/util/BiConsumer.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/BiConsumer.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/BiConsumer.java deleted file mode 100644 index 081b9c2..0000000 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/BiConsumer.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.apache.logging.log4j.core.util; - -/** - * An operation that accepts two input arguments and returns no result. - * - * @param <K> type of the first argument - * @param <V> type of the second argument - * @see org.apache.logging.log4j.core.ContextData - * @since 2.7 - */ -public interface BiConsumer<K, V> { - - /** - * Performs the operation given the specified arguments. - * @param k the first input argument - * @param v the second input argument - */ - void accept(K k, V v); -} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/main/java/org/apache/logging/log4j/core/util/TriConsumer.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/TriConsumer.java b/log4j-core/src/main/java/org/apache/logging/log4j/core/util/TriConsumer.java deleted file mode 100644 index a7d6213..0000000 --- a/log4j-core/src/main/java/org/apache/logging/log4j/core/util/TriConsumer.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.apache.logging.log4j.core.util; - -/** - * An operation that accepts three input arguments and returns no result. - * - * @param <K> type of the first argument - * @param <V> type of the second argument - * @param <S> type of the third argument - * @see org.apache.logging.log4j.core.ContextData - * @since 2.7 - */ -public interface TriConsumer<K, V, S> { - - /** - * Performs the operation given the specified arguments. - * @param k the first input argument - * @param v the second input argument - * @param s the third input argument - */ - void accept(K k, V v, S s); -} http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/TestBaseEntity.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/TestBaseEntity.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/TestBaseEntity.java index f0e94ec..facb29d 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/TestBaseEntity.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/TestBaseEntity.java @@ -34,7 +34,7 @@ import javax.persistence.Transient; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.ThreadContext; -import org.apache.logging.log4j.core.ContextData; +import org.apache.logging.log4j.spi.ContextData; import org.apache.logging.log4j.core.LogEvent; import org.apache.logging.log4j.core.appender.db.jpa.converter.LevelAttributeConverter; import org.apache.logging.log4j.core.appender.db.jpa.converter.MessageAttributeConverter; http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataAttributeConverterTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataAttributeConverterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataAttributeConverterTest.java index 9f86d16..00ee55f 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataAttributeConverterTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataAttributeConverterTest.java @@ -16,8 +16,8 @@ */ package org.apache.logging.log4j.core.appender.db.jpa.converter; -import org.apache.logging.log4j.core.impl.ArrayContextData; -import org.apache.logging.log4j.core.impl.MutableContextData; +import org.apache.logging.log4j.spi.ArrayContextData; +import org.apache.logging.log4j.spi.MutableContextData; import org.junit.After; import org.junit.Before; import org.junit.Test; http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataJsonAttributeConverterTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataJsonAttributeConverterTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataJsonAttributeConverterTest.java index 76ce5d2..6930ed5 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataJsonAttributeConverterTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/appender/db/jpa/converter/ContextDataJsonAttributeConverterTest.java @@ -16,9 +16,9 @@ */ package org.apache.logging.log4j.core.appender.db.jpa.converter; -import org.apache.logging.log4j.core.ContextData; -import org.apache.logging.log4j.core.impl.ArrayContextData; -import org.apache.logging.log4j.core.impl.MutableContextData; +import org.apache.logging.log4j.spi.ContextData; +import org.apache.logging.log4j.spi.ArrayContextData; +import org.apache.logging.log4j.spi.MutableContextData; import org.junit.After; import org.junit.Before; import org.junit.Test; http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java index cb1de14..46de4ab 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/async/RingBufferLogEventTest.java @@ -29,7 +29,7 @@ import org.apache.logging.log4j.Marker; import org.apache.logging.log4j.MarkerManager; import org.apache.logging.log4j.ThreadContext.ContextStack; import org.apache.logging.log4j.core.LogEvent; -import org.apache.logging.log4j.core.impl.MutableContextData; +import org.apache.logging.log4j.spi.MutableContextData; import org.apache.logging.log4j.core.impl.ThrowableProxy; import org.apache.logging.log4j.message.Message; import org.apache.logging.log4j.message.SimpleMessage; http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ArrayContextDataTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ArrayContextDataTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ArrayContextDataTest.java deleted file mode 100644 index 4613c04..0000000 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/ArrayContextDataTest.java +++ /dev/null @@ -1,568 +0,0 @@ -package org.apache.logging.log4j.core.impl;/* - * 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. - */ - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.IOException; -import java.io.ObjectInputStream; -import java.io.ObjectOutputStream; -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.Map; - -import org.apache.logging.log4j.core.util.BiConsumer; -import org.apache.logging.log4j.core.util.TriConsumer; -import org.junit.Test; - -import static org.junit.Assert.*; - -/** - * Tests the ArrayContextData class. - */ -public class ArrayContextDataTest { - - @Test(expected = IllegalArgumentException.class) - public void testConstructorDisallowsNegativeCapacity() throws Exception { - new ArrayContextData(-1); - } - - @Test(expected = IllegalArgumentException.class) - public void testConstructorDisallowsZeroCapacity() throws Exception { - new ArrayContextData(0); - } - - @Test - public void testConstructorIgnoresNull() throws Exception { - assertEquals(0, new ArrayContextData(null).size()); - } - - @Test - public void testToString() { - final ArrayContextData original = new ArrayContextData(); - original.putValue("a", "avalue"); - original.putValue("B", "Bvalue"); - original.putValue("3", "3value"); - assertEquals("{3=3value, B=Bvalue, a=avalue}", original.toString()); - } - - @Test - public void testSerialization() throws Exception { - final ArrayContextData original = new ArrayContextData(); - original.putValue("a", "avalue"); - original.putValue("B", "Bvalue"); - original.putValue("3", "3value"); - - final byte[] binary = serialize(original); - final ArrayContextData copy = deserialize(binary); - assertEquals(original, copy); - } - - private byte[] serialize(final ArrayContextData data) throws IOException { - final ByteArrayOutputStream arr = new ByteArrayOutputStream(); - final ObjectOutputStream out = new ObjectOutputStream(arr); - out.writeObject(data); - return arr.toByteArray(); - } - - private ArrayContextData deserialize(final byte[] binary) throws IOException, ClassNotFoundException { - final ByteArrayInputStream inArr = new ByteArrayInputStream(binary); - final ObjectInputStream in = new ObjectInputStream(inArr); - final ArrayContextData result = (ArrayContextData) in.readObject(); - return result; - } - - @Test - public void testPutAll() throws Exception { - final ArrayContextData original = new ArrayContextData(); - original.putValue("a", "avalue"); - original.putValue("B", "Bvalue"); - original.putValue("3", "3value"); - - final ArrayContextData other = new ArrayContextData(); - other.putAll(original); - assertEquals(original, other); - - other.putValue("3", "otherValue"); - assertNotEquals(original, other); - - other.putValue("3", null); - assertNotEquals(original, other); - - other.putValue("3", "3value"); - assertEquals(original, other); - } - - @Test - public void testEquals() { - final ArrayContextData original = new ArrayContextData(); - original.putValue("a", "avalue"); - original.putValue("B", "Bvalue"); - original.putValue("3", "3value"); - assertEquals(original, original); // equal to itself - - final ArrayContextData other = new ArrayContextData(); - other.putValue("a", "avalue"); - assertNotEquals(original, other); - - other.putValue("B", "Bvalue"); - assertNotEquals(original, other); - - other.putValue("3", "3value"); - assertEquals(original, other); - - other.putValue("3", "otherValue"); - assertNotEquals(original, other); - - other.putValue("3", null); - assertNotEquals(original, other); - - other.putValue("3", "3value"); - assertEquals(original, other); - } - - @Test - public void testAsMap() throws Exception { - final ArrayContextData original = new ArrayContextData(); - original.putValue("a", "avalue"); - original.putValue("B", "Bvalue"); - original.putValue("3", "3value"); - - final Map<String, Object> expected = new HashMap<>(); - expected.put("a", "avalue"); - expected.put("B", "Bvalue"); - expected.put("3", "3value"); - - assertEquals(expected, original.asMap()); - } - - @Test - public void testGetCopyDelegatesToAsMap() throws Exception { - final ArrayContextData original = new ArrayContextData(); - original.putValue("a", "avalue"); - assertEquals(original.getCopy(), original.asMap()); - - original.putValue("B", "Bvalue"); - assertEquals(original.getCopy(), original.asMap()); - - original.putValue("3", "3value"); - assertEquals(original.getCopy(), original.asMap()); - } - - @Test - public void testGetImmutableMapOrNull() throws Exception { - final ArrayContextData original = new ArrayContextData(); - original.putValue("a", "avalue"); - assertEquals(original.getImmutableMapOrNull(), original.asMap()); - - original.putValue("B", "Bvalue"); - assertEquals(original.getImmutableMapOrNull(), original.asMap()); - - original.putValue("3", "3value"); - assertEquals(original.getImmutableMapOrNull(), original.asMap()); - - try { - original.getImmutableMapOrNull().put("abc", "xyz"); - fail("Expected map to be immutable"); - } catch (final UnsupportedOperationException ok) { - //ok - } - } - - @Test - public void testPutInsertsInAlphabeticOrder() throws Exception { - final ArrayContextData original = new ArrayContextData(); - original.put("a", "avalue"); - original.put("B", "Bvalue"); - original.put("3", "3value"); - original.put("c", "cvalue"); - original.put("d", "dvalue"); - - assertEquals("avalue", original.getValue("a")); - assertEquals("avalue", original.getValueAt(2)); - - assertEquals("Bvalue", original.getValue("B")); - assertEquals("Bvalue", original.getValueAt(1)); - - assertEquals("3value", original.getValue("3")); - assertEquals("3value", original.getValueAt(0)); - - assertEquals("cvalue", original.getValue("c")); - assertEquals("cvalue", original.getValueAt(3)); - - assertEquals("dvalue", original.getValue("d")); - assertEquals("dvalue", original.getValueAt(4)); - } - - @Test - public void testPutValueInsertsInAlphabeticOrder() throws Exception { - final ArrayContextData original = new ArrayContextData(); - original.putValue("a", "avalue"); - original.putValue("B", "Bvalue"); - original.putValue("3", "3value"); - original.putValue("c", "cvalue"); - original.putValue("d", "dvalue"); - - assertEquals("avalue", original.getValue("a")); - assertEquals("avalue", original.getValueAt(2)); - - assertEquals("Bvalue", original.getValue("B")); - assertEquals("Bvalue", original.getValueAt(1)); - - assertEquals("3value", original.getValue("3")); - assertEquals("3value", original.getValueAt(0)); - - assertEquals("cvalue", original.getValue("c")); - assertEquals("cvalue", original.getValueAt(3)); - - assertEquals("dvalue", original.getValue("d")); - assertEquals("dvalue", original.getValueAt(4)); - } - - @Test - public void testNullKeysAllowed() { - final ArrayContextData original = new ArrayContextData(); - original.putValue("a", "avalue"); - original.putValue("B", "Bvalue"); - original.putValue("3", "3value"); - original.putValue("c", "cvalue"); - original.putValue("d", "dvalue"); - assertEquals(5, original.size()); - assertEquals("{3=3value, B=Bvalue, a=avalue, c=cvalue, d=dvalue}", original.toString()); - - original.putValue(null, "nullvalue"); - assertEquals(6, original.size()); - assertEquals("{null=nullvalue, 3=3value, B=Bvalue, a=avalue, c=cvalue, d=dvalue}", original.toString()); - - original.putValue(null, "otherNullvalue"); - assertEquals("{null=otherNullvalue, 3=3value, B=Bvalue, a=avalue, c=cvalue, d=dvalue}", original.toString()); - assertEquals(6, original.size()); - - original.putValue(null, "nullvalue"); - assertEquals(6, original.size()); - assertEquals("{null=nullvalue, 3=3value, B=Bvalue, a=avalue, c=cvalue, d=dvalue}", original.toString()); - - original.putValue(null, "abc"); - assertEquals(6, original.size()); - assertEquals("{null=abc, 3=3value, B=Bvalue, a=avalue, c=cvalue, d=dvalue}", original.toString()); - } - - @Test - public void testNullKeysCopiedToAsMap() { - final ArrayContextData original = new ArrayContextData(); - original.putValue("a", "avalue"); - original.putValue("B", "Bvalue"); - original.putValue("3", "3value"); - original.putValue("c", "cvalue"); - original.putValue("d", "dvalue"); - assertEquals(5, original.size()); - - HashMap<String, String> expected = new HashMap<>(); - expected.put("a", "avalue"); - expected.put("B", "Bvalue"); - expected.put("3", "3value"); - expected.put("c", "cvalue"); - expected.put("d", "dvalue"); - assertEquals("initial", expected, original.asMap()); - - original.putValue(null, "nullvalue"); - expected.put(null, "nullvalue"); - assertEquals(6, original.size()); - assertEquals("with null key", expected, original.asMap()); - - original.putValue(null, "otherNullvalue"); - expected.put(null, "otherNullvalue"); - assertEquals(6, original.size()); - assertEquals("with null key value2", expected, original.asMap()); - - original.putValue(null, "nullvalue"); - expected.put(null, "nullvalue"); - assertEquals(6, original.size()); - assertEquals("with null key value1 again", expected, original.asMap()); - - original.putValue(null, "abc"); - expected.put(null, "abc"); - assertEquals(6, original.size()); - assertEquals("with null key value3", expected, original.asMap()); - } - - @Test - public void testRemove() { - final ArrayContextData original = new ArrayContextData(); - original.putValue("a", "avalue"); - assertEquals(1, original.size()); - assertEquals("avalue", original.getValue("a")); - - original.remove("a"); - assertEquals(0, original.size()); - assertNull("no a val", original.getValue("a")); - - original.remove("B"); - assertEquals(0, original.size()); - assertNull("no B val", original.getValue("B")); - } - - @Test - public void testNullValuesArePreserved() { - final ArrayContextData original = new ArrayContextData(); - original.putValue("a", "avalue"); - assertEquals(1, original.size()); - assertEquals("avalue", original.getValue("a")); - - original.putValue("a", null); - assertEquals(1, original.size()); - assertNull("no a val", original.getValue("a")); - - original.putValue("B", null); - assertEquals(2, original.size()); - assertNull("no B val", original.getValue("B")); - } - - @Test - public void testGet() throws Exception { - final ArrayContextData original = new ArrayContextData(); - original.put("a", "avalue"); - original.put("B", "Bvalue"); - original.put("3", "3value"); - - assertEquals("avalue", original.get("a")); - assertEquals("Bvalue", original.get("B")); - assertEquals("3value", original.get("3")); - - original.putValue("0", "0value"); - assertEquals("0value", original.get("0")); - assertEquals("3value", original.get("3")); - assertEquals("Bvalue", original.get("B")); - assertEquals("avalue", original.get("a")); - } - - @Test - public void testGetValue_GetValueAt() throws Exception { - final ArrayContextData original = new ArrayContextData(); - original.putValue("a", "avalue"); - original.putValue("B", "Bvalue"); - original.putValue("3", "3value"); - - assertEquals("avalue", original.getValue("a")); - assertEquals("avalue", original.getValueAt(2)); - - assertEquals("Bvalue", original.getValue("B")); - assertEquals("Bvalue", original.getValueAt(1)); - - assertEquals("3value", original.getValue("3")); - assertEquals("3value", original.getValueAt(0)); - - original.putValue("0", "0value"); - assertEquals("0value", original.getValue("0")); - assertEquals("0value", original.getValueAt(0)); - assertEquals("3value", original.getValue("3")); - assertEquals("3value", original.getValueAt(1)); - assertEquals("Bvalue", original.getValue("B")); - assertEquals("Bvalue", original.getValueAt(2)); - assertEquals("avalue", original.getValue("a")); - assertEquals("avalue", original.getValueAt(3)); - } - - @Test - public void testClear() throws Exception { - final ArrayContextData original = new ArrayContextData(); - original.putValue("a", "avalue"); - original.putValue("B", "Bvalue"); - original.putValue("3", "3value"); - assertEquals(3, original.size()); - - original.clear(); - assertEquals(0, original.size()); - - // ensure slots in the values array are nulled out - Field f = ArrayContextData.class.getDeclaredField("values"); - f.setAccessible(true); - Object[] values = (Object[]) f.get(original); - for (int i = 0; i < values.length; i++) { - assertNull(values[i]); - } - } - - @Test - public void testIndexOfKey() throws Exception { - final ArrayContextData original = new ArrayContextData(); - original.putValue("a", "avalue"); - assertEquals(0, original.indexOfKey("a")); - - original.putValue("B", "Bvalue"); - assertEquals(1, original.indexOfKey("a")); - assertEquals(0, original.indexOfKey("B")); - - original.putValue("3", "3value"); - assertEquals(2, original.indexOfKey("a")); - assertEquals(1, original.indexOfKey("B")); - assertEquals(0, original.indexOfKey("3")); - - original.putValue("A", "AAA"); - assertEquals(3, original.indexOfKey("a")); - assertEquals(2, original.indexOfKey("B")); - assertEquals(1, original.indexOfKey("A")); - assertEquals(0, original.indexOfKey("3")); - - original.putValue("C", "CCC"); - assertEquals(4, original.indexOfKey("a")); - assertEquals(3, original.indexOfKey("C")); - assertEquals(2, original.indexOfKey("B")); - assertEquals(1, original.indexOfKey("A")); - assertEquals(0, original.indexOfKey("3")); - - original.putValue("2", "222"); - assertEquals(5, original.indexOfKey("a")); - assertEquals(4, original.indexOfKey("C")); - assertEquals(3, original.indexOfKey("B")); - assertEquals(2, original.indexOfKey("A")); - assertEquals(1, original.indexOfKey("3")); - assertEquals(0, original.indexOfKey("2")); - } - - @Test - public void testContainsKey() throws Exception { - final ArrayContextData original = new ArrayContextData(); - assertFalse("a", original.containsKey("a")); - assertFalse("B", original.containsKey("B")); - assertFalse("3", original.containsKey("3")); - assertFalse("A", original.containsKey("A")); - - original.putValue("a", "avalue"); - assertTrue("a", original.containsKey("a")); - assertFalse("B", original.containsKey("B")); - assertFalse("3", original.containsKey("3")); - assertFalse("A", original.containsKey("A")); - - original.putValue("B", "Bvalue"); - assertTrue("a", original.containsKey("a")); - assertTrue("B", original.containsKey("B")); - assertFalse("3", original.containsKey("3")); - assertFalse("A", original.containsKey("A")); - - original.putValue("3", "3value"); - assertTrue("a", original.containsKey("a")); - assertTrue("B", original.containsKey("B")); - assertTrue("3", original.containsKey("3")); - assertFalse("A", original.containsKey("A")); - - original.putValue("A", "AAA"); - assertTrue("a", original.containsKey("a")); - assertTrue("B", original.containsKey("B")); - assertTrue("3", original.containsKey("3")); - assertTrue("A", original.containsKey("A")); - } - - @Test - public void testGetValueAt() throws Exception { - final ArrayContextData original = new ArrayContextData(); - original.putValue("a", "avalue"); - assertEquals("a", original.getKeyAt(0)); - assertEquals("avalue", original.getValueAt(0)); - - original.putValue("B", "Bvalue"); - assertEquals("B", original.getKeyAt(0)); - assertEquals("Bvalue", original.getValueAt(0)); - assertEquals("a", original.getKeyAt(1)); - assertEquals("avalue", original.getValueAt(1)); - - original.putValue("3", "3value"); - assertEquals("3", original.getKeyAt(0)); - assertEquals("3value", original.getValueAt(0)); - assertEquals("B", original.getKeyAt(1)); - assertEquals("Bvalue", original.getValueAt(1)); - assertEquals("a", original.getKeyAt(2)); - assertEquals("avalue", original.getValueAt(2)); - } - - @Test - public void testSizeAndIsEmpty() throws Exception { - final ArrayContextData original = new ArrayContextData(); - assertEquals(0, original.size()); - assertTrue("initial", original.isEmpty()); - - original.putValue("a", "avalue"); - assertEquals(1, original.size()); - assertFalse("size=" + original.size(), original.isEmpty()); - - original.putValue("B", "Bvalue"); - assertEquals(2, original.size()); - assertFalse("size=" + original.size(), original.isEmpty()); - - original.putValue("3", "3value"); - assertEquals(3, original.size()); - assertFalse("size=" + original.size(), original.isEmpty()); - - original.remove("B"); - assertEquals(2, original.size()); - assertFalse("size=" + original.size(), original.isEmpty()); - - original.remove("3"); - assertEquals(1, original.size()); - assertFalse("size=" + original.size(), original.isEmpty()); - - original.remove("a"); - assertEquals(0, original.size()); - assertTrue("size=" + original.size(), original.isEmpty()); - } - - @Test - public void testForEachBiConsumer() throws Exception { - final ArrayContextData original = new ArrayContextData(); - original.putValue("a", "avalue"); - original.putValue("B", "Bvalue"); - original.putValue("3", "3value"); - - original.forEach(new BiConsumer<String, String>() { - int count = 0; - @Override - public void accept(final String key, final String value) { - assertEquals("key", key, original.getKeyAt(count)); - assertEquals("val", value, original.getValueAt(count)); - count++; - assertTrue("count should not exceed size but was " + count, count <= original.size()); - } - }); - } - - static class State { - ArrayContextData data; - int count; - } - static TriConsumer<String, String, State> COUNTER = new TriConsumer<String, String, State>() { - @Override - public void accept(final String key, final String value, final State state) { - assertEquals("key", key, state.data.getKeyAt(state.count)); - assertEquals("val", value, state.data.getValueAt(state.count)); - state.count++; - assertTrue("count should not exceed size but was " + state.count, - state.count <= state.data.size()); - } - }; - - @Test - public void testForEachTriConsumer() throws Exception { - final ArrayContextData original = new ArrayContextData(); - original.putValue("a", "avalue"); - original.putValue("B", "Bvalue"); - original.putValue("3", "3value"); - - final State state = new State(); - state.data = original; - original.forEach(COUNTER, state); - assertEquals(state.count, original.size()); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/Log4jLogEventTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/Log4jLogEventTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/Log4jLogEventTest.java index 964a017..931fb15 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/Log4jLogEventTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/Log4jLogEventTest.java @@ -40,6 +40,8 @@ import org.apache.logging.log4j.core.util.DummyNanoClock; import org.apache.logging.log4j.message.Message; import org.apache.logging.log4j.message.ObjectMessage; import org.apache.logging.log4j.message.SimpleMessage; +import org.apache.logging.log4j.spi.ArrayContextData; +import org.apache.logging.log4j.spi.MutableContextData; import org.apache.logging.log4j.util.Strings; import org.junit.AfterClass; import org.junit.BeforeClass; http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1118b27f/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java ---------------------------------------------------------------------- diff --git a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java index e531adc..0b2babf 100644 --- a/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java +++ b/log4j-core/src/test/java/org/apache/logging/log4j/core/impl/MutableLogEventTest.java @@ -29,6 +29,8 @@ import org.apache.logging.log4j.MarkerManager; import org.apache.logging.log4j.ThreadContext; import org.apache.logging.log4j.message.ParameterizedMessage; import org.apache.logging.log4j.message.SimpleMessage; +import org.apache.logging.log4j.spi.ArrayContextData; +import org.apache.logging.log4j.spi.MutableContextData; import org.apache.logging.log4j.spi.MutableThreadContextStack; import org.junit.Test;
