首页 > 编程语言 >ARC算法实现

ARC算法实现

时间:2024-07-12 15:19:40浏览次数:17  
标签:缓存 实现 T2 list elem Len 算法 ARC

1. 概述

Adaptive Replacement Cache(ARC)是一种缓存替换算法,用于提高缓存的命中率。ARC 动态调整缓存策略,以适应实际的访问模式,从而在不确定的工作负载下表现良好。它通过同时维护两个缓存列表来追踪最近使用和频繁使用的数据块,并根据访问模式在这两个列表之间动态分配缓存空间。

2. 基本概念

ARC 使用两个LRU队列(T1和T2)和两个历史列表(B1和B2):

  • T1: 存储一次命中(recently used once)的缓存项。
  • T2: 存储多次命中(recently used multiple times)的缓存项。
  • B1: 存储曾经在T1中,但已经被移除的缓存项。
  • B2: 存储曾经在T2中,但已经被移除的缓存项。

3. 主要操作

  • 缓存命中:如果缓存项在T1或T2中,则为缓存命中。
  • 缓存未命中:如果缓存项不在T1和T2中,则为缓存未命中。

ARC的核心操作如下:

  1. 插入
    • 若新缓存项在T1或T2中,则移动到T2的前端。
    • 若不在T1或T2中,则插入到T1的前端。
  2. 调整缓存大小
    • 若新缓存项在B1中,则表明最近访问模式偏向于访问新的缓存项,增加T1的容量。
    • 若新缓存项在B2中,则表明最近访问模式偏向于访问频繁访问的缓存项,增加T2的容量。
  3. 替换
    • 根据动态调整的容量,从T1或T2中移除最旧的缓存项,并将其元数据移动到B1或B2。

4. 线程安全的Go实现示例

以下是一个简单的线程安全的ARC缓存的Go实现:

package arc

import (
	"container/list"
	"sync"
)

type ARC struct {
	mtx      sync.Mutex
	capacity int
	t1       *list.List
	b1       *list.List
	t2       *list.List
	b2       *list.List
	cache    map[interface{}]*list.Element
}

func NewARC(capacity int) *ARC {
	return &ARC{
		capacity: capacity,
		t1:       list.New(),
		b1:       list.New(),
		t2:       list.New(),
		b2:       list.New(),
		cache:    make(map[interface{}]*list.Element),
	}
}

// Get returns the item from the cache.
func (c *ARC) Get(item any) any {
	c.mtx.Lock()
	defer c.mtx.Unlock()

	if elem, found := c.cache[item]; found {
		c.t2.MoveToFront(elem)
		return elem.Value
	}

	return nil
}

func (c *ARC) Put(item any) {
	c.mtx.Lock()
	defer c.mtx.Unlock()

	if c.capacity == 0 {
		return
	}

	if elem, found := c.cache[item]; found {
		elem.Value = item
		c.t2.MoveToFront(elem)
		return
	}

	// not found, so add it to the cache
	if c.t1.Len()+c.t2.Len() == c.capacity {
		if c.t1.Len() == c.capacity {
			c.removeLast(c.b1)
		} else {
			c.removeLast(c.t1)
		}
	} else if c.t1.Len()+c.b1.Len()+c.t2.Len()+c.b2.Len() >= c.capacity {
		if c.t1.Len()+c.b1.Len()+c.t2.Len()+c.b2.Len() == 2*c.capacity {
			c.removeLast(c.b2)
		} else {
			c.removeLast(c.t2)
		}
	}

	// add the new item to the cache
	elem := c.t1.PushFront(item)
	c.cache[item] = elem
}

// removeLast removes the last element from the list.
func (c *ARC) removeLast(l *list.List) {
	if l.Len() == 0 {
		return
	}

	elem := l.Back()
	l.Remove(elem)
	delete(c.cache, elem)
}

说明:

  • NewARC:创建一个新的ARC缓存实例。
  • Get:从缓存中获取值,并将其提升到T2。
  • Put:插入新的缓存项,并根据ARC的规则调整缓存。
  • removeLast:从指定列表中移除最后一个元素。

孟斯特

声明:本作品采用署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)进行许可,使用时请注明出处。
Author: mengbin
blog: mengbin
Github: mengbin92
cnblogs: 恋水无意
腾讯云开发者社区:孟斯特


标签:缓存,实现,T2,list,elem,Len,算法,ARC
From: https://www.cnblogs.com/lianshuiwuyi/p/18298460

相关文章

  • JDK 8 之后可以使用更加简单的方法 Stream 流来实现排序功能
    //创建并初始化ListList<Person>list=newArrayList<Person>(){{add(newPerson(1,30,"张三"));add(newPerson(2,20,"李四"));add(newPerson(3,40,"王五"));}};......
  • 代码随想录算法训练营第10天 | 复习队列和栈
    2024年7月12日题232.用栈实现队列两边倒即可,要出队列就倒到右边去,然后再回来。classMyQueue{Stack<Integer>s1;Stack<Integer>s2;intsize;publicMyQueue(){s1=newStack<>();s2=newStack<>();size=0;}......
  • 双指针法,高效移除数组特定值(思路+实现)
    题目①双指针解决本题的思路1.明确双指针slow、fast的作用:1_1.slow:数组该更新的位置,“新数组”(最终数组)的个数。 注意:本题新数组可以不需要辅助空间,而下一篇文章(有序数组的平方,就需要辅助数组)1_2.fast:遍历原数组(初始数组)2.双指针工作原理:(T是我们要删除的元素......
  • 算法力扣刷题记录 四十三【最大、最小深度问题】
    前言本文学习树的深度问题:二叉树(N叉树)最大深度、最小深度;记录三十九【层序遍历模版应用二】中解决过二叉树的最大深度和最小深度题目。思路是按层遍历:最大深度,相当于层序遍历结束;最小深度,相当于层序遍历过程中判断节点是不是叶子节点。那么此处的深度,还有什么知识点?......
  • 3.6--softmax回归的从零开始实现
    softmax回归从零实现前言一、导入相关的库二、数据和模型参数1.读取数据2.初始化模型参数三、实现softmax运算四、定义模型五、定义损失函数六、计算分类准确率七、训练模型八、预测总结前言本节介绍softmax和交叉熵损失函数的从零开始实现。一、导入相关的库imp......
  • html+js实现选中左边的数据到右边
    效果后台要开发个功能,给游戏内的用户赠送道具,先把道具列表展示,然后选择要增送的道具,可以加上道具图片之类的,美化index.html页面没有美化,只是实现了效果。<!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device......
  • 记一次原生AB分区OTA升级实现
    记一次原生AB分区OTA升级实现系统需要实现软件ota功能具体代码实现UpdateEnginemUpdateEngine=newUpdateEngine();UpdateParser.ParsedUpdatemParsedUpdate;try{mParsedUpdate=UpdateParser.parse(newFile(Environment.getDataDirectory(),"ota_package/upd......
  • 代码随想录算法训练营Day22 | Leetcode 77. 组合 | 216.组合总和III | 17.电话号码的
    今日任务77.组合题目链接:https://leetcode.cn/problems/combinations/description/题目描述:CodeclassSolution{vector<vector<int>>ans;vector<int>path;public:vector<vector<int>>combine(intn,intk){//intst......
  • 基于SpringBoot+Vue+数据可视化的药品商场购物系统设计和实现(源码+LW+部署讲解)
    博主介绍:✌全网粉丝50W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、P......
  • BUUCTF刷题_RoarCTF 2019_Easy Calc
    个人刷题学习记录,如有错误请多多指教进入题目如下,猜测是命令注入,输入ls弹框,估计是做了过滤查看页面源代码,发现一串代码,但是不怎么看得懂,查看网上大佬的wp进行学习看了别人的解题步骤知道这里有个url,存在calc.php,访问一下看看是啥上面注释里面写了有waf,猜测这里应该是waf的......