Java Web缓存算法(hashmaps键值问题?)
我是编程新手,尤其是Java。最近几个月,我在做一个关于Web缓存算法的项目。在做了很多工作之后,我已经完成了所有的事情(因为这是我第一个真正的项目,我对此非常高兴),除了一个小但重要的细节。让我更确切地说 在代码中,我生成随机的Zipf分布式请求。每个请求项通过其数字ID(reqID)进行区分。缓存实现为双链接列表(Java LinkedList)。缓存算法称为WeightLFU,其工作原理如下: 每个请求分配一个权重,该权重由公式给出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
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}或类似的东西。但我想我还是个新手!