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(); >> >> >> > >