User: d_jencks
  Date: 01/08/18 21:55:30

  Modified:    src/main/org/jboss/pool/cache CachedObjectFactory.java
                        LeastRecentlyUsedCache.java ObjectCache.java
  Log:
  Converted logging to log4j and prettied format
  
  Revision  Changes    Path
  1.2       +95 -89    jbosspool/src/main/org/jboss/pool/cache/CachedObjectFactory.java
  
  Index: CachedObjectFactory.java
  ===================================================================
  RCS file: 
/cvsroot/jboss/jbosspool/src/main/org/jboss/pool/cache/CachedObjectFactory.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- CachedObjectFactory.java  2001/05/15 07:58:24     1.1
  +++ CachedObjectFactory.java  2001/08/19 04:55:30     1.2
  @@ -3,99 +3,105 @@
    */
   package org.jboss.pool.cache;
   
  -import java.io.PrintWriter;
  -
   /**
  - * Creates objects for a cache.  The cache is essentially a map,
  - * so this factory is given a "key" and creates the appropriate "value"
  - * which will be cached.  There are a number of other functions that
  - * can be overridden for more specific control, but createObject is
  - * the only one that's required.
  + *  Creates objects for a cache. The cache is essentially a map, so this factory
  + *  is given a "key" and creates the appropriate "value" which will be cached.
  + *  There are a number of other functions that can be overridden for more
  + *  specific control, but createObject is the only one that's required.
    *
  - * @author Aaron Mulder [EMAIL PROTECTED]
  + * @author     Aaron Mulder [EMAIL PROTECTED]
  + * @created    August 18, 2001
    */
   public abstract class CachedObjectFactory {
   
  -    public CachedObjectFactory() {
  -    }
  +   public CachedObjectFactory() {
  +   }
   
  -    /**
  -     * Creates a new object to be stored in an object cache.  This is the
  -     * instance that will actually be stored in the cache and reused.  If you
  -     * want to wrap it somehow, or return instances of a different type that
  -     * refers to these, you can implement prepareObject.
  -     * @see #prepareObject
  -     */
  -    public abstract Object createObject(Object identifier);
  -
  -    /*
  -     * Indicates to the factory that the cache has started up.  This will be
  -     * called before any other methods of the factory are called (on behalf of
  -     * this cache).
  -     * @param cache The cache that is starting.  You may decide to allow
  -     *    multiple cached you use your factory, or to restrict it to a one-to-one
  -     *    relationship.
  -     * @param log A writer you can use to log messages.  Use this in preference
  -     *    to System.xxx.println.
  -     * @throws java.lang.IllegalArgumentException
  -     *         Occurs when the cache is null.
  -     */
  -    public void cacheStarted(ObjectCache cache, PrintWriter log) {
  -        if(cache == null)
  -            throw new IllegalArgumentException("Cannot start factory with null 
cache!");
  -    }
  -
  -    /**
  -     * Prepares an object to be returned to the client.  This may be used to
  -     * configure the object somehow, or actually return a completely different
  -     * object (so long as the original can be recovered in translateObject.
  -     * This will be called whenever an object is returned to the client, whether
  -     * a new object or a cached object.
  -     * @param cachedObject The object in the cache, as created by createObject.
  -     * @return The object to return to the client.  If different, the cached
  -     *    object must be recoverable by translateObject.
  -     */
  -    public Object prepareObject(Object cachedObject) {
  -        return cachedObject;
  -    }
  -
  -    /**
  -     * If the objects supplied to the client are different than the objects in
  -     * the cache, extracts a cache object from a client object.  This may be
  -     * called once after an object has been released if the garbage collector
  -     * and a client attempt to release an object at the same time.  In this
  -     * case, this method may work, return null, or throw an exception and the
  -     * cache will handle it gracefully.  The default implementation returns the
  -     * parameter object (assumes client and cached objects are the same).
  -     * @param clientObject The client object, as returned by prepareObject
  -     * @return The cached object, as originally returned by createObject
  -     */
  -    public Object translateObject(Object clientObject) {
  -        return clientObject;
  -    }
  -
  -    /**
  -     * Indicates to the factory that the cache is closing down.  This will be
  -     * called before all the instances are destroyed.  There may be calls to
  -     * returnObject or translateObject after this, but no calls to
  -     * createObject or prepareObject (on behalf of this cache).
  -     * @param cache The cache that is closing.  You may decide to allow
  -     *    multiple caches you use your factory, or to restrict it to a one-to-one
  -     *    relationship.
  -     * @throws java.lang.IllegalArgumentException
  -     *         Occurs when the pool is null.
  -     */
  -    public void cacheClosing(ObjectCache cache) {
  -        if(cache == null)
  -            throw new IllegalArgumentException("Cannot close factory with a null 
cache!");
  -    }
  -
  -    /**
  -     * Permanently closes an object, after it is removed from the cache.  The
  -     * object will not be returned to the cache - after this, it is gone.  This
  -     * is called when the cache is full and new objects are added, and when
  -     * the cache is closed.
  -     */
  -    public void deleteObject(Object pooledObject) {
  -    }
  +   /**
  +    *  Creates a new object to be stored in an object cache. This is the
  +    *  instance that will actually be stored in the cache and reused. If you
  +    *  want to wrap it somehow, or return instances of a different type that
  +    *  refers to these, you can implement prepareObject.
  +    *
  +    * @param  identifier  Description of Parameter
  +    * @return             Description of the Returned Value
  +    * @see                #prepareObject
  +    */
  +   public abstract Object createObject( Object identifier );
  +
  +   /*
  +    * Indicates to the factory that the cache has started up.  This will be
  +    * called before any other methods of the factory are called (on behalf of
  +    * this cache).
  +    * @param cache The cache that is starting.  You may decide to allow
  +    * multiple cached you use your factory, or to restrict it to a one-to-one
  +    * relationship.
  +    * @throws java.lang.IllegalArgumentException
  +    * Occurs when the cache is null.
  +    */
  +   public void cacheStarted( ObjectCache cache ) {
  +      if ( cache == null ) {
  +         throw new IllegalArgumentException( "Cannot start factory with null 
cache!" );
  +      }
  +   }
  +
  +   /**
  +    *  Prepares an object to be returned to the client. This may be used to
  +    *  configure the object somehow, or actually return a completely different
  +    *  object (so long as the original can be recovered in translateObject. This
  +    *  will be called whenever an object is returned to the client, whether a
  +    *  new object or a cached object.
  +    *
  +    * @param  cachedObject  The object in the cache, as created by createObject.
  +    * @return               The object to return to the client. If different,
  +    *      the cached object must be recoverable by translateObject.
  +    */
  +   public Object prepareObject( Object cachedObject ) {
  +      return cachedObject;
  +   }
  +
  +   /**
  +    *  If the objects supplied to the client are different than the objects in
  +    *  the cache, extracts a cache object from a client object. This may be
  +    *  called once after an object has been released if the garbage collector
  +    *  and a client attempt to release an object at the same time. In this case,
  +    *  this method may work, return null, or throw an exception and the cache
  +    *  will handle it gracefully. The default implementation returns the
  +    *  parameter object (assumes client and cached objects are the same).
  +    *
  +    * @param  clientObject  The client object, as returned by prepareObject
  +    * @return               The cached object, as originally returned by
  +    *      createObject
  +    */
  +   public Object translateObject( Object clientObject ) {
  +      return clientObject;
  +   }
  +
  +   /**
  +    *  Indicates to the factory that the cache is closing down. This will be
  +    *  called before all the instances are destroyed. There may be calls to
  +    *  returnObject or translateObject after this, but no calls to createObject
  +    *  or prepareObject (on behalf of this cache).
  +    *
  +    * @param  cache                                The cache that is closing.
  +    *      You may decide to allow multiple caches you use your factory, or to
  +    *      restrict it to a one-to-one relationship.
  +    * @throws  java.lang.IllegalArgumentException  Occurs when the pool is null.
  +    */
  +   public void cacheClosing( ObjectCache cache ) {
  +      if ( cache == null ) {
  +         throw new IllegalArgumentException( "Cannot close factory with a null 
cache!" );
  +      }
  +   }
  +
  +   /**
  +    *  Permanently closes an object, after it is removed from the cache. The
  +    *  object will not be returned to the cache - after this, it is gone. This
  +    *  is called when the cache is full and new objects are added, and when the
  +    *  cache is closed.
  +    *
  +    * @param  pooledObject  Description of Parameter
  +    */
  +   public void deleteObject( Object pooledObject ) {
  +   }
   }
  
  
  
  1.2       +343 -330  
jbosspool/src/main/org/jboss/pool/cache/LeastRecentlyUsedCache.java
  
  Index: LeastRecentlyUsedCache.java
  ===================================================================
  RCS file: 
/cvsroot/jboss/jbosspool/src/main/org/jboss/pool/cache/LeastRecentlyUsedCache.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- LeastRecentlyUsedCache.java       2001/05/15 07:58:24     1.1
  +++ LeastRecentlyUsedCache.java       2001/08/19 04:55:30     1.2
  @@ -3,344 +3,357 @@
    */
   package org.jboss.pool.cache;
   
  -import java.io.PrintWriter;
   import java.util.*;
   
  +import org.jboss.logging.log4j.JBossCategory;
  +
   /**
  - * A Least Recently Used cache implementation.  The object in the
  - * cache that was least recently used is dropped when the cache is
  - * full and a new request comes in.  The implementation uses a linked
  - * list (to track recentness) and a HashMap (to navigate quickly).
  - * @author Aaron Mulder [EMAIL PROTECTED]
  + *  A Least Recently Used cache implementation. The object in the cache that was
  + *  least recently used is dropped when the cache is full and a new request
  + *  comes in. The implementation uses a linked list (to track recentness) and a
  + *  HashMap (to navigate quickly).
  + *
  + * @author     Aaron Mulder [EMAIL PROTECTED]
  + * @created    August 18, 2001
    */
   public class LeastRecentlyUsedCache implements ObjectCache {
  -    private Object lock = new Object();
  -    private HashMap keyMap = new HashMap();
  -    private PrintWriter log;
  -    private Node mostRecentNode, leastRecentNode;
  -    private int size;
  -    private int maxSize;
  -    private CachedObjectFactory factory;
  -
  -    public LeastRecentlyUsedCache(CachedObjectFactory factory, int maxSize) {
  -        this.factory = factory;
  -        this.maxSize = maxSize;
  -    }
  -
  -    public Object getObject(Object key) {
  -        return getObject(key, false);
  -    }
  -
  -    public Object useObject(Object key) {
  -        return getObject(key, true);
  -    }
  -
  -    public void returnObject(Object key, Object value) {
  -        Object pooled = keyMap.get(key);
  -        Object source = factory.translateObject(value);
  -
  -        if(pooled == null) {
  -            factory.deleteObject(source);
  -        } else if(pooled instanceof Node) {
  -            Node node = (Node)pooled;
  -            if(node.data == source) {
  -                try {
  -                    node.setUsed(false);
  -                } catch(ConcurrentModificationException e) {}
  -            } else {
  -                factory.deleteObject(source);
  -            }
  -        } else if(pooled instanceof LinkedList) {
  -            for(Iterator it = ((LinkedList)pooled).iterator(); it.hasNext(); ) {
  -                Node node = (Node)it.next();
  -                if(node.data == source) {
  -                    try {
  -                        node.setUsed(false);
  -                    } catch(ConcurrentModificationException e) {}
  -                    return;
  -                }
  -            }
  -            factory.deleteObject(source);
  -        } else throw new Error("LRU Cache Assertion Failure: Wrong class 
'"+pooled.getClass().getName()+"' in keyMap!");
  -    }
  -
  -    public void removeObjects(Object key) {
  -        synchronized(lock) {
  -            Object value = keyMap.get(key);
  -            if(value == null) {
  -                return;
  -            } else if(value instanceof Node) {
  -                removeNode((Node)value);
  -            } else if(value instanceof LinkedList) {
  -                LinkedList list = (LinkedList)value;
  -                int max = list.size();
  -                for(int i=0; i<max; i++) {
  -                    removeNode((Node)list.get(0));
  -                }
  -            }
  -        }
  -    }
  -
  -    public void setSize(int maxSize) {
  -        this.maxSize = maxSize;
  -        checkMaxSize();
  -    }
  -
  -    public void close() {
  -        synchronized(lock) {
  -            Node current = leastRecentNode;
  -            Node next = current == null ? null : current.moreRecent;
  -            while(current != null) {
  -                removeNode(current);
  -                current = next;
  -                next = current == null ? null : current.moreRecent;
  -            }
  -        }
  -    }
  -
  -    private Object getObject(Object key, boolean use) {
  -        Node node = null;
  -        try {
  -            Object value = keyMap.get(key);
  -            if(value == null) {
  -                node = addObject(key);
  -            } else if(value instanceof Node) {
  -                node = (Node)value;
  -                if(!node.used) {
  -                    makeMostRecent(node);
  -                } else {
  -                    node = addObject(key);
  -                }
  -            } else if(value instanceof LinkedList) {
  -                for(Iterator it = ((LinkedList)value).iterator(); it.hasNext();) {
  -                    node = (Node)it.next();
  -                    if(!node.used) {
  -                        makeMostRecent(node);
  -                        break;
  -                    } else {
  -                        node = null;
  -                    }
  -                }
  -                if(node == null) {
  -                    node = addObject(key);
  -                }
  -            } else throw new Error("LRU Cache Assertion Failure: Wrong class 
'"+value.getClass().getName()+"' in keyMap!");
  -            if(use) {
  -                node.setUsed(true);
  -            }
  -        } catch(ConcurrentModificationException e) {
  -            return getObject(key, use);
  -        }
  -        return factory.prepareObject(node.data);
  -    }
  -
  -    private Node addObject(Object key) {
  -        Object data;
  -        try {
  -            data = factory.createObject(key);
  -        } catch(Exception e) {
  -            if(log != null)
  -                e.printStackTrace(log);
  -            return null;
  -        }
  -        Node result;
  -        synchronized(lock) {
  -            if(mostRecentNode == null) {
  -                result = new Node(null, null, data);
  -                mostRecentNode = result;
  -                leastRecentNode = result;
  -            } else {
  -                result = new Node(mostRecentNode, null, data);
  -                mostRecentNode.moreRecent = result;
  -                mostRecentNode = result;
  -            }
  -            ++size;
  -            checkMaxSize();
  -        }
  -
  -        // Put the key/value(s) and node/key in the map
  -        Object value = keyMap.get(key);
  -        if(value == null) {
  -            keyMap.put(key, result);
  -        } else if(value instanceof LinkedList) {
  -            ((LinkedList)value).add(result);
  -        } else if(value instanceof Node) {
  -            LinkedList list = new LinkedList();
  -            list.add(value);
  -            list.add(result);
  -            keyMap.put(key, list);
  -        } else throw new Error("LRU Cache Assertion Failure: Wrong class 
'"+value.getClass().getName()+"' in keyMap!");
  -        keyMap.put(result, key);
  -        return result;
  -    }
  -
  -    private void checkMaxSize() {
  -        if(maxSize <= 0)
  +   private Object   lock = new Object();
  +   private HashMap  keyMap = new HashMap();
  +   private Node     mostRecentNode, leastRecentNode;
  +   private int      size;
  +   private int      maxSize;
  +   private CachedObjectFactory factory;
  +
  +   private JBossCategory log = ( JBossCategory )JBossCategory.getInstance( 
LeastRecentlyUsedCache.class );
  +
  +
  +   public LeastRecentlyUsedCache( CachedObjectFactory factory, int maxSize ) {
  +      this.factory = factory;
  +      this.maxSize = maxSize;
  +   }
  +
  +   public void setSize( int maxSize ) {
  +      this.maxSize = maxSize;
  +      checkMaxSize();
  +   }
  +
  +   public Object getObject( Object key ) {
  +      return getObject( key, false );
  +   }
  +
  +   public Object useObject( Object key ) {
  +      return getObject( key, true );
  +   }
  +
  +   public void returnObject( Object key, Object value ) {
  +      Object pooled = keyMap.get( key );
  +      Object source = factory.translateObject( value );
  +
  +      if ( pooled == null ) {
  +         factory.deleteObject( source );
  +      } else if ( pooled instanceof Node ) {
  +         Node node = ( Node )pooled;
  +         if ( node.data == source ) {
  +            try {
  +               node.setUsed( false );
  +            } catch ( ConcurrentModificationException e ) {
  +            }
  +         } else {
  +            factory.deleteObject( source );
  +         }
  +      } else if ( pooled instanceof LinkedList ) {
  +         for ( Iterator it = ( ( LinkedList )pooled ).iterator(); it.hasNext();  ) {
  +            Node node = ( Node )it.next();
  +            if ( node.data == source ) {
  +               try {
  +                  node.setUsed( false );
  +               } catch ( ConcurrentModificationException e ) {
  +               }
  +               return;
  +            }
  +         }
  +         factory.deleteObject( source );
  +      } else {
  +         throw new Error( "LRU Cache Assertion Failure: Wrong class '" + 
pooled.getClass().getName() + "' in keyMap!" );
  +      }
  +   }
  +
  +   public void removeObjects( Object key ) {
  +      synchronized ( lock ) {
  +         Object value = keyMap.get( key );
  +         if ( value == null ) {
               return;
  -        while(size > maxSize) {
  -            Node drop = leastRecentNode;
  -            leastRecentNode = drop.moreRecent;
  -            leastRecentNode.lessRecent = null;
  -            --size;
  -
  -            removeNode(drop);
  -        }
  -    }
  -
  -    private void makeMostRecent(Node node) {
  -        synchronized(lock) {
  -            if(node.moreRecent == null) {
  -                if(mostRecentNode != node)
  -                    throw new ConcurrentModificationException();
  -                return;
  -            }
  -
  -            // Prepare surrounding nodes
  -            Node previous = node.moreRecent;
  -            Node next = node.lessRecent;
  -            previous.lessRecent = next;
  -            if(next == null) {
  -                leastRecentNode = previous;
  +         } else if ( value instanceof Node ) {
  +            removeNode( ( Node )value );
  +         } else if ( value instanceof LinkedList ) {
  +            LinkedList list = ( LinkedList )value;
  +            int max = list.size();
  +            for ( int i = 0; i < max; i++ ) {
  +               removeNode( ( Node )list.get( 0 ) );
  +            }
  +         }
  +      }
  +   }
  +
  +   public void close() {
  +      synchronized ( lock ) {
  +         Node current = leastRecentNode;
  +         Node next = current == null ? null : current.moreRecent;
  +         while ( current != null ) {
  +            removeNode( current );
  +            current = next;
  +            next = current == null ? null : current.moreRecent;
  +         }
  +      }
  +   }
  +
  +   private Object getObject( Object key, boolean use ) {
  +      Node node = null;
  +      try {
  +         Object value = keyMap.get( key );
  +         if ( value == null ) {
  +            node = addObject( key );
  +         } else if ( value instanceof Node ) {
  +            node = ( Node )value;
  +            if ( !node.used ) {
  +               makeMostRecent( node );
               } else {
  -                next.moreRecent = previous;
  -            }
  -
  -            // Prepare node and new 2nd most recent
  -            node.moreRecent = null;
  -            node.lessRecent = mostRecentNode;
  -            mostRecentNode.moreRecent = node;
  -            mostRecentNode = node;
  -        }
  -    }
  -
  -    // This should be called while holding the lock
  -    private void removeNode(Node node) {
  -        boolean used = node.used;
  -        if(!used) {
  -            node.used = true;
  -        }
  -        Object key = keyMap.remove(node);
  -
  -
  -        Object value = keyMap.get(key);
  -        if(value instanceof Node) {
  -            keyMap.remove(key);
  -        } else if(value instanceof LinkedList) {
  -            LinkedList list = (LinkedList)value;
  -            Iterator it = list.iterator();
  -            while(it.hasNext()) {
  -                Node current = (Node)it.next();
  -                if(current == node) {
  -                    it.remove();
  -                    break;
  -                }
  -            }
  -            if(list.size() == 1) {
  -                keyMap.put(key, list.get(0));
  +               node = addObject( key );
               }
  -        } else throw new Error("LRU Cache Assertion Failure: Wrong class 
'"+value.getClass().getName()+"' in keyMap!");
  -        if(!used)  {
  -            factory.deleteObject(node.data);
  -        }
  -        node.moreRecent = null;
  -        node.lessRecent = null;
  -    }
  -
  -    private class Node {
  -        Node lessRecent;
  -        Node moreRecent;
  -        Object data;
  -        boolean used = false;
  -
  -        public Node(Node lessRecent, Node moreRecent, Object data) {
  -            this(lessRecent, moreRecent, data, false);
  -        }
  -        public Node(Node lessRecent, Node moreRecent, Object data, boolean used) {
  -            this.lessRecent = lessRecent;
  -            this.moreRecent = moreRecent;
  -            this.data = data;
  -            this.used = used;
  -        }
  -
  -        public synchronized void setUsed(boolean used) {
  -            if(this.used == used)
  -                throw new ConcurrentModificationException();
  -            this.used = used;
  -        }
  -    }
  -
  -/*  This is for testing only
  -
  -    private void printList() {
  -        System.out.print("Fwd Nodes:");
  -        Node node = mostRecentNode;
  -        for(int i=0; i<size; i++) {
  -            System.out.print(" "+node.data);
  -            node = node.lessRecent;
  -        }
  -        System.out.println();
  -        Stack stack = new Stack();
  -        node = leastRecentNode;
  -        for(int i=0; i<size; i++) {
  -            stack.push(node.data);
  -            node = node.moreRecent;
  -        }
  -        System.out.print("Rev Nodes:");
  -        while(!stack.isEmpty())
  -            System.out.print(" "+stack.pop());
  -        System.out.println();
  -    }
  -
  -    public static void main(String args[]) {
  -        try {
  -            java.io.BufferedReader in = new java.io.BufferedReader(new 
java.io.InputStreamReader(System.in));
  -            LeastRecentlyUsedCache cache = new LeastRecentlyUsedCache(new 
CachedObjectFactory() {
  -                public Object createObject(Object identifier) {
  -                    return "v"+identifier;
  -                }
  -                public void deleteObject(Object object) {
  -                    System.out.println("Deleting Object "+object);
  -                }
  -            }, 5);
  -
  -            * *** THIS TESTS getObject ****
  -
  -            while(true) {
  -                cache.printList();
  -                System.out.print("> ");
  -                System.out.flush();
  -                String key = in.readLine();
  -                if(key.equalsIgnoreCase("quit") || key.equalsIgnoreCase("exit"))
  -                    return;
  -                Object value = cache.getObject(key);
  -                System.out.println("Got Value: "+value);
  +         } else if ( value instanceof LinkedList ) {
  +            for ( Iterator it = ( ( LinkedList )value ).iterator(); it.hasNext();  
) {
  +               node = ( Node )it.next();
  +               if ( !node.used ) {
  +                  makeMostRecent( node );
  +                  break;
  +               } else {
  +                  node = null;
  +               }
  +            }
  +            if ( node == null ) {
  +               node = addObject( key );
  +            }
  +         } else {
  +            throw new Error( "LRU Cache Assertion Failure: Wrong class '" + 
value.getClass().getName() + "' in keyMap!" );
  +         }
  +         if ( use ) {
  +            node.setUsed( true );
  +         }
  +      } catch ( ConcurrentModificationException e ) {
  +         return getObject( key, use );
  +      }
  +      return factory.prepareObject( node.data );
  +   }
  +
  +   private Node addObject( Object key ) {
  +      Object data;
  +      try {
  +         data = factory.createObject( key );
  +      } catch ( Exception e ) {
  +         log.error( "Could not add object", e );
  +         return null;
  +      }
  +      Node result;
  +      synchronized ( lock ) {
  +         if ( mostRecentNode == null ) {
  +            result = new Node( null, null, data );
  +            mostRecentNode = result;
  +            leastRecentNode = result;
  +         } else {
  +            result = new Node( mostRecentNode, null, data );
  +            mostRecentNode.moreRecent = result;
  +            mostRecentNode = result;
  +         }
  +         ++size;
  +         checkMaxSize();
  +      }
  +
  +      // Put the key/value(s) and node/key in the map
  +      Object value = keyMap.get( key );
  +      if ( value == null ) {
  +         keyMap.put( key, result );
  +      } else if ( value instanceof LinkedList ) {
  +         ( ( LinkedList )value ).add( result );
  +      } else if ( value instanceof Node ) {
  +         LinkedList list = new LinkedList();
  +         list.add( value );
  +         list.add( result );
  +         keyMap.put( key, list );
  +      } else {
  +         throw new Error( "LRU Cache Assertion Failure: Wrong class '" + 
value.getClass().getName() + "' in keyMap!" );
  +      }
  +      keyMap.put( result, key );
  +      return result;
  +   }
  +
  +   private void checkMaxSize() {
  +      if ( maxSize <= 0 ) {
  +         return;
  +      }
  +      while ( size > maxSize ) {
  +         Node drop = leastRecentNode;
  +         leastRecentNode = drop.moreRecent;
  +         leastRecentNode.lessRecent = null;
  +         --size;
  +
  +         removeNode( drop );
  +      }
  +   }
  +
  +   private void makeMostRecent( Node node ) {
  +      synchronized ( lock ) {
  +         if ( node.moreRecent == null ) {
  +            if ( mostRecentNode != node ) {
  +               throw new ConcurrentModificationException();
               }
  -
  -            * ********* *
  -
  -            **** THIS TESTS useObject AND returnObject ****
  -
  -            Object lastKey = null, last = null;
  -            while(true) {
  -                cache.printList();
  -                System.out.print("> ");
  -                System.out.flush();
  -                String key = in.readLine();
  -                if(key.equalsIgnoreCase("quit") || key.equalsIgnoreCase("exit"))
  -                    return;
  -                Object value = cache.useObject(key);
  -                if(last != null) {
  -                    cache.returnObject(lastKey, last);
  -                }
  -                lastKey = key;
  -                last = value;
  -                System.out.println("Got Value: "+value);
  -            }
  +            return;
  +         }
   
  -            ********** *
  -        } catch(Throwable e) {
  -            e.printStackTrace();
  -        }
  -    }
  -*/
  +         // Prepare surrounding nodes
  +         Node previous = node.moreRecent;
  +         Node next = node.lessRecent;
  +         previous.lessRecent = next;
  +         if ( next == null ) {
  +            leastRecentNode = previous;
  +         } else {
  +            next.moreRecent = previous;
  +         }
  +
  +         // Prepare node and new 2nd most recent
  +         node.moreRecent = null;
  +         node.lessRecent = mostRecentNode;
  +         mostRecentNode.moreRecent = node;
  +         mostRecentNode = node;
  +      }
  +   }
  +
  +   // This should be called while holding the lock
  +   private void removeNode( Node node ) {
  +      boolean used = node.used;
  +      if ( !used ) {
  +         node.used = true;
  +      }
  +      Object key = keyMap.remove( node );
  +
  +      Object value = keyMap.get( key );
  +      if ( value instanceof Node ) {
  +         keyMap.remove( key );
  +      } else if ( value instanceof LinkedList ) {
  +         LinkedList list = ( LinkedList )value;
  +         Iterator it = list.iterator();
  +         while ( it.hasNext() ) {
  +            Node current = ( Node )it.next();
  +            if ( current == node ) {
  +               it.remove();
  +               break;
  +            }
  +         }
  +         if ( list.size() == 1 ) {
  +            keyMap.put( key, list.get( 0 ) );
  +         }
  +      } else {
  +         throw new Error( "LRU Cache Assertion Failure: Wrong class '" + 
value.getClass().getName() + "' in keyMap!" );
  +      }
  +      if ( !used ) {
  +         factory.deleteObject( node.data );
  +      }
  +      node.moreRecent = null;
  +      node.lessRecent = null;
  +   }
  +
  +   /**
  +    * @created    August 18, 2001
  +    */
  +   private class Node {
  +      Node          lessRecent;
  +      Node          moreRecent;
  +      Object        data;
  +      boolean       used = false;
  +
  +      public Node( Node lessRecent, Node moreRecent, Object data ) {
  +         this( lessRecent, moreRecent, data, false );
  +      }
  +
  +      public Node( Node lessRecent, Node moreRecent, Object data, boolean used ) {
  +         this.lessRecent = lessRecent;
  +         this.moreRecent = moreRecent;
  +         this.data = data;
  +         this.used = used;
  +      }
  +
  +      public synchronized void setUsed( boolean used ) {
  +         if ( this.used == used ) {
  +            throw new ConcurrentModificationException();
  +         }
  +         this.used = used;
  +      }
  +   }
  +
  +   /*
  +    * This is for testing only
  +    * private void printList() {
  +    * System.out.print("Fwd Nodes:");
  +    * Node node = mostRecentNode;
  +    * for(int i=0; i<size; i++) {
  +    * System.out.print(" "+node.data);
  +    * node = node.lessRecent;
  +    * }
  +    * System.out.println();
  +    * Stack stack = new Stack();
  +    * node = leastRecentNode;
  +    * for(int i=0; i<size; i++) {
  +    * stack.push(node.data);
  +    * node = node.moreRecent;
  +    * }
  +    * System.out.print("Rev Nodes:");
  +    * while(!stack.isEmpty())
  +    * System.out.print(" "+stack.pop());
  +    * System.out.println();
  +    * }
  +    * public static void main(String args[]) {
  +    * try {
  +    * java.io.BufferedReader in = new java.io.BufferedReader(new 
java.io.InputStreamReader(System.in));
  +    * LeastRecentlyUsedCache cache = new LeastRecentlyUsedCache(new 
CachedObjectFactory() {
  +    * public Object createObject(Object identifier) {
  +    * return "v"+identifier;
  +    * }
  +    * public void deleteObject(Object object) {
  +    * System.out.println("Deleting Object "+object);
  +    * }
  +    * }, 5);
  +    * THIS TESTS getObject
  +    * while(true) {
  +    * cache.printList();
  +    * System.out.print("> ");
  +    * System.out.flush();
  +    * String key = in.readLine();
  +    * if(key.equalsIgnoreCase("quit") || key.equalsIgnoreCase("exit"))
  +    * return;
  +    * Object value = cache.getObject(key);
  +    * System.out.println("Got Value: "+value);
  +    * }
  +    *
  +    * THIS TESTS useObject AND returnObject
  +    * Object lastKey = null, last = null;
  +    * while(true) {
  +    * cache.printList();
  +    * System.out.print("> ");
  +    * System.out.flush();
  +    * String key = in.readLine();
  +    * if(key.equalsIgnoreCase("quit") || key.equalsIgnoreCase("exit"))
  +    * return;
  +    * Object value = cache.useObject(key);
  +    * if(last != null) {
  +    * cache.returnObject(lastKey, last);
  +    * }
  +    * lastKey = key;
  +    * last = value;
  +    * System.out.println("Got Value: "+value);
  +    * }
  +    *
  +    * } catch(Throwable e) {
  +    * e.printStackTrace();
  +    * }
  +    * }
  +    */
   }
  
  
  
  1.2       +74 -62    jbosspool/src/main/org/jboss/pool/cache/ObjectCache.java
  
  Index: ObjectCache.java
  ===================================================================
  RCS file: /cvsroot/jboss/jbosspool/src/main/org/jboss/pool/cache/ObjectCache.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- ObjectCache.java  2001/05/15 07:58:24     1.1
  +++ ObjectCache.java  2001/08/19 04:55:30     1.2
  @@ -4,68 +4,80 @@
   package org.jboss.pool.cache;
   
   /**
  - * A caching map.  This associates one or more values with a
  - * key.  When a value is requested for a key, a cached value
  - * will be returned if available, and a new value will be
  - * generated and cached otherwise.  Instances of this interface
  - * require a CachedObjectFactory to generate new values, and
  - * control the caching in custom ways.
  - * @see org.jboss.pool.cache.CachedObjectFactory
  - * @author Aaron Mulder [EMAIL PROTECTED]
  + *  A caching map. This associates one or more values with a key. When a value
  + *  is requested for a key, a cached value will be returned if available, and a
  + *  new value will be generated and cached otherwise. Instances of this
  + *  interface require a CachedObjectFactory to generate new values, and control
  + *  the caching in custom ways.
  + *
  + * @author     Aaron Mulder [EMAIL PROTECTED]
  + * @created    August 19, 2001
  + * @see        org.jboss.pool.cache.CachedObjectFactory
    */
   public interface ObjectCache {
  -    /**
  -     * When setting the size, this constant means there should
  -     * be no limit on the size of the cache.  This is not
  -     * recommended under ordinary circumstances.
  -     */
  -    public final static int UNLIMITED_SIZE = 0;
  -
  -    /**
  -     * Gets a cached object with the specified key.  This is not
  -     * an exclusive function - any number of clients may get the
  -     * same object at the same time.
  -     * @see #useObject
  -     */
  -    public Object getObject(Object key);
  -
  -    /**
  -     * Gets a cached object with the specified key.  This is an
  -     * exclusive function - no other client may get the same
  -     * object at the same time.  You must return the object using
  -     * returnObject before another client may reuse this object.
  -     * @see #getObject
  -     * @see #returnObject
  -     */
  -    public Object useObject(Object key);
  -
  -    /**
  -     * Returns an object to the cache that is currently in use
  -     * (checked out via useObject).  No other client can use
  -     * the same object until this method is called.  The original
  -     * client may not continue to use the object after this
  -     * method is called.
  -     * @see #useObject
  -     */
  -    public void returnObject(Object key, Object value);
  -
  -    /**
  -     * Removes all objects from the cache that have this key.
  -     * There will only be more than one object with the same
  -     * key if clients are using useObject and returnObject
  -     * instead of getObject.
  -     */
  -    public void removeObjects(Object key);
  -
  -    /**
  -     * Sets the maximum number of objects in the cache.  If the
  -     * number of objects is at the limit and a new object is
  -     * requested, other objects will be dropped from the cache.
  -     */
  -    public void setSize(int size);
  -
  -    /**
  -     * Removes all cached objects and stops the cache.
  -     */
  -    public void close();
  +   /**
  +    *  When setting the size, this constant means there should be no limit on
  +    *  the size of the cache. This is not recommended under ordinary
  +    *  circumstances.
  +    */
  +   public final static int UNLIMITED_SIZE = 0;
  +
  +   /**
  +    *  Gets a cached object with the specified key. This is not an exclusive
  +    *  function - any number of clients may get the same object at the same
  +    *  time.
  +    *
  +    * @param  key  Description of Parameter
  +    * @return      The Object value
  +    * @see         #useObject
  +    */
  +   public Object getObject( Object key );
  +
  +   /**
  +    *  Gets a cached object with the specified key. This is an exclusive
  +    *  function - no other client may get the same object at the same time. You
  +    *  must return the object using returnObject before another client may reuse
  +    *  this object.
  +    *
  +    * @param  key  Description of Parameter
  +    * @return      Description of the Returned Value
  +    * @see         #getObject
  +    * @see         #returnObject
  +    */
  +   public Object useObject( Object key );
  +
  +   /**
  +    *  Returns an object to the cache that is currently in use (checked out via
  +    *  useObject). No other client can use the same object until this method is
  +    *  called. The original client may not continue to use the object after this
  +    *  method is called.
  +    *
  +    * @param  key    Description of Parameter
  +    * @param  value  Description of Parameter
  +    * @see           #useObject
  +    */
  +   public void returnObject( Object key, Object value );
  +
  +   /**
  +    *  Removes all objects from the cache that have this key. There will only be
  +    *  more than one object with the same key if clients are using useObject and
  +    *  returnObject instead of getObject.
  +    *
  +    * @param  key  Description of Parameter
  +    */
  +   public void removeObjects( Object key );
  +
  +   /**
  +    *  Sets the maximum number of objects in the cache. If the number of objects
  +    *  is at the limit and a new object is requested, other objects will be
  +    *  dropped from the cache.
  +    *
  +    * @param  size  The new Size value
  +    */
  +   public void setSize( int size );
  +
  +   /**
  +    *  Removes all cached objects and stops the cache.
  +    */
  +   public void close();
   }
  
  
  

_______________________________________________
Jboss-development mailing list
[EMAIL PROTECTED]
http://lists.sourceforge.net/lists/listinfo/jboss-development

Reply via email to