lru.ts
interface Node {
k: number;
v: number ;
prev: Node | undefined;
next: Node | undefined;
}
class DoubleLink {
head: Node
tail: Node
constructor() {
this.head = this.buildNode(-1, -1);
this.tail = this.buildNode(-1, -1);
this.head.next = this.tail;
this.tail.prev = this.head;
}
buildNode = (k: number, v: number): Node => {
return {
k: k,
v: v,
prev: undefined,
next: undefined,
}
}
addHead = (node: Node): void => {
node.prev = this.head;
node.next = this.head.next;
this.head.next && (this.head.next.prev = node);
this.head.next = node;
}
remove = (node: Node): void => {
node.next && (node.next.prev = node.prev);
node.prev && (node.prev.next = node.next);
node.prev = undefined;
node.next = undefined;
}
getLast = (): (Node | undefined) => this.tail.prev;
}
export class HashDoubleLinkLru {
capacity: number;
doubleLink: DoubleLink;
map: Map<number, Node>;
constructor(capacity: number) {
this.capacity = capacity;
this.doubleLink = new DoubleLink();
this.map = new Map<number, Node>();
}
get = (k: number): number => {
const v = this.map.get(k);
if(v) {
this.doubleLink.remove(v);
this.doubleLink.addHead(v);
return v.v ;
}
return -1
}
put = (k: number, v: number): (number|undefined) => {
const n = this.map.get(k);
if(n) {
if(n.v !== v) {
n.v = v;
this.map.set(k, n);
}
this.doubleLink.remove(n);
this.doubleLink.addHead(n);
} else {
let last;
if(this.map.size === this.capacity){
last = this.doubleLink.getLast();
if(last) {
this.map.delete(last.k);
this.doubleLink.remove(last);
}
}
const n = this.doubleLink.buildNode(k, v);
this.map.set(k, n);
this.doubleLink.addHead(n);
return last ? last.v : -1
}
return -1
}
}
测试test.ts:
import { HashDoubleLinkLru } from './lru'
const lru = new HashDoubleLinkLru(10);
for (let index = 0; index < 10000; index++) {
lru.put(index, index)
}
console.log('==>', lru.get(9995))
console.log('==>', lru.get(9991))
console.log('==>', lru.put(9992, 9992))
console.log('==>', lru.put(9990, 9990))
console.log('==>', lru.put(6, 6))
let next = lru.doubleLink.head.next;
while(next && next.k !== -1) {
console.log({k: next.k, v: next.v})
next = next.next;
}
执行npx ts-node "./test.ts"结果:
$ npx ts-node "./test.ts"
==> 9995
==> 9991
==> -1
==> -1
==> 9993
{ k: 6, v: 6 }
{ k: 9990, v: 9990 }
{ k: 9992, v: 9992 }
{ k: 9991, v: 9991 }
{ k: 9995, v: 9995 }
{ k: 9999, v: 9999 }
{ k: 9998, v: 9998 }
{ k: 9997, v: 9997 }
{ k: 9996, v: 9996 }
{ k: 9994, v: 9994 }