zoukankan      html  css  js  c++  java
  • 分页缓存预加载算法

    分页缓存预加载算法:
         将数据分页(块)存储在缓存,这个页(块),一般大于应用实际请求的页面大小,分页(块)缓存的加载采取预加载方式,即在应用分页请求还没读到分页(块)的最后一页数据时,即预先加载下一页的缓存。这样做有点如下:(1)减少DB读取次数。(2)减少缓存传输数据大小。(3)预加载分页缓存则避免应用请求超时。
    令:
    total : 记录总数
    cm :缓存大小,每一次缓存的记录条数
    cp :当前缓存页数
    n :一次请求多少条数
    p :当前请求第几页
    x :提前几页开始预加载缓存
    bucket:缓存第几页(块)
    begin : 从缓存的第几条开始取
    threshold : 触发读取DB条件。
    令:cm >= n+ n*x  保证缓存数据可供至少请求一次才触发预加载
    则:
    bucket = (p * n) / cm + 1
    begin = (p - 1) * n  + 1
    threshold :((p * n) % cm + n * x) >= cm
    算法描述:
    1. 初始化加载缓存,从DB中取cm条记录存入缓存。
    2. 应用分页请求时,如果:
      1. (p * n) % cm >= n,在第(p * n) / cm + 1页缓存从((p - 1) * n ) % cm + 1 条开始取n条记录返回
      2. (p * n) % cm < n , 请求跨了两个(页)缓存,需要在两个缓存中各取一部分数据拼接返回。在缓存从 (p * n) / cm 页缓存中从  ((p - 1)*n - 1) % cm + 1条开始取 n - (p * n) % cm 条加上,在缓存从(p * n) / cm + 1页缓存中从第1条开始取(p * n) % cm条合并返回。
      3. 如果 (p * n) % cm + n * x  >= cm ,触发预加载,即从DB中加载cm条记录至缓存。
    3. 结束。

    算法demo:

    package com.xx.lt;
    
    import java.util.HashMap;
    import java.util.Map;
    
    /**
     * Created by Jenkin.K on 17/6/1.
     */
    public class PageCache {
        Map<Integer,Cache> cacheMemory = new HashMap<Integer, Cache>();
        Map<Integer, Record> dbData;
        int cm = 50;        //缓存大小
        int bucket ;        //当前缓存页
        int begin ;         //从缓存的第几条开始取
        int n ;             //一次请求多少条
        int p ;             //当前请求第几页
        int x = 2;          //提前
    
        public static void main(String args[]){
            PageCache pageCache = new PageCache();
            pageCache.dbData = pageCache.initData();
            pageCache.cacheMemory.put(1, pageCache.loadCache(pageCache.cm, 1));
            int total = 1000;
            int pageSize = 6;
            for(int i = 0; i < total/pageSize - 1; i++) {
                System.out.println("get "+ (i+1) +" page :" );
                pageCache.getPage(i + 1, pageSize);
            }
            System.out.println(pageCache.cacheMemory);
        }
    
        private Map<Integer, Record> initData(){
            Map<Integer, Record> data = new HashMap<Integer, Record>();
            for(int i = 0; i < 1000; i++){
                data.put(i+1, new Record(i+1));
            }
            return data;
        }
    
        public void getPage(int p, int n){
            Map<Integer, Record> page = new HashMap<Integer, Record>();
            bucket = (p * n) / cm + 1; //求当前取哪页缓存
            begin = ((p -1) * n)  + 1;
            if((p * n) % cm > n || (p * n) % cm == n){  //没跨缓存
                page = getFromCache(bucket, begin, n, page);
            }else {  //跨缓存
                page = getFromCache(bucket - 1, begin, n - (p * n) % cm, page);
                page = getFromCache(bucket, (bucket-1) * cm + 1, (p * n) % cm, page);
            }
            if((p * n) % cm > cm - n * x || (p * n) % cm == cm - n * x){
                System.out.println("load cache");
                cacheMemory.put(bucket + 1, loadCache(cm, bucket + 1));
            }
            System.out.println("page data : " + page);
        }
    
        /**
         *
         * @param bucket 第几页缓存
         * @param begin 从哪个开始取
         * @return
         */
        private Map<Integer, Record> getFromCache(int bucket, int begin, int n, Map<Integer, Record> page){
            Cache cache = cacheMemory.get(bucket);
            for(int i = 0; i < n; i++){
                Record r = cache.cache.get(begin + i);
                page.put(begin + i, r);
            }
            return page;
        }
    
        /**
         *
         * @param cm 缓存大小
         * @param bucket 第几页缓存
         * @return
         */
        private Cache loadCache(int cm, int bucket){
            Cache cache = new Cache();
            int deta = cm * (bucket-1) + 1;
            for(int i = 0; i < cm; i++){
                cache.cache.put(deta + i, dbData.get(deta + i));
            }
            return cache;
        }
    
        class Cache{
            Map<Integer, Record> cache = new HashMap<Integer, Record>();
            public String toString(){
                StringBuffer sb = new StringBuffer();
                for(Map.Entry entry : cache.entrySet()){
                    sb.append(entry.getKey() + ":" + entry.getValue() + ",");
                }
                return String.valueOf(sb);
            }
        }
    
        class Record{
            Object value;
            Record(Object o){
                value = o;
            }
            public String toString(){
                return String.valueOf(value);
            }
        }
    
    }
    

      

     
  • 相关阅读:
    Android手势锁实现
    网页模板pug基本语法
    React入门看这篇就够了
    我曾站在离你最近的天涯
    一文看懂浏览器事件循环
    Vi编辑网卡
    2019.6.11_MySQL进阶二:主键与外键
    2019.6.13_笔试题目及答案
    2019.6.13_MySQL简单命令的使用
    2019.6.13_SQL语句中----删除表数据drop、truncate和delete的用法
  • 原文地址:https://www.cnblogs.com/kisf/p/6930105.html
Copyright © 2011-2022 走看看