LRU Cache 데이터 구조 안내
LRU 는 Least Recently Used 의 줄 임 말로 최근 에 가장 적 게 사용 한 다 는 뜻 으로 Cache 교체 알고리즘 이다.캐 시가 뭐야?협의 적 인 Cache 는 CPU 와 메 인 메모리 사이 에 있 는 빠 른 RAM 을 말 하 는데 보통 시스템 메 인 메모리 처럼 D 램 기술 을 사용 하지 않 고 비 싸 지만 빠 른 SRAM 기술 을 사용한다.넓 은 의미 에서 Cache 는 속도 차이 가 비교적 큰 두 가지 하드웨어 사이 에 위치 하고 이들 의 데이터 전송 속도 차 이 를 조율 하 는 구 조 를 말한다.CPU 와 메 인 메모리 사이 에 Cache 가 있 는 것 을 제외 하고 메모리 와 하 드 디스크 사이 에 도 Cache 가 있 으 며 하 드 디스크 와 네트워크 사이 에 도 어떤 의미 의 Cache 가 있 습 니 다. 인터넷 임시 폴 더 나 네트워크 콘 텐 츠 캐 시 등 이 라 고 합 니 다.
Cache 의 용량 이 제한 되 어 있 기 때문에 Cache 의 용량 을 다 쓴 후에 새로운 내용 을 추가 해 야 할 때 원래 의 일부 내용 을 선택 하고 버 려 서 공간 을 비 워 새로운 내용 을 넣 어야 한다.LRU 캐 시의 교체 원칙 은 최근 가장 적 게 사용 한 콘 텐 츠 를 교체 하 는 것 이다.사실 LRU 를
으로 번역 하면 더욱 이미지 가 좋아 집 니 다. 이 알고리즘 은 매번 교체 할 때마다 한 동안 사용 하지 않 은 내용 이기 때 문 입 니 다.데이터 구조
LRU 의 전형 적 인 실현 은
hash map + doubly linked list
이 고 양 방향 링크 는 데이터 노드 를 저장 하 는 데 사용 되 며 노드 가 최근 에 사 용 된 시간 에 따라 저장 된다.만약 하나의 결점 이 방문 된다 면, 우 리 는 그것 이 다음 시간 에 방문 할 확률 이 다른 결점 보다 높다 고 믿 을 이유 가 있다.그래서 우 리 는 그것 을 양 방향 링크 의 머리 에 놓 았 다.우리 가 양 방향 링크 에 결점 을 삽입 하면 우 리 는 곧 그것 을 사용 할 수도 있 고 똑 같이 머리 에 삽입 할 수도 있다.우 리 는 이런 방식 으로 양 방향 링크 를 계속 조정 하고 있 습 니 다. 링크 꼬리 의 결점 은 자 연 스 럽 게 최근 한 동안 가장 오랫동안 사용 하지 못 한 결점 입 니 다.그러면 우리 의 Cache 가 가득 차 면 교체 해 야 할 것 은 바로 양 방향 링크 의 마지막 점 (끝 점 이 아니 라 머리 끝 점 은 실제 내용 을 저장 하지 않 습 니 다) 입 니 다.다음은 양 방향 링크 설명도 입 니 다. 머리 끝 에 있 는 노드 가 실제 내용 을 저장 하지 않도록 주의 하 세 요.
--> --> --> -->
만약 위의 그림 이 Cache 가 가득 찼 다 면, 우리 가 교체 해 야 할 것 은 결점 3 이다.
해시 표 의 역할 은 무엇 입 니까?만약 해시 표 가 없다 면, 우 리 는 어떤 결점 을 방문 하려 면 순서대로 하나씩 찾 아야 한다. 시간 복잡 도 는 O (n) 이다.해시 표를 사용 하면 O (1) 시간 에 접근 하고 싶 은 노드 를 찾 거나 찾 지 못 한 곳 으로 돌아 갈 수 있 습 니 다.
캐 시 인터페이스
T 형식의 데 이 터 를 키 로 접근 할 때 Get 함 수 를 호출 합 니 다.키 값 이 key 인 데이터 가 Cache 에 있 으 면 이 데 이 터 를 되 돌려 주 고 이 데 이 터 를 저장 하 는 노드 를 양 방향 링크 머리 로 옮 깁 니 다.만약 우리 가 조회 한 데이터 가 Cache 에 없다 면, 우 리 는 Put 인 터 페 이 스 를 통 해 데 이 터 를 양 방향 링크 에 삽입 할 수 있 습 니 다.만약 이때 의 Cache 가 채 워 지지 않 았 다 면, 우 리 는 새 노드 를 링크 머리 에 삽입 하 는 동시에 해시 표 로 노드 의 키 값 과 노드 주 소 를 저장 합 니 다.만약 Cache 가 가득 찼 다 면 우 리 는 링크 의 마지막 노드 (끝 점 이 아 닌 것 을 주의 하 세 요) 의 내용 을 새로운 내용 으로 바 꾼 다음 머리 로 이동 하여 해시 표를 업데이트 합 니 다.
C + + 코드
주의 하 세 요. hash map 는 C + 표준 의 일부분 이 아 닙 니 다. 저 는 Linux 에서 g + 4.6.1, hash 를 사용 합 니 다.map 는 / usr / include / c + / 4.6 / ext 에 놓 고
__gnu_cxx
명의 공간 을 사용 해 야 합 니 다. Linux 플랫폼 은 c + + 의 include 디 렉 터 리 로 전환 할 수 있 습 니 다. cd / usr / include / c + / 버 전 을 사용 한 다음 grep - ir "hash map". / 어떤 파일 에서 일반 헤더 파일 의 마지막 줄 은 이름 공간 을 알려 줍 니 다. 물론 C + + 11 을 패션 적 으로 사용 하고 있다 면 이런 작은 어려움 은 없 을 것 이다.#include
#include
#include
using namespace std;
using namespace stdext;
template
struct LRUCacheEntry
{
K key;
T data;
LRUCacheEntry* prev;
LRUCacheEntry* next;
};
template
class LRUCache
{
private:
hash_map< K, LRUCacheEntry* > _mapping;
vector< LRUCacheEntry* > _freeEntries;//
LRUCacheEntry * head;
LRUCacheEntry * tail;
LRUCacheEntry * entries;//
public:
LRUCache(size_t size){
entries = new LRUCacheEntry[size];
for (int i=0; i;
tail = new LRUCacheEntry;
head->prev = NULL;
head->next = tail;
tail->next = NULL;
tail->prev = head;
}
~LRUCache()
{
delete head;
delete tail;
delete [] entries;
}
void put(K key, T data)
{
LRUCacheEntry* node = _mapping[key];
if(node)
{
// refresh the link list
detach(node);
node->data = data;
attach(node);
}
else{
if ( _freeEntries.empty() )
{// , cache
node = tail->prev;
detach(node);
_mapping.erase(node->key);
node->data = data;
node->key = key;
attach(node);
}
else{
node = _freeEntries.back();
_freeEntries.pop_back();
node->key = key;
node->data = data;
_mapping[key] = node;
attach(node);
}
}
}
T get(K key)
{
LRUCacheEntry* node = _mapping[key];
if(node)
{
detach(node);
attach(node);
return node->data;
}
else return NULL;// cache , T 。 hashmap
}
private:
//
void detach(LRUCacheEntry* node)
{
node->prev->next = node->next;
node->next->prev = node->prev;
}
//
void attach(LRUCacheEntry* node)
{
node->next = head->next;
node->prev = head;
head->next = node;
node->next->prev = node;
}
};
int main(){
hash_map map;
map[9]= 999;
cout<
다음으로 전송:https://www.cnblogs.com/XP-Lee/p/3441555.html
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.