460. LFU Cache

typedef struct my_val my_val_t;
struct my_val {
int     key;
int     val;
int     frequency;
my_val_t* next;
my_val_t* pre;
my_val(int k, int v) { key = k;val = v;frequency = 1;next = NULL;pre = NULL; };
};
class LFUCache {
public:
LFUCache(int capacity) {
m_cap = capacity;
}


int get(int key) {
if (m_node.count(key))
{
my_val_t* p = m_node[key];
int fr = p->frequency;
int ans = p->val;
// get off the node from original frequency
my_val_t* head = m_fr[fr];
getoffNode(p);


//the original changed to empty , erase this frequency.
if (head->next == head)
{
delete head;
head = NULL;
m_fr.erase(fr);
}
// insert the  the node to the new frequency
p->frequency = ++fr;
// if the new frequency not empty
if (m_fr.count(fr))
{
my_val_t* headNew = m_fr[fr];
insertNodeTofirst(headNew, p);
}
else
{
m_fr[fr] = insertNodeTofirst(NULL, p);
}


return ans;
}
else
{
return -1;
}
}


void put(int key, int value) {


int ret = get(key);
if (ret != -1)
{
m_node[key]->val = value;
return;
}
if (0 == m_cap)
{
return;
};
my_val_t* p = new my_val_t(key,value);
if (m_node.size()<m_cap)
{
int fr = p->frequency;
if (m_fr.count(fr))
{
my_val_t* headNew = m_fr[fr];
insertNodeTofirst(headNew, p);
}
else
{
m_fr[fr] = insertNodeTofirst(NULL, p);
}


}
else
{
// find the min frenquency list
my_val_t* pHead = (*(m_fr.begin())).second;
// get rid of the last node;
my_val_t* pFree = pHead->pre;
getoffNode(pHead->pre);
// free pHead->pre
// get rid of pHead->pre from m_node
if (pHead->pre == pHead)
{
delete pHead;
pHead = NULL;
m_fr.erase(m_fr.begin());
}
m_node.erase(pFree->key);
delete pFree;
pFree = NULL;
int fr = p->frequency;
if (m_fr.count(fr))
{
my_val_t* headNew = m_fr[fr];
insertNodeTofirst(headNew, p);
}
else
{
m_fr[fr] = insertNodeTofirst(NULL, p);
}
}


m_node[key] = p;
}
private:
unordered_map<int, my_val_t*>    m_node;  // map node
map<int, my_val_t*>              m_fr;    // map frenquency
int                             m_cap;   // capacity
private:
void getoffNode(my_val_t* p)
{
p->pre->next = p->next;
p->next->pre = p->pre;
};
my_val_t* insertNodeTofirst(my_val_t* head, my_val_t* p)
{
if (head == NULL)
{
head = new my_val_t(0,0);
head->next = head;
head->pre = head;
}
p->next = head->next;
head->next->pre = p;
head->next = p;
p->pre = head;
return head;
}
};

猜你喜欢

转载自blog.csdn.net/bjzhaoxiao/article/details/80251637
LFU