基于Redis-bitmaps自动重命名工具类

本文介绍了一个GitHub项目,提供了一个基于Java的WRedisHelper工具类,该类利用Redis的位图(bitmaps)功能实现自动重命名的功能。此工具适用于需要高效管理大量唯一标识符并进行重命名操作的场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

github链接:https://github.com/striner/javaCode/blob/master/WRedisHelper


import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class WRedisHelper {

    private static Logger logger = LogManager.getLogger(WRedisHelper.class);

    private static final String SET_SUCCESS = "OK";
    private static final String SET_IF_NOT_EXIST = "NX";
    private static final String SET_EXPIRE_SECONDS = "EX";

    private static WJedisSentinelPool redisSentinelPool;

    private static final String APP_NAME = "aaa";

    private static final int COUNT = 20;
    private static final Pattern pattern = Pattern.compile("\\(\\d+\\)$"); //判断是否以带数字的括号结尾

    static {
        ClientConfig.init(CfgConstant.WREDIS_CONFIG_PATH);
        redisSentinelPool = ClientBuilder.redisSentinel(APP_NAME).build();
    }


    private static WJedis getJedis() {
        return redisSentinelPool.getResource();
    }


    private static void releaseJedis(final WJedis jedis) {
        if (jedis != null) {
            jedis.close();
        }
    }



    /**
     * 重名处理-获取name
     * @author : mulin
     * @date : 2019/8/23
     */
    public static String setName(String name, Long pid, int type) throws Exception{
        logger.info("setName -- name={}, pid={}, type={}", name, pid, type);
        WJedis jedis = getJedis();
        try {
            String key = pid + "_" + name.hashCode() + "_" + type;
            long offset = 0L;

            //判断name是否以带数字的括号结尾
            Matcher matcher = pattern.matcher(name);
            if (matcher.find()) {  //name后带有括号
                GetShortName getShortName = new GetShortName(name, matcher).invoke();
                long shortIndex = getShortName.getOffset();
                String shortKey = pid + "_" + getShortName.getName().hashCode() + "_" + type;

                //判断名字是否重复
                if(jedis.getbit(key, offset) || jedis.getbit(shortKey, shortIndex)) {

                    offset = jedis.bitpos(key, false);
                    String newKey= pid + "_" + (name + "("+offset+")").hashCode() + "_" + type;

                    while(jedis.getbit(newKey, 0)) {
                        jedis.setbit(key, offset, true);
                        offset++;
                        newKey = pid + "_" + (name + "("+offset+")").hashCode() + "_" + type;
                    }
                    jedis.setbit(newKey, 0, true);
                    jedis.setbit(key, offset, true);
                    String newName = name + "("+offset+")";

                    logger.info("setName -- newName={}", newName);
                    return newName;
                }
                jedis.setbit(key, offset, true);
                jedis.setbit(shortKey, shortIndex, true);
                logger.info("setName -- name={}", name);
                return name;
            }

            //如果名字不重复,则直接setbit
            if(!jedis.getbit(key, offset)) {
                jedis.setbit(key, offset, true);
                return name;
            }
            logger.info("setName -- offset={}", offset);

            offset = jedis.bitpos(key, false); //第一个为false的bit
            jedis.setbit(key, offset, true);
            String newName = name+"(" + offset + ")";
            jedis.setbit((pid + "_" + newName.hashCode() + "_" + type), 0, true);
            logger.info("setName -- newName={}", newName);
            return newName;

        } catch (Exception e) {
            logger.error("setName -- name处理失败 name={}, pid={}, type={}", name, pid, type, e);
            e.printStackTrace();
            throw new WRedisException();
        } finally {
            releaseJedis(jedis);
        }
    }

    /**
     * 重名处理-删除name
     * @author : mulin
     * @date : 2019/8/23
     */
    public static boolean delName(String name, Long pid, int type) {
        logger.info("delName -- name={}, pid={}, type={}", name, pid, type);
        WJedis jedis = getJedis();
        try {
            //获取name后括号中的数字
            Matcher matcher = pattern.matcher(name);

            long offset = 0L;
            if (matcher.find()) {
                logger.info("delName -- name={} end by '(number)'", name);
                GetShortName getShortName = new GetShortName(name, matcher).invoke();
                String shortName = getShortName.getName();
                long shortIndex = getShortName.getOffset();
                String shortKey = pid + "_" + shortName.hashCode() + "_" + type;
                logger.info("delName -- shortName={}, index={}", shortName, shortIndex);
                jedis.setbit(shortKey, shortIndex, false);
            }

            String key = pid + "_" + name.hashCode() + "_" + type;
            logger.info("delName -- name={}, index={}", name, offset);
            jedis.setbit(key, offset, false);

            return true;
        } catch (Exception e) {
            logger.error("delName -- name处理失败 name={}, pid={}, type={}", name, pid, type, e);
            return false;
        } finally {
            releaseJedis(jedis);
        }
    }

    /**
     * 重名处理-判断该name是否重复
     * @author : mulin
     * @date : 2019/8/26
     */
    public static boolean checkIsExist(String name, Long pid, int type) throws Exception {
        logger.info("checkIsExist -- name={}, pid={}, type={}", name, pid, type);
        WJedis jedis = getJedis();
        try {
            String key = pid + "_" + name.hashCode() + "_" + type;
            return jedis.bitcount(key) > 0;
        } catch (Exception e) {
            logger.error("checkIsExist -- name处理失败 name={}, pid={}, type={}", name, pid, type, e);
            throw new WRedisException(serverError);
        } finally {
            releaseJedis(jedis);
        }
    }

    /**
     * 批量删除该pid下的所有目录和文件
     * @author : mulin
     * @date : 2019/9/9
     */
    public static Long delDirsAndDocsUnderPid(Long pid) throws Exception {
        logger.info("delDirsAndDocsUnderPid -- pid={}", pid);
        WJedis jedis = getJedis();
        try {

            String pattern = pid + "_*";
            List<String> keys = new ArrayList<>();

            String cursor = ScanParams.SCAN_POINTER_START;
            ScanParams scanParams = new ScanParams();
            scanParams.count(COUNT);
            scanParams.match(pattern);
            logger.info("delDirsAndDocsUnderPid -- pid={}, pattern={}", pid, pattern);

            do {
                ScanResult<String> scanResult = jedis.scan(cursor, scanParams);
                keys.addAll(scanResult.getResult());
                cursor = scanResult.getStringCursor();
            }while(!"0".equals(cursor));

            logger.info("delDirsAndDocsUnderPid -- keys={}", keys);
            Iterator<String> key = keys.iterator();
            Long del = 0L;
            while(key.hasNext()) {
                String keyStr = key.next();
                logger.info("delDirsAndDocsUnderPid delKey -- key={}", keyStr);
                del += jedis.del(keyStr);
            }

            return del;
        } catch (Exception e) {
            logger.error("delDirsAndDocsUnderPid -- 数据删除失败 pid={}", pid);
            throw new WRedisException(serverError);
        } finally {
            releaseJedis(jedis);
        }
    }



    /**
     * 文件/目录移动
     *
     * @param sourceName    源name
     * @param sourcePid     源pid
     * @param type          数据类型 文件/目录
     * @param targetPid     目标pid
     * @author : mulin
     * @date : 2019/9/10
     */
    public static void moveDocsAndDirs(String sourceName, Long sourcePid, int type, Long targetPid) throws Exception {
        logger.info("moveDocsAndDirs -- sourceName={}, sourcePid={}, type={}, targetPid={}",sourceName, sourcePid, type, targetPid);
        WJedis jedis = getJedis();
        String name = null;
        try {
            name = setName(sourceName, targetPid, type);
            delName(sourceName, sourcePid, type);
        } catch (Exception e) {
            logger.error("moveDocsAndDirs 操作失败 -- sourceName={}, sourcePid={}, type={}, targetPid={}",sourceName, sourcePid, type, targetPid);
            //回滚
            if(StringUtils.isNotEmpty(name)) {
                delName(name, targetPid, type);
            }
            throw new WRedisException(serverError);
        } finally {
            releaseJedis(jedis);
        }
    }





    private static class GetShortName {
        private String name;
        private Matcher matcher;
        private long offset;

        GetShortName(String name, Matcher matcher) {
            this.name = name;
            this.matcher = matcher;
        }

        private String getName() {
            return name;
        }

        private long getOffset() {
            return offset;
        }

        private GetShortName invoke() {
            String index = matcher.group(0);
            index = index.substring(1, index.length()-1);
            offset = Long.valueOf(index);
            //name去掉括号和数字,获取key
            name = name.substring(0, name.length()-index.length()-2);
            return this;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值