时钟缓存算法

时间:2012-04-12 11:06:24

标签: java caching clock browser-cache

我想了解时钟缓存替换策略的原理。

什么时候开始工作? 我们有例如缓存大小= 5。 因此,首先我们将5个随机对象添加到缓存中。当我认为所有这些对象最初都是clockbit = 0时,我是真的吗? 然后当第六个物体到来时,我们必须为它找到一个地方。 我们应该尝试在没有Clock hand的情况下在缓存中找到相同的对象(只是ifInCache(comingObject))? 如果缓存中没有这样的对象会发生什么? 时钟指针的起始位置在哪里?

我阅读了很多文章,只想了解有关时钟的主要问题。

2 个答案:

答案 0 :(得分:4)

  

当我认为所有这些对象最初都是clockbit = 0时,我是真的吗?

如果没有引用它们,那么是。

  

我们是否应该尝试在没有Clock hand的情况下在缓存中找到相同的对象(只是ifInCache(comingObject))?

是的,你必须检查对象是否已经在缓存中。如果是,则参考位(clockbit)将设置为1。

  

如果缓存中没有这样的对象会怎样?时钟指针的起始位置在哪里?

如果对象尚未在缓存中,则在时钟指针处检查对象。手的位置将是缓存中的最后位置(如果它尚未填满),并且在两个缓存查找之间保持相同(它将通过查找本身递增)。

示例(缓存大小= 5):

  • 添加A - >
  • 之前的0和之后的1
  • 添加B - >
  • 之前的1和之后的2
  • 添加C - >
  • 之前和之后的2
  • 添加D - >
  • 之前和之后4点
  • 添加E - >
  • 之前4和之后0
  • 添加F - >在0处,检查A的参考位,如果是0替换并递增指针,否则仅递增指针 - >之后手是1

请注意,如果所有对象的引用位都设置为1,则将更换手中的对象,因为在检查对象后,其引用位设置为0,因此第二次检查对象时该位将为0。

编辑

这是@PeterLawrey代码的扩展/调整版本:

private final Object[] objects= new Object[5]; 
private final boolean[] referenced = new boolean[5]; //boolean for simplicity
private int clock = 0;

public Object getOrCache(Object obj) {
   for(int i = 0; i < objects.length; ++i) {
     if (obj.equals(objects[i])) {
       referenced[i] = true; //object has been referenced, note that this is for simplicity and could be optimized
       return obj;
     }
   }

   //loop over the entries until there is a non-referenced one
   //reference flags are removed in the process
   while( referenced[clock] ) {
     referenced[clock] = false;
     clock = (clock + 1) % objects.length; //for clarity
   }

   //replace the object at the current clock position and increment clock
   objects[clock] = obj;
   referenced[clock] = true;
   clock = (clock + 1) % objects.length; //for clarity

   return obj;
}

答案 1 :(得分:2)

我认为你让自己变得复杂。人们使用这种方法的原因是它非常简单。

这样可以避免更换最近使用的熵。

private final Object[] objects = new Object[5];
private final boolean[] referenced = new boolean[objects.length];
private int clock = 0;

public Object getOrCache(Object obj) {
    for (int i = 0, objectsLength = objects.length; i < objectsLength; i++) {
        Object o = objects[i];
        if (obj.equals(o)) {
            referenced[i] = true;
            return obj;
        }
    }
    while(referenced[clock]) {
        referenced[clock] = false;
        incrClock();
    }
    objects[clock] = obj;
    incrClock();
    return obj;
}

private void incrClock() {
    if (++clock >= objects.length)
        clock = 0;
}

这不会打扰。

private final Object[] objects= new Object[5];
private int clock = 0;

public Object getOrCache(Object obj) {
   for(Object o: objects) 
       if (obj.equals(o))
           return obj;
   objects[clock++ % objects.length] = obj;
   return obj;
}