| 1 package com.tirsen.nanning.samples.rmi; 2 3 import org.apache.commons.logging.Log; 4 import org.apache.commons.logging.LogFactory; 5 6 import java.util.HashMap ; 7 import java.util.Iterator ; 8 import java.util.Map ; 9 import java.util.Collections ; 10 11 class ObjectTable { 12 private static final Log logger = LogFactory.getLog(ObjectTable.class); 13 14 private static final int DEFAULT_TIMEOUT = 60 * 60 * 1000; 15 16 private Map objectToId = Collections.synchronizedMap(new HashMap ()); 17 private Map idToReference = Collections.synchronizedMap(new HashMap ()); 18 19 private long currentId = 0; 20 private long timeout; 21 22 public ObjectTable() { 23 this(DEFAULT_TIMEOUT); 24 } 25 26 public ObjectTable(long timeout) { 27 this.timeout = timeout; 28 } 29 30 Object getFromID(Object id) { 31 LocalReference o = (LocalReference) idToReference.get(id); 32 assert o != null; 33 o.touch(); 34 cleanupStale(); 35 return o.getReferred(); 36 } 37 38 private synchronized void cleanupStale() { 39 try { 40 for (Iterator i = idToReference.values().iterator(); i.hasNext();) { 41 LocalReference ref = (LocalReference) i.next(); 42 if (ref.isStale(timeout)) { 43 if (logger.isDebugEnabled()) { 44 logger.debug("Removing " + ref.getReferred()); 45 } 46 objectToId.remove(ref.getReferred()); 47 i.remove(); 48 } 49 } 50 } catch (Exception ignore) { 51 logger.warn("Got error while cleaning out stale objects (ignored)", ignore); 52 } 53 } 54 55 synchronized Object register(Object o) { 56 Object id = objectToId.get(o); 57 if (id == null) { 58 if (logger.isDebugEnabled()) { 59 logger.debug("Registering " + o); 60 } 61 id = newId(); 62 objectToId.put(o, id); 63 idToReference.put(id, new LocalReference(o)); 64 } 65 return id; 66 } 67 68 private Object newId() { 69 return new Long (currentId++); 70 } 71 72 public boolean hasID(Object o) { 73 return objectToId.containsKey(o); 74 } 75 76 boolean isIDRegistered(Object id) { 77 cleanupStale(); 78 return idToReference.containsKey(id); 79 } 80 81 public synchronized void clear() { 82 if (logger.isDebugEnabled()) { 83 logger.debug("Clearing"); 84 } 85 objectToId.clear(); 86 idToReference.clear(); 87 currentId = 0; 88 } 89 90 private static class LocalReference { 91 private Object object; 92 private long lastTimeTouched; 93 94 LocalReference(Object object) { 95 this.object = object; 96 touch(); 97 } 98 99 Object getReferred() { 100 return object; 101 } 102 103 void touch() { 104 lastTimeTouched = System.currentTimeMillis(); 105 } 106 107 boolean isStale(long timeout) { 108 return System.currentTimeMillis() - lastTimeTouched >= timeout; 109 } 110 } 111 } 112 | Popular Tags |