You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by tw...@apache.org on 2007/09/18 13:55:51 UTC

svn commit: r576857 - in /incubator/uima/uimaj/trunk/uimaj-core/src: main/java/org/apache/uima/cas/impl/ test/java/org/apache/uima/cas/impl/ test/java/org/apache/uima/cas/test/

Author: twgoetz
Date: Tue Sep 18 04:55:50 2007
New Revision: 576857

URL: http://svn.apache.org/viewvc?rev=576857&view=rev
Log:
Jira UIMA-574: fix heap implementation to grow reasonably fast, even if a very small starting size has been specified.

https://issues.apache.org/jira/browse/UIMA-574

Added:
    incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/GrowingTheCasTest.java
Modified:
    incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java
    incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASSerializer.java
    incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/Heap.java
    incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/XCASSerializer.java
    incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/impl/CasResetResizeTest.java
    incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/CASTest.java

Modified: incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java?rev=576857&r1=576856&r2=576857&view=diff
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java Tue Sep 18 04:55:50 2007
@@ -871,11 +871,11 @@
         ((CASImpl) tcas).mySofaRef = (1 == view) ? -1 : 0;
       }
     }
-    if (this.getHeap().getCurrentTempSize() > CASImpl.resetHeapSize) {
-      this.getHeap().resetTempHeap(true);
+    if (this.getHeap().getHeapSize() > CASImpl.resetHeapSize) {
+      this.getHeap().reset(true);
       resetStringTable(true);
     } else {
-      this.getHeap().resetTempHeap(false);
+      this.getHeap().reset(false);
       resetStringTable(false);
     }
 
@@ -1600,23 +1600,6 @@
   }
 
   /**
-   * Create a permanent array on the heap.
-   * 
-   * @param type
-   *                The type of the array.
-   * @param len
-   *                The length of the array.
-   * @return The address of the new FS. This is an int <code>&gt;=0</code>.
-   *         If it is <code>0</code>, something went wrong; <code>0</code>
-   *         is not a valid address.
-   */
-  public int createPermArray(int type, int len) {
-    final int addr = this.getHeap().addToHeap(this.svd.casMetadata.fsSpaceReq[type] + len, type);
-    this.getHeap().heap[(addr + arrayLengthFeatOffset)] = len;
-    return addr;
-  }
-
-  /**
    * Get the value of an address on the heap.
    * 
    * @param addr
@@ -2597,7 +2580,7 @@
   }
 
   public final int ll_createFS(int typeCode) {
-    return this.getHeap().addToTempHeap(this.svd.casMetadata.fsSpaceReq[typeCode], typeCode);
+    return this.getHeap().add(this.svd.casMetadata.fsSpaceReq[typeCode], typeCode);
   }
 
   public final int ll_createFS(int typeCode, boolean doCheck) {
@@ -2650,7 +2633,7 @@
    *                    If <code>type</code> is not a type.
    */
   public int createTempArray(int type, int len) {
-    final int addr = this.getHeap().addToTempHeap(arrayContentOffset + len, type);
+    final int addr = this.getHeap().add(arrayContentOffset + len, type);
     this.getHeap().heap[(addr + arrayLengthFeatOffset)] = len;
     return addr;
   }
@@ -2661,13 +2644,13 @@
    * @see org.apache.uima.cas.impl.LowLevelCAS#ll_createArray(int, int)
    */
   public int ll_createArray(int typeCode, int arrayLength) {
-    final int addr = this.getHeap().addToTempHeap(arrayContentOffset + arrayLength, typeCode);
+    final int addr = this.getHeap().add(arrayContentOffset + arrayLength, typeCode);
     this.getHeap().heap[(addr + arrayLengthFeatOffset)] = arrayLength;
     return addr;
   }
 
   public int ll_createAuxArray(int typeCode, int arrayLength) {
-    final int addr = this.getHeap().addToTempHeap(arrayContentOffset + 1, typeCode);
+    final int addr = this.getHeap().add(arrayContentOffset + 1, typeCode);
     this.getHeap().heap[(addr + arrayLengthFeatOffset)] = arrayLength;
     return addr;
   }

Modified: incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASSerializer.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASSerializer.java?rev=576857&r1=576856&r2=576857&view=diff
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASSerializer.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASSerializer.java Tue Sep 18 04:55:50 2007
@@ -99,7 +99,7 @@
    */
 	public void addCAS(CASImpl cas, boolean addMetaData) {
 		this.fsIndex = cas.getIndexedFSs();
-		final int heapSize = cas.getHeap().getCurrentTempSize();
+		final int heapSize = cas.getHeap().getCellsUsed();
 		this.heapArray = new int[heapSize];
 		System.arraycopy(cas.getHeap().heap, 0, this.heapArray, 0, heapSize);
 		if (addMetaData) {
@@ -181,7 +181,7 @@
 			dos.writeInt(version);
 
 			// output the FS heap
-			final int heapSize = cas.getHeap().getCurrentTempSize();
+			final int heapSize = cas.getHeap().getCellsUsed();
 			dos.writeInt(heapSize);
 			for (int i = 0; i < heapSize; i++) {
 				dos.writeInt(cas.getHeap().heap[i]);

Modified: incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/Heap.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/Heap.java?rev=576857&r1=576856&r2=576857&view=diff
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/Heap.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/Heap.java Tue Sep 18 04:55:50 2007
@@ -22,68 +22,49 @@
 import java.util.Arrays;
 
 import org.apache.uima.internal.util.IntArrayUtils;
-import org.apache.uima.internal.util.SortedIntSet;
 
 /**
- * A heap for CAS. Actually provides two heaps: a temporary one for per-document structures, and a
- * permanent one. The space in the temporary heap can be reused by calling
- * <code>resetTempHeap()</code>. Note though that the two heaps share an address space.
+ * A heap for CAS.
  * 
  * <p>
- * This class is agnostic about what you store on the heap. It only copies values from integer
- * arrays.
- * 
- * <p>
- * Finally, a word of caution. This class works internally with pages of a certain size (see
- * {@link Heap#DEFAULT_PAGE_SIZEDEFAULT_PAGE_SIZE}). It will not accept structures larger than this
- * size. You can set a larger value by using the appropriate constructor. Use a smaller value only
- * if you know exactly what you are doing.
- * 
- * 
- * @version $Id: Heap.java,v 1.8 2002/08/08 13:59:29 goetz Exp $
+ * This class is agnostic about what you store on the heap. It only copies
+ * values from integer arrays.
  */
 public final class Heap {
 
   /**
-   * Minimum size of internal pages. Currently set to <code>1000</code>.
+   * Minimum size of the heap. Currently set to <code>1000</code>.
    */
-  public static final int MIN_PAGE_SIZE = 1000;
+  public static final int MIN_SIZE = 1000;
 
   /**
-   * Default size of internal pages. Currently set to <code>500000</code>(2 MB).
+   * Default size of the heap. Currently set to <code>500000</code>(2 MB).
    */
-  public static final int DEFAULT_PAGE_SIZE = 500000; // 2 MB pages
+  public static final int DEFAULT_SIZE = 500000; // 2 MB pages
 
-  private int PAGE_SIZE;
+  // Initial size of the heap. This is also the size the heap will be reset to
+  // on a full reset.
+  private int initialSize;
 
   // The array that represents the actual heap is package private and
   // can be directly addressed by the LowLevelCAS.
   int[] heap;
 
-  // private int size;
-  private int tempPos;
-
-  private int tempMax;
-
-  private int permPos;
+  // Next free position on the heap.
+  private int pos;
 
-  private int permMax;
+  // End of heap. In the current implementation, this is the same as
+  // this.heap.length at all times.
+  private int max;
 
-  private SortedIntSet availablePages;
-
-  private SortedIntSet tempPages;
-
-  // Serialization constants.
+  // Serialization constants. There are holes in the numbering for historical
+  // reasons. Keep the holes for compatibility.
   private static final int SIZE_POS = 0;
 
   private static final int TMPP_POS = 1;
 
   private static final int TMPM_POS = 2;
 
-  private static final int PRMP_POS = 3;
-
-  private static final int PRMM_POS = 4;
-
   private static final int PGSZ_POS = 5;
 
   private static final int AVSZ_POS = 6;
@@ -94,33 +75,31 @@
    * Default constructor.
    */
   public Heap() {
-    this(DEFAULT_PAGE_SIZE);
+    this(DEFAULT_SIZE);
   }
 
   /**
-   * Constructor lets you set page size. Use only if you know what you're doing.
+   * Constructor lets you set initial heap size. Use only if you know what
+   * you're doing.
    * 
-   * @param pageSize
-   *          The page size. If this is smaller than the {@link #MIN_PAGE_SIZE MIN_PAGE_SIZE}, the
-   *          default will be used instead.
+   * @param initialSize
+   *                The initial heap size. If this is smaller than the
+   *                {@link #MIN_SIZE MIN_SIZE}, the default will be used
+   *                instead.
    */
-  public Heap(int pageSize) {
+  public Heap(int initialSize) {
     super();
-    if (pageSize < MIN_PAGE_SIZE) {
-      pageSize = MIN_PAGE_SIZE;
+    if (initialSize < MIN_SIZE) {
+      initialSize = MIN_SIZE;
     }
-    this.PAGE_SIZE = pageSize;
-    this.initHeap();
+    this.initialSize = initialSize;
+    initHeap();
   }
 
   private final void initHeap() {
-    this.heap = new int[0];
-    this.availablePages = new SortedIntSet();
-    this.tempPages = new SortedIntSet();
-    // System.out.println("Creating first temp page.");
-    newTempPage();
-    // System.out.println("Creating first perm page.");
-    // newPermPage();
+    this.heap = new int[this.initialSize];
+    this.pos = 1; // 0 is not a valid address
+    this.max = this.heap.length;
   }
 
   void reinit(int[] md, int[] shortHeap) {
@@ -131,296 +110,140 @@
     // assert(md != null);
     // assert(shortHeap != null);
     final int heapSize = md[SIZE_POS];
-    this.tempPos = md[TMPP_POS];
-    this.tempMax = md[TMPM_POS];
-    this.permPos = md[PRMP_POS];
-    this.permMax = md[PRMM_POS];
-    this.PAGE_SIZE = md[PGSZ_POS];
+    this.pos = md[TMPP_POS];
+    this.max = md[TMPM_POS];
+    this.initialSize = md[PGSZ_POS];
 
     // Copy the shortened version of the heap into a full version.
     this.heap = new int[heapSize];
     System.arraycopy(shortHeap, 0, this.heap, 0, shortHeap.length);
 
-    final int avMax = AVST_POS + md[AVSZ_POS];
-    this.availablePages = new SortedIntSet();
-    // assert(avMax <= md.length);
-    for (int i = AVST_POS; i < avMax; i++) {
-      this.availablePages.add(md[i]);
-    }
-    this.tempPages = new SortedIntSet();
-    for (int i = avMax; i < md.length; i++) {
-      this.tempPages.add(md[i]);
-    }
   }
 
   /**
-   * Re-init the heap without metadata (i.e., most likely from TAF). Note that we have no good way
-   * of determining page size. We just use the size of the incoming heap, unless it's smaller than
-   * our minimum. Something more sophisticated could be implemented, but let's see how we do with
-   * this simple strategy first.
+   * Re-init the heap without metadata. Use default values for metadata.
    * 
    * @param shortHeap
    */
   private void reinitNoMetaData(int[] shortHeap) {
-    this.PAGE_SIZE = (shortHeap.length < MIN_PAGE_SIZE) ? MIN_PAGE_SIZE : shortHeap.length;
-    this.availablePages = new SortedIntSet();
-    this.tempPages = new SortedIntSet();
-    if (shortHeap.length >= this.PAGE_SIZE) {
+    this.initialSize = (shortHeap.length < MIN_SIZE) ? MIN_SIZE : shortHeap.length;
+    if (shortHeap.length >= this.initialSize) {
       this.heap = shortHeap;
     } else {
       System.arraycopy(shortHeap, 0, this.heap, 0, shortHeap.length);
     }
-    this.tempPages.add(0);
-    // Add the rest of the heap as available pages.
-    int nextPageEnd = this.PAGE_SIZE * 2;
-    // int nextPageStart = PAGE_SIZE;
-    int pageNumber = 1;
-    while (nextPageEnd <= this.heap.length) {
-      this.availablePages.add(pageNumber);
-      // nextPageStart = nextPageEnd;
-      nextPageEnd += this.PAGE_SIZE;
-      ++pageNumber;
-    }
-    // Set the temp position and max.
-    this.tempPos = shortHeap.length;
-    // Current max is the size of the first page we created. The rest of the
-    // space is held in availablePages.
-    this.tempMax = this.PAGE_SIZE;
-    // Create perm page (never used in current implementation).
-    // WARNING: if we ever want to use a permanent heap, this needs to go
-    // back
-    // in.
-    // newPermPage();
+    // Set position and max.
+    this.pos = shortHeap.length;
+    this.max = this.initialSize;
   }
 
   /**
-   * Re-create the heap for the given size. Just use the size of the incoming heap, unless it's
-   * smaller than our minimum. It is expected that the caller will then fill in the new heap up to
-   * newSize.
+   * Re-create the heap for the given size. Just use the size of the incoming
+   * heap, unless it's smaller than our minimum. It is expected that the caller
+   * will then fill in the new heap up to newSize.
    * 
    * @param newSize
    */
   void reinitSizeOnly(int newSize) {
-    this.PAGE_SIZE = (newSize < MIN_PAGE_SIZE) ? MIN_PAGE_SIZE : newSize;
-    this.availablePages = new SortedIntSet();
-    this.tempPages = new SortedIntSet();
-    this.heap = new int[this.PAGE_SIZE];
-    this.tempPages.add(0);
-    // Add the rest of the heap as available pages.
-    int nextPageEnd = this.PAGE_SIZE * 2;
-    // int nextPageStart = PAGE_SIZE;
-    int pageNumber = 1;
-    while (nextPageEnd <= this.heap.length) {
-      this.availablePages.add(pageNumber);
-      // nextPageStart = nextPageEnd;
-      nextPageEnd += this.PAGE_SIZE;
-      ++pageNumber;
-    }
-    // Set the temp position and max.
-    this.tempPos = newSize;
-    // Current max is the size of the first page we created. The rest of the
-    // space is held in availablePages.
-    this.tempMax = this.PAGE_SIZE;
+    this.initialSize = (newSize < MIN_SIZE) ? MIN_SIZE : newSize;
+    this.heap = new int[this.initialSize];
+    // Set position and max.
+    this.pos = newSize;
+    this.max = this.initialSize;
+  }
+
+  /**
+   * Return the number of cells used.
+   */
+  int getCellsUsed() {
+    return this.pos;
   }
 
   /**
-   * Return the number of cells used, ignoring permanent structures.
+   * @return The overall size of the heap (including unused space).
    */
-  int getCurrentTempSize() {
-    // Since this is only for the purposes of the CASBean, and we know there
-    // are no permanent feature structures, just return tempPos.
-    return this.tempPos;
+  int getHeapSize() {
+    return this.heap.length;
   }
 
   int[] getMetaData() {
-    final int arSize = AVST_POS + this.availablePages.size() + this.tempPages.size();
+    final int arSize = AVST_POS;
     int[] ar = new int[arSize];
     ar[SIZE_POS] = this.heap.length;
-    ar[TMPP_POS] = this.tempPos;
-    ar[TMPM_POS] = this.tempMax;
-    ar[PRMP_POS] = this.permPos;
-    ar[PRMM_POS] = this.permMax;
-    ar[PGSZ_POS] = this.PAGE_SIZE;
-    final int availablePagesSize = this.availablePages.size();
+    ar[TMPP_POS] = this.pos;
+    ar[TMPM_POS] = this.max;
+    ar[PGSZ_POS] = this.initialSize;
+    final int availablePagesSize = 0;
     ar[AVSZ_POS] = availablePagesSize;
 
-    int[] pageData = this.availablePages.toArray();
-    for (int i = 0; i < pageData.length; i++) {
-      ar[i + AVST_POS] = pageData[i];
-    }
-    final int tmpOffset = AVST_POS + availablePagesSize;
-    pageData = this.tempPages.toArray();
-    for (int i = 0; i < pageData.length; i++) {
-      ar[i + tmpOffset] = pageData[i];
-    }
     return ar;
   }
 
-  private int newPage() {
+  // Grow the heap.
+  private void grow() {
     final int start = this.heap.length;
-    // This will grow the heap by by exactly one page.
-    this.heap = IntArrayUtils.ensure_size(this.heap, start + this.PAGE_SIZE, 2, this.PAGE_SIZE);
-    return start;
-  }
-
-  private void newTempPage() {
-    // First, check if we have an old page lying around.
-    if (this.availablePages.size() > 0) {
-      final int pageCode = this.availablePages.get(0);
-      this.availablePages.remove(pageCode);
-      this.tempPages.add(pageCode);
-      if (pageCode == 0) {
-        this.tempPos = 1;
-        this.tempMax = this.PAGE_SIZE;
-      }
-       else {
-      // this.tempPos = pageCode * this.PAGE_SIZE;
-         this.tempMax = this.tempPos + this.PAGE_SIZE;
-       }
-      return;
-    }
-    // Allocate a new page.
-    final int start = newPage();
-    // Do not use 0 as a valid address.
-    if (start == 0) {
-      this.tempPos = 1;
-    }
-    // else {
-    // this.tempPos = start;
-    // }
-    this.tempMax = start + this.PAGE_SIZE;
-    this.tempPages.add(start / this.PAGE_SIZE);
-  }
-
-  private void newPermPage() {
-    final int start = newPage();
-    this.permPos = start;
-    this.permMax = start + this.PAGE_SIZE;
+    // This will grow the heap by doubling its size if it's smaller than
+    // DEFAULT_SIZE, and by DEFAULT_SIZE if it's larger.
+    this.heap = IntArrayUtils.ensure_size(this.heap, start + this.initialSize, 2, DEFAULT_SIZE);
+    this.max = this.heap.length;
   }
 
   /**
    * Reset the temporary heap.
    */
-  public void resetTempHeap() {
-    this.resetTempHeap(false);
+  public void reset() {
+    this.reset(false);
   }
 
   /**
    * Reset the temporary heap.
    */
-  void resetTempHeap(boolean doFullReset) {
+  void reset(boolean doFullReset) {
     if (doFullReset) {
       this.initHeap();
     } else {
-      // Reset the temp areas of the heap to 0. Each page n starts at
-      // PAGE_SIZE*n.
-      int pageNum, pageStart, pageEnd;
-      for (int i = 0; i < this.tempPages.size(); i++) {
-        pageNum = this.tempPages.get(i);
-        pageStart = this.PAGE_SIZE * pageNum;
-        pageEnd = pageStart + this.PAGE_SIZE;
-        if ((pageStart <= this.tempPos) && (this.tempPos < pageEnd)) {
-          // If this page is the current page, it is not completely
-          // full
-          // and we
-          // only need to reset up to the point it's been filled.
-          pageEnd = this.tempPos;
-        }
-        Arrays.fill(this.heap, pageStart, pageEnd, 0);
-      }
-
-      // Could do this slightly more efficiently, but this way, it's
-      // clear what's going on.
-      this.availablePages.union(this.tempPages);
-      this.tempPages.removeAll();
-      newTempPage();
+      Arrays.fill(this.heap, 0, this.heap.length, 0);
+      this.pos = 1;
     }
   }
 
   /**
-   * Add a structure to the temporary heap.
+   * Add a structure to the heap.
    * 
    * @param fs
-   *          The input structure.
-   * @return The position where the structure was added, i.e., a pointer to the first element of the
-   *         structure.
-   */
-  public int addToTempHeap(int[] fs) {
-    while ((this.tempPos + fs.length) >= this.tempMax) {
-      newTempPage();
-    }
-    System.arraycopy(fs, 0, this.heap, this.tempPos, fs.length);
-    final int pos = this.tempPos;
-    this.tempPos += fs.length;
-    return pos;
-  }
-
-  /**
-   * Reserve space for <code>len</code> items on the temp heap and set the first item to
-   * <code>val</code>. The other items are set to <code>0</code>.
-   * 
-   * @param len
-   *          The length of the new structure.
-   * @param val
-   *          The value of the first cell in the new structure.
-   * @return The position where the structure was added, i.e., a pointer to the first element of the
-   *         structure.
-   */
-  public int addToTempHeap(int len, int val) {
-    while ((this.tempPos + len) >= this.tempMax) {
-      newTempPage();
-    }
-    final int pos = this.tempPos;
-    this.tempPos += len;
-    this.heap[pos] = val;
-    return pos;
-  }
-
-  /**
-   * Add a structure to the permanent heap.
-   * 
-   * @param fs
-   *          The input structure.
-   * @return The position where the structure was added, i.e., a pointer to the first element of the
-   *         structure.
-   */
-  public int addToHeap(int[] fs) {
-    if (fs.length > this.PAGE_SIZE) {
-      // Change this to an appropriate exception.
-      throw new ArrayIndexOutOfBoundsException();
-    }
-    if ((this.permPos + fs.length) >= this.permMax) {
-      newPermPage();
+   *                The input structure.
+   * @return The position where the structure was added, i.e., a pointer to the
+   *         first element of the structure.
+   */
+  public int add(int[] fs) {
+    while ((this.pos + fs.length) >= this.max) {
+      grow();
     }
-    System.arraycopy(fs, 0, this.heap, this.permPos, fs.length);
-    final int pos = this.permPos;
-    this.permPos += fs.length;
-    return pos;
+    System.arraycopy(fs, 0, this.heap, this.pos, fs.length);
+    final int pos1 = this.pos;
+    this.pos += fs.length;
+    return pos1;
   }
 
   /**
-   * Reserve space for <code>len</code> items on the heap and set the first item to
-   * <code>val</code>. The other items are set to <code>0</code>.
+   * Reserve space for <code>len</code> items on the heap and set the first
+   * item to <code>val</code>. The other items are set to <code>0</code>.
    * 
    * @param len
-   *          The length of the new structure.
+   *                The length of the new structure.
    * @param val
-   *          The value of the first cell in the new structure.
-   * @return The position where the structure was added, i.e., a pointer to the first element of the
-   *         structure.
-   */
-  public int addToHeap(int len, int val) {
-    if (len > this.PAGE_SIZE) {
-      // Change this to an appropriate exception.
-      throw new ArrayIndexOutOfBoundsException();
-    }
-    if ((this.permPos + len) >= this.permMax) {
-      newPermPage();
-    }
-    final int pos = this.permPos;
-    this.permPos += len;
-    this.heap[pos] = val;
-    return pos;
+   *                The value of the first cell in the new structure.
+   * @return The position where the structure was added, i.e., a pointer to the
+   *         first element of the structure.
+   */
+  public int add(int len, int val) {
+    while ((this.pos + len) >= this.max) {
+      grow();
+    }
+    final int pos1 = this.pos;
+    this.pos += len;
+    this.heap[pos1] = val;
+    return pos1;
   }
 
 }

Modified: incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/XCASSerializer.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/XCASSerializer.java?rev=576857&r1=576856&r2=576857&view=diff
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/XCASSerializer.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/XCASSerializer.java Tue Sep 18 04:55:50 2007
@@ -249,7 +249,7 @@
       enqueueFeaturesOfIndexed();
       if (outOfTypeSystemData != null) {
         // Queues out of type system data.
-        int nextId = cas.getHeap().getCurrentTempSize();
+        int nextId = cas.getHeap().getCellsUsed();
         Iterator it = outOfTypeSystemData.fsList.iterator();
         while (it.hasNext()) {
           FSData fs = (FSData) it.next();

Modified: incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/impl/CasResetResizeTest.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/impl/CasResetResizeTest.java?rev=576857&r1=576856&r2=576857&view=diff
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/impl/CasResetResizeTest.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/impl/CasResetResizeTest.java Tue Sep 18 04:55:50 2007
@@ -51,7 +51,7 @@
       // check default setting
       TextAnalysisEngine taeDefault = UIMAFramework.produceTAE(testDescriptor);
       CAS cas = taeDefault.newCAS();
-      int heapSize = ((CASImpl) cas).getHeap().getCurrentTempSize();
+      int heapSize = ((CASImpl) cas).getHeap().getHeapSize();
       int bufSize = ((CASImpl)cas).getHeap().heap.length;
       //System.out.println("Heap size: " + heapSize + ", buffer size: " + bufSize);       
       Assert.assertTrue(bufSize < CASImpl.DEFAULT_RESET_HEAP_SIZE);
@@ -63,7 +63,7 @@
         cas.createAnnotation(annotType, i, i);
       }
       
-      heapSize = ((CASImpl) cas).getHeap().getCurrentTempSize();
+      heapSize = ((CASImpl) cas).getHeap().getHeapSize();
       bufSize = ((CASImpl)cas).getHeap().heap.length;
       //System.out.println("Heap size: " + heapSize + ", buffer size: " + bufSize);      
       assertTrue(heapSize <= bufSize);
@@ -71,7 +71,7 @@
       
       //reset the CAS - it should shrink
       cas.reset();
-      heapSize = ((CASImpl) cas).getHeap().getCurrentTempSize();
+      heapSize = ((CASImpl) cas).getHeap().getHeapSize();
       bufSize = ((CASImpl)cas).getHeap().heap.length;
       //System.out.println("Heap size: " + heapSize + ", buffer size: " + bufSize);
       assertTrue(heapSize <= bufSize);
@@ -85,7 +85,7 @@
           cas.createAnnotation(annotType, i, i);
         }
         
-        heapSize = ((CASImpl) cas).getHeap().getCurrentTempSize();
+        heapSize = ((CASImpl) cas).getHeap().getHeapSize();
         bufSize = ((CASImpl)cas).getHeap().heap.length;
         //System.out.println("Heap size: " + heapSize + ", buffer size: " + bufSize);      
         assertTrue(heapSize <= bufSize);

Modified: incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/CASTest.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/CASTest.java?rev=576857&r1=576856&r2=576857&view=diff
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/CASTest.java (original)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/CASTest.java Tue Sep 18 04:55:50 2007
@@ -94,7 +94,7 @@
     final int arraySize = 1000000;
     // Make sure that the structure we're trying to create is actually larger
     // than the page size we're testing with.
-    assertTrue(arraySize > Heap.DEFAULT_PAGE_SIZE);
+    assertTrue(arraySize > Heap.DEFAULT_SIZE);
     IntArrayFS array = null;
     try {
       array = this.cas.createIntArrayFS(arraySize);

Added: incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/GrowingTheCasTest.java
URL: http://svn.apache.org/viewvc/incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/GrowingTheCasTest.java?rev=576857&view=auto
==============================================================================
--- incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/GrowingTheCasTest.java (added)
+++ incubator/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/GrowingTheCasTest.java Tue Sep 18 04:55:50 2007
@@ -0,0 +1,150 @@
+/*
+ * 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 org.apache.uima.cas.test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Properties;
+
+import junit.framework.TestCase;
+
+import org.apache.uima.UIMAFramework;
+import org.apache.uima.analysis_engine.AnalysisEngine;
+import org.apache.uima.analysis_engine.AnalysisEngineDescription;
+import org.apache.uima.analysis_engine.AnalysisEngineProcessException;
+import org.apache.uima.cas.CASException;
+import org.apache.uima.internal.util.TimeSpan;
+import org.apache.uima.jcas.JCas;
+import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.uima.test.junit_extension.JUnitExtension;
+import org.apache.uima.util.CasCreationUtils;
+import org.apache.uima.util.FileUtils;
+import org.apache.uima.util.InvalidXMLException;
+import org.apache.uima.util.XMLInputSource;
+import org.apache.uima.util.XMLParser;
+
+/**
+ * Class comment for IteratorTest.java goes here.
+ * 
+ */
+public class GrowingTheCasTest extends TestCase {
+
+  private AnalysisEngine ae = null;
+
+  private JCas smallHeapCas = null;
+
+  public GrowingTheCasTest(String arg0) {
+    super(arg0);
+  }
+
+  public void setUp() {
+    File descriptorFile = JUnitExtension.getFile("CASTests/desc/TokensAndSentences.xml");
+    assertTrue("Descriptor must exist: " + descriptorFile.getAbsolutePath(), descriptorFile
+	.exists());
+
+    try {
+      XMLParser parser = UIMAFramework.getXMLParser();
+      AnalysisEngineDescription spec = (AnalysisEngineDescription) parser.parse(new XMLInputSource(
+	  descriptorFile));
+      this.ae = UIMAFramework.produceAnalysisEngine(spec);
+      Properties props = new Properties();
+      props.setProperty(UIMAFramework.CAS_INITIAL_HEAP_SIZE, "0");
+      this.smallHeapCas = CasCreationUtils.createCas(spec, props).getJCas();
+    } catch (IOException e) {
+      e.printStackTrace();
+      assertTrue(false);
+    } catch (InvalidXMLException e) {
+      e.printStackTrace();
+      assertTrue(false);
+    } catch (ResourceInitializationException e) {
+      e.printStackTrace();
+      assertTrue(false);
+    } catch (CASException e) {
+      e.printStackTrace();
+      assertTrue(false);
+    }
+
+  }
+
+  public void tearDown() {
+    if (this.ae != null) {
+      this.ae.destroy();
+      this.ae = null;
+    }
+  }
+
+  public void testAnnotator() {
+    File textFile = JUnitExtension.getFile("data/moby.txt");
+    String text = null;
+    try {
+      text = FileUtils.file2String(textFile, "utf-8");
+    } catch (IOException e) {
+      e.printStackTrace();
+      assertTrue(false);
+    }
+    StringBuffer buf = new StringBuffer(text.length() * 10);
+    for (int i = 0; i < 10; i++) {
+      buf.append(text);
+    }
+    JCas jcas = null;
+    try {
+      jcas = this.ae.newJCas();
+    } catch (ResourceInitializationException e) {
+      e.printStackTrace();
+      assertTrue(false);
+    }
+    text = buf.toString();
+    jcas.setDocumentText(text);
+    int numberOfSentences = 0;
+    int numberOfTokens = 0;
+    try {
+//      long time = System.currentTimeMillis();
+      this.ae.process(jcas);
+//      time = System.currentTimeMillis() - time;
+//      System.out.println("Time for large CAS: " + new TimeSpan(time));
+      numberOfSentences = jcas.getAnnotationIndex(Sentence.type).size();
+      numberOfTokens = jcas.getAnnotationIndex(Token.type).size();
+//      System.out.println(numberOfSentences);
+//      System.out.println(numberOfTokens);
+    } catch (AnalysisEngineProcessException e) {
+      e.printStackTrace();
+      assertTrue(false);
+    }
+    this.smallHeapCas.setDocumentText(text);
+    try {
+//      long time = System.currentTimeMillis();
+      this.ae.process(this.smallHeapCas);
+//      time = System.currentTimeMillis() - time;
+//      System.out.println("Time for small CAS: " + new TimeSpan(time));
+      assertTrue(this.getClass().toString() + ": number of sentences does not match",
+	  numberOfSentences == this.smallHeapCas.getAnnotationIndex(Sentence.type).size());
+      assertTrue(this.getClass().toString() + ": number of tokens does not match",
+	  numberOfTokens == this.smallHeapCas.getAnnotationIndex(Token.type).size());
+    } catch (AnalysisEngineProcessException e) {
+      e.printStackTrace();
+      assertTrue(false);
+    }
+  }
+
+  public static void main(String[] args) {
+    junit.textui.TestRunner.run(GrowingTheCasTest.class);
+  }
+
+}