You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@pivot.apache.org by gb...@apache.org on 2009/06/01 16:07:19 UTC

svn commit: r780654 - in /incubator/pivot/trunk/core/src/pivot/collections: ArrayList.java ArrayQueue.java ArrayStack.java EnumList.java EnumMap.java EnumSet.java HashMap.java QueueListener.java StackListener.java

Author: gbrown
Date: Mon Jun  1 14:07:18 2009
New Revision: 780654

URL: http://svn.apache.org/viewvc?rev=780654&view=rev
Log:
Minor fixes to ArrayList, ArrayQueue, and ArrayStack; remove enum setter from EnumList; update EnumSet; add EnumMap; add Queue and Stack listeners.

Added:
    incubator/pivot/trunk/core/src/pivot/collections/EnumMap.java
    incubator/pivot/trunk/core/src/pivot/collections/QueueListener.java
    incubator/pivot/trunk/core/src/pivot/collections/StackListener.java
Modified:
    incubator/pivot/trunk/core/src/pivot/collections/ArrayList.java
    incubator/pivot/trunk/core/src/pivot/collections/ArrayQueue.java
    incubator/pivot/trunk/core/src/pivot/collections/ArrayStack.java
    incubator/pivot/trunk/core/src/pivot/collections/EnumList.java
    incubator/pivot/trunk/core/src/pivot/collections/EnumSet.java
    incubator/pivot/trunk/core/src/pivot/collections/HashMap.java

Modified: incubator/pivot/trunk/core/src/pivot/collections/ArrayList.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/pivot/collections/ArrayList.java?rev=780654&r1=780653&r2=780654&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/pivot/collections/ArrayList.java (original)
+++ incubator/pivot/trunk/core/src/pivot/collections/ArrayList.java Mon Jun  1 14:07:18 2009
@@ -166,9 +166,15 @@
         }
 
         if (comparator != null
-            && validate
-            && binarySearch(this, item, comparator) != -(index + 1)) {
-            throw new IllegalArgumentException("Illegal insertion point.");
+            && validate) {
+            int i = binarySearch(this, item, comparator);
+            if (i < 0) {
+                i = -(i + 1);
+            }
+
+            if (index != i) {
+                throw new IllegalArgumentException("Illegal insertion point.");
+            }
         }
 
         // Insert item
@@ -245,12 +251,8 @@
 
     public void clear() {
         if (length > 0) {
-            for (int i = 0; i < length; i++) {
-                items[i] = null;
-            }
-
+            items = new Object[items.length];
             length = 0;
-
             listListeners.listCleared(this);
         }
     }
@@ -369,12 +371,12 @@
 
         sb.append("[");
 
-        for (int i = 0, n = getLength(); i < n; i++) {
+        for (int i = 0; i < items.length; i++) {
             if (i > 0) {
                 sb.append(", ");
             }
 
-            sb.append(get(i));
+            sb.append(items[i]);
         }
 
         sb.append("]");

Modified: incubator/pivot/trunk/core/src/pivot/collections/ArrayQueue.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/pivot/collections/ArrayQueue.java?rev=780654&r1=780653&r2=780654&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/pivot/collections/ArrayQueue.java (original)
+++ incubator/pivot/trunk/core/src/pivot/collections/ArrayQueue.java Mon Jun  1 14:07:18 2009
@@ -19,14 +19,6 @@
 /**
  * Implementation of the {@link Queue} interface that is backed by an
  * array.
- * <p>
- * TODO The current implementation is not optimal, since it requires shifting
- * all elements on every call to enqueue(). Use an approach that maintains
- * rotating headIndex and tailIndex values and override List methods to use
- * these as offsets from the current capacity value. When the capacity needs
- * to increase, we'll copy the elements in a contiguous block to the new array
- * (we may want to make this operation a protected method so ArrayList can call
- * it polymorphically).
  *
  * @author gbrown
  */
@@ -42,16 +34,31 @@
     }
 
     public void enqueue(T item) {
-        insert(item, getComparator() == null ? 0 : -1);
+        add(item);
+
+        // TODO Fire enqueue event
     }
 
     public T dequeue() {
-        // TODO Throw if empty
-        return remove(getLength() - 1, 1).get(0);
+        int length = getLength();
+        if (length == 0) {
+            throw new IllegalStateException();
+        }
+
+        T item = remove(length - 1, 1).get(0);
+
+        // TODO Fire dequeue event
+
+        return item;
     }
 
     public T peek() {
-        // TODO Return null if empty
-        return get(0);
+        T item = null;
+        int length = getLength();
+        if (length > 0) {
+            item = get(length - 1);
+        }
+
+        return item;
     }
 }

Modified: incubator/pivot/trunk/core/src/pivot/collections/ArrayStack.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/pivot/collections/ArrayStack.java?rev=780654&r1=780653&r2=780654&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/pivot/collections/ArrayStack.java (original)
+++ incubator/pivot/trunk/core/src/pivot/collections/ArrayStack.java Mon Jun  1 14:07:18 2009
@@ -34,7 +34,9 @@
     }
 
     public void push(T item) {
-        insert(item, getComparator() == null ? getLength() : -1);
+        add(item);
+
+        // TODO Fire push event
     }
 
     public T pop() {
@@ -43,13 +45,21 @@
             throw new IllegalStateException();
         }
 
-        return remove(length - 1, 1).get(0);
+        T item = remove(length - 1, 1).get(0);
+
+        // TODO Fire pop event
+
+        return item;
     }
 
     public T peek() {
+        T item = null;
         int length = getLength();
+        if (length > 0) {
+            item = get(length - 1);
+        }
 
-        return (length == 0) ? null : get(length - 1);
+        return item;
     }
 
     public T poke(T item) {
@@ -60,8 +70,4 @@
 
         return update(length - 1, item);
     }
-
-    public int getRemainingCapacity() {
-        return -1;
-    }
 }

Modified: incubator/pivot/trunk/core/src/pivot/collections/EnumList.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/pivot/collections/EnumList.java?rev=780654&r1=780653&r2=780654&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/pivot/collections/EnumList.java (original)
+++ incubator/pivot/trunk/core/src/pivot/collections/EnumList.java Mon Jun  1 14:07:18 2009
@@ -33,71 +33,40 @@
  * @author gbrown
  */
 public class EnumList<E extends Enum<E>> implements List<E>, Serializable {
-    private static final long serialVersionUID = 0;
-
-    private Class<E> enumClass;
-    private E[] elements;
+    private class ItemIterator implements Iterator<E> {
+        private int i = 0;
 
-    private transient ListListenerList<E> listListeners = null;
-
-    public EnumList() {
-        this(null);
-    }
+        public boolean hasNext() {
+            return (i < items.length);
+        }
 
-    public EnumList(Class<E> enumClass) {
-        this.enumClass = enumClass;
+        public E next() {
+            if (i >= items.length) {
+                throw new NoSuchElementException();
+            }
 
-        if (enumClass == null) {
-            elements = null;
-        } else {
-            elements = enumClass.getEnumConstants();
+            return items[i++];
         }
-    }
 
-    public Class<E> getEnumClass() {
-        return enumClass;
-    }
-
-    public void setEnumClass(Class<E> enumClass) {
-        Class<E> previousEnumClass = this.enumClass;
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    };
 
-        if (enumClass != previousEnumClass) {
-            this.enumClass = enumClass;
+    private static final long serialVersionUID = 0;
 
-            // Clear old elements
-            if (elements != null) {
-                elements = null;
-
-                // Notify listeners
-                if (listListeners != null) {
-                    listListeners.listCleared(this);
-                }
-            }
+    private Class<E> enumClass;
+    private E[] items;
 
-            // Add new elements
-            elements = enumClass.getEnumConstants();
+    private transient ListListenerList<E> listListeners = new ListListenerList<E>();
 
-            if (elements != null) {
-                // Notify listeners of the new elements
-                if (listListeners != null) {
-                    for (int i = 0; i < elements.length; i++) {
-                        listListeners.itemInserted(this, i);
-                    }
-                }
-            }
-        }
+    public EnumList(Class<E> enumClass) {
+        this.enumClass = enumClass;
+        items = enumClass.getEnumConstants();
     }
 
-    @SuppressWarnings("unchecked")
-    public final void setEnumClass(String enumClassName) {
-        Class<E> enumClass;
-        try {
-            enumClass = (Class<E>)Class.forName(enumClassName);
-        } catch (ClassNotFoundException exception) {
-            throw new IllegalArgumentException(exception);
-        }
-
-        setEnumClass(enumClass);
+    public Class<E> getEnumClass() {
+        return enumClass;
     }
 
     public int add(E item) {
@@ -125,36 +94,25 @@
     }
 
     public E get(int index) {
-        return (elements != null ? elements[index] : null);
+        return items[index];
     }
 
     public int indexOf(E item) {
-        int index = -1;
-
-        if (elements != null) {
-            for (int i = 0; i < elements.length; i++) {
-                if (elements[i] == item) {
-                    index = i;
-                    break;
-                }
-            }
+        if (item == null) {
+            throw new IllegalArgumentException();
         }
 
-        return index;
+        return item.ordinal();
     }
 
     public int getLength() {
-        return (elements != null ? elements.length : 0);
+        return items.length;
     }
 
     @SuppressWarnings("unchecked")
     public E[] toArray() {
-        Object[] array = null;
-
-        if (elements != null) {
-            array = new Object[elements.length];
-            System.arraycopy(elements, 0, array, 0, elements.length);
-        }
+        Object[] array = new Object[items.length];
+        System.arraycopy(items, 0, array, 0, items.length);
 
         return (E[])array;
     }
@@ -168,32 +126,10 @@
     }
 
     public Iterator<E> iterator() {
-        return new Iterator<E>() {
-            private int i = 0;
-
-            public boolean hasNext() {
-                return (elements != null && i < elements.length);
-            }
-
-            public E next() {
-                if (elements == null || i >= elements.length) {
-                    throw new NoSuchElementException();
-                }
-
-                return elements[i++];
-            }
-
-            public void remove() {
-                throw new UnsupportedOperationException();
-            }
-        };
+        return new ItemIterator();
     }
 
     public ListenerList<ListListener<E>> getListListeners() {
-        if (listListeners == null) {
-            listListeners = new ListListenerList<E>();
-        }
-
         return listListeners;
     }
 
@@ -202,12 +138,12 @@
 
         sb.append("[");
 
-        for (int i = 0, n = getLength(); i < n; i++) {
+        for (int i = 0; i < items.length; i++) {
             if (i > 0) {
                 sb.append(", ");
             }
 
-            sb.append(get(i));
+            sb.append(items[i]);
         }
 
         sb.append("]");

Added: incubator/pivot/trunk/core/src/pivot/collections/EnumMap.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/pivot/collections/EnumMap.java?rev=780654&view=auto
==============================================================================
--- incubator/pivot/trunk/core/src/pivot/collections/EnumMap.java (added)
+++ incubator/pivot/trunk/core/src/pivot/collections/EnumMap.java Mon Jun  1 14:07:18 2009
@@ -0,0 +1,122 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.collections;
+
+import java.io.Serializable;
+import java.util.Comparator;
+import java.util.Iterator;
+
+import pivot.util.ListenerList;
+
+/**
+ * Implementation of the {@link Set} interface whose keys are backed by a set
+ * of enum values.
+ */
+public class EnumMap<E extends Enum<E>, V> implements Map<E, V>, Serializable {
+    private static final long serialVersionUID = 0;
+
+    private EnumSet<E> keySet;
+    private Object[] values;
+
+    private transient MapListenerList<E, V> mapListeners = new MapListenerList<E, V>();
+
+    public EnumMap(Class<E> enumClass) {
+        keySet = new EnumSet<E>(enumClass);
+
+        E[] constants = enumClass.getEnumConstants();
+        values = new Object[constants.length];
+    }
+
+    @SuppressWarnings("unchecked")
+    public V get(E key) {
+        if (key == null) {
+            throw new IllegalArgumentException();
+        }
+
+        return (V)values[key.ordinal()];
+    }
+
+    @SuppressWarnings("unchecked")
+    public V put(E key, V value) {
+        if (key == null) {
+            throw new IllegalArgumentException();
+        }
+
+        int ordinal = key.ordinal();
+        V previousValue = (V)values[ordinal];
+        values[ordinal] = value;
+
+        if (keySet.contains(key)) {
+            mapListeners.valueUpdated(this, key, previousValue);
+        } else {
+            keySet.add(key);
+            mapListeners.valueAdded(this, key);
+        }
+
+        return previousValue;
+    }
+
+    @SuppressWarnings("unchecked")
+    public V remove(E key) {
+        if (key == null) {
+            throw new IllegalArgumentException();
+        }
+
+        V value = null;
+        if (keySet.contains(key)) {
+            int ordinal = key.ordinal();
+            value = (V)values[ordinal];
+            values[ordinal] = null;
+            keySet.remove(key);
+            mapListeners.valueRemoved(this, key, value);
+        }
+
+        return value;
+    }
+
+    public void clear() {
+        if (!keySet.isEmpty()) {
+            values = new Object[values.length];
+            keySet.clear();
+            mapListeners.mapCleared(this);
+        }
+    }
+
+    public boolean containsKey(E key) {
+        return keySet.contains(key);
+    }
+
+    public boolean isEmpty() {
+        return keySet.isEmpty();
+    }
+
+    public Comparator<E> getComparator() {
+        return null;
+    }
+
+    public void setComparator(Comparator<E> comparator) {
+        throw new UnsupportedOperationException();
+    }
+
+    public Iterator<E> iterator() {
+        return keySet.iterator();
+    }
+
+    public ListenerList<MapListener<E, V>> getMapListeners() {
+        return mapListeners;
+    }
+}

Modified: incubator/pivot/trunk/core/src/pivot/collections/EnumSet.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/pivot/collections/EnumSet.java?rev=780654&r1=780653&r2=780654&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/pivot/collections/EnumSet.java (original)
+++ incubator/pivot/trunk/core/src/pivot/collections/EnumSet.java Mon Jun  1 14:07:18 2009
@@ -19,42 +19,101 @@
 import java.io.Serializable;
 import java.util.Comparator;
 import java.util.Iterator;
+import java.util.NoSuchElementException;
 
 import pivot.util.ListenerList;
 
 /**
- * Implementation of the {@link Set} interface that is backed by a bitfield
- * representing enum> values. Values are mapped to the bitfield by their
- * ordinal value.
+ * Implementation of the {@link Set} interface that is backed by an array of
+ * enum values.
  */
 public class EnumSet<E extends Enum<E>> implements Set<E>, Serializable {
+    private class ElementIterator implements Iterator<E> {
+        private int i = 0;
+        private E next;
+
+        private ElementIterator() {
+            next();
+        }
+
+        public boolean hasNext() {
+            return (next != null);
+        }
+
+        public E next() {
+            while (i < elements.length
+                && !members[i]) {
+                i++;
+            }
+
+            if (i < elements.length) {
+                next = elements[i];
+            } else {
+                throw new NoSuchElementException();
+            }
+
+            return next;
+        }
+
+        public void remove() {
+            throw new UnsupportedOperationException();
+        }
+    };
+
     private static final long serialVersionUID = 0;
 
-    private int bitSet = 0;
+    private Class<E> enumClass;
+    private E[] elements;
+    private boolean[] members;
+    private int count = 0;
+
     private transient SetListenerList<E> setListeners = new SetListenerList<E>();
 
+    public EnumSet(Class<E> enumClass) {
+        this.enumClass = enumClass;
+
+        elements = enumClass.getEnumConstants();
+        members = new boolean[elements.length];
+    }
+
+    public Class<E> getEnumClass() {
+        return enumClass;
+    }
+
     public void add(E element) {
-        bitSet |= (1 << element.ordinal());
+        int ordinal = element.ordinal();
+
+        if (!members[ordinal]) {
+            members[ordinal] = true;
+            count++;
+            setListeners.elementAdded(this, element);
+        }
     }
 
     public void remove(E element) {
-        bitSet &= ~(1 << element.ordinal());
+        int ordinal = element.ordinal();
+
+        if (members[ordinal]) {
+            members[ordinal] = false;
+            count--;
+            setListeners.elementRemoved(this, element);
+        }
     }
 
     public void clear() {
-        bitSet = 0;
+        if (count > 0) {
+            members = new boolean[members.length];
+            count = 0;
+            setListeners.setCleared(this);
+        }
     }
 
     public boolean contains(E element) {
-        return (bitSet & (1 << element.ordinal())) > 0;
+        return members[element.ordinal()];
     }
 
     public boolean isEmpty() {
-        return bitSet > 0;
-    }
-
-    public ListenerList<SetListener<E>> getSetListeners() {
-        return setListeners;
+        return count == 0;
     }
 
     public Comparator<E> getComparator() {
@@ -66,7 +125,10 @@
     }
 
     public Iterator<E> iterator() {
-        // TODO
-        return null;
+        return new ElementIterator();
+    }
+
+    public ListenerList<SetListener<E>> getSetListeners() {
+        return setListeners;
     }
 }

Modified: incubator/pivot/trunk/core/src/pivot/collections/HashMap.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/pivot/collections/HashMap.java?rev=780654&r1=780653&r2=780654&view=diff
==============================================================================
--- incubator/pivot/trunk/core/src/pivot/collections/HashMap.java (original)
+++ incubator/pivot/trunk/core/src/pivot/collections/HashMap.java Mon Jun  1 14:07:18 2009
@@ -97,8 +97,10 @@
     }
 
     public void clear() {
-        hashMap.clear();
-        mapListeners.mapCleared(this);
+        if (!hashMap.isEmpty()) {
+            hashMap.clear();
+            mapListeners.mapCleared(this);
+        }
     }
 
     public boolean containsKey(K key) {

Added: incubator/pivot/trunk/core/src/pivot/collections/QueueListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/pivot/collections/QueueListener.java?rev=780654&view=auto
==============================================================================
--- incubator/pivot/trunk/core/src/pivot/collections/QueueListener.java (added)
+++ incubator/pivot/trunk/core/src/pivot/collections/QueueListener.java Mon Jun  1 14:07:18 2009
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.collections;
+
+/**
+ * Queue listener interface.
+ *
+ * @author gbrown
+ */
+public interface QueueListener<T> {
+    /**
+     * Called when an item has been inserted into the tail of a queue.
+     *
+     * @param queue
+     * @param item
+     */
+    public void itemEnqueued(Queue<T> queue, T item);
+
+    /**
+     * Called when an item has been removed from the head of a queue.
+     *
+     * @param queue
+     * @param item
+     */
+    public void itemDequeued(Queue<T> queue, T item);
+}

Added: incubator/pivot/trunk/core/src/pivot/collections/StackListener.java
URL: http://svn.apache.org/viewvc/incubator/pivot/trunk/core/src/pivot/collections/StackListener.java?rev=780654&view=auto
==============================================================================
--- incubator/pivot/trunk/core/src/pivot/collections/StackListener.java (added)
+++ incubator/pivot/trunk/core/src/pivot/collections/StackListener.java Mon Jun  1 14:07:18 2009
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to you under the Apache License,
+ * Version 2.0 (the "License"); you may not use this file except in
+ * compliance with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pivot.collections;
+
+/**
+ * Stack listener interface.
+ *
+ * @author gbrown
+ */
+public interface StackListener<T> {
+    /**
+     * Called when an item has been pushed onto a stack.
+     *
+     * @param stack
+     * @param item
+     */
+    public void itemPushed(Stack<T> stack, T item);
+
+    /**
+     * Called when an item has been popped off of a stack.
+     *
+     * @param stack
+     * @param item
+     */
+    public void itemPopped(Stack<T> stack, T item);
+}