栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

c++实现高速缓存Cache

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

c++实现高速缓存Cache

c++实现高速缓存Cache
    • 需求:
    • 分析:
    • 实现:

需求:

Cache对键值对进行存储,capacity为Cache最大容量
1.get(key)方法获取对应映射值,不存在返回-1;
2.put(key,value)方法插入键值对。

分析:

1.get()方法要经常获取对应值所以低层存储应该是hashMap;
2.要及时更新频次,每次使用过一个节点之后要更新频次,对于频次更新可以使用双向结构,每次插入首部,删除时直接删除尾部;常用的双向结构主要有双向队列,双向链表,队列可以满足put需求,但get方法使用完之后需要将该键值对更新至队首,队列对于该任务太过复杂。
3. 选用双向链表实现,链表节点中存储key,value以及链表前后节点的两个指针pre,next;

实现:
//定义双链表结构体
struct DoubleLinkedNode{
​	int val;
​	int key;
​	DoubleLinkedNode *pre;
​	DoubleLinkedNode *next;
	//定义结构体初始化方法
​	DoubleLinkedNode():key(0),val(0),pre(nullptr),nxt(nullptr);
​	DoubleLinkedNode(int x,int y):key(x),val(y),pre(nullptr),nxt(nullptr);
}

Class Cache{
private:
	//定义head,tail :最新节点永远在head->next,频次最低的为tail->pre;
	//hashMap中存储key-键值对节点地址,可以快速访问对应节点
	//定义容量与当前使用内存
	unordered_maptempList;
	int capacity;
	DoubleLinkedNode *head;	
	DoubleLinkedNode *tail;
	int curSize;
public:
​	//构造函数完成 私有变量的初始化;
	Cache(int x):capacity(x),curSize(0){
		this->head = new DoubleLinkedNode();
		this->tail = new DoubleLinkedNode();
		this->head->next = this->tail;
		this->tail->pre = this->head;
	}
	//先来定义节点的操作
	//1.在首部插入
	void addNew(DoubleLinkedNode* x){
		head->next->pre = x;
		x->next = head->next;
		x->pre = head;
		head->next = x;
	}
	//2.在尾部删除
	//由于删除完还需要更新hashMap所以需要对所删除节点进行返回
	DoubleLinkedNode* removeTail(DoubleLinkedNode* x){
		DoubleLinkedNode* node = tail->pre;
		removeNode(tail);
		return node;
	}
	//3. 删除任意节点
	//更新操作其实可以理解为 先删除,再首部插入
	void removeNode(DoubleLinkedNode* x){
		node->pre->next = node->next;
		node->next->pre = node->pre;
	}
	//获取更新,不牵扯容量
	int get(int key){
		if(tempList.count(key)==0) return -1;
		DoubleLinkedNode* node = tempList[key];
		removeNode(node);
		addNew(node);
		return node->val;
	}
	//
	int put(int key,int val){
		if(tmpList.count(key)==0){
			DoubleLinkedNode* node = new DoubleLinkedNode(key,val);
			tmpList[key] = node;
			addNew(node);
			size++;
			if(size>capacity){
				//这里是唯一会产生内存泄露的地方
				//假设removeTail()为返回节点而直接返回node->key,而节点都是在put()方法中堆空间申请
				//所以删除节点的时候需要将其返回,再此处将节点delete,释放堆空间内存
				DoubleListNode* eraseNode = removeTail();
				tmpList.erase(key);
				delete (eraseNode);
				size--;
			}
		}else{
			DoubleLinkedNode* node = tmpList(key);
			removeNode(node);
			addNew(node);
		}		
	}
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1021984.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号