You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by su...@apache.org on 2020/07/09 14:21:12 UTC

[groovy] branch GROOVY-9631 updated: GROOVY-9631: Replace legacy data structure with Java collection

This is an automated email from the ASF dual-hosted git repository.

sunlan pushed a commit to branch GROOVY-9631
in repository https://gitbox.apache.org/repos/asf/groovy.git


The following commit(s) were added to refs/heads/GROOVY-9631 by this push:
     new ec57d3e  GROOVY-9631: Replace legacy data structure with Java collection
ec57d3e is described below

commit ec57d3ee9046223d4d0017dfbb41b72d474043ac
Author: Daniel Sun <su...@apache.org>
AuthorDate: Thu Jul 9 22:20:06 2020 +0800

    GROOVY-9631: Replace legacy data structure with Java collection
---
 .../metaclass/ThreadManagedMetaBeanProperty.java   |   2 +-
 .../groovy/util/AbstractConcurrentMap.java         | 184 +-----------
 .../groovy/util/AbstractConcurrentMapBase.java     | 330 +++------------------
 .../codehaus/groovy/util/ManagedConcurrentMap.java |  97 +-----
 .../util/AbstractConcurrentMapSegmentTest.groovy   | 193 ------------
 .../groovy/util/ManagedConcurrentMapTest.groovy    |   4 +-
 6 files changed, 56 insertions(+), 754 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/runtime/metaclass/ThreadManagedMetaBeanProperty.java b/src/main/java/org/codehaus/groovy/runtime/metaclass/ThreadManagedMetaBeanProperty.java
index 5074908..b6ac4cf 100644
--- a/src/main/java/org/codehaus/groovy/runtime/metaclass/ThreadManagedMetaBeanProperty.java
+++ b/src/main/java/org/codehaus/groovy/runtime/metaclass/ThreadManagedMetaBeanProperty.java
@@ -176,7 +176,7 @@ public class ThreadManagedMetaBeanProperty extends MetaBeanProperty {
            * @see groovy.lang.MetaMethod#invoke(java.lang.Object, java.lang.Object[])
            */
         public Object invoke(Object object, Object[] arguments) {
-            return instance2Prop.getOrPut(object, getInitialValue()).getValue();
+            return instance2Prop.computeIfAbsent(object, k -> getInitialValue());
         }
     }
 
diff --git a/src/main/java/org/codehaus/groovy/util/AbstractConcurrentMap.java b/src/main/java/org/codehaus/groovy/util/AbstractConcurrentMap.java
index 66ccc34..1554bce 100644
--- a/src/main/java/org/codehaus/groovy/util/AbstractConcurrentMap.java
+++ b/src/main/java/org/codehaus/groovy/util/AbstractConcurrentMap.java
@@ -18,190 +18,8 @@
  */
 package org.codehaus.groovy.util;
 
-public abstract class AbstractConcurrentMap<K, V> extends AbstractConcurrentMapBase {
-
+public abstract class AbstractConcurrentMap<K, V> extends AbstractConcurrentMapBase<K, V> {
     public AbstractConcurrentMap(ReferenceBundle segmentInfo) {
         super(segmentInfo);
     }
-
-    public Segment segmentFor (int hash) {
-        return (Segment) super.segmentFor(hash);
-    }
-
-    public V get(K key) {
-        int hash = hash(key);
-        return (V) segmentFor(hash).get(key, hash);
-    }
-
-    public Entry<K,V> getOrPut(K key, V value) {
-        int hash = hash(key);
-        return segmentFor(hash).getOrPut(key, hash, value);
-    }
-
-    public void put(K key, V value) {
-        int hash = hash(key);
-        segmentFor(hash).put(key, hash, value);
-    }
-
-    public void remove(K key) {
-        int hash = hash(key);
-        segmentFor(hash).remove(key, hash);
-    }
-
-    public abstract static class Segment<K,V> extends AbstractConcurrentMapBase.Segment {
-
-        private static final long serialVersionUID = -2392526467736920612L;
-
-        protected Segment(int initialCapacity) {
-            super(initialCapacity);
-        }
-
-        public final V get(K key, int hash) {
-            Object[] tab = table;
-            Object o = tab[hash & (tab.length - 1)];
-            if (o != null) {
-                if (o instanceof Entry) {
-                    Entry<K,V> e = (Entry) o;
-                    if (e.isEqual(key, hash)) {
-                        return e.getValue();
-                    }
-                }
-                else {
-                    Object[] arr = (Object[]) o;
-                    for (Object value : arr) {
-                        Entry<K, V> e = (Entry<K, V>) value;
-                        if (e != null && e.isEqual(key, hash)) {
-                            return e.getValue();
-                        }
-                    }
-                }
-            }
-            return null;
-        }
-
-        public final Entry<K,V> getOrPut(K key, int hash, V value) {
-            Object[] tab = table;
-            Object o = tab[hash & (tab.length - 1)];
-            if (o != null) {
-                if (o instanceof Entry) {
-                    Entry<K,V> e = (Entry) o;
-                    if (e.isEqual(key, hash)) {
-                        return e;
-                    }
-                }
-                else {
-                    Object[] arr = (Object[]) o;
-                    for (Object item : arr) {
-                        Entry<K, V> e = (Entry<K, V>) item;
-                        if (e != null && e.isEqual(key, hash)) {
-                            return e;
-                        }
-                    }
-                }
-            }
-            return put(key, hash, value);
-        }
-
-        public final Entry put(K key, int hash, V value) {
-            lock();
-            try {
-                rehashIfThresholdExceeded();
-
-                Object[] tab = table;
-                int index = hash & (tab.length - 1);
-                Object o = tab[index];
-                if (o != null) {
-                    if (o instanceof Entry) {
-                        Entry e = (Entry) o;
-                        if (e.isEqual(key, hash)) {
-                            e.setValue(value);
-                            return e;
-                        }
-                        else {
-                            Object[] arr = new Object [2];
-                            final Entry ee = createEntry(key, hash, value);
-                            arr [0] = ee;
-                            arr [1] = e;
-                            tab[index] = arr;
-                            count++;
-                            return ee;
-                        }
-                    }
-                    else {
-                        Object[] arr = (Object[]) o;
-                        for (Object item : arr) {
-                            Entry e = (Entry) item;
-                            if (e != null && e.isEqual(key, hash)) {
-                                e.setValue(value);
-                                return e;
-                            }
-                        }
-
-                        final Entry ee = createEntry(key, hash, value);
-                        for (int i = 0; i < arr.length; i++) {
-                            Entry e = (Entry) arr[i];
-                            if (e == null) {
-                                arr [i] = ee;
-                                count++;
-                                return ee;
-                            }
-                        }
-
-                        Object[] newArr = new Object[arr.length+1];
-                        newArr [0] = ee;
-                        System.arraycopy(arr, 0, newArr, 1, arr.length);
-                        tab [index] = newArr;
-                        count++;
-                        return ee;
-                    }
-                }
-
-                Entry e = createEntry(key, hash, value);
-                tab[index] = e;
-                count++; // write-volatile
-                return e;
-            } finally {
-                unlock();
-            }
-        }
-
-        public void remove(K key, int hash) {
-            lock();
-            try {
-                int c = count-1;
-                final Object[] tab = table;
-                final int index = hash & (tab.length - 1);
-                Object o = tab[index];
-
-                if (o != null) {
-                    if (o instanceof Entry) {
-                        if (((Entry<K,V>)o).isEqual(key, hash)) {
-                          tab[index] = null;
-                          count = c;
-                        }
-                    }
-                    else {
-                        Object[] arr = (Object[]) o;
-                        for (int i = 0; i < arr.length; i++) {
-                            Entry<K,V> e = (Entry<K,V>) arr[i];
-                            if (e != null && e.isEqual(key, hash)) {
-                                arr [i] = null;
-                                count = c;
-                                break;
-                            }
-                        }
-                    }
-                }
-            }
-            finally {
-                unlock();
-            }
-        }
-
-        protected abstract Entry<K,V> createEntry(K key, int hash, V value);
-    }
-
-    public interface Entry<K, V> extends AbstractConcurrentMapBase.Entry<V>{
-        boolean isEqual(K key, int hash);
-    }
 }
diff --git a/src/main/java/org/codehaus/groovy/util/AbstractConcurrentMapBase.java b/src/main/java/org/codehaus/groovy/util/AbstractConcurrentMapBase.java
index ba66374..8735e61 100644
--- a/src/main/java/org/codehaus/groovy/util/AbstractConcurrentMapBase.java
+++ b/src/main/java/org/codehaus/groovy/util/AbstractConcurrentMapBase.java
@@ -19,313 +19,81 @@
 package org.codehaus.groovy.util;
 
 import java.util.Collection;
-import java.util.LinkedList;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Function;
 
 public abstract class AbstractConcurrentMapBase<K, V> {
-    protected static final int MAXIMUM_CAPACITY = 1 << 30;
-    final int segmentMask;
-    final int segmentShift;
-    protected final Segment[] segments;
+    private final ConcurrentHashMap<K, ManagedReference<V>> internalMap = new ConcurrentHashMap<>();
+    private ReferenceBundle bundle;
 
-    public AbstractConcurrentMapBase(ReferenceBundle segmentInfo) {
-        int sshift = 0;
-        int ssize = 1;
-        while (ssize < 16) {
-            ++sshift;
-            ssize <<= 1;
-        }
-        segmentShift = 32 - sshift;
-        segmentMask = ssize - 1;
-        this.segments = new Segment[ssize];
-
-        int c = 512 / ssize;
-        if (c * ssize < 512)
-            ++c;
-        int cap = 1;
-        while (cap < c)
-            cap <<= 1;
-
-        for (int i = 0; i < this.segments.length; ++i)
-            this.segments[i] = createSegment(segmentInfo, cap);
+    public AbstractConcurrentMapBase(ReferenceBundle bundle) {
+        this.bundle = bundle;
     }
 
-    protected abstract Segment createSegment(ReferenceBundle segmentInfo, int cap);
-
-    protected static <K> int hash(K key) {
-        int h = System.identityHashCode(key);
-        h += ~(h << 9);
-        h ^=  (h >>> 14);
-        h +=  (h << 4);
-        h ^=  (h >>> 10);
-        return h;
+    /**
+     * Returns the value stored for the given key at the point of call.
+     *
+     * @param key a non null key
+     * @return the value stored in the map for the given key
+     */
+    public V get(Object key) {
+        ManagedReference<V> ref = internalMap.get(key);
+        if (ref != null) return ref.get();
+        return null;
     }
 
-    public Segment segmentFor(int hash) {
-        return segments[(hash >>> segmentShift) & segmentMask];
+    /**
+     * Sets a new value for a given key. an older value is overwritten.
+     *
+     * @param key   a non null key
+     * @param value the new value
+     */
+    public void put(final K key, V value) {
+        internalMap.put(key, toManagedReference(key, value));
     }
 
-    public int fullSize() {
-        int count = 0;
-        for (Segment segment : segments) {
-            segment.lock();
-            try {
-                for (int j = 0; j < segment.table.length; j++) {
-                    Object o = segment.table[j];
-                    if (o != null) {
-                        if (o instanceof Entry) {
-                            count++;
-                        } else {
-                            Object[] arr = (Object[]) o;
-                            count += arr.length;
-                        }
-                    }
-                }
-            } finally {
-                segment.unlock();
-            }
-        }
-        return count;
+    public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
+        return toValue(getOrPut(key, mappingFunction));
     }
 
-    public int size() {
-        int count = 0;
-        for (Segment segment : segments) {
-            segment.lock();
-            try {
-                for (int j = 0; j < segment.table.length; j++) {
-                    Object o = segment.table[j];
-                    if (o != null) {
-                        if (o instanceof Entry) {
-                            Entry e = (Entry) o;
-                            if (e.isValid())
-                                count++;
-                        } else {
-                            Object[] arr = (Object[]) o;
-                            for (Object value : arr) {
-                                Entry info = (Entry) value;
-                                if (info != null && info.isValid())
-                                    count++;
-                            }
-                        }
-                    }
-                }
-            } finally {
-                segment.unlock();
-            }
-        }
-        return count;
+    public ManagedReference<V> getOrPut(K key, Function<? super K, ? extends V> mappingFunction) {
+        return internalMap.computeIfAbsent(key, k -> toManagedReference(k, mappingFunction.apply(k)));
     }
 
-    public Collection values() {
-        Collection result = new LinkedList();
-        for (Segment segment : segments) {
-            segment.lock();
-            try {
-                for (int j = 0; j < segment.table.length; j++) {
-                    Object o = segment.table[j];
-                    if (o != null) {
-                        if (o instanceof Entry) {
-                            Entry e = (Entry) o;
-                            if (e.isValid())
-                                result.add(e);
-                        } else {
-                            Object[] arr = (Object[]) o;
-                            for (Object value : arr) {
-                                Entry info = (Entry) value;
-                                if (info != null && info.isValid())
-                                    result.add(info);
-                            }
-                        }
-                    }
-                }
-            } finally {
-                segment.unlock();
-            }
-        }
-        return result;
+    public V remove(Object key) {
+        return toValue(internalMap.remove(key));
     }
 
-    public static class Segment extends LockableObject {
-        private static final long serialVersionUID = -4128828550135386431L;
-        volatile int count;
-
-        int threshold;
-
-        protected volatile Object[] table;
-
-        protected Segment(int initialCapacity) {
-            setTable(new Object[initialCapacity]);
-        }
-
-        void setTable(Object[] newTable) {
-            threshold = (int) (newTable.length * 0.75f);
-            table = newTable;
-        }
-
-        void removeEntry (Entry e) {
-            lock ();
-            int newCount = count;
-            try {
-                Object [] tab = table;
-                int index = e.getHash() & (tab.length-1);
-                Object o = tab[index];
-                if (o != null) {
-                    if (o instanceof Entry) {
-                        if (o == e) {
-                            tab [index] = null;
-                            newCount--;
-                        }
-                    }
-                    else {
-                        Object[] arr = (Object[]) o;
-                        Object res = null;
-                        for (Object value : arr) {
-                            Entry info = (Entry) value;
-                            if (info != null) {
-                                if (info != e) {
-                                    if (info.isValid()) {
-                                        res = put(info, res);
-                                    } else {
-                                        newCount--;
-                                    }
-                                } else {
-                                    newCount--;
-                                }
-                            }
-                        }
-                        tab [index] = res;
-                    }
-                    count = newCount;
-                }
-            }
-            finally {
-                unlock();
-            }
-        }
-
-        void rehashIfThresholdExceeded() {
-            if(count > threshold) {
-                rehash();
-            }
-        }
-
-        void rehash() {
-            Object[] oldTable = table;
-            int oldCapacity = oldTable.length;
-            if (oldCapacity >= MAXIMUM_CAPACITY)
-                return;
-
-            int newCount = 0;
-            for (int i = 0; i < oldCapacity ; i++) {
-                Object o = oldTable [i];
-                if (o != null) {
-                    if (o instanceof Entry) {
-                        Entry e = (Entry) o;
-                        if (e.isValid()) {
-                            newCount++;
-                        }
-                        else {
-                            oldTable[i] = null;
-                        }
-                    }
-                    else {
-                        Object[] arr = (Object[]) o;
-                        int localCount = 0;
-                        for (int index = 0; index < arr.length; index++) {
-                            Entry e = (Entry) arr[index];
-                            if (e != null && e.isValid()) {
-                                localCount++;
-                            }
-                            else {
-                                arr [index] = null;
-                            }
-                        }
-                        if (localCount == 0)
-                          oldTable[i] = null;
-                        else
-                          newCount += localCount;
-                    }
-                }
-            }
+    public Collection<ManagedReference<V>> values() {
+        return internalMap.values();
+    }
 
-            Object[] newTable = new Object[newCount+1 < threshold ? oldCapacity : oldCapacity << 1];
-            int sizeMask = newTable.length - 1;
-            newCount = 0;
-            for (Object o : oldTable) {
-                if (o != null) {
-                    if (o instanceof Entry) {
-                        Entry e = (Entry) o;
-                        if (e.isValid()) {
-                            int index = e.getHash() & sizeMask;
-                            put(e, index, newTable);
-                            newCount++;
-                        }
-                    } else {
-                        Object[] arr = (Object[]) o;
-                        for (Object value : arr) {
-                            Entry e = (Entry) value;
-                            if (e != null && e.isValid()) {
-                                int index = e.getHash() & sizeMask;
-                                put(e, index, newTable);
-                                newCount++;
-                            }
-                        }
-                    }
-                }
-            }
+    public int size() {
+        return internalMap.size();
+    }
 
-            threshold = (int)(newTable.length * 0.75f);
+    private V toValue(ManagedReference<V> mv) {
+        if (null == mv) return null;
 
-            table = newTable;
-            count = newCount;
-        }
+        return mv.get();
+    }
 
-        private static void put(Entry ee, int index, Object[] tab) {
-            Object o = tab[index];
-            if (o != null) {
-                if (o instanceof Entry) {
-                    Object[] arr = new Object [2];
-                    arr [0] = ee;
-                    arr [1] = o;
-                    tab[index] = arr;
-                    return;
-                }
-                else {
-                    Object[] arr = (Object[]) o;
-                    Object[] newArr = new Object[arr.length+1];
-                    newArr [0] = ee;
-                    System.arraycopy(arr, 0, newArr, 1, arr.length);
-                    tab [index] = newArr;
-                    return;
-                }
+    private ManagedReference<V> toManagedReference(K key, V value) {
+        ManagedReference<V> ref = new ManagedReference<V>(bundle, value) {
+            @Override
+            public void finalizeReference() {
+                internalMap.remove(key, this);
+                super.finalizeReference();
             }
-            tab[index] = ee;
-        }
+        };
 
-        private static Object put(Entry ee, Object o) {
-            if (o != null) {
-                if (o instanceof Entry) {
-                    Object[] arr = new Object [2];
-                    arr [0] = ee;
-                    arr [1] = o;
-                    return arr;
-                }
-                else {
-                    Object[] arr = (Object[]) o;
-                    Object[] newArr = new Object[arr.length+1];
-                    newArr [0] = ee;
-                    System.arraycopy(arr, 0, newArr, 1, arr.length);
-                    return newArr;
-                }
-            }
-            return ee;
-        }
+        return ref;
     }
 
     public interface Entry<V> {
         V getValue();
 
-        void setValue(V value);
+        void setValue(V var1);
 
         int getHash();
 
diff --git a/src/main/java/org/codehaus/groovy/util/ManagedConcurrentMap.java b/src/main/java/org/codehaus/groovy/util/ManagedConcurrentMap.java
index fb2bb11..c36f055 100644
--- a/src/main/java/org/codehaus/groovy/util/ManagedConcurrentMap.java
+++ b/src/main/java/org/codehaus/groovy/util/ManagedConcurrentMap.java
@@ -18,102 +18,13 @@
  */
 package org.codehaus.groovy.util;
 
-public class ManagedConcurrentMap<K,V> extends AbstractConcurrentMap<K,V> {
+public class ManagedConcurrentMap<K, V> extends AbstractConcurrentMap<K, V> {
     protected ReferenceBundle bundle;
+
     public ManagedConcurrentMap(ReferenceBundle bundle) {
         super(bundle);
-        this.bundle = bundle;
-        if (bundle==null) throw new IllegalArgumentException("bundle must not be null");
-    }
-
-    protected Segment<K,V> createSegment(ReferenceBundle segmentInfo, int cap) {
-        ReferenceBundle bundle = (ReferenceBundle) segmentInfo;
-        if (bundle==null) throw new IllegalArgumentException("bundle must not be null");
-        return new ManagedConcurrentMap.Segment<K,V>(bundle, cap);
-    }
-
-    public static class Segment<K,V> extends AbstractConcurrentMap.Segment<K,V>{
-        private static final long serialVersionUID = 2742952509311037869L;
-        protected final ReferenceBundle bundle;
-        public Segment(ReferenceBundle bundle, int cap) {
-            super(cap);
-            this.bundle = bundle;
-            if (bundle==null) throw new IllegalArgumentException("bundle must not be null");
-
-        }
-
-        protected AbstractConcurrentMap.Entry<K,V> createEntry(K key, int hash, V value) {
-            if (bundle==null) throw new IllegalArgumentException("bundle must not be null");
-            return new EntryWithValue<K,V>(bundle, this, key, hash, value);
-        }
-    }
-
-    public static class Entry<K,V> extends ManagedReference<K> implements AbstractConcurrentMap.Entry<K,V> {
-        private final Segment segment;
-        private final int hash;
-
-        public Entry(ReferenceBundle bundle, Segment segment, K key, int hash) {
-            super(bundle, key);
-            this.segment = segment;
-            this.hash = hash;
-        }
-
-        public boolean isValid() {
-            return get() != null;
-        }
 
-        public boolean isEqual(K key, int hash) {
-            return this.hash == hash && get() == key;
-        }
-
-        public V getValue() {
-            return (V)this;
-        }
-
-        public void setValue(V value) {
-        }
-
-        public int getHash() {
-            return hash;
-        }
-
-        @Override
-        public void finalizeReference() {
-            segment.removeEntry(this);
-            super.finalizeReference();
-        }
-
-        /**
-         * @deprecated use finalizeReference
-         */
-        @Deprecated
-        public void finalizeRef() {
-            finalizeReference();
-        }
-    }
-
-    public static class EntryWithValue<K,V> extends Entry<K,V> {
-        private V value;
-
-        public EntryWithValue(ReferenceBundle bundle, Segment segment, K key, int hash, V value) {
-            super(bundle, segment, key, hash);
-            setValue(value);
-        }
-
-        @Override
-        public V getValue() {
-            return value;
-        }
-
-        @Override
-        public void setValue(V value) {
-            this.value = value;
-        }
-
-        @Override
-        public void finalizeReference() {
-            value = null;
-            super.finalizeReference();
-        }
+        if (bundle == null) throw new IllegalArgumentException("bundle must not be null");
+        this.bundle = bundle;
     }
 }
diff --git a/src/test/org/codehaus/groovy/util/AbstractConcurrentMapSegmentTest.groovy b/src/test/org/codehaus/groovy/util/AbstractConcurrentMapSegmentTest.groovy
deleted file mode 100644
index 4f275f5..0000000
--- a/src/test/org/codehaus/groovy/util/AbstractConcurrentMapSegmentTest.groovy
+++ /dev/null
@@ -1,193 +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.codehaus.groovy.util
-
-import org.junit.Before
-import org.junit.Test
-
-class AbstractConcurrentMapSegmentTest {
-    private static final Integer INITIAL_SEGMENT_SIZE = 100
-    private static final Integer SEGMENT_THRESHOLD = 0.75f * INITIAL_SEGMENT_SIZE
-
-    // Incrementing counter used to generate unique key names for TestEntry objects
-    // across all test methods in this class
-    private static int keyId
-
-    TestSegment segment
-    List<TestEntry> entries = []
-    int rehashCount = 0
-
-    @Before
-    public void setUp() throws Exception {
-        segment = new TestSegment(INITIAL_SEGMENT_SIZE)
-    }
-
-    @Test
-    public void testSegmentWillNotRehash() {
-        whenIAddElements(50)
-        thenRehashHappenedTimes(0)
-        thenSegmentExpands(false)
-    }
-
-    @Test
-    public void testSegmentWillNotRehashEdgeCase() {
-        whenIAddElements(SEGMENT_THRESHOLD + 1)
-        thenRehashHappenedTimes(0)
-        thenSegmentExpands(false)
-    }
-
-    @Test
-    public void testSegmentWillRehashAndExpand() {
-        whenIAddElements(SEGMENT_THRESHOLD + 2)
-        thenRehashHappenedTimes(1)
-        thenSegmentExpands(true)
-    }
-
-    @Test
-    public void testSegmentWillRehashAndExpandManyTimes() {
-        int elementCount = (SEGMENT_THRESHOLD + 1 ) * 6
-        whenIAddElements(elementCount)
-        //456 elements fit into segment of size 800, which is 100 * 2 * 2 * 2
-        thenSegmentSizeIs(INITIAL_SEGMENT_SIZE * 2 * 2 * 2)
-        thenRehashHappenedTimes(3)
-    }
-
-    @Test
-    public void testSegmentWillRehashWithNoExpansion() {
-        whenIAddElements(SEGMENT_THRESHOLD)
-        whenISetElementsAsInvalid(50)
-        whenIAddElements(50)
-        thenRehashHappenedTimes(1)
-        thenSegmentExpands(false)
-    }
-
-    @Test
-    public void testSegmentWillRehashAndEventuallyExpand() {
-        whenIAddElements(SEGMENT_THRESHOLD)
-
-        // 1-st rehash
-        whenISetElementsAsInvalid(50)
-        whenIAddElements(50)
-        thenSegmentExpands(false)
-
-        // 2-nd rehash
-        whenISetElementsAsInvalid(30)
-        whenIAddElements(30)
-        thenSegmentExpands(false)
-
-        // 3-nd rehash
-        whenISetElementsAsInvalid(20)
-        whenIAddElements(20)
-        thenSegmentExpands(false)
-
-        // 4-th rehash with none invalid => expansion: segment * 2
-        whenIAddElements(SEGMENT_THRESHOLD)
-
-        thenRehashHappenedTimes(4)
-        thenSegmentSizeIs(INITIAL_SEGMENT_SIZE * 2)
-    }
-
-    private void whenIAddElements(int count) {
-        count.times {
-            String key = "k:${++keyId}-${it}"
-            segment.put(key, key.hashCode(), "v${it}")
-        }
-    }
-
-    private void whenISetElementsAsInvalid(int count) {
-        List<TestEntry> validEntires = entries.findAll { it.isValid() }
-        count.times {
-            validEntires.get(it).setValid(false)
-        }
-    }
-
-    private void thenRehashHappenedTimes(int expectedRehashCount) {
-        assert rehashCount == expectedRehashCount
-    }
-
-    private void thenSegmentSizeIs(int expectedSize) {
-        assert segment.table.length == expectedSize
-    }
-
-    private void thenSegmentExpands(boolean truth) {
-        assert segment.table.length > INITIAL_SEGMENT_SIZE == truth
-    }
-
-    class TestSegment extends org.codehaus.groovy.util.AbstractConcurrentMap.Segment {
-
-        protected TestSegment(int initialCapacity) {
-            super(initialCapacity)
-        }
-
-        @Override
-        protected org.codehaus.groovy.util.AbstractConcurrentMap.Entry createEntry(Object key, int hash, Object value) {
-            TestEntry entry = new TestEntry(key, hash, value)
-            entries.add(entry)
-            return entry
-        }
-
-        @Override
-        void rehash() {
-            rehashCount++
-            super.rehash()
-        }
-    }
-}
-
-class TestEntry implements org.codehaus.groovy.util.AbstractConcurrentMap.Entry {
-    Object key
-    Object value
-    int hash
-    boolean valid = true;
-
-    public TestEntry(Object key, int hash, Object value) {
-        this.key = key
-        this.hash = hash
-        this.value = value
-    }
-
-    @Override
-    boolean isEqual(Object key, int hash) {
-        return hash == this.hash && key.equals(this.key)
-    }
-
-    @Override
-    Object getValue() {
-        return value
-    }
-
-    @Override
-    void setValue(Object value) {
-        this.value = value
-    }
-
-    @Override
-    int getHash() {
-        return hash
-    }
-
-    @Override
-    boolean isValid() {
-        return valid
-    }
-
-    public void setValid(boolean valid) {
-        this.valid = valid
-    }
-}
diff --git a/src/test/org/codehaus/groovy/util/ManagedConcurrentMapTest.groovy b/src/test/org/codehaus/groovy/util/ManagedConcurrentMapTest.groovy
index d87704f..e1e0b87 100644
--- a/src/test/org/codehaus/groovy/util/ManagedConcurrentMapTest.groovy
+++ b/src/test/org/codehaus/groovy/util/ManagedConcurrentMapTest.groovy
@@ -28,16 +28,14 @@ class ManagedConcurrentMapTest extends GroovyTestCase {
     void testEntriesRemoveSelfFromMapWhenFinalized() {
         List<ManagedReference<Object>> entries = []
         for (int i = 0; i < 5; i++) {
-            entries << map.getOrPut(new Object(), "Object ${i}")
+            entries << map.getOrPut(new Object(), k -> "Object ${i}")
         }
 
         assert map.size() == 5
-        assert map.fullSize() == 5
 
         entries*.finalizeReference()
 
         assert map.size() == 0
-        assert map.fullSize() == 0
     }
 
 }