[jboss-cvs] JBossCache/src/org/jboss/cache/util ...

Elias Ross genman at noderunner.net
Wed Feb 7 17:06:42 EST 2007


  User: genman  
  Date: 07/02/07 17:06:42

  Modified:    src/org/jboss/cache/util    MapCopy.java
  Added:       src/org/jboss/cache/util    Caches.java SimpleEntry.java
  Log:
  JBCACHE-969 - Move transaction classes to org.jboss.cache.transaction
  
  Revision  Changes    Path
  1.8       +4 -54     JBossCache/src/org/jboss/cache/util/MapCopy.java
  
  (In the diff below, changes in quantity of whitespace are not shown.)
  
  Index: MapCopy.java
  ===================================================================
  RCS file: /cvsroot/jboss/JBossCache/src/org/jboss/cache/util/MapCopy.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -b -r1.7 -r1.8
  --- MapCopy.java	3 Jan 2007 16:42:34 -0000	1.7
  +++ MapCopy.java	7 Feb 2007 22:06:42 -0000	1.8
  @@ -40,6 +40,10 @@
         init();
      }
   
  +   public MapCopy() {
  +      this(new java.util.HashMap());
  +   }
  +   
      private void init()
      {
         this.entrySet = new AbstractSet<Map.Entry<K, V>>()
  @@ -76,60 +80,6 @@
         }
      }
   
  -   /**
  -    * Where is Java 1.6?
  -    */
  -   private static class SimpleEntry<K, V> implements Map.Entry<K, V>, Serializable
  -   {
  -      private static final long serialVersionUID = -6092752114794052323L;
  -
  -      private K key;
  -
  -      private V value;
  -
  -      public SimpleEntry(Entry<K, V> me)
  -      {
  -         key = me.getKey();
  -         value = me.getValue();
  -      }
  -
  -      public K getKey()
  -      {
  -         return key;
  -      }
  -
  -      public V getValue()
  -      {
  -         return value;
  -      }
  -
  -      public V setValue(V arg0)
  -      {
  -         throw new UnsupportedOperationException();
  -      }
  -
  -      @Override
  -      public boolean equals(Object o)
  -      {
  -         Map.Entry e2 = (Map.Entry) o;
  -         return (getKey() == null ? e2.getKey() == null : getKey().equals(e2.getKey()))
  -                 && (getValue() == null ? e2.getValue() == null : getValue().equals(e2.getValue()));
  -      }
  -
  -      @Override
  -      public int hashCode()
  -      {
  -         return (getKey() == null ? 0 : getKey().hashCode()) ^
  -                 (getValue() == null ? 0 : getValue().hashCode());
  -      }
  -
  -      @Override
  -      public String toString()
  -      {
  -         return key + "=" + value;
  -      }
  -   }
  -
      @Override
      public Set entrySet()
      {
  
  
  
  1.1      date: 2007/02/07 22:06:42;  author: genman;  state: Exp;JBossCache/src/org/jboss/cache/util/Caches.java
  
  Index: Caches.java
  ===================================================================
  package org.jboss.cache.util;
  
  import java.util.AbstractMap;
  import java.util.AbstractSet;
  import java.util.ConcurrentModificationException;
  import java.util.Iterator;
  import java.util.Map;
  import java.util.Set;
  
  import org.jboss.cache.Cache;
  import org.jboss.cache.Fqn;
  import org.jboss.cache.Node;
  import org.jboss.cache.loader.CacheLoader;
  import org.jboss.cache.pojo.collection.IntegerCache;
  
  /**
   * Adaptors for {@link Cache} classes, such as {@link Node}.
   * This is useful for integration of JBoss Cache into existing applications.
   * 
   * Example use:
   * <pre>
   * Cache c = ...;
   * Map m = Caches.asMap(c);
   * m.put("a", "b"); // null
   * m.containsKey("a"); // true
   * m.remove("a"); // "b"
   * </pre> 
   */
  public class Caches
  {
  
     private Caches()
     {
     }
  
     /**
      * Returns a {@link Map} from the root node.
      * @see #asMap(Node)
      */
     public static Map asMap(Cache cache)
     {
        if (cache == null)
           throw new NullPointerException("cache");
        return asMap(cache.getRoot());
     }
  
     /**
      * Returns a {@link Map}, where map keys are named children of the given Node,
      * and values are kept under a single key for this node.
      * The map may be safely concurrently modified through this Map or externally,
      * and its contents reflect the cache state and
      * existing data of the Node.
      * This means that {@link ConcurrentModificationException} is never thrown
      * and all methods are thread safe.
      * <p/>
      * The map is not serializable.
      * <p/>
      * Usage note:  As a single node is used for every key, it is most efficient to store
      * data for a single entity (e.g. Person) in a single object.
      * <p/>
      * Also, when using a {@link CacheLoader} for storage, keys used must be valid as
      * part of the {@link Fqn} used in calls. Generally speaking, simple string values are
      * preferred. 
      */
     public static Map asMap(Node node)
     {
        return new MapNode(node);
     }
  
     /**
      * Returns a {@link Map}, where map data is put and returned directly from a single Node.
      * This method is "simple" as data is kept under a single node.
      * Note that storing all data in a single Node can be inefficient when using persistence,
      * replication, or transactions.
      * The map may be safely concurrently modified through this Map or externally.
      * This means that {@link ConcurrentModificationException} is never thrown
      * and all methods are thread safe.
      * <p/>
      * The methods {@link Map#entrySet} and {@link Map#values} and {@link Map#keySet}
      * do not allow for modification of the Node.
      * Further all these methods return a collection which is a snapshot (copy)
      * of the data at time of calling. This may be very inefficient.
      * <p/>
      * The map is not serializable.
      */
     public static Map asSimpleMap(Node node)
     {
        return new SimpleMapNode(node);
     }
  
     /**
      * Returns a {@link Set}, where set entries are data entries of the given Node.
      * This method is "simple" as data is kept under a single node.
      * <p/>
      * Note that storing all data in a single Node can be inefficient when using persistence,
      * replication, or transactions.
      * The set may be safely concurrently modified through this Map or externally.
      * This means that {@link ConcurrentModificationException} is never thrown
      * and all methods are thread safe.
      * <p/>
      * The set is not serializable. 
      */
     public static Set asSimpleSet(Node node)
     {
        return new SimpleSetNode(node);
     }
  
     /**
      * Returns a {@link Map}, where map entries are partitioned into
      * children nodes, within a cache node.
      * The default child selector divides the data into 16 child nodes based on hash code.
      * Note that for large data sets, the number of child nodes should be increased. 
      * 
      * @param node node to cache under
      */
     public static Map asPartitionedMap(Node node)
     {
        return new PartitionedMapNode(node, HashKeySelector.DEFAULT);
     }
  
     /**
      * Returns a {@link Map}, where map entries are partitioned
      * into children, within a cache node, by key hash code.
      * <p/>
      * The map is not serializable.
      * <p/>
      * Usage note:  This is a performance (and size) compromise between {@link #asMap(Node)}
      * and {@link #asSimpleMap(Node)}. For applications using a {@link org.jboss.cache.CacheLoader},
      * {@link #asMap(Node)} is a better choice.
      * <p/> 
      * 
      * @param node node to cache under
      * @param selector selector strategy that chooses a segment based on key
      */
     public static Map asPartitionedMap(Node node, ChildSelector selector)
     {
        return new PartitionedMapNode(node, selector);
     }
  
     /**
      * Returns a {@link Map}, where map entries are partitioned into child nodes,
      * within the cache root, by key hash code.
      * 
      * @param cache cache to use
      * @return
      */
     public static Map asPartitionedMap(Cache cache)
     {
        return asPartitionedMap(cache.getRoot());
     }
  
     /**
      * Returns a segment ({@link Node#getChild(Object) child node name})
      * to use based on the characteristics of a key.
      * <p/>
      * Here is an example class which selects a child based on a person's department:
     <pre>
     public static class DepartmentSelector implements ChildSelector<Person>
     {
        
        public Object childName(Person key)
        {
           return key.getDepartment();
        }
  
     }
     </pre>
      * @
      */
     public interface ChildSelector<T>
     {
        /**
         * Returns a child node name for a key. 
         * @param key for calls to {@link Map#put}, {@link Map#get} etc.
         * @return node name
         */
        Object childName(T key);
     }
  
     /**
      * Class that returns a child name to use based on the hash code of a key.
      */
     public static class HashKeySelector implements ChildSelector
     {
        
        static ChildSelector DEFAULT = new HashKeySelector(16);
  
        protected int segments;
  
        /**
         * Constructs with N segments, where N must be a power of 2.
         */
        public HashKeySelector(int segments)
        {
           this.segments = segments;
           if (Integer.bitCount(segments) != 1)
              throw new IllegalArgumentException();
           if (segments <= 0)
              throw new IllegalArgumentException();
        }
  
        /**
         * Computes an improved hash code from an object's hash code.
         */
        protected int hashCode(int i)
        {
           i ^= i >>> 20 ^ i >>> 12;
           return i ^ i >>> 7 ^ i >>> 4;
        }
  
        /**
         * Returns the segment for this key, in the inclusive range 0 to {@link #segments} - 1.
         */
        protected int segmentFor(Object key)
        {
           if (key == null)
              return 0;
           int hc = key.hashCode();
           return hashCode(hc) & (segments - 1);
        }
  
        /**
         * Returns the node name for this segment.
         */
        protected Object childName(int segment)
        {
           return IntegerCache.toString(segment);
        }
           
        /**
         * Returns the node name for this key.
         * By default, returns a String containing the segment.
         */
        public Object childName(Object key)
        {
           return childName(segmentFor(key));
        }
  
        public String toString()
        {
           return super.toString() + " segments=" + segments;
        }
  
     }
  
     static class MapNode extends AbstractMap
     {
  
        public static final String KEY = "K";
  
        private Node node;
  
        public MapNode(Node node)
        {
           if (node == null)
              throw new NullPointerException("node");
           this.node = node;
        }
  
        @Override
        public Set entrySet()
        {
           return new AbstractSet()
           {
  
              @Override
              public Iterator iterator()
              {
                 final Iterator<Node> i = set().iterator();
                 return new Iterator()
                 {
  
                    Object name;
  
                    boolean next = false;
  
                    public boolean hasNext()
                    {
                       return i.hasNext();
                    }
  
                    public Object next()
                    {
                       Node n = i.next();
                       this.name = n.getFqn().getLastElement();
                       this.next = true;
                       Object key = n.get(KEY);
                       return new SimpleEntry(name, key);
                    }
  
                    public void remove()
                    {
                       if (!next)
                          throw new IllegalStateException();
                       node.removeChild(name);
                    }
  
                    public String toString()
                    {
                       return "Itr name=" + name;
                    }
  
                 };
              }
  
              private Set<Node> set()
              {
                 return node.getChildren();
              }
  
              @Override
              public int size()
              {
                 return set().size();
              }
  
           };
        }
  
        @Override
        public void clear()
        {
           for (Object o : node.getChildrenNames())
              node.removeChild(o);
        }
  
        @Override
        public boolean containsKey(Object arg0)
        {
           return node.getChild(arg0) != null;
        }
  
        @Override
        public Object get(Object arg0)
        {
           Node child = node.getChild(arg0);
           if (child == null)
              return null;
           return child.get(KEY);
        }
  
        @Override
        public boolean isEmpty()
        {
           return node.getChildrenNames().isEmpty();
        }
  
        @Override
        public Set keySet()
        {
  
           return new AbstractSet()
           {
  
              private Set set()
              {
                 return node.getChildrenNames();
              }
  
              @Override
              public Iterator iterator()
              {
                 final Iterator i = set().iterator();
                 return new Iterator()
                 {
  
                    Object child;
  
                    public boolean hasNext()
                    {
                       return i.hasNext();
                    }
  
                    public Object next()
                    {
                       child = i.next();
                       return child;
                    }
  
                    public void remove()
                    {
                       if (child == null)
                          throw new IllegalStateException();
                       node.removeChild(child);
                       // since set is read-only, invalidate
                    }
  
                 };
              }
  
              @Override
              public boolean remove(Object key)
              {
                 return node.removeChild(key);
              }
  
              @Override
              public int size()
              {
                 return set().size();
              }
  
           };
  
        }
  
        @Override
        public Object put(Object arg0, Object arg1)
        {
           return node.addChild(new Fqn(arg0)).put(KEY, arg1);
        }
  
        @Override
        public Object remove(Object arg0)
        {
           Node child = node.getChild(arg0);
           if (child == null)
              return null;
           Object o = child.remove(KEY);
           node.removeChild(arg0);
           return o;
        }
  
        @Override
        public int size()
        {
           return node.getChildrenNames().size();
        }
  
     }
  
     static class SimpleMapNode extends AbstractMap implements java.util.Map
     {
  
        private Node node;
  
        public SimpleMapNode(Node node)
        {
           if (node == null)
              throw new NullPointerException("node");
           this.node = node;
        }
  
        @Override
        public void clear()
        {
           node.clearData();
        }
  
        @Override
        public boolean containsKey(Object key)
        {
           return node.getKeys().contains(key);
        }
  
        @Override
        public boolean containsValue(Object value)
        {
           return node.getData().containsValue(value);
        }
  
        /**
         * getData returns a snapshot of the data.
         */
        public Set entrySet()
        {
           return node.getData().entrySet();
        }
  
        @Override
        public Object get(Object key)
        {
           return node.get(key);
        }
  
        @Override
        public Set keySet()
        {
           return node.getKeys();
        }
  
        @Override
        public Object put(Object key, Object value)
        {
           return node.put(key, value);
        }
  
        @Override
        public void putAll(Map map)
        {
           node.putAll(map);
        }
  
        @Override
        public Object remove(Object key)
        {
           return node.remove(key);
        }
  
        @Override
        public int size()
        {
           return node.dataSize();
        }
  
     }
  
     static class SimpleSetNode extends AbstractSet implements java.util.Set
     {
  
        private Node node;
  
        private static final Boolean VALUE = Boolean.TRUE;
  
        public SimpleSetNode(Node node)
        {
           if (node == null)
              throw new NullPointerException("node");
           this.node = node;
        }
  
        @Override
        public void clear()
        {
           node.clearData();
        }
  
        @Override
        public boolean contains(Object key)
        {
           return node.getKeys().contains(key);
        }
  
        @Override
        public boolean remove(Object key)
        {
           return node.remove(key) != null;
        }
  
        @Override
        public int size()
        {
           return node.dataSize();
        }
  
        @Override
        public boolean add(Object arg0)
        {
           return node.put(arg0, VALUE) == null;
        }
  
        @Override
        public Iterator iterator()
        {
           final Iterator i = node.getKeys().iterator();
           return new Iterator()
           {
              Object key;
  
              boolean next = false;
  
              public boolean hasNext()
              {
                 return i.hasNext();
              }
  
              public Object next()
              {
                 key = i.next();
                 next = true;
                 return key;
              }
  
              public void remove()
              {
                 if (!next)
                    throw new IllegalStateException();
                 node.remove(key);
              }
  
           };
        }
  
     }
  
     static class PartitionedMapNode extends AbstractMap
     {
  
        private Node node;
  
        private ChildSelector selector;
  
        public PartitionedMapNode(Node node, ChildSelector selector)
        {
           if (node == null)
              throw new IllegalArgumentException("node");
           if (selector == null)
              throw new IllegalArgumentException("selector");
           this.node = node;
           this.selector = selector;
        }
  
        @Override
        public Set entrySet()
        {
           return new AbstractSet<Map.Entry>()
           {
  
              Iterator<Node> ci = node.getChildren().iterator();
  
              @Override
              public Iterator<Entry> iterator()
              {
                 return new Iterator<Entry>()
                 {
  
                    Iterator ni;
                    {
                       nextChild();
                       findNext();
                    }
  
                    private void nextChild()
                    {
                       ni = new SimpleMapNode(ci.next()).entrySet().iterator();
                    }
  
                    private void findNext()
                    {
                       while (!ni.hasNext())
                       {
                          if (!ci.hasNext())
                             return;
                          nextChild();
                       }
                    }
  
                    public boolean hasNext()
                    {
                       return ni.hasNext();
                    }
  
                    public Entry next()
                    {
                       Entry n = (Entry) ni.next();
                       findNext();
                       return n;
                    }
  
                    public void remove()
                    {
                       ni.remove();
                    }
  
                 };
              }
  
              @Override
              public int size()
              {
                 return PartitionedMapNode.this.size();
              }
  
           };
        }
  
        @Override
        public Set keySet()
        {
           return new AbstractSet<Map.Entry>()
           {
  
              @Override
              public Iterator<Entry> iterator()
              {
                 return PartitionedMapNode.super.keySet().iterator();
              }
              
              @Override            
              public boolean remove(Object o)
              {
                 boolean key = PartitionedMapNode.this.containsKey(o);
                 PartitionedMapNode.this.remove(o);
                 return key;
              }
  
              @Override
              public boolean contains(Object o)
              {
                 return PartitionedMapNode.this.containsKey(o);
              }
  
              @Override
              public int size()
              {
                 return PartitionedMapNode.this.size();
              }
  
           };
        }
  
        @Override
        public void clear()
        {
           for (Object childName : node.getChildrenNames())
              node.removeChild(childName);
        }
  
        private Node nodeFor(Object o)
        {
           return node.getChild(selector.childName(o));
        }
  
        @Override
        public boolean containsKey(Object o)
        {
           Node n = nodeFor(o);
           if (n == null) return false;
           return n.getKeys().contains(o);
        }
  
        @Override
        public Object get(Object o)
        {
           Node n = nodeFor(o);
           if (n == null) return null;
           return n.get(o);
        }
  
        @Override
        public Object put(Object key, Object value)
        {
           Object name = selector.childName(key);
           Node n = node.getChild(name);
           if (n == null)
              n = node.addChild(new Fqn(name));
           return n.put(key, value);
        }
  
        @Override
        public Object remove(Object o)
        {
           Node n = nodeFor(o);
           if (n == null)
              return null;
           return n.remove(o);
        }
        
        /**
         * Removes nodes without any data.
         */
        public void clean()
        {
           for (Node n : node.getChildren())
           {
              if (n.dataSize() == 0)
                 node.removeChild(n.getFqn().getLastElement());
           }
        }
  
        @Override
        public int size()
        {
           int size = 0;
           for (Object o : node.getChildrenNames())
           {
              Node child = node.getChild(o);
              size += child.dataSize();
           }
           return size;
        }
  
     }
  }
  
  
  
  1.1      date: 2007/02/07 22:06:42;  author: genman;  state: Exp;JBossCache/src/org/jboss/cache/util/SimpleEntry.java
  
  Index: SimpleEntry.java
  ===================================================================
  package org.jboss.cache.util;
  
  import java.io.Serializable;
  import java.util.Map;
  import java.util.Map.Entry;
  
  /**
   * Where is Java 1.6?
   */
  class SimpleEntry<K, V> implements Map.Entry<K, V>, Serializable
  {
     private static final long serialVersionUID = -6092752114794052323L;
  
     private K key;
  
     private V value;
  
     public SimpleEntry(Entry<K, V> me)
     {
        key = me.getKey();
        value = me.getValue();
     }
  
     public SimpleEntry(K key, V value)
     {
        this.key = key;
        this.value = value;
     }
  
     public K getKey()
     {
        return key;
     }
  
     public V getValue()
     {
        return value;
     }
  
     public V setValue(V arg0)
     {
        throw new UnsupportedOperationException();
     }
  
     @Override
     public boolean equals(Object o)
     {
        Map.Entry e2 = (Map.Entry) o;
        return (getKey() == null ? e2.getKey() == null : getKey().equals(e2.getKey()))
                && (getValue() == null ? e2.getValue() == null : getValue().equals(e2.getValue()));
     }
  
     @Override
     public int hashCode()
     {
        return (getKey() == null ? 0 : getKey().hashCode()) ^
                (getValue() == null ? 0 : getValue().hashCode());
     }
  
     @Override
     public String toString()
     {
        return key + "=" + value;
     }
  }
  
  



More information about the jboss-cvs-commits mailing list