EhCache 核心功能實現

剛纔我弄了一下EhCache

底層有用鏈表實現的,並且默認使用lru算法來提高效率,當把元素放進去的時候,會先放到頭部鏈表

然後在使用數據的時候,會從頭部查找這個數據,然後把找到的數據放到頭部,然後返回

並且還會開啓線程來定時從尾部清理節點

 

 

看代碼吧

public void put(String key, Object val) {

        if(headNode==null){
            CacheNode cacheNode=new CacheNode(key,val,tailNode,null);
            headNode=cacheNode;
            System.out.println("頭部初始化");
            return;
        }
        if(tailNode==null){
            CacheNode cacheNode=new CacheNode(key,val,null,headNode);
            tailNode=cacheNode;
            System.out.println("尾部初始化");
            return;
        }


        //直接插入到尾部
        CacheNode cacheNode = new CacheNode();
        cacheNode.setKey(key);
        cacheNode.setVal(val);

        //放到頭部的,搞錯了
        headNode.setLast(cacheNode);
        cacheNode.setNext(headNode);
        headNode=cacheNode;

        size++;
        System.out.println("放進去了");
    }

 

先看頭部和尾部是否爲空,如果都不爲空就直接把節點放到頭部

然後就是獲取數據的方法


    public Object get(String key) {
        if(size==0){
            return null;
        }
        if (headNode.getKey().equals(key))
            return headNode.getVal();

        //遍歷節點找到使用了這個key的
        for (CacheNode cacheNode = headNode; cacheNode != null; cacheNode = cacheNode.getNext()) {
            if (cacheNode.getKey().equals(key)) {
                //找到了就把這個節點放到頭部,然後把結果返回給調用者
                switchToHead(cacheNode);
                return cacheNode.getVal();
            }
        }
        return null;
    }

如果找到節點後,就把這個節點放到頭部,然後把節點返回給調用者

 

下面是把節點放到頭部的方法

簡單的引用指向

private void switchToHead(CacheNode cacheNode) {
        if (cacheNode.getLast() != null) {
            CacheNode last = cacheNode.getLast();
            if (cacheNode.getNext() != null) {
                //處理他前面和後面的節點
                CacheNode next = cacheNode.getNext();
                next.setLast(last);
                last.setNext(next);
            }

            //直接和頭部交換就行
            headNode.setLast(cacheNode);
            headNode = cacheNode;
            return;
        }
        //如果前面是空的,那說明你已經是頭了,我就不管你
    }

 

 

接下來就是定時清理的方法

private void doClean(CacheNode cacheNode, int needCount) {
        if (size <= needCount)
            return;

        //開始清理
        if (cacheNode.getLast() == null) {
            cacheNode = null;
            return;
        }
        cacheNode.getLast().setNext(null);
        cacheNode = null;
        System.out.println("----------清理掉一個");
        size--;

        if(cacheNode==null||cacheNode.getLast()==null)
            return;

        doClean(cacheNode.getLast(), needCount);
    }

 

就是定時從尾部開始清理節點,直到要清理的大小不滿足條件

 

然後就是方法的調用

  CacheChain cacheChain=new CacheChain();
        cacheChain.put("a",new Student("zhangjun","zhangjun249",19));
        cacheChain.put("b",new Student("asdf","zhangjun249",19));
        cacheChain.put("c",new Student("zhanasdgjun","zhangjun249",19));
        cacheChain.put("d",new Student("asdf","zhangjun249",19));
        cacheChain.put("e",new Student("fffffff","zhangjun249",19));
        cacheChain.put("f",new Student("aaaaaaaaaaa","zhangjun249",19));


        cacheChain.cleanNode(3000,2);

        System.out.println(cacheChain.get("a")!=null);

 

完整代碼可以去我的GitHub

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章