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

dengliming pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shenyu.git


The following commit(s) were added to refs/heads/master by this push:
     new 5e190b07db refactor(common): remove unused memory-safe cache (#7377)
5e190b07db is described below

commit 5e190b07dbbea6117ab9380e631b31dc76e1072e
Author: Eymen Onar <[email protected]>
AuthorDate: Sat Oct 3 07:02:15 2026 +0300

    refactor(common): remove unused memory-safe cache (#7377)
    
    Signed-off-by: Eymen <[email protected]>
    Co-authored-by: Eymen <[email protected]>
---
 RELEASE-NOTES.md                                   |   1 +
 .../common/cache/MemorySafeWindowTinyLFUMap.java   | 190 ---------------------
 .../apache/shenyu/common/constant/Constants.java   |   5 -
 .../cache/MemorySafeWindowTinyLFUMapTest.java      |  85 ---------
 4 files changed, 1 insertion(+), 280 deletions(-)

diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index aede17dfee..73bf4efaff 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -30,6 +30,7 @@
   to disable their deadline as well, and review route, retry and caller 
deadlines.
   The client factory now retains its connection-handler configuration, so 
configured
   read, write and idle handlers are installed on new connections.
+- Remove the unused `MemorySafeWindowTinyLFUMap` cache implementation.
 
 ## [v2.7.0]- 2024-12-23
 
diff --git 
a/shenyu-common/src/main/java/org/apache/shenyu/common/cache/MemorySafeWindowTinyLFUMap.java
 
b/shenyu-common/src/main/java/org/apache/shenyu/common/cache/MemorySafeWindowTinyLFUMap.java
deleted file mode 100644
index 1500ae2277..0000000000
--- 
a/shenyu-common/src/main/java/org/apache/shenyu/common/cache/MemorySafeWindowTinyLFUMap.java
+++ /dev/null
@@ -1,190 +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.shenyu.common.cache;
-
-import com.github.benmanes.caffeine.cache.Cache;
-import com.github.benmanes.caffeine.cache.Caffeine;
-import org.apache.shenyu.common.concurrent.MemoryLimitCalculator;
-import org.apache.shenyu.common.concurrent.ShenyuThreadFactory;
-import org.apache.shenyu.common.constant.Constants;
-import org.checkerframework.checker.nullness.qual.NonNull;
-
-import javax.annotation.concurrent.ThreadSafe;
-import java.io.Serializable;
-import java.lang.ref.WeakReference;
-import java.util.AbstractMap;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicBoolean;
-
-/**
- * The differences between this class and {@link MemorySafeLRUMap}
- * is that this class is thread safe, and it use WindowTinyLFU algorithm
- * provided by caffeine which is better than LRU algorithm.
- */
-@ThreadSafe
-public class MemorySafeWindowTinyLFUMap<K, V> extends AbstractMap<K, V> 
implements Serializable {
-
-    private static final long serialVersionUID = -3288161459386389022L;
-
-    private static final AtomicBoolean GLOBAL = new AtomicBoolean(false);
-
-    private static final Set<WeakReference<MemorySafeWindowTinyLFUMap<?, ?>>> 
ALL = new CopyOnWriteArraySet<>();
-
-    private final int maxFreeMemory;
-
-    private final Cache<K, V> cache;
-
-    public MemorySafeWindowTinyLFUMap(final int maxFreeMemory,
-                                      final int initialSize) {
-        this(maxFreeMemory, initialSize, Long.MAX_VALUE, 
Constants.LRU_MAP_MAXSIZE);
-    }
-
-    public MemorySafeWindowTinyLFUMap(final int maxFreeMemory,
-                                      final int initialSize,
-                                      final long expireAfterWrite,
-                                      final long maximumSize) {
-        this.maxFreeMemory = maxFreeMemory;
-        //see https://github.com/ben-manes/caffeine/issues/776
-        this.cache = Caffeine.newBuilder()
-                .expireAfterWrite(expireAfterWrite, TimeUnit.MILLISECONDS)
-                .maximumSize(maximumSize)
-                .initialCapacity(initialSize)
-                .build();
-    }
-
-    @Override
-    public V get(final Object key) {
-        return cache.getIfPresent(key);
-    }
-
-    @Override
-    public V put(final K key, final V value) {
-        checkAndScheduleRefresh(this);
-        final V previous = cache.getIfPresent(key);
-        cache.put(key, value);
-        return previous;
-    }
-
-    @Override
-    public V remove(final Object key) {
-        final V previous = cache.getIfPresent(key);
-        cache.invalidate(key);
-        cache.cleanUp();
-        return previous;
-    }
-
-    @Override
-    public Set<Entry<K, V>> entrySet() {
-        return cache.asMap().entrySet();
-    }
-
-    /**
-     * clean invalidated cache now.
-     */
-    public void cleanUp() {
-        while (isFull()) {
-            invalidate();
-        }
-    }
-
-    /**
-     * invalidate coldest cache now.
-     */
-    public void invalidate() {
-        cache.policy().eviction().ifPresent(eviction -> {
-            final Map<@NonNull K, @NonNull V> coldest = eviction.coldest(1);
-            if (coldest.size() == 0) {
-                return;
-            }
-            Optional.ofNullable(coldest.entrySet().iterator().next())
-                    .ifPresent(entry -> cache.invalidate(entry.getKey()));
-        });
-    }
-
-    /**
-     * whether to full.
-     *
-     * @return true if it's full
-     */
-    public boolean isFull() {
-        // when free memory less than certain value, consider it's full
-        return cache.estimatedSize() > 0 && 
MemoryLimitCalculator.maxAvailable() < maxFreeMemory;
-    }
-
-    @Override
-    public boolean equals(final Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (!(o instanceof MemorySafeWindowTinyLFUMap)) {
-            return false;
-        }
-        if (!super.equals(o)) {
-            return false;
-        }
-        MemorySafeWindowTinyLFUMap<?, ?> that = (MemorySafeWindowTinyLFUMap<?, 
?>) o;
-        return maxFreeMemory == that.maxFreeMemory && Objects.equals(cache, 
that.cache);
-    }
-
-    @Override
-    public int hashCode() {
-        return Objects.hash(super.hashCode(), maxFreeMemory, cache);
-    }
-
-    private static void checkAndScheduleRefresh(final 
MemorySafeWindowTinyLFUMap<?, ?> map) {
-        ALL.add(new WeakReference<>(map));
-        if (!GLOBAL.get()) {
-            refresh();
-            if (GLOBAL.compareAndSet(false, true)) {
-                ScheduledExecutorService scheduledExecutorService =
-                        new ScheduledThreadPoolExecutor(1, 
ShenyuThreadFactory.create("Shenyu-Memory-Safe-Lru-Map", false));
-                // check every 50 ms to improve performance
-                
scheduledExecutorService.scheduleWithFixedDelay(MemorySafeWindowTinyLFUMap::refresh,
 50, 50, TimeUnit.MILLISECONDS);
-                Runtime.getRuntime().addShutdownHook(new Thread(() -> {
-                    GLOBAL.set(false);
-                    scheduledExecutorService.shutdown();
-                }));
-            }
-        }
-    }
-
-    private static void refresh() {
-        // try to clear weak reference
-        for (WeakReference<MemorySafeWindowTinyLFUMap<?, ?>> weakReference : 
ALL) {
-            MemorySafeWindowTinyLFUMap<?, ?> cacheMap = weakReference.get();
-            if (Objects.isNull(cacheMap)) {
-                ALL.remove(weakReference);
-            }
-        }
-        // if jvm memory is full, try to release memory from caffine
-        boolean anyFull = 
ALL.stream().map(WeakReference::get).filter(Objects::nonNull)
-                .anyMatch(MemorySafeWindowTinyLFUMap::isFull);
-        while (anyFull) {
-            
ALL.stream().map(WeakReference::get).filter(Objects::nonNull).forEach(MemorySafeWindowTinyLFUMap::invalidate);
-            anyFull = 
ALL.stream().map(WeakReference::get).filter(Objects::nonNull)
-                    .anyMatch(MemorySafeWindowTinyLFUMap::isFull);
-        }
-    }
-}
diff --git 
a/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java 
b/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java
index cb96014e49..b4654e8e8a 100644
--- 
a/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java
+++ 
b/shenyu-common/src/main/java/org/apache/shenyu/common/constant/Constants.java
@@ -821,11 +821,6 @@ public interface Constants {
      */
     String DEFAULT_CLUSTER = "failover";
 
-    /**
-     * cache data max size, means map size.
-     */
-    Long LRU_MAP_MAXSIZE = 65536L;
-
     /**
      * namespace,sush as nacos .
      */
diff --git 
a/shenyu-common/src/test/java/org/apache/shenyu/common/cache/MemorySafeWindowTinyLFUMapTest.java
 
b/shenyu-common/src/test/java/org/apache/shenyu/common/cache/MemorySafeWindowTinyLFUMapTest.java
deleted file mode 100644
index caa9da4274..0000000000
--- 
a/shenyu-common/src/test/java/org/apache/shenyu/common/cache/MemorySafeWindowTinyLFUMapTest.java
+++ /dev/null
@@ -1,85 +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.shenyu.common.cache;
-
-import org.apache.shenyu.common.utils.ReflectUtils;
-import org.junit.Assert;
-import org.junit.Test;
-
-import java.lang.ref.WeakReference;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Test cases for MemorySafeWindowTinyLFUMap.
- */
-public class MemorySafeWindowTinyLFUMapTest {
-
-    @Test
-    public void testPut() {
-        MemorySafeWindowTinyLFUMap<String, String> lru = new 
MemorySafeWindowTinyLFUMap<>(1 << 10, 16);
-        lru.put("1", "1");
-        Assert.assertEquals(1, lru.size());
-        lru.put("2", "2");
-        lru.put("3", "3");
-        Assert.assertEquals(3, lru.size());
-    }
-
-    @Test
-    public void testWindowTinyLFU() {
-        MemorySafeWindowTinyLFUMap<Integer, Integer> cache = new 
MemorySafeWindowTinyLFUMap<>(1, 1024) {
-
-            private static final long serialVersionUID = 8897028073615563875L;
-
-            @Override
-            public synchronized boolean isFull() {
-                //just for test
-                return size() > 1;
-            }
-
-            @Override
-            public synchronized void cleanUp() {
-                super.cleanUp();
-            }
-        };
-        cache.put(1, 1);
-        Assert.assertEquals(1, cache.size());
-        cache.put(2, 2);
-        cache.put(3, 3);
-        cache.invalidate();
-        cache.cleanUp();
-        Assert.assertEquals(1, cache.size());
-        final Map.Entry<Integer, Integer> entry = 
cache.entrySet().iterator().next();
-        final Integer key = entry.getKey();
-        final Integer value = entry.getValue();
-        Assert.assertEquals(3, (int) key);
-        Assert.assertEquals(3, (int) value);
-    }
-
-    @Test
-    public void testWindowTinyLFUOutOufMemoryException() {
-        final int mb = 1024 * 1024;
-        for (int i = 0; i < 1000; i++) {
-            MemorySafeWindowTinyLFUMap<String, Byte[]> instance = new 
MemorySafeWindowTinyLFUMap<>(1, 1024);
-            instance.put(String.valueOf(1), new Byte[mb]);
-        }
-        Set<WeakReference<MemorySafeWindowTinyLFUMap<?, ?>>> all =
-                (Set<WeakReference<MemorySafeWindowTinyLFUMap<?, ?>>>) 
ReflectUtils.getFieldValue(new MemorySafeWindowTinyLFUMap(1, 1024), "ALL");
-        Assert.assertNotEquals(1000, all.size());
-    }
-}

Reply via email to