Web缓存算法(hashmaps keys-values问题?)

时间:2013-12-08 19:53:36

标签: java caching hashmap key key-value

我是编程方面的新手,尤其是Java。最近几个月我正在开发一个关于Web缓存算法的项目。经过大量的工作,我已经完成了所有工作(因为这是我的第一个真正的项目,我很高兴),除了一个小但重要的细节。让我更加准确。

在代码中我生成随机的Zipf分布式请求。每个请求的项目由其数字ID(reqID)区分。缓存实现为双向链表(Java LinkedList)。缓存算法称为WeightLFU,它的工作原理如下:

为每个请求分配一个由公式

给出的权重
    weight = Math.pow(1/p, reqIndex);

其中p是权重因子,reqIndex是请求的数字索引(第1,第2,第3等)。

每个缓存项目的分数(我称之为加权频率,weightFreq)作为其权重之和给出。让我们看一个例子来说明这一点。假设我们有以下请求流(给出了reqID):

ReqIndex:1 | 2 | 3 | 4 |五 要求:7 | 3 | 7 | 1 | 3

假设p = 0.5(只是一个方便的值),分配给每个请求的权重是:

ReqIndex:1 | 2 | 3 | 4 |五 重量:1 | 2 | 4 | 8 | 16

因此,reqID 7的请求项目的分数是1 + 4 = 5,reqID 3的项目的分数是2 + 16 = 18,最后reqID 1项目的分数是8。

现在这就是我做错了。在这个例子中,我将得到以下结果:项目3的得分为16 + 8 + 4 + 2 + 1 = 31,项目1的得分为8 + 4 + 2 + 1 = 15等,即无论请求ID如何,代码都会对所有先前的权重进行求和。以下是代码的相关部分:

Class WeightLFU

    public class WeightLFU {

//////////////////////////////////////////
// member attributes

/** weightLFU cache */
private List<Request> weightLFU = new LinkedList<Request>();

/** Max cache size */
private int M;

/** Fading factor */
private double p;

/** Weight */
private double weight;

/** Score (weightFreq) */
private double weightFreq;

/** Map of reqID (K) and weight (V) */
private Map<Integer, Double> weights;

/** Map of reqID (K) and weightFreq (V) */
private Map<Integer, Double> weightFreqs;

    //////////////////////////////////////////
// member methods

    // constructor, printing methods, initializers etc.

    /**
 * Getter for weight of request
 * @param   request                                 The requested item
 * @param   reqIndex                                The index of the request
 * @return  this.weights.get(request.reqID)     The weight of the request
 */
public double getWeight(Request request, int reqIndex) {

    // calculate weight
    weight = Math.pow(1/p, reqIndex);

    // put request along with its weight to the weights map
    weights.put(request.reqID, weight);

    // return weight of requested item
    return this.weights.get(request.reqID);

}

/**
 * Calculate weightFreq of requested item
 * @param   request    The requested item
 * @param   reqIndex   Index of the request     
 */
public void calcWeightFreq(Request request, int reqIndex) {

    // initialize weightFreq
    initWeightFreqs(request);

    // calculate weight freq
    weightFreq += getWeight(request, reqIndex);

    // put reqID along with its weightFreq into the weightFreqs map
    weightFreqs.put(request.reqID, weightFreq);

}

/**
 * Getter for weightFreq of requested item
 * @param   request                                 The requested item
 * @return  this.weightFreqs.get(request.reqID);    weightFreq of req. item
 */
public double getWeightFreq(Request request) {

    // return weightFreq of requested item
    return this.weightFreqs.get(request.reqID);

}

    // other stuff (cache lookup, insertion, replacement etc.)
}

我使用方法calcWeightFreq和另一个方法作为getter而不是将它们组合在一个getter方法中的原因只是为了避免在后面的缓存插入和替换操作中调用getter方法时使用reqIndex作为参数。这与我的问题无关。

主要课程:

    // several irrelevant stuff

    // scan the request list
    for(int ir = 0; ir < reqs.size(); ir++) {

        // assign the item in position ir in the reqs list to a Request item r
    Request r = reqs.get(ir);

       // other stuff

}

// other stuff

} 

我明白这种异常行为是有道理的。我假设在calcWeightFreq方法中我必须扫描权重图以获得仅针对特定reqID的权重之和,但这也不起作用(我得到所有weightFreq值的0值)。

我希望我已经明确说明了这个问题。我假设它只需要5到10行额外的代码来解决,但我不知道该怎么做。任何指导将不胜感激。提前谢谢。

0 个答案:

没有答案