You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by sc...@apache.org on 2016/11/16 16:25:26 UTC

svn commit: r1770011 - in /uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas: FSArray.java FSHashSet.java

Author: schor
Date: Wed Nov 16 16:25:26 2016
New Revision: 1770011

URL: http://svn.apache.org/viewvc?rev=1770011&view=rev
Log:
[UIMA-5164] improve FSHashSet to support lazy init, fix equals 

Modified:
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/FSArray.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/FSHashSet.java

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/FSArray.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/FSArray.java?rev=1770011&r1=1770010&r2=1770011&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/FSArray.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/FSArray.java Wed Nov 16 16:25:26 2016
@@ -22,10 +22,7 @@ package org.apache.uima.jcas.cas;
 import org.apache.uima.cas.ArrayFS;
 import org.apache.uima.cas.CASRuntimeException;
 import org.apache.uima.cas.FeatureStructure;
-import org.apache.uima.cas.SelectFSs;
-import org.apache.uima.cas.Type;
 import org.apache.uima.cas.impl.CASImpl;
-import org.apache.uima.cas.impl.SelectFSs_impl;
 import org.apache.uima.cas.impl.TypeImpl;
 import org.apache.uima.jcas.JCas;
 import org.apache.uima.jcas.JCasRegistry;
@@ -204,12 +201,12 @@ public final class FSArray extends TOP i
   }
 
   // internal use
-  // used by serializers
+  // used by serializers, other impls (e.g. FSHashSet)
   // no conversion to Pear trampolines done
   public TOP[] _getTheArray() {
     return theArray;
   }
-  
+    
   /* (non-Javadoc)
    * @see org.apache.uima.jcas.cas.CommonArray#copyValuesFrom(org.apache.uima.jcas.cas.CommonArray)
    * no conversion to Pear trampolines done

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/FSHashSet.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/FSHashSet.java?rev=1770011&r1=1770010&r2=1770011&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/FSHashSet.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/FSHashSet.java Wed Nov 16 16:25:26 2016
@@ -19,6 +19,7 @@
 
 package org.apache.uima.jcas.cas;
 
+import java.lang.reflect.Array;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
@@ -36,18 +37,17 @@ import org.apache.uima.cas.impl.TypeSyst
 import org.apache.uima.jcas.JCas;
 import org.apache.uima.jcas.JCasRegistry;
 
-// TODO: Auto-generated Javadoc
 /**
  * A HashSet type containing Feature Structures,
  *   - Has all the methods of HashSet
  *   - Implements the select(...) APIs 
  *   
  * Implementation notes:
- *   - Uses UimaSerializable APIs *
+ *   - Uses UimaSerializable APIs 
  *
  * @param <T> the generic type
  */
-public final class FSHashSet <T extends FeatureStructure> extends TOP implements 
+public final class FSHashSet <T extends TOP> extends TOP implements 
                                  UimaSerializableFSs, SelectViaCopyToArray, 
                                  Set<T>, RandomAccess, Cloneable {
 
@@ -69,9 +69,18 @@ public final class FSHashSet <T extends
   public int getTypeIndexID() {
     return typeIndexID;
   }
-
-  /** lifecycle   - starts as empty array list   - becomes non-empty when updated (add)       -- used from that point on. */
-  private final HashSet<T> fsHashSet;
+  
+  public final TOP[] emptyArray = new TOP[0];
+  
+  /** lifecycle   
+   *   - starts as empty array list   
+   *   - becomes non-empty when updated (add)       
+   *   -- used from that point on. */
+  
+  private boolean isPendingInit = false;
+  private boolean isSaveNeeded = false;
+  
+  private final HashSet<T> fsHashSet; // not set here to allow initial size version
    
   /** The Constant _FI_fsArray. */
   public static final int _FI_fsArray = TypeSystemImpl.getAdjustedFeatureOffset("fsArray");
@@ -154,23 +163,37 @@ public final class FSHashSet <T extends
    * @see org.apache.uima.UimaSerializable#_init_from_cas_data()
    */
   public void _init_from_cas_data() {
+    isPendingInit = true;
+  }
+
+  private void maybeLazyInit() {
+    if (isPendingInit) {
+      lazyInit();
+    }
+  }
+  
+  private void lazyInit() {  
+    isPendingInit = false;
     fsHashSet.clear();
     FSArray a = getFsArray();
     if (a != null) {
       fsHashSet.addAll((Collection<? extends T>) Arrays.asList(a));
     }
   }
-  
+    
   /* (non-Javadoc)
    * @see org.apache.uima.UimaSerializable#_save_to_cas_data()
    */
   public void _save_to_cas_data() {
-    FSArray a = getFsArray();
-    if (a == null || a.size() != fsHashSet.size()) {
-      a = new FSArray(_casView.getExistingJCas(), fsHashSet.size());
-      setFsArray(a);
+    if (isSaveNeeded) {
+      isSaveNeeded = false;
+      FSArray a = getFsArray();
+      if (a == null || a.size() != fsHashSet.size()) {
+        a = new FSArray(_casView.getExistingJCas(), fsHashSet.size());
+        setFsArray(a);
+      }
+      fsHashSet.toArray(a._getTheArray());
     }
-    fsHashSet.toArray(a._getTheArray());
   }
 
   /* (non-Javadoc)
@@ -184,6 +207,16 @@ public final class FSHashSet <T extends
   @Override
   public FeatureStructureImplC _superClone() { return clone();}  // enable common clone
   
+  private TOP[] gta() {
+    FSArray fsa = getFsArray();
+    if (null == fsa) {
+      return emptyArray;
+    }
+    TOP[] a = fsa._getTheArray();
+    return (null == a) 
+        ? emptyArray
+        : a;
+  }
   
   /**
    * Equals.
@@ -193,7 +226,16 @@ public final class FSHashSet <T extends
    * @see java.util.AbstractSet#equals(java.lang.Object)
    */
   public boolean equals(Object o) {
-    return fsHashSet.equals(o);
+    if (!(o instanceof FSHashSet)) return false;
+    FSHashSet other = (FSHashSet) o;
+    if (size() != other.size()) return false;
+    if (size() == 0) return true;
+    
+    for (T item : this) {
+      if (!other.contains(item)) return false;
+    }
+    
+    return true;
   }
 
   /**
@@ -203,7 +245,9 @@ public final class FSHashSet <T extends
    * @see java.util.AbstractSet#hashCode()
    */
   public int hashCode() {
-    return fsHashSet.hashCode();
+    return isSaveNeeded
+        ? fsHashSet.hashCode()
+        : Arrays.hashCode(gta());
   }
 
   /**
@@ -212,19 +256,24 @@ public final class FSHashSet <T extends
    * @return the feature structure[]
    * @see java.util.AbstractCollection#toArray()
    */
-  public FeatureStructure[] toArray() {
-    return (FeatureStructure[]) fsHashSet.toArray();
+  public Object[] toArray() {    
+    return isSaveNeeded
+        ? fsHashSet.toArray()
+        : gta().clone();
   }
 
   /**
-   * Removes the all.
+   * Removes all elements matching c
    *
-   * @param c the c
-   * @return true, if successful
+   * @param c the elements to remove
+   * @return true, if set changed 
    * @see java.util.AbstractSet#removeAll(java.util.Collection)
    */
   public boolean removeAll(Collection<?> c) {
-    return fsHashSet.removeAll(c);
+    maybeLazyInit();
+    boolean r = fsHashSet.removeAll(c); 
+    if (r) isSaveNeeded = true;
+    return r;
   }
 
   /**
@@ -232,11 +281,21 @@ public final class FSHashSet <T extends
    *
    * @param <T> the generic type
    * @param a the a
-   * @return the t[]
-   * @see java.util.AbstractCollection#toArray(java.lang.Object[])
+   * @return the T[]
+   * @see java.util.AbstractCollection#toArray(T[])
    */
-  public <T> T[] toArray(T[] a) {
-    return fsHashSet.toArray(a);
+  public <N> N[] toArray(N[] a) {
+    if (isSaveNeeded) {
+      return fsHashSet.toArray(a);
+    }
+    final int sz = size();
+    if (a.length < sz) {
+      a = (N[]) Array.newInstance(a.getClass().getComponentType(), sz);
+    }
+    
+    TOP[] d = gta();
+    System.arraycopy(d, 0, a, 0, d.length);
+    return a;
   }
 
   /**
@@ -245,8 +304,10 @@ public final class FSHashSet <T extends
    * @return the iterator
    * @see java.util.HashSet#iterator()
    */
-  public Iterator<T> iterator() {
-    return fsHashSet.iterator();
+  public Iterator<T> iterator() {  
+    return isSaveNeeded 
+        ? fsHashSet.iterator()
+        : (Iterator<T>) Arrays.asList(gta()).iterator();
   }
 
   /**
@@ -256,7 +317,9 @@ public final class FSHashSet <T extends
    * @see java.util.HashSet#size()
    */
   public int size() {
-    return fsHashSet.size();
+    return isSaveNeeded 
+        ? fsHashSet.size()
+        : gta().length;
   }
 
   /**
@@ -266,7 +329,7 @@ public final class FSHashSet <T extends
    * @see java.util.HashSet#isEmpty()
    */
   public boolean isEmpty() {
-    return fsHashSet.isEmpty();
+    return size() == 0;
   }
 
   /**
@@ -277,29 +340,36 @@ public final class FSHashSet <T extends
    * @see java.util.HashSet#contains(java.lang.Object)
    */
   public boolean contains(Object o) {
+    maybeLazyInit();
     return fsHashSet.contains(o);
   }
 
   /**
-   * Adds the.
+   * Adds the element to the set
    *
-   * @param e the e
-   * @return true, if successful
+   * @param e the element to add
+   * @return true, if the set didn't already contain this element
    * @see java.util.HashSet#add(java.lang.Object)
    */
   public boolean add(T e) {
-    return fsHashSet.add(e);
+    maybeLazyInit();
+    boolean r = fsHashSet.add(e); 
+    if (r) isSaveNeeded = true;
+    return r;
   }
 
   /**
-   * Removes the.
+   * Removes the element
    *
    * @param o the o
-   * @return true, if successful
+   * @return true, if the set contained the element
    * @see java.util.HashSet#remove(java.lang.Object)
    */
   public boolean remove(Object o) {
-    return fsHashSet.remove(o);
+    maybeLazyInit();
+    boolean r = fsHashSet.remove(o);
+    if (r) isSaveNeeded = true;
+    return r;
   }
 
   /**
@@ -308,32 +378,36 @@ public final class FSHashSet <T extends
    * @see java.util.HashSet#clear()
    */
   public void clear() {
+    if (size() == 0) return;
+    maybeLazyInit();
+    isSaveNeeded = true;
     fsHashSet.clear();
   }
 
-
-
-
   /**
    * Contains all.
    *
    * @param c the c
-   * @return true, if successful
+   * @return true, if set contains all of the elements in c
    * @see java.util.AbstractCollection#containsAll(java.util.Collection)
    */
   public boolean containsAll(Collection<?> c) {
+    maybeLazyInit();
     return fsHashSet.containsAll(c);
   }
 
   /**
-   * Adds the all.
+   * Adds all the elements 
    *
    * @param c the c
-   * @return true, if successful
+   * @return true, if set changed
    * @see java.util.AbstractCollection#addAll(java.util.Collection)
    */
   public boolean addAll(Collection<? extends T> c) {
-    return fsHashSet.addAll(c);
+    maybeLazyInit();
+    boolean r = fsHashSet.addAll(c);
+    if (r) isSaveNeeded = true;
+    return r;
   }
 
   /**
@@ -343,29 +417,46 @@ public final class FSHashSet <T extends
    * @see java.util.HashSet#spliterator()
    */
   public Spliterator<T> spliterator() {
-    return fsHashSet.spliterator();
+    return isSaveNeeded
+        ? fsHashSet.spliterator()
+        : (Spliterator<T>) Arrays.asList(gta()).spliterator();
   }
 
   /**
    * Retain all.
    *
    * @param c the c
-   * @return true, if successful
+   * @return true, if collection changed
    * @see java.util.AbstractCollection#retainAll(java.util.Collection)
    */
   public boolean retainAll(Collection<?> c) {
-    return fsHashSet.retainAll(c);
+    maybeLazyInit();
+    boolean r = fsHashSet.retainAll(c);
+    if (r) isSaveNeeded = true;
+    return r;
   }
 
-  /**
-   * To string.
-   *
-   * @return the string
-   * @see java.util.AbstractCollection#toString()
+  /* (non-Javadoc)
+   * @see java.lang.Object#toString()
    */
+  @Override
   public String toString() {
-    return fsHashSet.toString();
+    final int maxLen = 10;
+    return "FSHashSet [isPendingInit=" + isPendingInit + ", isSaveNeeded=" + isSaveNeeded
+        + ", fsHashSet=" + (fsHashSet != null ? toString(fsHashSet, maxLen) : null) + "]";
   }
-    
-  
+
+  private String toString(Collection<?> collection, int maxLen) {
+    StringBuilder builder = new StringBuilder();
+    builder.append("[");
+    int i = 0;
+    for (Iterator<?> iterator = collection.iterator(); iterator.hasNext() && i < maxLen; i++) {
+      if (i > 0)
+        builder.append(", ");
+      builder.append(iterator.next());
+    }
+    builder.append("]");
+    return builder.toString();
+  }
+
 }