Java Web缓存算法(hashmaps键值问题?)

Java Web缓存算法(hashmaps键值问题?),java,caching,hashmap,key,key-value,Java,Caching,Hashmap,Key,Key Value,我是编程新手,尤其是Java。最近几个月,我在做一个关于Web缓存算法的项目。在做了很多工作之后,我已经完成了所有的事情(因为这是我第一个真正的项目,我对此非常高兴),除了一个小但重要的细节。让我更确切地说 在代码中,我生成随机的Zipf分布式请求。每个请求项通过其数字ID(reqID)进行区分。缓存实现为双链接列表(Java LinkedList)。缓存算法称为WeightLFU,其工作原理如下: 每个请求分配一个权重,该权重由公式给出 weight = Math.pow(1/p, r

我是编程新手,尤其是Java。最近几个月,我在做一个关于Web缓存算法的项目。在做了很多工作之后,我已经完成了所有的事情(因为这是我第一个真正的项目,我对此非常高兴),除了一个小但重要的细节。让我更确切地说

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

每个请求分配一个权重,该权重由公式给出

    weight = Math.pow(1/p, reqIndex);
其中p是权重因子,reqIndex是请求的数字索引(第1、第2、第3等)

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

需求指标:1 | 2 | 3 | 4 | 5 需求:7 | 3 | 7 | 1 | 3

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

需求指标:1 | 2 | 3 | 4 | 5 体重:1 | 2 | 4 | 8 | 16

因此,需求编号为7的请求项目得分为1+4=5,需求编号为3的项目得分为2+16=18,最终需求编号为1的项目得分为8

这就是我做错的地方。在本例中,我将有以下内容:第3项的分数将为16+8+4+2+1=31,第1项的分数将为8+4+2+1=15,等等,即代码将所有之前的权重相加,而不考虑请求ID。以下是代码的相关部分:

类权重

    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.)
}
公共类权重lfu{
//////////////////////////////////////////
//成员属性
/**weightLFU缓存*/
private List weightLFU=new LinkedList();
/**最大缓存大小*/
私有INTM;
/**衰减因子*/
私人双p;
/**重量*/
私人双倍重量;
/**分数(权重频率)*/
私人双重频;
/**需求(K)和重量(V)图*/
私有地图权重;
/**reqID(K)和weightFreq(V)图*/
私人地图权重;
//////////////////////////////////////////
//成员方法
//构造函数、打印方法、初始值设定项等。
/**
*请求权重的Getter
*@param请求请求的项目
*@param reqIndex请求的索引
*@return this.weights.get(request.reqID)请求的权重
*/
公共双getWeight(请求请求、int-reqIndex){
//计算重量
重量=数学功率(1/p,要求指数);
//将请求及其权重放入权重映射
重量。放置(request.reqID,重量);
//返回所需物品的重量
返回此.weights.get(request.reqID);
}
/**
*计算请求项的权重频率
*@param请求请求的项目
*@param reqIndex请求的索引
*/
公共无效CalcWeightRequest(请求请求,内部请求索引){
//初始化权重频率
初始化(请求);
//计算重量频率
weightFreq+=getWeight(请求、请求索引);
//将reqID及其weightFreq放入weightFreqs映射中
weightFreqs.put(request.reqID,weightFreq);
}
/**
*请求项的weightFreq的Getter
*@param请求请求的项目
*@return this.weightFreqs.get(request.reqID);req.item的weightFreq
*/
公共双getWeightFreq(请求){
//返回请求项的权重频率
返回这个.weightFreqs.get(request.reqID);
}
//其他内容(缓存查找、插入、替换等)
}
我之所以使用方法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

} 
//几个不相关的东西
//扫描请求列表
对于(int-ir=0;ir
我理解这种不正常的行为是有道理的。我假设在calcWeightFreq方法中,我必须扫描权重映射,以便仅获取特定reqID的权重之和,但这也不起作用(我为所有weightFreq值获取0值)


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

是的,没错。我这样做是因为我认为我必须将其权重与请求ID相关联,以便在calcWeightFreq中获得每个请求ID的权重之和,从而计算其得分,而不是像我现在这样将之前的所有权重相加。您还没有显示足够的代码。@RobinGreen我有完全相反的感觉,我认为我发布了太多的代码!IMO的问题在于我计算分数的方法(WeightFreq)。我应该以某种方式利用这样一个事实,即我已经使用相关的HashMap权重将一个reqID与每个权重相关联,以便在该方法中获取每个单独reqID的权重之和。但我不知道怎么做。它应该类似于for(Entry:this.weights.entrySet){//stuff}或类似的东西。但我想我还是个新手!