sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1450374 - in /sis/branches/JDK7/sis-utility/src: main/java/org/apache/sis/util/collection/CodeListSet.java test/java/org/apache/sis/util/collection/CodeListSetTest.java
Date Tue, 26 Feb 2013 19:50:05 GMT
Author: desruisseaux
Date: Tue Feb 26 19:50:05 2013
New Revision: 1450374

URL: http://svn.apache.org/r1450374
Log:
Convenience constructor for creating a CodeListSet filled with all known elements.

Modified:
    sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/CodeListSet.java
    sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/CodeListSetTest.java

Modified: sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/CodeListSet.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/CodeListSet.java?rev=1450374&r1=1450373&r2=1450374&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/CodeListSet.java
[UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/main/java/org/apache/sis/util/collection/CodeListSet.java
[UTF-8] Tue Feb 26 19:50:05 2013
@@ -23,6 +23,7 @@ import java.util.Iterator;
 import java.util.NoSuchElementException;
 import java.io.Serializable;
 import java.lang.reflect.Modifier;
+import net.jcip.annotations.NotThreadSafe;
 import org.opengis.util.CodeList;
 import org.apache.sis.util.iso.Types;
 import org.apache.sis.util.resources.Errors;
@@ -30,7 +31,23 @@ import org.apache.sis.util.resources.Err
 
 /**
  * A specialized {@code Set} implementation for use with {@link CodeList} values.
- * This implementation uses a bit mask for efficient storage.
+ * All elements in a {@code CodeListSet} are of the same {@code CodeList} class,
+ * which must be final. Iterators traverse the elements in the order in which the
+ * code list constants are declared.
+ *
+ * {@section Implementation note}
+ * {@code CodeListSet} is implemented internally by bit vectors for compact and efficient
storage.
+ * All bulk operations ({@code addAll}, {@code removeAll}, {@code containsAll}) are very
quick if
+ * their argument is also a {@code CodeListSet} instance.
+ *
+ * {@section Usage example}
+ * The following example creates a set of {@link org.opengis.referencing.cs.AxisDirection}s
+ * for a (<var>x</var>,<var>y</var>,<var>z</var>) coordinate
system:
+ *
+ * {@preformat java
+ *   CodeListSet<AxisDirection> codes = new CodeListSet<>(AxisDirection.class);
+ *   Collections.addAll(codes, AxisDirection.EAST, AxisDirection.NORTH, AxisDirection.UP),
+ * }
  *
  * @param <E> The type of code list elements in the set.
  *
@@ -38,7 +55,10 @@ import org.apache.sis.util.resources.Err
  * @since   0.3
  * @version 0.3
  * @module
+ *
+ * @see java.util.EnumSet
  */
+@NotThreadSafe
 public class CodeListSet<E extends CodeList<E>> extends AbstractSet<E>
         implements CheckedContainer<E>, Cloneable, Serializable
 {
@@ -48,6 +68,12 @@ public class CodeListSet<E extends CodeL
     private static final long serialVersionUID = 3648460713432430695L;
 
     /**
+     * A pool of code list arrays. When many {@code CodeListSet} instances are for the
+     * same code list type, this allows those instances to share the same arrays.
+     */
+    private static final WeakHashSet<CodeList[]> POOL = new WeakHashSet<>(CodeList[].class);
+
+    /**
      * The type of code list elements.
      *
      * @see #getElementType()
@@ -95,6 +121,35 @@ public class CodeListSet<E extends CodeL
     }
 
     /**
+     * Creates set for code lists of the given type. If the {@code fill} argument is {@code
false},
+     * then the new set will be initially empty. Otherwise the new set will be filled with
all code
+     * list elements of the given type that are known at construction time. Note that if
new code
+     * list elements are created after the invocation of this {@code CodeListSet} constructor,
then
+     * those new elements will <em>not</em> be in this set.
+     *
+     * @param  elementType The type of code list elements to be included in this set.
+     * @param  fill {@code true} for filling the set with all known elements if the given
type,
+     *         or {@code false} for leaving the set empty.
+     * @throws IllegalArgumentException If the given class is not final.
+     */
+    public CodeListSet(final Class<E> elementType, final boolean fill) throws IllegalArgumentException
{
+        this(elementType);
+        if (fill) {
+            codes = POOL.unique(Types.getCodeValues(elementType));
+            int n = codes.length;
+            if (n < Long.SIZE) {
+                values = (1L << n) - 1;
+            } else {
+                values = -1;
+                if ((n -= Long.SIZE) != 0) {
+                    supplementary = new BitSet(n);
+                    supplementary.set(0, n);
+                }
+            }
+        }
+    }
+
+    /**
      * Returns the type of code list elements in this set.
      *
      * @return The type of code list elements in this set.
@@ -111,7 +166,7 @@ public class CodeListSet<E extends CodeL
     final E valueOf(final int ordinal) {
         E[] array = codes;
         if (array == null || ordinal >= array.length) {
-            codes = array = Types.getCodeValues(elementType);
+            codes = array = POOL.unique(Types.getCodeValues(elementType));
         }
         return array[ordinal];
     }

Modified: sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/CodeListSetTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/CodeListSetTest.java?rev=1450374&r1=1450373&r2=1450374&view=diff
==============================================================================
--- sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/CodeListSetTest.java
[UTF-8] (original)
+++ sis/branches/JDK7/sis-utility/src/test/java/org/apache/sis/util/collection/CodeListSetTest.java
[UTF-8] Tue Feb 26 19:50:05 2013
@@ -212,6 +212,23 @@ public final strictfp class CodeListSetT
     }
 
     /**
+     * Tests the creation of a set filled with with all known values.
+     */
+    @Test
+    @DependsOnMethod("testContains")
+    public void testFill() {
+        final CodeListSet<AxisDirection> c = new CodeListSet<>(AxisDirection.class,
true);
+        assertTrue("Expect at least 32 elements as of GeoAPI 3.0.0.", c.size() >= 32);
+        assertTrue(c.toString().startsWith("[AxisDirection[OTHER], AxisDirection[NORTH],
"));
+        /*
+         * Testing the full array would be too long and may change in future GeoAPI version
+         * anyway. Actually the main interest of this test is to ensure that the toString()
+         * method doesn't throw an IndexOutOfBoundsException (as it would be the case if
+         * the constructor had set too many bits).
+         */
+    }
+
+    /**
      * Tests the various methods with a code list containing more than 64 elements.
      */
     @Test
@@ -233,6 +250,7 @@ public final strictfp class CodeListSetT
         final CodeListSet<LargeCodeList> clone = c.clone();
         assertNotSame("Clone shall be a new instance.", c, clone);
         assertEquals("Clone shall be equal to the original.", master, clone);
+        assertEquals(clone, new CodeListSet<>(LargeCodeList.class, true));
         /*
          * Tests contains(Object) and remove(Object). We also remove elements
          * from the master set, then we verify that the result is the same.



Mime
View raw message