This does not create a new object, but changes an existing object. On Mon, Sep 5, 2016 at 1:09 AM, Gary Gregory <garydgreg...@gmail.com> wrote:
> Wait a sec. If this creates a new object, it should be a "to" or "as" > method. If not, then yeah, freeze seems ok. > > Gary > > On Sep 4, 2016 12:03 PM, "Remko Popma" <remko.po...@gmail.com> wrote: > >> I Googled if there was any established terminology for turning a mutable >> object into an immutable one and "freeze" came up multiple times. >> >> >> >> >> On Sun, Sep 4, 2016 at 11:48 PM, Gary Gregory <garydgreg...@gmail.com> >> wrote: >> >>> Resending: >>> >>> Hm... the "freeze" terminology seems odd. Why not "lock"? >>> >>> Gary >>> >>> > >>> > >>> > On Sep 4, 2016 6:33 AM, <rpo...@apache.org> wrote: >>> >> >>> >> Repository: logging-log4j2 >>> >> Updated Branches: >>> >> refs/heads/LOG4J2-1349-gcfree-threadcontext 191c3f958 -> 7615afadd >>> >> >>> >> >>> >> LOG4J2-1349 implement support for freeze() and isFrozen() in >>> OpenHashMapContextData (for MutableContextData interface change) >>> >> >>> >> >>> >> Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo >>> >> Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit >>> /7615afad >>> >> Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/7 >>> 615afad >>> >> Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/7 >>> 615afad >>> >> >>> >> Branch: refs/heads/LOG4J2-1349-gcfree-threadcontext >>> >> Commit: 7615afadd1ba368ed07e8967c270940f624925bb >>> >> Parents: 191c3f9 >>> >> Author: rpopma <rpo...@apache.org> >>> >> Authored: Sun Sep 4 19:33:46 2016 +0900 >>> >> Committer: rpopma <rpo...@apache.org> >>> >> Committed: Sun Sep 4 19:33:46 2016 +0900 >>> >> >>> >> ------------------------------------------------------------ >>> ---------- >>> >> .../log4j/perf/nogc/OpenHashMapContextData.java | 85 >>> +++++++++++++++----- >>> >> 1 file changed, 67 insertions(+), 18 deletions(-) >>> >> ------------------------------------------------------------ >>> ---------- >>> >> >>> >> >>> >> http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/7 >>> 615afad/log4j-perf/src/main/java/org/apache/logging/log4j/pe >>> rf/nogc/OpenHashMapContextData.java >>> >> ------------------------------------------------------------ >>> ---------- >>> >> diff --git a/log4j-perf/src/main/java/org >>> /apache/logging/log4j/perf/nogc/OpenHashMapContextData.java >>> b/log4j-perf/src/main/java/org/apache/logging/log4j/perf/nog >>> c/OpenHashMapContextData.java >>> >> index 26bdf53..a7357b8 100644 >>> >> --- a/log4j-perf/src/main/java/org/apache/logging/log4j/perf/nog >>> c/OpenHashMapContextData.java >>> >> +++ b/log4j-perf/src/main/java/org/apache/logging/log4j/perf/nog >>> c/OpenHashMapContextData.java >>> >> @@ -67,6 +67,7 @@ public class OpenHashMapContextData<K, V> >>> implements MutableContextData, ThreadC >>> >> /** The default load factor of a hash table. */ >>> >> public static final float DEFAULT_LOAD_FACTOR = .75f; >>> >> >>> >> + private static final String FROZEN = "Frozen collection cannot >>> be modified"; >>> >> private static final long serialVersionUID = >>> -1486744623338827187L; >>> >> >>> >> /** The array of keys. */ >>> >> @@ -89,6 +90,8 @@ public class OpenHashMapContextData<K, V> >>> implements MutableContextData, ThreadC >>> >> protected final float loadFactor; >>> >> >>> >> private V defRetValue = null; >>> >> + private boolean immutable; >>> >> + private transient boolean iterating; >>> >> >>> >> /** >>> >> * Creates a new hash map with initial expected >>> >> @@ -193,6 +196,18 @@ public class OpenHashMapContextData<K, V> >>> implements MutableContextData, ThreadC >>> >> } >>> >> }; >>> >> >>> >> + private void assertNotFrozen() { >>> >> + if (immutable) { >>> >> + throw new UnsupportedOperationException(FROZEN); >>> >> + } >>> >> + } >>> >> + >>> >> + private void assertNoConcurrentModification() { >>> >> + if (iterating) { >>> >> + throw new ConcurrentModificationException(); >>> >> + } >>> >> + } >>> >> + >>> >> @SuppressWarnings("unchecked") >>> >> private void initFrom0(final OpenHashMapContextData other) { >>> >> // this.loadFactor = other.loadFactor; // final field >>> >> @@ -250,6 +265,9 @@ public class OpenHashMapContextData<K, V> >>> implements MutableContextData, ThreadC >>> >> if (size == 0) { >>> >> return; >>> >> } >>> >> + assertNotFrozen(); >>> >> + assertNoConcurrentModification(); >>> >> + >>> >> size = 0; >>> >> containsNullKey = false; >>> >> Arrays.fill(keys, (null)); >>> >> @@ -323,20 +341,26 @@ public class OpenHashMapContextData<K, V> >>> implements MutableContextData, ThreadC >>> >> 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) { >>> >> + >>> >> + iterating = true; >>> >> + try { >>> >> + 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(); >>> >> + } >>> >> + } >>> >> + } >>> >> + } finally { >>> >> + iterating = false; >>> >> } >>> >> } >>> >> >>> >> @@ -346,20 +370,26 @@ public class OpenHashMapContextData<K, V> >>> implements MutableContextData, ThreadC >>> >> 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) { >>> >> + >>> >> + iterating = true; >>> >> + try { >>> >> + 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(); >>> >> + } >>> >> + } >>> >> + } >>> >> + } finally { >>> >> + iterating = false; >>> >> } >>> >> } >>> >> >>> >> @@ -453,6 +483,9 @@ public class OpenHashMapContextData<K, V> >>> implements MutableContextData, ThreadC >>> >> >>> >> @Override >>> >> public void putAll(final ContextData source) { >>> >> + assertNotFrozen(); >>> >> + assertNoConcurrentModification(); >>> >> + >>> >> if (size() == 0 && source instanceof OpenHashMapContextData) >>> { >>> >> initFrom0((OpenHashMapContextData) source); >>> >> } else if (source != null) { >>> >> @@ -475,6 +508,9 @@ public class OpenHashMapContextData<K, V> >>> implements MutableContextData, ThreadC >>> >> } >>> >> >>> >> private V putObjectValue(final K k, final V v) { >>> >> + assertNotFrozen(); >>> >> + assertNoConcurrentModification(); >>> >> + >>> >> final int pos = insert(k, v); >>> >> if (pos < 0) { >>> >> return defRetValue; >>> >> @@ -495,8 +531,21 @@ public class OpenHashMapContextData<K, V> >>> implements MutableContextData, ThreadC >>> >> removeObjectKey((Object) key); >>> >> } >>> >> >>> >> + @Override >>> >> + public void freeze() { >>> >> + immutable = true; >>> >> + } >>> >> + >>> >> + @Override >>> >> + public boolean isFrozen() { >>> >> + return immutable; >>> >> + } >>> >> + >>> >> @SuppressWarnings("unchecked") >>> >> private V removeObjectKey(final Object k) { >>> >> + assertNotFrozen(); >>> >> + assertNoConcurrentModification(); >>> >> + >>> >> if (k == null) { >>> >> if (containsNullKey) { >>> >> return removeNullEntry(); >>> >> >>> >> >>