91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PHP如何實現LRU算法

發布時間:2021-06-30 10:44:03 來源:億速云 閱讀:174 作者:小新 欄目:編程語言

小編給大家分享一下PHP如何實現LRU算法,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

整體設計

1:用數組保存緩存對象(Node);

2:緩存對象(Node)之間通過nextKey,preKey組成一個雙向鏈表;

3:保存鏈表頭 跟尾;

處理流程如下圖:

PHP如何實現LRU算法

主要代碼

1:Node 節點類

/**
 * 緩存值保存類,
 * Class Node
 * @package app\common\model
 */
class Node{
    private $preKey=null;//鏈表前一個節點
    private $nextKey=null;//鏈表后一個節點
    private $value=null;//當前的值
    private $key=null;//當前key


    public function __construct(string  $key,$value)
    {
        $this->value=$value;
        $this->key=$key;
    }

    public function setPreKey($preValue){
        $this->preKey=$preValue;
    }
    public function setNextKey($nextValue){
        $this->nextKey=$nextValue;
    }

    public function getPreKey(){
        return $this->preKey;
    }

    public function getNextKey(){
        return $this->nextKey;
    }

    public function getValue(){
        return $this->value;
    }

    public function setValue($value){
        $this->value=$value;
    }

    public function setKey(string  $key){
        $this->key=$key;
    }

    public function getKey(){
        return $this->key;
    }
}

2:緩存類

/**
 * 實現lru緩存
 * Class LruCache
 * @package app\common\model
 */
class LruCache
{
    public $cacheTable =[];
    private $headNode=null;
    private $lastNode=null;
    private $cacheCount=0;
    private $cacheMax=100;


    /**
     * 測試輸出使用
     */
    public function dumpAllData(){
        if (!empty($this->headNode)){
            $node=$this->headNode;
            while (!empty($node)){
                echo 'key='.$node->getKey().'  nextKey='.(empty($node->getNextKey())?'null':$node->getNextKey()->getKey()).' preKey='.(empty($node->getPreKey())?'null':$node->getPreKey()->getKey()).' value='.$node->getValue()."</br>";
                $node=$node->getNextKey();
            }
        }
    }


    /**
     * @param int $count
     */
    public function setCacheMax(int $count){
        $this->cacheMax=$count;
    }

    /**
     * @param string $key
     * @param $value
     * @return bool
     */
    public function set(string $key,$value){

        //設置值為null,則認為刪除緩存節點
        if ($value===null){
            $this->del($key);
            return true;
        }

        //判斷是否存在表中,存在則更新連表
        if (!empty($this->cacheTable[$key])){
            $this->updateList($key);
            return true;
        }

        //先判斷是否要刪除
        $this->shiftNode();
        $this->addNode($key,$value);
        return true;

    }

    /**
     * @param string $key
     * @return bool
     */
    public function del(string $key){
        if (!empty($this->cacheTable[$key])){
            $node=&$this->cacheTable[$key];

            //摘出節點
            $this->jumpNode($node);
            //置空刪除
            $node->setPreKey(null);
            $node->setNextKey(null);
            unset($this->cacheTable[$key]);
            return true;
        }

        return false;
    }

    /**
     * @param string $key
     * @return null
     */
    public function get(string $key){
        if (!empty($this->cacheTable[$key])){
            $this->updateList($key);
            return $this->cacheTable[$key]->getValue();
        }

        return null;
    }


    //直接添加節點
    private function addNode($key,$value){
        $addNode=new Node($key,$value);
        if (!empty($this->headNode)){
            $this->headNode->setPreKey($addNode);
        }
        $addNode->setNextKey($this->headNode);

        //第一次保存最后一個節點為頭節點
        if ($this->lastNode==null){
            $this->lastNode=$addNode;
        }
        $this->headNode=$addNode;
        $this->cacheTable[$key]=$addNode;
        $this->cacheCount++;
    }


    //主動刪超出的緩存
    private function shiftNode(){
        while ($this->cacheCount>=$this->cacheMax){
            if (!empty($this->lastNode)){
                if (!empty($this->lastNode->getPreKey())){
                    $this->lastNode->getPreKey()->setNextKey(null);
                }
                $lastKey=$this->lastNode->getKey();
                unset($this->cacheTable[$lastKey]);
            }
            $this->cacheCount--;
        }

    }

    //更新節點鏈表
    private function updateList($key){
        //這里需要使用引用傳值
        $node=&$this->cacheTable[$key];

        //當前結點為頭結點 直接不用處理
        if ($this->headNode===$node){
            return true;
        }

        //摘出結點
        $this->jumpNode($node);
        //跟頭結點交換
        $node->setNextKey($this->headNode);
        $this->headNode->setPreKey($node);
        $node->setPreKey(null);
        $this->headNode=$node;

        return true;

    }


    //將某個節點摘出來
    private function jumpNode(Node &$node){
        if (!empty($node->getPreKey())){
            $node->getPreKey()->setNextKey($node->getNextKey());
        }

        if (!empty($node->getNextKey())){
            $node->getNextKey()->setPreKey($node->getPreKey());
        }

        //如果是最后一個節點,則更新最后節點為它的前節點
        if ($node->getNextKey()==null){
            $this->lastNode=$node->getPreKey();
        }

        //如果是頭結點
        if ($node->getPreKey()==null){
            $this->headNode=$node->getNextKey();
        }
    }



}

3:測試代碼

    public function tt(){
    $cath=model("LruCache");
    $cath->setCacheMax(3);
    $cath->set("aa","aaaaaaaaaaa");
    $cath->set("bb","bbbbbbbbbbbb");
    $cath->set("cc","ccccccccccccc");
    $cath->get("aa");

//        $cath->dumpAllData();
        $cath->set("dd","ddddddddddddd");
//        $cath->del("cc");
//        var_dump($cath->cacheTable);
        $cath->dumpAllData();
        exit();



    }

以上是“PHP如何實現LRU算法”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

桐乡市| 博乐市| 晋宁县| 三江| 庆安县| 手游| 共和县| 焦作市| 建阳市| 离岛区| 上饶市| 平遥县| 宁乡县| 宁远县| 环江| 沈阳市| 岑巩县| 长兴县| 修文县| 白山市| 揭东县| 新竹县| 城固县| 岫岩| 元阳县| 霸州市| 敖汉旗| 阳原县| 新河县| 玛纳斯县| 乌苏市| 华坪县| 合山市| 浦城县| 孟连| 平安县| 中方县| 运城市| 建水县| 铁岭市| 五峰|