Redis implements Msetex and Getdel commands

Source: Internet
Author: User
Tags sha1
1. Redis itself does not provide the msetex command (bulk increase the key and set the expiration time)

class RedisExtend {
    private static final Logger logger = LoggerFactory.getLogger (RedisExtend.class);
    private static final int Port = 6379;
    private static final String Host = "192.168.1.1";
    private static final String PASS_WORD = "1234";
    private static Jedis instance;
    / **
     * Lua script (msetex)
     * /
    private static final String LUA_SCRIPT_MSETEX = "local keysLen = table.getn (KEYS);" +
            "local argvLen = table.getn (ARGV);" +
            "local idx = 1;" +
            "local argVIdx = 1;" +
            "for idx = 1, keysLen, 1 do" +
            "argVIdx = (idx-1) * 2 + 1;" +
            "redis.call (‘ Set ’, KEYS [idx], ARGV [argVIdx],‘ EX ‘, ARGV [argVIdx + 1]);" +
            "end" +
            "return keysLen;";

    private static String LUA_SCRIPT_MSETEX_SHA1;

    / **
     * Lua script (deleted after acquisition)
     * /
    private static final String LUA_SCRIPT_GET_AND_DELETE =
            "local current = redis.call (‘ get ‘, KEYS [1]); \ n" +
                    "if (current) then \ n" +
                    "redis.call (‘ del ‘, KEYS [1]); \ n" +
                    "end \ n" +
                    "return current;";
    private static String LUA_SCRIPT_GET_AND_DELETE_SHA1;

    static {
        LUA_SCRIPT_MSETEX_SHA1 = SHA1.encode (LUA_SCRIPT_MSETEX);
        LUA_SCRIPT_GET_AND_DELETE_SHA1 = SHA1.encode (LUA_SCRIPT_GET_AND_DELETE);
    }

    public static Jedis getInstance () {
        if (instance == null) {
            instance = initJedisLite (). getTemplate (). getJedisPool (). getResource ();
        }
        return instance;
    }


    private static JedisLite initJedisLite () {
        return new JedisLite (Host, Port);
    }

    private static JedisTemplate jedisTemplate = initJedisLite (). getTemplate ();
 

    public static long msetex (List <RedisKeyValue> redisKeyValues) {
        if (CollectionUtils.isEmpty (redisKeyValues)) {
            return 0;
        }

        int keyCount = redisKeyValues.size ();
        List <String> param = new ArrayList <> (keyCount * 3);
        for (RedisKeyValue item: redisKeyValues) {
            Assert.notNull (item, "KeyValue is not allowed to be empty");
            Assert.hasLength (item.getKey (), "Key is not allowed to be empty");
            param.add (item.getKey ());
        }

        for (RedisKeyValue item: redisKeyValues) {
            param.add (item.getValue ());
            param.add (Integer.toString (item.getSeconds ()));
        }
        String [] paramArr = new String [param.size ()];
        param.toArray (paramArr);
        return execLunaScript (new RedisScript (LUA_SCRIPT_MSETEX, LUA_SCRIPT_MSETEX_SHA1), keyCount, paramArr,
                (o)-> (long) (o == null? 0L: Integer.parseInt (o.toString ())));
    }

    public static String getdel (String key) {
        return execLunaScript (new RedisScript (LUA_SCRIPT_GET_AND_DELETE, LUA_SCRIPT_GET_AND_DELETE_SHA1), 1, new String [] {key},
                (o)-> (o == null? null: o.toString ()));
    }

    private static <T> T execLunaScript (RedisScript redisScriptObj, int keyCount, String [] param,
            Function <Object, T> function) {
        try {
            return jedisTemplate.execute ((Jedis jedis)-> function.apply (jedis.evalsha (redisScriptObj.sha1, keyCount,
                    param)));
        } catch (redis.clients.jedis.exceptions.JedisNoScriptException ex) {
            return jedisTemplate.execute ((Jedis jedis)-> function.apply (jedis.eval (redisScriptObj.script, keyCount,
                    param)));
        } catch (Exception ex) {
            logger.error ("Execution of redis script exception!", ex);
            return null;
        }
    }
 
    static class RedisScript {
        private String script;
        private String sha1;

        public RedisScript (String script) {
            this (script, SHA1.encode (script));
        }

        public RedisScript (String script, String sha1) {
            this.script = script;
            this.sha1 = sha1;
        }
    }

    static class RedisKeyValue {
        private String key;
        private String value;
        private int seconds;

        public RedisKeyValue (String key, String value) {
            this (key, value, -1);
        }

        public RedisKeyValue (String key, String value, int seconds) {
            this.key = key;
            this.value = value;
            this.seconds = seconds;
        }

        public String getKey () {
            return key;
        }

        public String getValue () {
            return value;
        }

        public int getSeconds () {
            return seconds;
        }
    }
}
 

2. The calling code is as follows

 

    public static void main (String [] args) {
        long r = msetex (
                Arrays.asList (new RedisKeyValue ("key1", "value1", 5000),
                        new RedisKeyValue ("key2", "value2", 5000),
                        new RedisKeyValue ("ke3", "value3", 5000)
                ));
        System.out.println ("Return value:" + r);

        String key1Val = getdel ("key1");
        System.out.println ("Key1 value:" + key1Val);

        key1Val = getdel ("key1");

System.out.println ("Key1 value:" + key1Val);
    }
 

3. The returned results are as follows

Return value: 3
The value of key1: value1
value of key1: null
 

 

4. The code of sha1 is as follows

import java.security.MessageDigest;


public class SHA1 {
    private static final char [] HEX_DIGITS = {‘0‘, ‘1‘, ‘2‘, ‘3’, ‘4‘, ‘5’,
            ‘6’, ‘7’, ‘8’, ‘9’, ‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘f’};

    / **
     * Takes the raw bytes from the digest and formats them correct.
     *
     * @param bytes the raw bytes from the digest.
     * @return the formatted bytes.
     * /
    private static String getFormattedText (byte [] bytes) {
        int len = bytes.length;
        StringBuilder buf = new StringBuilder (len * 2);
        // Convert the ciphertext to hexadecimal string form
        for (int j = 0; j <len; j ++) {
            buf.append (HEX_DIGITS [(bytes [j] >> 4) & 0x0f]);
            buf.append (HEX_DIGITS [bytes [j] & 0x0f]);
        }
        return buf.toString ();
    }

    public static String encode (String str) {
        if (str == null) {
            return null;
        }
        try {
            MessageDigest messageDigest = MessageDigest.getInstance ("SHA1");
            messageDigest.update (str.getBytes ());
            return getFormattedText (messageDigest.digest ());
        } catch (Exception e) {
            throw new RuntimeException (e);
        }
    }
}
 

Redis implements msetex and getdel commands

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.