/* package whatever; // don't place package name! */
import java.util.*;
import java.lang.*;
import java.io.*;
/* Name of the class has to be "Main" only if the class is public. */
class Ideone
{
{
LRUCacheLHM
<Integer, String
> cache
= new LRUCacheLHM
<>(5); System.
out.
println("In:quick"+" Out:"+cache.
place(0,
"quick")); System.
out.
println("In:brown"+" Out:"+cache.
place(1,
"brown")); System.
out.
println("In:fox"+" Out:"+cache.
place(2,
"fox")); System.
out.
println("In:jumps"+" Out:"+cache.
place(3,
"jumps")); System.
out.
println("In:over"+" Out:"+cache.
place(4,
"over")); System.
out.
println("In:the"+" Out:"+cache.
place(5,
"the")); System.
out.
println("In:lazy"+" Out:"+cache.
place(6,
"lazy")); System.
out.
println("In:dog"+" Out:"+cache.
place(7,
"dog")); }
}
class LRUCacheLHM<K,V> extends LinkedHashMap<K,V> {
private int capacity;
public LRUCacheLHM(int capacity) {
//1 extra element as add happens before remove (101), and load factor big
//enough to avoid triggering resize. True = keep in access order.
super(capacity + 1, 1.1f, true);
this.capacity = capacity;
}
private ThreadLocal
<Map.
Entry<K,V
>> removed
= new ThreadLocal
<Map.
Entry<K,V
>>(); private ThreadLocal<Boolean> report = new ThreadLocal<Boolean>();
{
report.set(false);
}
@Override
public boolean removeEldestEntry
(Map.
Entry<K,V
> eldest
) { boolean res = size() > capacity;
if (res && report.get()) {
removed.set(eldest);
}
return res;
}
public Map.
Entry<K,V
> place
(K k, V v
) { report.set(true);
put(k, v);
try {
return removed.get();
} finally {
removed.set(null);
report.set(false);
}
}
}
LyogcGFja2FnZSB3aGF0ZXZlcjsgLy8gZG9uJ3QgcGxhY2UgcGFja2FnZSBuYW1lISAqLwoKaW1wb3J0IGphdmEudXRpbC4qOwppbXBvcnQgamF2YS5sYW5nLio7CmltcG9ydCBqYXZhLmlvLio7CgovKiBOYW1lIG9mIHRoZSBjbGFzcyBoYXMgdG8gYmUgIk1haW4iIG9ubHkgaWYgdGhlIGNsYXNzIGlzIHB1YmxpYy4gKi8KY2xhc3MgSWRlb25lCnsKCXB1YmxpYyBzdGF0aWMgdm9pZCBtYWluIChTdHJpbmdbXSBhcmdzKSB0aHJvd3MgamF2YS5sYW5nLkV4Y2VwdGlvbgoJewoJCUxSVUNhY2hlTEhNPEludGVnZXIsIFN0cmluZz4gY2FjaGUgPSBuZXcgTFJVQ2FjaGVMSE08Pig1KTsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkluOnF1aWNrIisiIE91dDoiK2NhY2hlLnBsYWNlKDAsICJxdWljayIpKTsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkluOmJyb3duIisiIE91dDoiK2NhY2hlLnBsYWNlKDEsICJicm93biIpKTsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkluOmZveCIrIiBPdXQ6IitjYWNoZS5wbGFjZSgyLCAiZm94IikpOwogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiSW46anVtcHMiKyIgT3V0OiIrY2FjaGUucGxhY2UoMywgImp1bXBzIikpOwogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiSW46b3ZlciIrIiBPdXQ6IitjYWNoZS5wbGFjZSg0LCAib3ZlciIpKTsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkluOnRoZSIrIiBPdXQ6IitjYWNoZS5wbGFjZSg1LCAidGhlIikpOwogICAgICAgIFN5c3RlbS5vdXQucHJpbnRsbigiSW46bGF6eSIrIiBPdXQ6IitjYWNoZS5wbGFjZSg2LCAibGF6eSIpKTsKICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oIkluOmRvZyIrIiBPdXQ6IitjYWNoZS5wbGFjZSg3LCAiZG9nIikpOwoJfQp9CgpjbGFzcyBMUlVDYWNoZUxITTxLLFY+IGV4dGVuZHMgTGlua2VkSGFzaE1hcDxLLFY+IHsKIAogICAgcHJpdmF0ZSBpbnQgY2FwYWNpdHk7CiAKICAgIHB1YmxpYyBMUlVDYWNoZUxITShpbnQgY2FwYWNpdHkpIHsKICAgICAgICAvLzEgZXh0cmEgZWxlbWVudCBhcyBhZGQgaGFwcGVucyBiZWZvcmUgcmVtb3ZlICgxMDEpLCBhbmQgbG9hZCBmYWN0b3IgYmlnCiAgICAgICAgLy9lbm91Z2ggdG8gYXZvaWQgdHJpZ2dlcmluZyByZXNpemUuICBUcnVlID0ga2VlcCBpbiBhY2Nlc3Mgb3JkZXIuCiAgICAgICAgc3VwZXIoY2FwYWNpdHkgKyAxLCAxLjFmLCB0cnVlKTsKICAgICAgICB0aGlzLmNhcGFjaXR5ID0gY2FwYWNpdHk7CiAgICB9CiAgICBwcml2YXRlIFRocmVhZExvY2FsPE1hcC5FbnRyeTxLLFY+PiByZW1vdmVkID0gbmV3IFRocmVhZExvY2FsPE1hcC5FbnRyeTxLLFY+PigpOwogICAgcHJpdmF0ZSBUaHJlYWRMb2NhbDxCb29sZWFuPiByZXBvcnQgPSBuZXcgVGhyZWFkTG9jYWw8Qm9vbGVhbj4oKTsKICAgIHsKICAgIAlyZXBvcnQuc2V0KGZhbHNlKTsKICAgIH0KICAgIEBPdmVycmlkZQogICAgcHVibGljIGJvb2xlYW4gcmVtb3ZlRWxkZXN0RW50cnkoTWFwLkVudHJ5PEssVj4gZWxkZXN0KSB7CiAgICAgICAgYm9vbGVhbiByZXMgPSBzaXplKCkgPiBjYXBhY2l0eTsKICAgICAgICBpZiAocmVzICYmIHJlcG9ydC5nZXQoKSkgewogICAgICAgIAlyZW1vdmVkLnNldChlbGRlc3QpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gcmVzOwogICAgfQogICAgcHVibGljIE1hcC5FbnRyeTxLLFY+IHBsYWNlKEsgaywgViB2KSB7CiAgICAJcmVwb3J0LnNldCh0cnVlKTsKICAgIAlwdXQoaywgdik7CiAgICAJdHJ5IHsKICAgIAkgICAgcmV0dXJuIHJlbW92ZWQuZ2V0KCk7CiAgICAJfSBmaW5hbGx5IHsKICAgIAkgICAgcmVtb3ZlZC5zZXQobnVsbCk7CiAgICAJICAgIHJlcG9ydC5zZXQoZmFsc2UpOwogICAgCX0KICAgIH0KICAgIAp9