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

vip.breakpoint.cache.ExpireWithTtlCache Maven / Gradle / Ivy

The newest version!
package vip.breakpoint.cache;


import vip.breakpoint.log.WebLogFactory;
import vip.breakpoint.log.adaptor.Logger;
import vip.breakpoint.utils.EasyIDUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
 * 带有版本号的cache
 *
 * @author breakpoint/赵先生
 * create on 2021/03/24
 */
public class ExpireWithTtlCache implements TtlCache {

    private static final Logger log = WebLogFactory.getLogger(ExpireWithTtlCache.class);

    // 包装类 进行 对于我们存储的对象进行操作
    private final Cache> delegate;

    public ExpireWithTtlCache(Supplier size) {
        this.delegate = new LruCache<>(
                new PerpetualCache<>(EasyIDUtils.generateIdStr()),
                size.get());
        // 清理 cache
        TtlClearContext.addClearCache(this);
    }

    @Override
    public String getId() {
        return delegate.getId();
    }

    @Override
    public int getSize() {
        return delegate.getSize();
    }

    @Override
    public void putObject(String key, T value, long ttl, TimeUnit timeUnit) {
        // 转换成包装类
        TtlObjectWrapper wrapper = new TtlObjectWrapper<>(key, value,
                System.currentTimeMillis(), timeUnit.toMillis(ttl));
        delegate.putObject(key, wrapper);
    }

    @Override
    public T getObject(String key) {
        TtlObjectWrapper wrapper = delegate.getObject(key);
        if (null != wrapper) {
            long currentTimeMillis = System.currentTimeMillis();
            if (currentTimeMillis - wrapper.getLastAccessTime() > wrapper.getTtl()) {
                // 说明数据过期了
                this.removeObject(key);
                return null;
            } else {
                this.putObject(key, wrapper.getData(), wrapper.getTtl(), TimeUnit.MILLISECONDS);
                return wrapper.getData();
            }
        } else {
            return null;
        }
    }

    @Override
    public T removeObject(String key) {
        TtlObjectWrapper wrapper = delegate.removeObject(key);
        return null != wrapper ? wrapper.getData() : null;
    }

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

    @Override
    public void clearExpireData() {
        List> allData = delegate.getAll();
        if (null != allData) {
            for (int i = 0; i < allData.size(); i++) {
                TtlObjectWrapper wrapper = allData.get(i);
                if (!isNotExpire(wrapper)) {
                    // 失效了 进行删除hh
                    log.warn("the expire data have cleared from the cache; key:{}", wrapper.getKey());
                    this.removeObject(wrapper.getKey());
                }
                // for gc
                if (i % 5000 == 0) {
                    try {
                        Thread.sleep(0);
                    } catch (InterruptedException e) {
                        log.error("clearExpireData", e);
                    }
                }
            }
        }
    }

    // 判断是否是过期的数据
    private boolean isNotExpire(TtlObjectWrapper wrapper) {
        return System.currentTimeMillis() - wrapper.getLastAccessTime() < wrapper.getTtl();
    }

    @Override
    public List getAll() {
        List res = new ArrayList<>();
        List> delegateAll = delegate.getAll();
        // 返回操作的数据
        if (null != delegateAll) {
            List> collect = delegateAll.stream()
                    .filter(this::isNotExpire).collect(Collectors.toList());
            collect.forEach(delegate -> res.add(delegate.getData()));
            collect.clear();
        }
        return res;
    }

    @Override
    public ReadWriteLock getReadWriteLock() {
        return delegate.getReadWriteLock();
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy