All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.rx.core.Internal Maven / Gradle / Ivy

package org.rx.core;

import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.rx.util.function.BiFunc;

import java.util.Collections;
import java.util.Map;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.TimeUnit;

import static org.rx.core.Contract.*;
import static org.rx.core.Contract.require;

class Internal {
    @Slf4j
    static class WeakCache implements MemoryCache {
        private final Map container = Collections.synchronizedMap(new WeakHashMap<>());  //ReferenceQueue、ConcurrentMap> 不准

        @Override
        public int size() {
            return container.size();
        }

        @Override
        public Set keySet() {
            return container.keySet();
        }

        @Override
        public void add(TK key, TV val) {
            container.put(key, val);
        }

        @Override
        public void remove(TK key, boolean destroy) {
            TV val = container.remove(key);
            if (destroy) {
                tryClose(val);
            }
        }

        @Override
        public void clear() {
            container.clear();
        }

        @Override
        public TV get(TK key) {
            TV val = container.get(key);
            if (val == null) {
                log.debug("get key {} is gc", key);
                remove(key);
                return null;
            }
            return val;
        }

        @SneakyThrows
        @Override
        public TV get(TK key, BiFunc supplier) {
            require(supplier);

            TV v = get(key);
            if (v == null) {
                add(key, v = supplier.invoke(key));
            }
            return v;
        }
    }

    @RequiredArgsConstructor
    static class GoogleCache implements MemoryCache {
        private final Cache cache;

        @Override
        public int size() {
            return (int) cache.size();
        }

        @Override
        public Set keySet() {
            return cache.asMap().keySet();
        }

        @Override
        public void add(TK key, TV val) {
            cache.put(key, val);
        }

        @Override
        public void remove(TK key, boolean destroy) {
            TV val = cache.getIfPresent(key);
            if (val == null) {
                return;
            }

            cache.invalidate(key);
            if (destroy) {
                tryClose(val);
            }
        }

        @Override
        public void clear() {
            cache.invalidateAll();
        }

        @Override
        public TV get(TK key) {
            return cache.getIfPresent(key);
        }

        @SneakyThrows
        @Override
        public TV get(TK key, BiFunc supplier) {
            return cache.get(key, () -> {
                try {
                    return supplier.invoke(key);
                } catch (Throwable e) {
                    throw SystemException.wrap(e);
                }
            });
        }
    }

    static final WeakCache WeakCache = new WeakCache<>();
    static final GoogleCache SoftCache = new GoogleCache<>(newBuilder().softValues().build());
    static final Lazy LazyCache = new Lazy<>(() -> new GoogleCache<>(newBuilder().expireAfterAccess(App.Config.getCacheLiveMinutes(), TimeUnit.MINUTES).build()));

    private static CacheBuilder newBuilder() {
        return CacheBuilder.newBuilder().maximumSize(MaxInt);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy