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 17:15:26 UTC

[groovy] branch GROOVY-9631 updated (4190437 -> 1a424e2)

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

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


 discard 4190437  GROOVY-9631: Replace legacy data structure with Java collection
     new 1a424e2  GROOVY-9631: Replace legacy data structure with Java collection

This update added new revisions after undoing existing revisions.
That is to say, some revisions that were in the old version of the
branch are not in the new version.  This situation occurs
when a user --force pushes a change and generates a repository
containing something like this:

 * -- * -- B -- O -- O -- O   (4190437)
            \
             N -- N -- N   refs/heads/GROOVY-9631 (1a424e2)

You should already have received notification emails for all of the O
revisions, and so the following emails describe only the N revisions
from the common base, B.

Any revisions marked "omit" are not gone; other references still
refer to them.  Any revisions marked "discard" are gone forever.

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 src/main/java/org/codehaus/groovy/util/ManagedConcurrentMap.java | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)


[groovy] 01/01: GROOVY-9631: Replace legacy data structure with Java collection

Posted by su...@apache.org.
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

commit 1a424e28f6a0b9074904b9d1287d765f00868266
Author: Daniel Sun <su...@apache.org>
AuthorDate: Fri Jul 10 01:14:06 2020 +0800

    GROOVY-9631: Replace legacy data structure with Java collection
---
 .../groovy/reflection/GroovyClassValueFactory.java |   7 +-
 .../reflection/GroovyClassValuePreJava7.java       | 106 -------
 .../metaclass/ThreadManagedMetaBeanProperty.java   |   2 +-
 .../groovy/util/AbstractConcurrentMap.java         | 207 -------------
 .../groovy/util/AbstractConcurrentMapBase.java     | 336 ---------------------
 .../codehaus/groovy/util/ManagedConcurrentMap.java | 146 ++++-----
 .../util/AbstractConcurrentMapSegmentTest.groovy   | 193 ------------
 .../groovy/util/ManagedConcurrentMapTest.groovy    |   4 +-
 8 files changed, 78 insertions(+), 923 deletions(-)

diff --git a/src/main/java/org/codehaus/groovy/reflection/GroovyClassValueFactory.java b/src/main/java/org/codehaus/groovy/reflection/GroovyClassValueFactory.java
index 0565f92..b761895 100644
--- a/src/main/java/org/codehaus/groovy/reflection/GroovyClassValueFactory.java
+++ b/src/main/java/org/codehaus/groovy/reflection/GroovyClassValueFactory.java
@@ -18,7 +18,6 @@
  */
 package org.codehaus.groovy.reflection;
 
-import org.apache.groovy.util.SystemUtil;
 import org.codehaus.groovy.reflection.GroovyClassValue.ComputeValue;
 import org.codehaus.groovy.reflection.v7.GroovyClassValueJava7;
 
@@ -29,11 +28,7 @@ class GroovyClassValueFactory {
 	 * See https://bugs.openjdk.java.net/browse/JDK-8136353
 	 * This issue does not exist on IBM Java (J9) so use ClassValue by default on that JVM.
 	 */
-	private static final boolean USE_CLASSVALUE = Boolean.parseBoolean(SystemUtil.getSystemPropertySafe("groovy.use.classvalue", "true"));
-
 	public static <T> GroovyClassValue<T> createGroovyClassValue(ComputeValue<T> computeValue) {
-		return (USE_CLASSVALUE)
-                ? new GroovyClassValueJava7<>(computeValue)
-                : new GroovyClassValuePreJava7<>(computeValue);
+		return new GroovyClassValueJava7<>(computeValue);
 	}
 }
diff --git a/src/main/java/org/codehaus/groovy/reflection/GroovyClassValuePreJava7.java b/src/main/java/org/codehaus/groovy/reflection/GroovyClassValuePreJava7.java
deleted file mode 100644
index 02f893c..0000000
--- a/src/main/java/org/codehaus/groovy/reflection/GroovyClassValuePreJava7.java
+++ /dev/null
@@ -1,106 +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.reflection;
-
-import org.codehaus.groovy.util.Finalizable;
-import org.codehaus.groovy.util.ManagedConcurrentMap;
-import org.codehaus.groovy.util.ReferenceBundle;
-
-/** Approximation of Java 7's {@link java.lang.ClassValue} that works on earlier versions of Java.
- * Note that this implementation isn't as good at Java 7's; it doesn't allow for some GC'ing that Java 7 would allow.
- * But, it's good enough for our use.
- *
- * @param <T>
- */
-class GroovyClassValuePreJava7<T> implements GroovyClassValue<T> {
-	private static final ReferenceBundle weakBundle = ReferenceBundle.getWeakBundle();
-
-	private class EntryWithValue extends ManagedConcurrentMap.EntryWithValue<Class<?>,T>{
-
-		public EntryWithValue(GroovyClassValuePreJava7Segment segment, Class<?> key, int hash) {
-			super(weakBundle, segment, key, hash, computeValue.computeValue(key));
-		}
-
-		@Override
-		public void setValue(T value) {
-			if(value!=null) super.setValue(value);
-		}
-
-		@Override
-		public void finalizeReference() {
-			T value = getValue();
-			if (value instanceof Finalizable) {
-				((Finalizable) value).finalizeReference();
-			}
-			super.finalizeReference();
-		}
-	}
-
-	private class GroovyClassValuePreJava7Segment extends ManagedConcurrentMap.Segment<Class<?>,T> {
-
-        private static final long serialVersionUID = 1289753977947029168L;
-
-        GroovyClassValuePreJava7Segment(ReferenceBundle bundle, int initialCapacity) {
-			super(bundle, initialCapacity);
-		}
-
-		@Override
-		protected EntryWithValue createEntry(Class<?> key, int hash,
-				T unused) {
-			return new EntryWithValue(this, key, hash);
-		}
-	}
-
-	private class GroovyClassValuePreJava7Map extends ManagedConcurrentMap<Class<?>,T> {
-
-		public GroovyClassValuePreJava7Map() {
-			super(weakBundle);
-		}
-
-		@Override
-		protected GroovyClassValuePreJava7Segment createSegment(Object segmentInfo, int cap) {
-			ReferenceBundle bundle = (ReferenceBundle) segmentInfo;
-			if (bundle==null) throw new IllegalArgumentException("bundle must not be null ");
-			return new GroovyClassValuePreJava7Segment(bundle, cap);
-		}
-
-	}
-
-	private final ComputeValue<T> computeValue;
-
-	private final GroovyClassValuePreJava7Map map = new GroovyClassValuePreJava7Map();
-
-	public GroovyClassValuePreJava7(ComputeValue<T> computeValue){
-		this.computeValue = computeValue;
-	}
-
-	@Override
-	public T get(Class<?> type) {
-		// the value isn't use in the getOrPut call - see the EntryWithValue constructor above
-		T value = ((EntryWithValue)map.getOrPut(type, null)).getValue();
-		//all entries are guaranteed to be EntryWithValue. Value can only be null if computeValue returns null
-		return value;
-	}
-
-	@Override
-	public void remove(Class<?> type) {
-		map.remove(type);
-	}
-
-}
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
deleted file mode 100644
index 6168877..0000000
--- a/src/main/java/org/codehaus/groovy/util/AbstractConcurrentMap.java
+++ /dev/null
@@ -1,207 +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;
-
-public abstract class AbstractConcurrentMap<K, V> extends AbstractConcurrentMapBase {
-
-    public AbstractConcurrentMap(Object 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
deleted file mode 100644
index 01f84af..0000000
--- a/src/main/java/org/codehaus/groovy/util/AbstractConcurrentMapBase.java
+++ /dev/null
@@ -1,336 +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 java.util.Collection;
-import java.util.LinkedList;
-
-public abstract class AbstractConcurrentMapBase {
-    protected static final int MAXIMUM_CAPACITY = 1 << 30;
-    static final int MAX_SEGMENTS = 1 << 16;
-    static final int RETRIES_BEFORE_LOCK = 2;
-    final int segmentMask;
-    final int segmentShift;
-    protected final Segment[] segments;
-
-    public AbstractConcurrentMapBase(Object 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);
-    }
-
-    protected abstract Segment createSegment(Object 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;
-    }
-
-    public Segment segmentFor(int hash) {
-        return segments[(hash >>> segmentShift) & segmentMask];
-    }
-
-    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 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 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 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;
-                    }
-                }
-            }
-
-            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++;
-                            }
-                        }
-                    }
-                }
-            }
-
-            threshold = (int)(newTable.length * 0.75f);
-
-            table = newTable;
-            count = newCount;
-        }
-
-        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;
-                }
-            }
-            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;
-        }
-    }
-
-    public interface Entry<V> {
-        V getValue();
-
-        void setValue(V value);
-
-        int getHash();
-
-        boolean isValid();
-    }
-}
diff --git a/src/main/java/org/codehaus/groovy/util/ManagedConcurrentMap.java b/src/main/java/org/codehaus/groovy/util/ManagedConcurrentMap.java
index d1cf760..c637f92 100644
--- a/src/main/java/org/codehaus/groovy/util/ManagedConcurrentMap.java
+++ b/src/main/java/org/codehaus/groovy/util/ManagedConcurrentMap.java
@@ -18,102 +18,106 @@
  */
 package org.codehaus.groovy.util;
 
-public class ManagedConcurrentMap<K,V> extends AbstractConcurrentMap<K,V> {
-    protected ReferenceBundle bundle;
+import java.util.Collection;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+public class ManagedConcurrentMap<K, V> {
+    private final ConcurrentMap<Key<K>, ManagedReference<V>> internalMap = new ConcurrentHashMap<>();
+    private final ReferenceBundle bundle;
+
     public ManagedConcurrentMap(ReferenceBundle bundle) {
-        super(bundle);
+        if (bundle == null) throw new IllegalArgumentException("bundle must not be null");
         this.bundle = bundle;
-        if (bundle==null) throw new IllegalArgumentException("bundle must not be null");
     }
 
-    protected Segment<K,V> createSegment(Object 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);
+    /**
+     * 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) {
+        return toValue(internalMap.get(new Key(key)));
     }
 
-    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);
-        }
+    /**
+     * 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) {
+        final Key<K> k = new Key<K>(key);
+        internalMap.put(k, toManagedReference(k, value));
     }
 
-    public static class Entry<K,V> extends ManagedReference<K> implements AbstractConcurrentMap.Entry<K,V> {
-        private final Segment segment;
-        private final int hash;
+    public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) {
+        return toValue(getOrPut(key, mappingFunction));
+    }
 
-        public Entry(ReferenceBundle bundle, Segment segment, K key, int hash) {
-            super(bundle, key);
-            this.segment = segment;
-            this.hash = hash;
-        }
+    public ManagedReference<V> getOrPut(K key, Function<? super K, ? extends V> mappingFunction) {
+        final Key<K> key1 = new Key<K>(key);
+        return internalMap.computeIfAbsent(key1, k -> toManagedReference(key1, mappingFunction.apply(k.key)));
+    }
 
-        public boolean isValid() {
-            return get() != null;
-        }
+    public V remove(Object key) {
+        return toValue(internalMap.remove(new Key(key)));
+    }
 
-        public boolean isEqual(K key, int hash) {
-            return this.hash == hash && get() == key;
-        }
+    public Collection<V> values() {
+        return internalMap.values().stream().map(this::toValue).collect(Collectors.toList());
+    }
 
-        public V getValue() {
-            return (V)this;
-        }
+    public int size() {
+        return internalMap.size();
+    }
 
-        public void setValue(V value) {
-        }
+    private V toValue(ManagedReference<V> mv) {
+        if (null == mv) return null;
 
-        public int getHash() {
-            return hash;
-        }
+        return mv.get();
+    }
 
-        @Override
-        public void finalizeReference() {
-            segment.removeEntry(this);
-            super.finalizeReference();
-        }
+    private ManagedReference<V> toManagedReference(Key<K> key, V value) {
+        ManagedReference<V> ref = new ManagedReference<V>(bundle, value) {
+            @Override
+            public void finalizeReference() {
+                internalMap.remove(key, this);
+                super.finalizeReference();
+            }
+        };
 
-        /**
-         * @deprecated use finalizeReference
-         */
-        @Deprecated
-        public void finalizeRef() {
-            finalizeReference();
-        }
+        return ref;
     }
 
-    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);
-        }
+    private static class Key<K> {
+        K key;
 
-        @Override
-        public V getValue() {
-            return value;
+        Key(K key) {
+            this.key = key;
         }
 
         @Override
-        public void setValue(V value) {
-            this.value = value;
+        public boolean equals(Object o) {
+            if (this == o) return true;
+            if (!(o instanceof Key)) return false;
+            Key<?> other = (Key<?>) o;
+            return key == other.key;
         }
 
         @Override
-        public void finalizeReference() {
-            value = null;
-            super.finalizeReference();
+        public int hashCode() {
+            int hash = System.identityHashCode(key);
+            hash += (hash << 15) ^ 0xffffcd7d;
+            hash ^= (hash >>> 10);
+            hash += (hash << 3);
+            hash ^= (hash >>> 6);
+            hash += (hash << 2) + (hash << 14);
+            hash ^= (hash >>> 16);
+            return hash;
         }
     }
 }
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
     }
 
 }