zoukankan      html  css  js  c++  java
  • PHP实现Redis的数据结构和LFU/LRU

    谈一谈Redis的数据结构,如果换做PHP,怎么实现?如果再考虑用上LFU或LRU,又该如何实现?
     
    Redis的数据结构有String、List、Set、Sorted Set、Hash等,而PHP支持String、Array、Object等八种基本数据类型。
    如果换成PHP,Redis的String可以用PHP的String实现,Redis的List、Set、Sorted Set可以用PHP的索引数组实现,Redis的Hash可以用PHP的关联数组实现。
     
    String
    Redis字符串命令用于管理Redis中的字符串值。
    PHP里,可以用字符串实现。
     
    List
    Redis的List是string列表,按插入顺序排序。 
    PHP里,可以用索引数组实现,数据结构类似于array(value1, value2, value3, ...)。
     
    Set
    Redis的Set是string类型的无序集合。集合成员是唯一的,即集合中不能出现重复的数据。
    PHP里,去重过后的索引数组就相当于Redis中的Set,所以实现Set的过程与实现List相似,但需要向数组添加数据时进行去重操作,或者在添加数据前先判定该值是否存在,如果存在就不添加。
     
    Sorted Set
    Redis的Sorted Set也是string类型的无序集合,且不允许重复的成员。但每个元素都会关联一个double类型的分数,Redis通过分数来为集合中的成员进行从小到大的排序。
    PHP的数组里,key不能重复,所以用key表示成员,value可以重复,所以用value表示分数,数据结构类似于array(member1=>score1, member2=>score2, member3=>score3, ...)。
     
    Hash
    Redis的Hash是一个string类型的field和value的映射表。
    PHP里,可以用关联数组实现,数据结构类似于array(key1=>value1, key2=>value2, key3=>value3, ...)。
     
    实现LFU/LRU的思路:
    定义三个关联数组,key都一样,一个数组叫kv数组,存值,形如key => value;一个数组叫kc数组,存值被访问的次数,形如key => count,用于实现LFU,当缓存满了,count值最小的数据即最少被访问的数据,最先被淘汰掉;一个数组叫kt数组,形如key => time,存值最后一次被访问的时间,用于实现LRU,当缓存满了,time值最小的数据即最先被访问的数据(不是最新数据),最先被淘汰掉。
     
    部分代码:
    /*php实现redis的string*/
    <?php
    class stringCache
    {
        var $hitNume;
        var $requestNum;
        // 缓存类型
        var $type;
        // 缓存总大小
        var $totalSize;
        // 存值$key=>$string
        var $data = array();
        // 存访问次数$key=>$count
        var $lfu = array();
        // 存访问时间$key=>$time
        var $lru = array();
        public function __construct($cacheType, $totalSize) {
            $this->type = $cacheType;
            $this->totalSize = $totalSize;
        }
        /* SET key value [EX seconds] [PX milliseconds] [NX|XX]
         * 将字符串值 value 关联到 key 。
         * 如果 key 已经持有其他值, SET 就覆写旧值,无视类型。
         * 对于某个原本带有生存时间(TTL)的键来说, 当 SET 命令成功在这个键上执行时, 这个键原有的 TTL 将被清除。
         * */
        public function add($key, $value) {
            $this->cleanup();
            $this->data[$key] = $value;
            if ($this->type == "lfu") {
                $this->lfu[$key] += 1;
            }
            if ($this->type == "lru") {
                $this->lru[$key] = date("Y-m-d H:i:s");
            }
            return true;
        }
        /* GET key
         * 返回 key 所关联的字符串值。
         * 如果 key 不存在那么返回特殊值 nil 。
         * 假如 key 储存的值不是字符串类型,返回一个错误,因为 GET 只能用于处理字符串值。
         * */
        public function get($key) {
            $value = "";
            $this->requestNum += 1;
            if ($this->data[$key]) {
                $this->hitNum += 1;
                if ($this->type == "lfu") {
                    $this->lfu[$key] += 1;
                }
                if ($this->type == "lru") {
                    $this->lru[$key] = date("Y-m-d H:i:s");
                }
                if (is_string($this->data[$key])) {
                    $value = $this->data[$key];
                }
            }
            return $value;
        }
        /* APPEND key value
         * 如果 key 已经存在并且是一个字符串, APPEND 命令将 value 追加到 key 原来的值的末尾。
         * 如果 key 不存在, APPEND 就简单地将给定 key 设为 value ,就像执行 SET key value 一样。
         * 返回追加 value 之后 key 中字符串的长度。
         */
        public function append($key, $value) {
            $this->requestNum += 1;
            if ($this->data[$key]) {
                $this->hitNum += 1;
                $this->data[$key] .= $value;
            } else {
                $this->data[$key] = $value;
            }
            $len = strlen($this->data[$key]);
            if ($this->type == "lfu") {
                $this->lfu[$key] += 1;
            }
            if ($this->type == "lru") {
                $this->lru[$key] = date("Y-m-d H:i:s");
            }
            return $len;
        }
        // 清除缓存
        public function cleanup() {
            if (count($this->data) == $this->totalSize) {
                if ($this->type == "lfu") {
                    asort($this->lfu);
                    $keys = array_keys($this->lfu);
                    $k = $keys[0];
                    unset($this->data[$k]);
                    unset($this->lfu[$k]);
                }
                if ($this->type == "lru") {
                    asort($this->lru);
                    $keys = array_keys($this->lru);
                    $k = $keys[0];
                    unset($this->data[$k]);
                    unset($this->lru[$k]);
                }
            }
            return true;
        }
    }
    /*php实现redis的list*/
    class listCache
    {
        var $hitNume;
        var $requestNum;
        // 缓存类型
        var $type;
        // 缓存总大小
        var $totalSize;
        // 存值$key=>$array
        var $data = array();
        // 存访问次数$key=>$count
        var $lfu = array();
        // 存访问时间$key=>$time
        var $lru = array();
        public function __construct($cacheType, $totalSize) {
            $this->type = $cacheType;
            $this->totalSize = $totalSize;
        }
        /* LINDEX key index
         * 返回列表 key 中,下标为 index 的元素。
         * 下标(index)参数 start 和 stop 都以 0 为底,也就是说,以 0 表示列表的第一个元素,以 1 表示列表的第二个元素,以此类推。
         * 你也可以使用负数下标,以 -1 表示列表的最后一个元素, -2 表示列表的倒数第二个元素,以此类推。
         * 如果 key 不是列表类型,返回一个错误。
         */
        public function get($key, $index) {
            $this->requestNum += 1;
            $result = "";
            if ($this->data[$key]) {
                $this->hitNum += 1;
                if ($this->type == "lfu") {
                    $this->lfu[$key] += 1;
                }
                if ($this->type == "lru") {
                    $this->lru[$key] = date("Y-m-d H:i:s");
                }
                $result = $this->data[$key][$index];
            }
            return $result;
        }
        // 清除缓存
        public function cleanup() {
            if (count($this->data) == $this->totalSize) {
                if ($this->type == "lfu") {
                    asort($this->lfu);
                    $keys = array_keys($this->lfu);
                    $k = $keys[0];
                    unset($this->data[$k]);
                    unset($this->lfu[$k]);
                }
                if ($this->type == "lru") {
                    asort($this->lru);
                    $keys = array_keys($this->lru);
                    $k = $keys[0];
                    unset($this->data[$k]);
                    unset($this->lru[$k]);
                }
            }
            return true;
        }
        /* LINSERT key BEFORE|AFTER pivot value
         * 将值 value 插入到列表 key 当中,位于值 pivot 之前或之后。
         * 当 pivot 不存在于列表 key 时,不执行任何操作。
         * 当 key 不存在时, key 被视为空列表,不执行任何操作。
         * 如果 key 不是列表类型,返回一个错误。
         * @param $pos before或after,在存在的值之前插入还是之后插入
         * @param $pivot 列表里存在的值
         * @param $value 要插入的值
         * @return 如果命令执行成功,返回插入操作完成之后,列表的长度。
                   如果没有找到 pivot ,返回 -1 。
                   如果 key 不存在或为空列表,返回 0 。
         */
        public function insert($key, $pos, $pivot, $value) {
            $this->cleanup();
            $result = 0;
            if ($this->data[$key]) {
                if ($this->type == "lfu") {
                    $this->lfu[$key] += 1;
                }
                if ($this->type == "lru") {
                    $this->lru[$key] = date("Y-m-d H:i:s");
                }
                $index = array_search($pivot, $this->data[$key]);
                if ($index !== false) { // 找到pivot
                    if ($pos == "before") {
                        array_splice($this->data[$key], $index, 0, array($value));
                    } else { // after
                        array_splice($this->data[$key], $index + 1, 0, array($value));
                    }
                    $result = count($this->data[$key]);
                } else {
                    $result = -1;
                }
            }
            return $result;
        }
        /* LPOP key
         * 移除并返回列表 key 的头元素。
         * 相当于php的array_shift()函数
         */
        public function lpop($key) {
            $this->requestNum += 1;
            $result = "";
            if ($this->data[$key]) {
                $this->hitNum += 1;
                if ($this->type == "lfu") {
                    $this->lfu[$key] += 1;
                }
                if ($this->type == "lru") {
                    $this->lru[$key] = date("Y-m-d H:i:s");
                }
                $result = array_shift($this->data[$key]);
            }
            return $result;
        }
        /* LPUSH key value [value ...]
        * 将一个或多个值 value 插入到列表 key 的表头
        * 如果有多个 value 值,那么各个 value 值按从左到右的顺序依次插入到表头:比如说,对空列表 mylist 执行命令 LPUSH mylist a b c ,列表的值将是 c b a ,
        这等同于原子性地执行 LPUSH  mylist a 、 LPUSH mylist b 和 LPUSH mylist c 三个命令。
        * 如果 key 不存在,一个空列表会被创建并执行 LPUSH 操作。
        * 当 key 存在但不是列表类型时,返回一个错误。
        * 返回执行 LPUSH 命令后列表的长度。
        * @param string $values 一个或多个值,用“,”隔开
        */
        public function lpush($key, $values) {
            $this->cleanup();
            $values_arr = explode(",", $values);
            $cnt = count($values_arr);
            for ($i = 0; $i <= $cnt - 1; $i++) {
                $value = array_pop($values_arr);
                $this->data[$key][] = $value;
            }
            if ($this->type == "lfu") {
                $this->lfu[$key] += 1;
            }
            if ($this->type == "lru") {
                $this->lru[$key] = date("Y-m-d H:i:s");
            }
            return count($this->data[$key]);
        }
        /* RPOP key
         * 移除并返回列表 key 的尾元素。
         * 相当于php的array_pop()函数
         */
        public function rpop($key) {
            $this->requestNum += 1;
            $result = "";
            if ($this->data[$key]) {
                $this->hitNum += 1;
                if ($this->type == "lfu") {
                    $this->lfu[$key] += 1;
                }
                if ($this->type == "lru") {
                    $this->lru[$key] = date("Y-m-d H:i:s");
                }
                $result = array_pop($this->data[$key]);
            }
            return $result;
        }
        /* RPUSH key value [value ...]
         * 将一个或多个值 value 插入到列表 key 的表尾(最右边)。
         * 如果有多个 value 值,那么各个 value 值按从左到右的顺序依次插入到表尾:比如对一个空列表 mylist 执行 RPUSH mylist a b c ,得出的结果列表为 a b c,
           等同于执行命令 RPUSH mylist a 、 RPUSH mylist b 、 RPUSH mylist c 。
         * 如果 key 不存在,一个空列表会被创建并执行 RPUSH 操作。
         * 当 key 存在但不是列表类型时,返回一个错误。
         * 返回执行 RPUSH 操作后表的长度。
         * @param string $values 一个或多个值,用“,”隔开
         */
        public function rpush($key, $values) {
            $this->cleanup();
            $values_arr = explode(",", $values);
            foreach ($values_arr as $v) {
                $this->data[$key][] = $v;
            }
            if ($this->type == "lfu") {
                $this->lfu[$key] += 1;
            }
            if ($this->type == "lru") {
                $this->lru[$key] = date("Y-m-d H:i:s");
            }
            return count($this->data[$key]);
        }
    }
    /*php实现redis的set*/
    class setCache
    {
        var $hitNume;
        var $requestNum;
        // 缓存类型
        var $type;
        // 缓存总大小
        var $totalSize;
        // 存值$key=>$array
        var $data = array();
        // 存访问次数$key=>$count
        var $lfu = array();
        // 存访问时间$key=>$time
        var $lru = array();
        public function __construct($cacheType, $totalSize) {
            $this->type = $cacheType;
            $this->totalSize = $totalSize;
        }
        /* SMEMBERS key
         * 返回集合 key 中的所有成员。
         * 不存在的 key 被视为空集合。
         */
        public function getMembers($key) {
            $this->requestNum += 1;
            $members = array();
            if ($this->data[$key]) {
                $this->hitNum += 1;
                if ($this->type == "lfu") {
                    $this->lfu[$key] += 1;
                }
                if ($this->type == "lru") {
                    $this->lru[$key] = date("Y-m-d H:i:s");
                }
                $members = $this->data[$key];
            }
            return $members;
        }
        /* SADD key member [member ...]
         * 将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。
         * 假如 key 不存在,则创建一个只包含 member 元素作成员的集合。
         */
        public function add($key, $member) {
            $this->cleanup();
            $this->data[$key][] = $member;
            $result = array_unique($this->data);
            $this->data = $result;
            if ($this->type == "lfu") {
                $this->lfu[$key] += 1;
            }
            if ($this->type == "lru") {
                $this->lru[$key] = date("Y-m-d H:i:s");
            }
            return true;
        }
        // 清除缓存
        public function cleanup() {
            if (count($this->data) == $this->totalSize) {
                if ($this->type == "lfu") {
                    asort($this->lfu);
                    $keys = array_keys($this->lfu);
                    $k = $keys[0];
                    unset($this->data[$k]);
                    unset($this->lfu[$k]);
                }
                if ($this->type == "lru") {
                    asort($this->lru);
                    $keys = array_keys($this->lru);
                    $k = $keys[0];
                    unset($this->data[$k]);
                    unset($this->lru[$k]);
                }
            }
            return true;
        }
        /* SCARD key
         * 返回集合 key 的基数(集合中元素的数量)。
         * 当 key 不存在时,返回 0 。
         */
        public function count($key) {
            $this->requestNum += 1;
            $cnt = 0;
            if ($this->data[$key]) {
                $this->hitNum += 1;
                $cnt = count($this->data[$key]);
                if ($this->type == "lfu") {
                    $this->lfu[$key] += 1;
                }
                if ($this->type == "lru") {
                    $this->lru[$key] = date("Y-m-d H:i:s");
                }
            }
            return $cnt;
        }
        /* SISMEMBER key member
         * 判断 member 元素是否集合 key 的成员。
         * 如果 member 元素是集合的成员,返回 1 。
         * 如果 member 元素不是集合的成员,或 key 不存在,返回 0 。
         */
        public function isMember($key, $member) {
            $this->requestNum += 1;
            $flag = 0;
            if($this->data[$key]) {
                $this->hitNum += 1;
                if ($this->type == "lfu") {
                    $this->lfu[$key] += 1;
                }
                if ($this->type == "lru") {
                    $this->lru[$key] = date("Y-m-d H:i:s");
                }
                if (in_array($member, $this->data[$key])) {
                    $flag = 1;
                }
            }
            return $flag;
        }
        /* SPOP key
         * 移除并返回集合中的一个随机元素。
         * 如果只想获取一个随机元素,但不想该元素从集合中被移除的话,可以使用 SRANDMEMBER 命令。
         */
        public function randomDel($key) {
            $this->requestNum += 1;
            $result = "";
            if ($this->data[$key]) {
                $this->hitNum += 1;
                if ($this->type == "lfu") {
                    $this->lfu[$key] += 1;
                }
                if ($this->type == "lru") {
                    $this->lru[$key] = date("Y-m-d H:i:s");
                }
                $randomKey = array_rand($this->data[$key]);
                $result = $this->data[$key][$randomKey];
                unset($this->data[$key][$randomKey]);
            }
            return $result;
        }
    }
    /*php实现redis的sorted set*/
    class sortedsetCache
    {
        var $hitNume;
        var $requestNum;
        // 缓存类型
        var $type;
        // 缓存总大小
        var $totalSize;
        // 存值$key=>$array
        var $data = array();
        // 存访问次数$key=>$count
        var $lfu = array();
        // 存访问时间$key=>$time
        var $lru = array();
        public function __construct($cacheType, $totalSize) {
            $this->type = $cacheType;
            $this->totalSize = $totalSize;
        }
        /* ZADD key score member [[score member] [score member] ...]
         * 将一个或多个 member 元素及其 score 值加入到有序集 key 当中。
         * 如果某个 member 已经是有序集的成员,那么更新这个 member 的 score 值,并通过重新插入这个 member 元素,来保证该 member 在正确的位置上。
         * score 值可以是整数值或双精度浮点数。
         * 如果 key 不存在,则创建一个空的有序集并执行 ZADD 操作。
         * 当 key 存在但不是有序集类型时,返回一个错误。
        
         * @param array $values [member1=>score1, member2=>score2,……]的数组
         */
        public function add($key, $values) {
            $this->cleanup();
            foreach ($values as $member => $score) {
                $this->data[$key][$member] = $score;
            }
            asort($this->data[$key]);
            if ($this->type == "lfu") {
                $this->lfu[$key] += 1;
            }
            if ($this->type == "lru") {
                $this->lru[$key] = date("Y-m-d H:i:s");
            }
            return true;
        }
        // 清除缓存
        public function cleanup() {
            if (count($this->data) == $this->totalSize) {
                if ($this->type == "lfu") {
                    asort($this->lfu);
                    $keys = array_keys($this->lfu);
                    $k = $keys[0];
                    unset($this->data[$k]);
                    unset($this->lfu[$k]);
                }
                if ($this->type == "lru") {
                    asort($this->lru);
                    $keys = array_keys($this->lru);
                    $k = $keys[0];
                    unset($this->data[$k]);
                    unset($this->lru[$k]);
                }
            }
            return true;
        }
        /* ZRANGE key start stop [WITHSCORES]
         * 返回有序集 key 中,指定区间内的成员。
         * 其中成员的位置按 score 值递增(从小到大)来排序。
         * 具有相同 score 值的成员按字典序(lexicographical order)来排列。
         * 下标参数 start 和 stop 都以 0 为底,也就是说,以 0 表示有序集第一个成员,以 1 表示有序集第二个成员,以此类推。
         * 也可以使用负数下标,以 -1 表示最后一个成员, -2 表示倒数第二个成员,以此类推。
         * 比如说,当 start 的值比有序集的最大下标还要大,或是 start > stop 时, ZRANGE 命令只是简单地返回一个空列表。
         * 另一方面,假如 stop 参数的值比有序集的最大下标还要大,那么 Redis 将 stop 当作最大下标来处理。
         * 可以通过使用 WITHSCORES 选项,来让成员和它的 score 值一并返回,返回列表以 value1,score1, ..., valueN,scoreN 的格式表示。
         */
        // TODO:只考虑了下标为正的情况
        public function range($key, $start, $stop, $withScore = "false") {
            $this->requestNum += 1;
            $res = array();
            $end = $this->card($key) - 1;
            if ($this->data[$key]) {
                $this->hitNum += 1;
                if ($this->type == "lfu") {
                    $this->lfu[$key] += 1;
                }
                if ($this->type == "lru") {
                    $this->lru[$key] = date("Y-m-d H:i:s");
                }
                if ($start < $stop && $start < $end) {
                    if ($stop > $end) {
                        $stop = $end;
                        $ks = array_keys($this->data[$key]);
                        for ($i = $start; $i <= $stop; $i++) {
                            $k = $ks[$i];
                            if ($withScore == "true") {
                                $res[] = array($k => $this->data[$key][$k]);
                            } else {
                                $res[] = $k;
                            }
                        }
                    }
                }
            }
            return $res;
        }
        /* ZRANK key member
         * 返回有序集 key 中成员 member 的排名。其中有序集成员按 score 值递增(从小到大)顺序排列。
         * 排名以 0 为底,也就是说, score 值最小的成员排名为 0 。
         */
        public function rank($key, $member) {
            $this->requestNum += 1;
            $rank = 0;
            if ($this->data[$key]) {
                $this->hitNum += 1;
                if ($this->type == "lfu") {
                    $this->lfu[$key] += 1;
                }
                if ($this->type == "lru") {
                    $this->lru[$key] = date("Y-m-d H:i:s");
                }
                $rank = array_search($member, array_keys($this->data[$key]));
            }
            return $rank;
        }
    }
    /*php实现redis的hash*/
    class hashCache
    {
        var $hitNume;
        var $requestNum;
        // 缓存类型
        var $type;
        // 缓存总大小
        var $totalSize;
        // 存值$key=>$array
        var $data = array();
        // 存访问次数$key=>$count
        var $lfu = array();
        // 存访问时间$key=>$time
        var $lru = array();
        public function __construct($cacheType, $totalSize) {
            $this->type = $cacheType;
            $this->totalSize = $totalSize;
        }
        /*
         * HDEL key field [field ...]
         * 删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略。
         * fields为key中的域,多个域之间用","隔开
         * 返回被成功移除的域的数量,不包括被忽略的域。
         */
        public function delField($key, $fields)
        {
            $i = 0;
            $this->requestNum += 1;
            if ($this->data[$key]) {
                $this->hitNum += 1;
                if ($this->type == "lfu") {
                    $this->lfu[$key] += 1;
                }
                if ($this->type == "lru") {
                    $this->lru[$key] = date("Y-m-d H:i:s");
                }
                $fields_arr = explode(",", $fields);
                foreach ($fields_arr as $field) {
                    if (in_array($this->data[$key][$field], $this->data[$key])) {
                        $i++;
                        unset($this->data[$key][$field]);
                    }
                }
            }
            return $i;
        }
        /*
         * HGET key field
         * 返回哈希表 key 中给定域 field 的值。
         * 当给定域不存在或是给定 key 不存在时,返回 nil 。
        */
        public function getValue($key, $field)
        {
            $result = "";
            $this->requestNum += 1;
            if ($this->data[$key]) {
                $this->hitNum += 1;
                if ($this->type = "lfu") {
                    $this->lfu[$key] += 1;
                }
                if ($this->type = "lru") {
                    $this->lru[$key] = date("Y-m-d H:i:s");
                }
                if ($this->data[$key][$field]) {
                    $result = $this->data[$key][$field];
                }
            }
            return $result;
        }
        /*
         * HGETALL key
         * 返回哈希表 key 中,所有的域和值。
         * 在返回值里,紧跟每个域名(field name)之后是域的值(value),所以返回值的长度是哈希表大小的两倍。
         * 以列表形式返回哈希表的域和域的值。
         * 若 key 不存在,返回空列表。
        */
        public function getAll($key)
        {
            $result = array();
            $this->requestNum += 1;
            if ($this->data[$key]) {
                $this->hitNum += 1;
                if ($this->type = "lfu") {
                    $this->lfu[$key] += 1;
                }
                if ($this->type = "lru") {
                    $this->lru[$key] = date("Y-m-d H:i:s");
                }
                foreach ($this->data[$key] as $k => $v) {
                    $result[] = $k . "," . $v;
                }
            }
            return $result;
        }
        /*
         * HKEYS key
         * 返回哈希表 key 中的所有域。
         * 当 key 不存在时,返回一个空表。
         */
        public function getFields($key)
        {
            $this->requestNum += 1;
            $result = array();
            if ($this->data[$key]) {
                $this->hitNum += 1;
                if ($this->type = "lfu") {
                    $this->lfu[$key] += 1;
                }
                if ($this->type = "lru") {
                    $this->lru[$key] = date("Y-m-d H:i:s");
                }
                foreach ($this->data[$key] as $k => $v) {
                    $result[] = $k;
                }
            }
            return $result;
        }
        // 清除缓存
        public function cleanup() {
            if (count($this->data) == $this->totalSize) {
                if ($this->type == "lfu") {
                    asort($this->lfu);
                    $keys = array_keys($this->lfu);
                    $k = $keys[0];
                    unset($this->data[$k]);
                    unset($this->lfu[$k]);
                }
                if ($this->type == "lru") {
                    asort($this->lru);
                    $keys = array_keys($this->lru);
                    $k = $keys[0];
                    unset($this->data[$k]);
                    unset($this->lru[$k]);
                }
            }
            return true;
        }
        /*
         * HSET key field value
         * 将哈希表 key 中的域 field 的值设置为 value。
         * 如果 key 不存在,一个新哈希表被创建并执行 HSET 命令。
         * 如果域 field 已经存在于哈希表中,旧值将被覆盖。
         * 返回值:
            如果 field 是哈希表中的一个新建域,并且值设置成功,返回 1 。
            如果哈希表中域 field 已经存在且旧值已被新值覆盖,返回 0 。
         */
        public function set($key, $field, $value) {
            $this->cleanup();
            $result = 0;
            if ($this->data[$key]) {
                if ($this->type = "lfu") {
                    $this->lfu[$key] += 1;
                }
                if ($this->type = "lru") {
                    $this->lru[$key] = date("Y-m-d H:i:s");
                }
                if (!$this->data[$field]) {
                    $result = 1;
                }
            } else {
                $result = 1;
            }
            $this->data[$key][$field] = $value;
            return $result;
        }
        /*
         * HVALS key
         * 返回哈希表 key 中所有域的值。
         * 当 key 不存在时,返回一个空表。
         */
        public function getValues($key)
        {
            $this->requestNum += 1;
            $result = array();
            if ($this->data[$key]) {
                $this->hitNum += 1;
                if ($this->type = "lfu") {
                    $this->lfu[$key] += 1;
                }
                if ($this->type = "lru") {
                    $this->lru[$key] = date("Y-m-d H:i:s");
                }
                foreach ($this->data[$key] as $value) {
                    $result[] = $value;
                }
            }
            return $result;
        }
    }
  • 相关阅读:
    POWERDESIGNER中显示样式设置
    DatagridView 最后编辑状态数据无法自动提交的问题
    oracle 10G以上版本 树形查询新加的几个功能
    net farmework 4安装不了 原因是 HRESULT 0xc8000222
    npoi 导出
    oracle rowtype
    fiddler https
    一次linux站点安装经验
    小米手机安装https证书报错:无法安装该证书 因为无法读取该证书文件
    日志系统
  • 原文地址:https://www.cnblogs.com/sunshineliulu/p/7462653.html
Copyright © 2011-2022 走看看