package dmg.util ;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
public class AgingHash {
private int _maxSize;
private Node _first;
private Node _last;
private Hashtable<Object, Node> _hash = new Hashtable<>() ;
public synchronized void clear(){
_first = null ;
_last = null ;
_hash.clear() ;
}
private class Node {
private Object _value;
private Object _key;
private Node _next;
private Node _previous;
private Node( Object key , Object value ){
_value = value ;
_key = key ;
}
public String toString(){
return "(" + _key + ':' + _value + ')';
}
private void link(){
_next = _first ;
_previous = null ;
if( _first != null ) {
_first._previous = this;
}
_first = this ;
if( _last == null ) {
_last = this;
}
}
private void unlink(){
if( _next != null ) {
_next._previous = _previous;
} else {
_last = _previous;
}
if( _previous != null ) {
_previous._next = _next;
} else {
_first = _next;
}
}
}
public AgingHash( int maxSize ){
_maxSize = maxSize ;
}
public synchronized Object get( Object key ){
if( key == null ) {
throw new
NullPointerException("Key == null");
}
Node node = _hash.get( key );
if( node == null ) {
return null;
}
node.unlink() ;
node.link() ;
return node._value ;
}
public synchronized void put( Object key , Object value ){
if( ( key == null ) || ( value == null ) ) {
throw new
NullPointerException("Key/Value == null");
}
Node node = _hash.get( key );
if( node == null ){
node = new Node( key , value ) ;
_hash.put( key , node ) ;
}else{
node._value = value ;
//
// we have to relink to become top of stack.
//
node.unlink() ;
}
node.link() ;
if( _hash.size() > _maxSize ){
_hash.remove( _last._key ) ;
_last.unlink() ;
}
}
public int size(){ return _hash.size() ; }
public synchronized Object remove( Object key ){
Node node = _hash.remove( key );
if( node == null ) {
return null;
}
node.unlink() ;
return node._value ;
}
public synchronized Iterator<Node> valuesIterator(){
return new ArrayList<>(_hash.values()).iterator() ;
}
public synchronized Iterator<Object> keysIterator(){
return new ArrayList<>(_hash.keySet()).iterator() ;
}
public synchronized String toString(){
Node node;
StringBuilder sb = new StringBuilder() ;
for( node = _first ; node != null ; node = node._next ){
sb.append(node).append(';') ;
}
sb.append('[').append(_first).append(';').append(_last).append(']');
return sb.toString() ;
}
public static void main( String [] args ){
AgingHash hash = new AgingHash(3) ;
System.out.println(hash) ;
hash.put("1","1");
System.out.println(hash) ;
hash.put("2","2");
System.out.println(hash) ;
hash.put("3","3");
System.out.println(hash) ;
hash.put("4","4");
System.out.println(hash) ;
hash.put("5","5");
System.out.println(hash) ;
hash.remove("4");
System.out.println(hash) ;
hash.remove("3");
System.out.println(hash) ;
hash.remove("5");
System.out.println(hash) ;
}
}