• LevelDB封装和功能拓展


    上期分享了LevelDB Java&Go实践内容,按照惯例,我自然不会傻傻地使用原生API,肯定要进行一番封装。经过一段时间的尝试和测试,功能终于稳定下来。

    这次我不仅封装了LevelDB API,还进行了一定程度的拓展,分别拓展了存储类型int类型和原有value上追加的功能,使得LevelDB更像Redis。

    封装

    本次依旧采取之前base对象的思路,将每一个LevelDB封装到一个自定义的类里面,通过类方法的封装来个性化实现各个功能。封装完成之后,至少收获了两个好处:1. 再也不用将String字符串和byte数组转来转去了;2. 统一了语法之后,代码看起来整洁多了。

    下面是我对原生API的封装:

    
    /**
     * LevelDB数据库操作类
     */
    class LevelBase extends SourceCode {
    
        static Iq80DBFactory factory = Iq80DBFactory.factory
    
        static Options options = new Options()
    
        DB db
    
        /**
         * 创建对象
         * @param path
         */
        LevelBase(String path) {
            db = factory.open(new File(getLongFile(path)), options)
        }
    
        /**
         * 获取value
         * @param key
         * @return
         */
        def get(String key) {
            new String(db.get(bytes(key)), DEFAULT_CHARSET)
        }
    
        /**
         * 存储数据
         * @param key
         * @param value
         * @return
         */
        def put(String key, String value) {
            db.put(bytes(key), bytes(value))
        }
    
        /**
         * 删除某个值
         * @param key
         * @return
         */
        def del(String key) {
            db.delete(bytes(key))
        }
    
        /**
         * 获取所有key
         * @return
         */
        def keys() {
            def keys = []
            DBIterator iterator = db.iterator();
            while (iterator.hasNext()) {
                Map.Entry<byte[], byte[]> next = iterator.next();
                keys << next.key
            }
            return keys
        }
    
        /**
         * 关闭
         * @return
         */
        def close() {
            db.close()
        }
    
    }
    
    

    功能拓展

    首先我拓展了value值的范围,兼容了value值是int类型的,这里想不到太好的办法,只能在int和String之间转来转去。以后我根据com.funtester.db.redis.RedisBase类中的功能,对照拓展了:自增、自减、增减数值、追加和删除片段。同样的也是在String和byte数组转来转去。

    增减方法我加了锁,为了在性能测试中避免线程不安全。此处没有确定,等后面实践时候再修改。

    
        /**
         * 获取int类型
         * @param key
         * @return
         */
        def getInt(String key) {
            return changeStringToInt(get(key))
        }
    
        /**
         * 在原来的结果上追加
         * @param key
         * @param content
         * @return
         */
        def append(String key, String content) {
            put(key, get(key) + content)
        }
    
        /**
         * 在原来的结果中删除
         * @param key
         * @param content
         * @return
         */
        def cut(String key, String content) {
            put(key, get(key) - content)
        }
    
        /**
         * put int类型的值
         * @param key
         * @param value
         * @return
         */
        def putInt(String key, int value) {
            db.put(bytes(key), bytes(value + EMPTY))
        }
    
        /**
         * 自增
         * @param key
         * @return
         */
        def incr(String key) {
            add(key, 1)
        }
    
        /**
         * 自减
         * @param key
         * @return
         */
        def decr(String key) {
            minus(key, 1)
        }
    
        /**
         * value 值增加
         * @param key
         * @param i
         * @return
         */
        def add(String key, int i) {
            synchronized (this) {
                putInt(key, getInt(key) + i)
            }
        }
    
        /**
         * value 值减少
         * @param key
         * @param i
         * @return
         */
        def minus(String key, int i) {
            add(key, -i)
        }
    
    

    本期就分享Java的实践和拓展,下期再分享Go语言实践和LevelDB在测试工作中应用的几种场景,欢迎大家持续关注FunTester。

    欢迎关注FunTester,Have Fun ~ Tester !

  • 相关阅读:
    递归和迭代
    The Rose
    读周国平作品有感
    matlab最小二乘法数据拟合函数详解
    读周国平作品有感
    three.js之创建一条直线
    three.js之创建一个几何体
    Go语言标准库之strconv
    Go语言基础之网络编程
    Go语言基础之并发
  • 原文地址:https://www.cnblogs.com/FunTester/p/15698606.html
Copyright © 2020-2023  润新知