db-derby-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kahat...@apache.org
Subject svn commit: r760422 - /db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/NodeAllocator.java
Date Tue, 31 Mar 2009 12:49:23 GMT
Author: kahatlen
Date: Tue Mar 31 12:49:16 2009
New Revision: 760422

URL: http://svn.apache.org/viewvc?rev=760422&view=rev
Log:
DERBY-4119: Compress on a large table fails with IllegalArgumentException - Illegal Capacity

Use long arithmetic to prevent overflow in intermediate results when
increasing the capacity of NodeAllocator. Also make sure that the Node
array does not exceed maxSize, and allow the sort to continue even if
a larger array cannot be allocated.

Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/NodeAllocator.java

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/NodeAllocator.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/NodeAllocator.java?rev=760422&r1=760421&r2=760422&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/NodeAllocator.java
(original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/store/access/sort/NodeAllocator.java
Tue Mar 31 12:49:16 2009
@@ -75,12 +75,29 @@
 			if (array.length >= maxSize)
 				return null;
 
+            // Calculate the new length. The new array should be no longer
+            // than maxSize. Use a long for the intermediate result to prevent
+            // newLength from going negative due to integer overflow when
+            // array.length is close to Integer.MAX_VALUE.
+            int newLength = (int) Math.min(
+                    (long) array.length * GROWTH_MULTIPLIER,
+                    (long) maxSize);
+
 			// Attempt to allocate a new array.  If the allocation
 			// fails, tell the caller that there are no more
-			// nodes available.
-			Node[] newArray = new Node[array.length * GROWTH_MULTIPLIER];
-			if (newArray == null)
-				return null;
+            // nodes available. The allocation may fail if there's
+            // not enough memory to allocate a new array, or if the
+            // JVM doesn't support that big arrays (some JVMs have
+            // a limit on the array length that is different from
+            // Integer.MAX_VALUE --- DERBY-4119).
+            Node[] newArray;
+            try {
+                newArray = new Node[newLength];
+            } catch (OutOfMemoryError oome) {
+                // Could not allocate a larger array, so tell the caller that
+                // there are no nodes available.
+                return null;
+            }
 
 			// The new array was successfully allocated.  Copy the
 			// nodes from the original array into it, and make the
@@ -152,8 +169,14 @@
 	**/
 	public void grow(int percent)
 	{
-		if (percent > 0)		// cannot shrink
-			maxSize = maxSize * (100+percent)/100;
+        if (percent > 0) { // cannot shrink
+            // Calculate the new maximum size. Use long arithmetic so that
+            // intermediate results don't overflow and make maxSize go
+            // negative (DERBY-4119).
+            maxSize = (int) Math.min(
+                    (long) maxSize * (100 + percent) / 100,
+                    (long) Integer.MAX_VALUE);
+        }
 	}
 
 	/**



Mime
View raw message