private void MoveUpByFrequency(LFUCacheItem item) { if (item == _head) { return; } if (item.previous == null) { return; } LFUCacheItem oldprev = item.previous; LFUCacheItem oldnex = item.next; LFUCacheItem temp = oldprev; while ((temp != null) && (temp.freq <= item.freq)) { temp = temp.previous; } if (temp == oldprev) { return; } oldprev.next = oldnex; if (oldnex != null) { oldnex.previous = oldprev; } else { _tail = oldprev; } if (temp == null) { //item would be inserted at the very front ////////////////////////////////////////// item.next = _head; _head.previous = item; _head = item; item.previous = null; } else { //item will be inserted after temp ////////////////////////////////////////// LFUCacheItem tempoldnext = temp.next; item.next = tempoldnext; tempoldnext.previous = item; temp.next = item; item.previous = temp; } }
private void Touch(int key) { LFUCacheItem item = _dict[key]; item.freq += 1; if (item == _head) { //do nothing } else { MoveUpByFrequency(item); } }
public void Put(int key, int value) { if (_capacity <= 0) { return; } if (_dict.ContainsKey(key)) { //Set instead of insert _dict[key].value = value; //update freq etc Touch(key); return; } if (_currentCount < _capacity) { //add to the Doubly linked list LFUCacheItem newitem = new LFUCacheItem(); newitem.key = key; newitem.value = value; newitem.freq = 1; newitem.next = null; //by default newitem.previous = null; //by default _dict.Add(key, newitem); if (_head == null) { //very very first item _head = newitem; _tail = newitem; } else { //add to the back _tail.next = newitem; newitem.next = null; newitem.previous = _tail; _tail = newitem; } _currentCount++; MoveUpByFrequency(newitem); } else { //Reached Capacity //find the least recent used item int tailkey = _tail.key; //remove it from Doubly Linked List LFUCacheItem prev = _tail.previous; if (_capacity > 1) { prev.next = null; _tail = prev; } else { //to handle 1 capacity _tail = null; _head = null; } //remove it from dict _dict.Remove(tailkey); _currentCount--; //try again Put(key, value); } }