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

com.jn.agileway.redis.l2cache.RedisCache Maven / Gradle / Ivy

Go to download

Provides a large number of convenient redis tools: distributed locks, distributed count, distributed cache, distributed id generator, jdk collection implements, the enhanced RedisTemplate based on a specified key prefix and the agileway-codec module

There is a newer version: 5.0.4
Show newest version
package com.jn.agileway.redis.l2cache;

import com.jn.agileway.redis.core.key.RedisKeyWrapper;
import com.jn.agileway.redis.core.RedisTemplate;
import com.jn.langx.annotation.NonNull;
import com.jn.langx.annotation.Nullable;
import com.jn.langx.cache.*;
import com.jn.langx.util.Emptys;
import com.jn.langx.util.Objs;
import com.jn.langx.util.collection.Collects;
import com.jn.langx.util.collection.Pipeline;
import com.jn.langx.util.function.*;
import com.jn.langx.util.timing.timer.Timeout;
import org.springframework.data.redis.core.BoundValueOperations;

import java.util.*;
import java.util.concurrent.TimeUnit;

public class RedisCache extends BaseCache {
    @NonNull
    private RedisTemplate redisTemplate;
    @Nullable
    private Loader loader;
    // unit: seconds
    @Nullable
    private RemoveListener removeListener = RemoveListeners.noop();

    @NonNull
    private RedisKeyWrapper keyWrapper = new RedisKeyWrapper().prefix("iredis:cache");

    @Override
    public void set(String key, V value) {
        BoundValueOperations valueOperations = redisTemplate.boundValueOps(keyWrapper.wrap(key));
        valueOperations.set(value);
    }

    @Override
    public void set(String key, V value, long expire) {
        long now = System.currentTimeMillis();
        long ttl = expire - now;
        set(key, value, ttl, TimeUnit.MILLISECONDS);
    }

    @Override
    public void set(String key, V value, long ttl, TimeUnit timeUnit) {
        BoundValueOperations valueOperations = redisTemplate.boundValueOps(keyWrapper.wrap(key));
        if (ttl < 0) {
            valueOperations.set(value);
        }
        if (ttl > 0) {
            valueOperations.set(value, ttl, timeUnit);
        }
    }

    @Override
    public V get(String key) {
        V v = getFromRedis(key);
        if (v == null && loader != null) {
            v = loader.load(key);
            if (v != null) {
                set(key, v);
            }
        }
        return v;
    }

    private V getFromRedis(String unwrappedKey) {
        V v = null;
        BoundValueOperations valueOperations = redisTemplate.boundValueOps(keyWrapper.wrap(unwrappedKey));
        v = valueOperations.get();
        return v;
    }

    private V getAndUpdateExpireTime(String key, long durationMills) {
        return redisTemplate.executeScript("GetAndUpdateExpireTime", Collects.asList(keyWrapper.wrap(key)), durationMills);
    }

    @Override
    public Map getAll(Iterable keys) {
        List keyList = keyWrapper.wrap(keys);
        final List values = redisTemplate.opsForValue().multiGet(keyList);
        final Map map = new HashMap();
        if (Emptys.isNotEmpty(values)) {
            Collects.forEach(keyList, new Consumer2() {
                @Override
                public void accept(Integer index, String wrappedKey) {
                    String unwrappedKey = keyWrapper.unwrap(wrappedKey);
                    V v = values.get(index);
                    if (v == null && loader != null) {
                        v = loader.load(unwrappedKey);
                        if (v != null) {
                            set(unwrappedKey, v);
                        }
                    }
                    map.put(unwrappedKey, v);
                }
            });
        }
        return map;
    }

    @Override
    public Map getAllIfPresent(Iterable keys) {
        List keyList = Collects.asList(keys);
        final List values = redisTemplate.opsForValue().multiGet(keyList);
        final Map map = new HashMap();
        Collects.forEach(keyList, new Consumer2() {
            @Override
            public void accept(Integer index, String key) {
                V v = values.get(index);
                if (v != null) {
                    map.put(key, v);
                }
            }
        });
        return map;
    }

    @Override
    public V getIfPresent(String key) {
        BoundValueOperations valueOperations = redisTemplate.boundValueOps(key);
        return valueOperations.get();
    }

    @Override
    public V get(String key, Supplier loader) {
        V value = getFromRedis(key);
        if (value == null) {
            if (loader != null) {
                value = loader.get(key);
            }
            if (value == null && this.loader != null) {
                value = this.loader.load(key);
            }
        }
        if (value != null) {
            set(key, value);
        }
        return null;
    }

    @Override
    public V remove(String key) {
        V ret = redisTemplate.executeScript("GetAndRemove", Collects.asList(keyWrapper.wrap(key)));
        removeListener.onRemove(key, ret, RemoveCause.EXPLICIT);
        return ret;
    }

    @Override
    public List remove(Collection keys) {
        return redisTemplate.executeScript("mGetAndRemove", keyWrapper.wrap(keys));
    }

    @Override
    public void refresh(String key) {
        if (loader != null) {
            V v = loader.load(key);
            if (v == null) {
                redisTemplate.delete(keyWrapper.wrap(key));
            } else {
                set(key, v);
                removeListener.onRemove(key, v, RemoveCause.REPLACED);
            }
        }
    }

    @Override
    protected void refreshAllAsync(@Nullable final Timeout timeout) {
        Set keys = this.keys();
        Pipeline.of(keys)
                .map(new Function() {
                    @Override
                    public String apply(String wrappedKey) {
                        return keyWrapper.unwrap(wrappedKey);
                    }
                }).forEach(new Consumer() {
                    public void accept(String key) {
                        refresh(key);
                    }
                });
    }

    @Override
    public void evictExpired() {
        // noop
    }

    @Override
    public Set keys() {
        return redisTemplate.keys(keyWrapper.wrap("*"));
    }

    @Override
    public void clean() {
        Set wrappedKeys = keys();
        redisTemplate.delete(wrappedKeys);
    }

    @Override
    public int size() {
        Set wrappedKeys = keys();
        return Objs.length(wrappedKeys);
    }

    @Override
    public Map toMap() {
        Set wrappedKeys = keys();
        final List values = redisTemplate.opsForValue().multiGet(wrappedKeys);
        final Map map = Collects.emptyHashMap();
        Collects.forEach(wrappedKeys, new Consumer2() {
            @Override
            public void accept(Integer index, String wrappedKey) {
                String unwrappedKey = keyWrapper.unwrap(wrappedKey);
                map.put(unwrappedKey, values.get(index));
            }
        });
        return map;
    }

    public void setRemoveListener(RemoveListener removeListener) {
        if (removeListener != null) {
            this.removeListener = removeListener;
        }
    }

    public RedisTemplate getRedisTemplate() {
        return redisTemplate;
    }

    public void setRedisTemplate(RedisTemplate redisTemplate) {
        this.redisTemplate = redisTemplate;
    }

    public Loader getLoader() {
        return loader;
    }

    public void setLoader(Loader loader) {
        this.loader = loader;
    }

    public RemoveListener getRemoveListener() {
        return removeListener;
    }

    public RedisKeyWrapper getKeyWrapper() {
        return keyWrapper;
    }

    public void setKeyWrapper(RedisKeyWrapper keyWrapper) {
        if (keyWrapper != null) {
            this.keyWrapper = keyWrapper;
        }
    }

    /********************************************************************************
     *  hash 相关操作
     ********************************************************************************/

    /**
     * hash delete
     */
    public void hashDelete(String key, Object... fields) {
        String wrappedKey = keyWrapper.wrap(key);
        redisTemplate.opsForHash().delete(wrappedKey, fields);
    }

    public  void hashMultiGet(String key, List fields) {
        String wrappedKey = keyWrapper.wrap(key);
        fields = Pipeline.of(fields)
                .clearNulls().asList();
        Map map = new HashMap();
        Collection f = fields;
        List hashValues = redisTemplate.opsForHash().multiGet(wrappedKey, f);
        for (int i = 0; i < fields.size(); i++) {
            HK hk = fields.get(i);
            HV hv = hashValues.get(i);
            map.put(hk, hv);
        }
    }

    public void hashPut(String key, Object field, Object fieldValue) {
        String wrappedKey = keyWrapper.wrap(key);
        redisTemplate.opsForHash().put(wrappedKey, field, fieldValue);
    }

    public void hashIncrement(String key, Object field, double delta) {
        String wrappedKey = keyWrapper.wrap(key);
        redisTemplate.opsForHash().increment(wrappedKey, field, delta);
    }

    public void hashIncrement(String key, Object field, long delta) {
        String wrappedKey = keyWrapper.wrap(key);
        redisTemplate.opsForHash().increment(wrappedKey, field, delta);
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy