You are viewing a plain text version of this content. The canonical link for it is here.
Posted to derby-commits@db.apache.org by rh...@apache.org on 2011/06/22 14:37:15 UTC

svn commit: r1138434 - in /db/derby/code/trunk: java/engine/org/apache/derby/catalog/ java/engine/org/apache/derby/iapi/reference/ java/engine/org/apache/derby/impl/sql/catalog/ java/engine/org/apache/derby/loc/ java/shared/org/apache/derby/shared/comm...

Author: rhillegas
Date: Wed Jun 22 12:37:14 2011
New Revision: 1138434

URL: http://svn.apache.org/viewvc?rev=1138434&view=rev
Log:
DERBY-4437: Make the allocation of sequence/identity ranges pluggable.

Added:
    db/derby/code/trunk/java/engine/org/apache/derby/catalog/SequencePreallocator.java   (with props)
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SequenceRange.java   (with props)
Modified:
    db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Property.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SequenceGenerator.java
    db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SequenceUpdater.java
    db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
    db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
    db/derby/code/trunk/java/storeless/org/apache/derby/impl/storeless/EmptyDictionary.java
    db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SequenceGeneratorTest.java
    db/derby/code/trunk/tools/javadoc/publishedapi.ant

Added: db/derby/code/trunk/java/engine/org/apache/derby/catalog/SequencePreallocator.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/catalog/SequencePreallocator.java?rev=1138434&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/catalog/SequencePreallocator.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/catalog/SequencePreallocator.java Wed Jun 22 12:37:14 2011
@@ -0,0 +1,73 @@
+/*
+
+   Derby - Class org.apache.derby.catalog.SequencePreallocator
+
+   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.derby.catalog;
+
+import java.sql.SQLException;
+
+/**
+ * <p>
+ * Logic to determine how many values to pre-allocate for an identity column or sequence.
+ * By default, Derby boosts concurrency by pre-allocating ranges of numbers for identity columns and sequences.
+ * During orderly database shutdown, the unused numbers are reclaimed so that shutdown will
+ * not create holes in the sequences.  However, holes may appear if the application fails to shut
+ * down its databases before the JVM exits.
+ * </p>
+ *
+ * <p>
+ * Logic in this class is called every time Derby needs to pre-allocate a new range of identity/sequence
+ * values. Users can override Derby's default behavior by writing their own implementation of this
+ * interface and then setting the following Derby property:
+ * </p>
+ *
+ * <pre>
+ *  -Dderby.language.sequence.preallocator=com.acme.MySequencePreallocator
+ * </pre>
+ *
+ * <p>
+ * Classes which implement this interface must also provide a public 0-arg constructor so
+ * that Derby can instantiate them. Derby will instantiate a SequencePreallocator for each identity
+ * column and sequence.
+ * </p>
+ *
+ */
+public  interface   SequencePreallocator
+{
+    /**
+     * <p>
+     * This method returns the size of the next pre-allocated range for the specified
+     * identity column or sequence. Names are case-sensitive, as specified in CREATE SEQUENCE
+     * and CREATE TABLE statements.
+     * </p>
+     *
+     * @param schemaName Name of schema holding the sequence or identity-laden table.
+     * @param sequenceName Specific name of the sequence or identity-laden table.
+     */
+    public  int nextRangeSize
+        (
+         String schemaName,
+         String sequenceName
+         );
+    
+}
+
+
+

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/catalog/SequencePreallocator.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Property.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Property.java?rev=1138434&r1=1138433&r2=1138434&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Property.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/iapi/reference/Property.java Wed Jun 22 12:37:14 2011
@@ -636,6 +636,15 @@ public interface Property { 
 	int		LANG_IDGEN_CACHE_SIZE_DEFAULT =32;
 
 	/**
+	 * Name of the implementation of SequencePreallocator which is used
+     * to tune how many values Derby pre-allocates for identity columns
+     * and sequences. Database.  Static.
+	 * <p>
+	 * Externally visible.
+	 */
+	String	LANG_SEQUENCE_PREALLOCATOR = "derby.language.sequence.preallocator";
+    
+	/**
 	  derby.language.stalePlanCheckInterval
 
 	  <P>

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SequenceGenerator.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SequenceGenerator.java?rev=1138434&r1=1138433&r2=1138434&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SequenceGenerator.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SequenceGenerator.java Wed Jun 22 12:37:14 2011
@@ -20,6 +20,7 @@
  */
 package org.apache.derby.impl.sql.catalog;
 
+import org.apache.derby.catalog.SequencePreallocator;
 import org.apache.derby.iapi.error.StandardException;
 import org.apache.derby.iapi.reference.SQLState;
 import org.apache.derby.iapi.services.cache.Cacheable;
@@ -111,14 +112,6 @@ public class SequenceGenerator
     //
     ///////////////////////////////////////////////////////////////////////////////////
 
-    /**
-     * Default number of values to pre-allocate. In the future, we may want to provide
-     * something more sophisticated. For instance, we might want to make Derby tune
-     * this number per sequence generator or give the user the power to override Derby's
-     * decision.
-     */
-    public static final int DEFAULT_PREALLOCATION_COUNT = 5;
-
     /** If pre-allocation drops below this level, then we need to grab another chunk of numbers */
     private static final int PREALLOCATION_THRESHHOLD = 1;
 
@@ -168,9 +161,15 @@ public class SequenceGenerator
     // This is where we restart the sequence if we wrap around.
     private final long _RESTART_VALUE;
 
-    // Name of the sequence (for error messages).
+    // Name of the schema that the sequence lives in.
+    private final String _SCHEMA_NAME;
+
+    // Name of the sequence.
     private final String _SEQUENCE_NAME;
 
+    // Logic to determine how many values to pre-allocate
+    private final   SequencePreallocator    _PREALLOCATOR;
+
     ///////////////////////////////////////////////////////////////////////////////////
     //
     // VARIABLES
@@ -183,12 +182,6 @@ public class SequenceGenerator
     // This is the next value which the generator will hand out.
     private long _currentValue;
 
-    // This is the number of values to pre-allocate per chunk. Right now this
-    // is a constant which we figure out when we initialize the generator.
-    // However, this number could change over time if, for instance, Derby
-    // tunes it on the fly.
-    private long _valuesPerAllocation;
-    
     // This is the remaining number of values which were pre-allocated on disk
     // by bumping the contents of SYSSEQUENCES.CURRENTVALUE.
     private long _remainingPreallocatedValues;
@@ -209,7 +202,9 @@ public class SequenceGenerator
          long maxValue,
          long minValue,
          long restartValue,
-         String sequenceName
+         String schemaName,
+         String sequenceName,
+         SequencePreallocator   sequencePreallocator
          )
     {
         if ( currentValue == null )
@@ -229,14 +224,14 @@ public class SequenceGenerator
         _MIN_VALUE = minValue;
         _RESTART_VALUE = restartValue;
         _STEP_INCREASES = ( _INCREMENT > 0 );
+        _SCHEMA_NAME = schemaName;
         _SEQUENCE_NAME = sequenceName;
+        _PREALLOCATOR = sequencePreallocator;
 
         //
         // Next call to getCurrentValueAndAdvance() will cause  us to ask our caller to allocate a new range of values.
         //
         _remainingPreallocatedValues = 1L;
-
-        _valuesPerAllocation = computePreAllocationCount();
     }
     
     ///////////////////////////////////////////////////////////////////////////////////
@@ -247,6 +242,15 @@ public class SequenceGenerator
 
     /**
      * <p>
+     * Get the name of the schema of this sequence generator. Technically, this doesn't need to be
+     * synchronized. But it is simpler to just maintain a rule that all public methods
+     * should be synchronized.
+     * </p>
+     */
+    public synchronized String getSchemaName() { return _SCHEMA_NAME; }
+    
+    /**
+     * <p>
      * Get the name of this sequence generator. Technically, this doesn't need to be
      * synchronized. But it is simpler to just maintain a rule that all public methods
      * should be synchronized.
@@ -299,7 +303,7 @@ public class SequenceGenerator
         if ( _isExhausted )
         {
             throw StandardException.newException
-                ( SQLState.LANG_SEQUENCE_GENERATOR_EXHAUSTED, _SEQUENCE_NAME );
+                ( SQLState.LANG_SEQUENCE_GENERATOR_EXHAUSTED, _SCHEMA_NAME, _SEQUENCE_NAME );
         }
 
         long retval[] = new long[ CVAA_LENGTH ];
@@ -403,6 +407,8 @@ public class SequenceGenerator
      */
     private void computeNewAllocation( long oldCurrentValue, long[] retval ) throws StandardException
     {
+        int preferredValuesPerAllocation = computePreAllocationCount();
+        
         //
         // The values are growing toward one of the endpoints of the legal range,
         // either the largest legal value or the smallest legal value. First find out
@@ -414,10 +420,10 @@ public class SequenceGenerator
         long newValueOnDisk;
         long valuesToAllocate;
 
-        if ( remainingLegalValues >= _valuesPerAllocation )
+        if ( remainingLegalValues >= preferredValuesPerAllocation )
         {
-            newValueOnDisk = oldCurrentValue + ( _valuesPerAllocation * _INCREMENT );
-            valuesToAllocate = _valuesPerAllocation;
+            newValueOnDisk = oldCurrentValue + ( preferredValuesPerAllocation * _INCREMENT );
+            valuesToAllocate = preferredValuesPerAllocation;
         }
         else
         {
@@ -425,13 +431,13 @@ public class SequenceGenerator
 
             if ( _CAN_CYCLE )
             {
-                long spillOverValues = _valuesPerAllocation - remainingLegalValues;
+                long spillOverValues = preferredValuesPerAllocation - remainingLegalValues;
 
                 // account for the fact that the restart value itself is a legal value
                 spillOverValues--;
 
                 newValueOnDisk = _RESTART_VALUE + ( spillOverValues * _INCREMENT );
-                valuesToAllocate = _valuesPerAllocation;
+                valuesToAllocate = preferredValuesPerAllocation;
             }
             else
             {
@@ -490,9 +496,11 @@ public class SequenceGenerator
      */
     private int computePreAllocationCount()
     {
-        int happyResult = DEFAULT_PREALLOCATION_COUNT;
+        int happyResult = _PREALLOCATOR.nextRangeSize(  _SCHEMA_NAME, _SEQUENCE_NAME );
         int unhappyResult = PREALLOCATION_THRESHHOLD;
 
+        if ( happyResult < unhappyResult ) { return unhappyResult; }
+
         double min = _MIN_VALUE;
         double max = _MAX_VALUE;
         double range = max - min;

Added: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SequenceRange.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SequenceRange.java?rev=1138434&view=auto
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SequenceRange.java (added)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SequenceRange.java Wed Jun 22 12:37:14 2011
@@ -0,0 +1,79 @@
+/*
+
+   Derby - Class org.apache.derby.impl.sql.catalog.SequenceRange
+
+   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.derby.impl.sql.catalog;
+
+import org.apache.derby.catalog.SequencePreallocator;
+
+/**
+ * <p>
+ * Default Derby logic for determining how many values to pre-allocate for an
+ * identity column or sequence.
+ * </p>
+ */
+public  class   SequenceRange   implements  SequencePreallocator
+{
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTANTS
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    /**
+     * Default number of values to pre-allocate. In the future, we may want to provide
+     * something more sophisticated. For instance, we might want to make Derby tune
+     * this number per sequence generator or give the user the power to override Derby's
+     * decision.
+     */
+    private static final int DEFAULT_PREALLOCATION_COUNT = 5;
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // STATE
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // CONSTRUCTOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    /** <p>0-arg constructore needed to satisfy the SequencePreallocator contract.</p> */
+    public  SequenceRange() {}
+
+    ///////////////////////////////////////////////////////////////////////////////////
+    //
+    // SequencePreallocator BEHAVIOR
+    //
+    ///////////////////////////////////////////////////////////////////////////////////
+
+    public  int nextRangeSize
+        (
+         String schemaName,
+         String sequenceName
+         )
+    {
+        return DEFAULT_PREALLOCATION_COUNT;
+    }
+
+
+}

Propchange: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SequenceRange.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SequenceUpdater.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SequenceUpdater.java?rev=1138434&r1=1138433&r2=1138434&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SequenceUpdater.java (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/impl/sql/catalog/SequenceUpdater.java Wed Jun 22 12:37:14 2011
@@ -20,13 +20,16 @@
  */
 package org.apache.derby.impl.sql.catalog;
 
+import org.apache.derby.catalog.SequencePreallocator;
 import org.apache.derby.iapi.db.Database;
 import org.apache.derby.iapi.error.StandardException;
+import org.apache.derby.iapi.reference.Property;
 import org.apache.derby.iapi.reference.SQLState;
 import org.apache.derby.iapi.services.cache.Cacheable;
 import org.apache.derby.iapi.services.cache.CacheManager;
 import org.apache.derby.iapi.services.context.ContextManager;
 import org.apache.derby.iapi.services.context.ContextService;
+import org.apache.derby.iapi.services.property.PropertyUtil;
 import org.apache.derby.iapi.services.sanity.SanityManager;
 import org.apache.derby.iapi.sql.conn.LanguageConnectionContext;
 import org.apache.derby.iapi.sql.dictionary.SequenceDescriptor;
@@ -434,6 +437,28 @@ public abstract class SequenceUpdater im
     //
     ///////////////////////////////////////////////////////////////////////////////////
 
+    /** Make a new range allocator (called when the generator is instantiated) */
+    protected SequencePreallocator  makePreallocator( TransactionController tc )
+        throws StandardException
+    {
+        String  propertyName = Property.LANG_SEQUENCE_PREALLOCATOR;
+        String  className = PropertyUtil.getServiceProperty( tc, propertyName );
+
+        if ( className == null ) { return new SequenceRange(); }
+
+        try {
+            return (SequencePreallocator) Class.forName( className ).newInstance();
+        }
+        catch (ClassNotFoundException e) { throw missingAllocator( propertyName, className, e ); }
+        catch (ClassCastException e) { throw missingAllocator( propertyName, className, e ); }
+        catch (InstantiationException e) { throw missingAllocator( propertyName, className, e ); }
+        catch (IllegalAccessException e) { throw missingAllocator( propertyName, className, e ); }
+    }
+    private StandardException   missingAllocator( String propertyName, String className, Exception e )
+    {
+        return StandardException.newException( SQLState.LANG_UNKNOWN_SEQUENCE_PREALLOCATOR, e, propertyName, className );
+    }
+    
     /** Get the time we wait for a lock, in milliseconds--overridden by unit tests */
     protected int getLockTimeout()
     {
@@ -495,7 +520,9 @@ public abstract class SequenceUpdater im
                  isd.getMaximumValue(),
                  isd.getMinimumValue(),
                  isd.getStartValue(),
-                 isd.getSequenceName()
+                 isd.getSchemaDescriptor().getSchemaName(),
+                 isd.getSequenceName(),
+                 makePreallocator( readOnlyTC )
                  );
         }
 
@@ -542,7 +569,9 @@ public abstract class SequenceUpdater im
                  isd.getMaximumValue(),
                  isd.getMinimumValue(),
                  isd.getStartValue(),
-                 isd.getSequenceName()
+                 isd.getSchemaDescriptor().getSchemaName(),
+                 isd.getSequenceName(),
+                 makePreallocator( readOnlyTC )
                  );
         }
 

Modified: db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml?rev=1138434&r1=1138433&r2=1138434&view=diff
==============================================================================
--- db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml (original)
+++ db/derby/code/trunk/java/engine/org/apache/derby/loc/messages.xml Wed Jun 22 12:37:14 2011
@@ -680,7 +680,8 @@ Guide.
 
             <msg>
                 <name>2200H.S</name>
-                <text>Sequence generator '{0}' does not cycle. No more values can be obtained from this sequence generator.</text>
+                <text>Sequence generator '{0}.{1}' does not cycle. No more values can be obtained from this sequence generator.</text>
+                <arg>schemaName</arg>
                 <arg>sequenceName</arg>
             </msg>
 
@@ -3439,6 +3440,13 @@ Guide.
                 <arg>sequenceName</arg>
             </msg>
 
+            <msg>
+                <name>X0Y85.S</name>
+                <text>The Derby property '{0}' identifies a class which cannot be instantiated: '{1}'. See the next exception for details.</text>
+                <arg>propertyName</arg>
+                <arg>className</arg>
+            </msg>
+
         </family>
 
 

Modified: db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java?rev=1138434&r1=1138433&r2=1138434&view=diff
==============================================================================
--- db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java (original)
+++ db/derby/code/trunk/java/shared/org/apache/derby/shared/common/reference/SQLState.java Wed Jun 22 12:37:14 2011
@@ -719,8 +719,8 @@ public interface SQLState {
 	String LANG_INVALID_TRIM_SET                                       = "22027";
     String LANG_STRING_TOO_LONG                                        = "22028";
 	String LANG_ESCAPE_IS_NULL                                  	   = "22501";
-	String LANG_INVALID_ROW_COUNT_OFFSET                               = "2201X";
 	String LANG_INVALID_ROW_COUNT_FIRST                                = "2201W";
+	String LANG_INVALID_ROW_COUNT_OFFSET                               = "2201X";
 	String LANG_ROW_COUNT_OFFSET_FIRST_IS_NULL                         = "2201Z";
 
 	/*
@@ -1369,6 +1369,7 @@ public interface SQLState {
 	String LANG_NULL_DATA_IN_NON_NULL_COLUMN               	   	   	   = "X0Y80.S";
     String LANG_IGNORE_MISSING_INDEX_ROW_DURING_DELETE                 = "X0Y83.S";
     String LANG_TOO_MUCH_CONTENTION_ON_SEQUENCE                 = "X0Y84.S";
+	String LANG_UNKNOWN_SEQUENCE_PREALLOCATOR                                = "X0Y85.S";
 
 
 	// TEMPORARY EXECUTION RESTRICTIONS

Modified: db/derby/code/trunk/java/storeless/org/apache/derby/impl/storeless/EmptyDictionary.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/storeless/org/apache/derby/impl/storeless/EmptyDictionary.java?rev=1138434&r1=1138433&r2=1138434&view=diff
==============================================================================
--- db/derby/code/trunk/java/storeless/org/apache/derby/impl/storeless/EmptyDictionary.java (original)
+++ db/derby/code/trunk/java/storeless/org/apache/derby/impl/storeless/EmptyDictionary.java Wed Jun 22 12:37:14 2011
@@ -1,6 +1,6 @@
 /*
 
-   Derby - Class org.apache.impl.storeless.EmptyDictionary
+   Derby - Class org.apache.derby.impl.storeless.EmptyDictionary
 
    Licensed to the Apache Software Foundation (ASF) under one or more
    contributor license agreements.  See the NOTICE file distributed with

Modified: db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SequenceGeneratorTest.java
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SequenceGeneratorTest.java?rev=1138434&r1=1138433&r2=1138434&view=diff
==============================================================================
--- db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SequenceGeneratorTest.java (original)
+++ db/derby/code/trunk/java/testing/org/apache/derbyTesting/functionTests/tests/lang/SequenceGeneratorTest.java Wed Jun 22 12:37:14 2011
@@ -41,7 +41,9 @@ import org.apache.derbyTesting.junit.Cle
 import org.apache.derbyTesting.junit.JDBC;
 
 import org.apache.derby.impl.sql.catalog.SequenceGenerator;
+import org.apache.derby.impl.sql.catalog.SequenceRange;
 import org.apache.derby.impl.sql.catalog.SequenceUpdater;
+import org.apache.derby.catalog.SequencePreallocator;
 import org.apache.derby.iapi.types.SQLLongint;
 import org.apache.derby.iapi.store.access.TransactionController;
 
@@ -60,12 +62,15 @@ public class SequenceGeneratorTest  exte
 
     // number of pre-allocated values in a sequence generator
     private static final long ALLOCATION_COUNT = 5L;
+    private static final int TWEAKED_ALLOCATION_COUNT = 7;
 
     private static  final   String      TEST_DBO = "TEST_DBO";
     private static  final   String      RUTH = "RUTH";
     private static  final   String      ALICE = "ALICE";
     private static  final   String[]    LEGAL_USERS = { TEST_DBO, ALICE, RUTH  };
 
+    private static  final   String      MISSING_ALLOCATOR = "X0Y85";
+
     ///////////////////////////////////////////////////////////////////////////////////
     //
     // STATE
@@ -536,6 +541,49 @@ public class SequenceGeneratorTest  exte
         expectCompilationError( OBJECT_DOES_NOT_EXIST, "values ( next value for seq_07 )\n" );
     }
     
+    /**
+     * <p>
+     * Test user-written range allocators.
+     * </p>
+     */
+    public void test_08_userWrittenAllocators() throws Exception
+    {
+        Connection  conn = openUserConnection( TEST_DBO );
+        String  className;
+
+        goodStatement( conn, "create sequence seq_08\n" );
+
+        className = getClass().getName() + "$" + "UnknownClass";
+        goodStatement
+            (
+             conn,
+             "call syscs_util.syscs_set_database_property( 'derby.language.sequence.preallocator', '" + className + "')"
+             );
+        expectExecutionError( conn, MISSING_ALLOCATOR, "values ( next value for seq_08 )" );
+
+        className = getClass().getName() + "$" + "BadAllocator";
+        goodStatement
+            (
+             conn,
+             "call syscs_util.syscs_set_database_property( 'derby.language.sequence.preallocator', '" + className + "')"
+             );
+        expectExecutionError( conn, MISSING_ALLOCATOR, "values ( next value for seq_08 )" );
+
+        className = getClass().getName() + "$" + "LegalAllocator";
+        goodStatement
+            (
+             conn,
+             "call syscs_util.syscs_set_database_property( 'derby.language.sequence.preallocator', '" + className + "')"
+             );
+        vetBumping( conn, TEST_DBO, "SEQ_08", Integer.MIN_VALUE, Integer.MIN_VALUE + TWEAKED_ALLOCATION_COUNT );
+
+        goodStatement
+            (
+             conn,
+             "call syscs_util.syscs_set_database_property( 'derby.language.sequence.preallocator', null )"
+             );
+    }
+        
     ///////////////////////////////////////////////////////////////////////////////////
     //
     // MINIONS
@@ -589,7 +637,7 @@ public class SequenceGeneratorTest  exte
 
     ///////////////////////////////////////////////////////////////////////////////////
     //
-    // INNER CLASSES
+    // NESTED CLASSES
     //
     ///////////////////////////////////////////////////////////////////////////////////
 
@@ -622,7 +670,9 @@ public class SequenceGeneratorTest  exte
                  maxValue,
                  minValue,
                  restartValue,
-                 "DUMMY_SEQUENCE"
+                 "DUMMY_SCHEMA",
+                 "DUMMY_SEQUENCE",
+                 new SequenceRange()
                  );
         }
         
@@ -658,5 +708,16 @@ public class SequenceGeneratorTest  exte
     
     }
 
+    // Illegal preallocator, which does not implement the correct interface
+    public  static  final   class   BadAllocator {}
+
+    // Legal preallocator, which preallocates a fixed size range
+    public  static final   class   LegalAllocator  implements  SequencePreallocator
+    {
+        public  LegalAllocator() {}
+        
+        public  int nextRangeSize( String s, String n ) { return TWEAKED_ALLOCATION_COUNT; }
+    }
+
 }
 

Modified: db/derby/code/trunk/tools/javadoc/publishedapi.ant
URL: http://svn.apache.org/viewvc/db/derby/code/trunk/tools/javadoc/publishedapi.ant?rev=1138434&r1=1138433&r2=1138434&view=diff
==============================================================================
--- db/derby/code/trunk/tools/javadoc/publishedapi.ant (original)
+++ db/derby/code/trunk/tools/javadoc/publishedapi.ant Wed Jun 22 12:37:14 2011
@@ -31,6 +31,10 @@
 
 org/apache/derby/authentication/UserAuthenticator.java
 
+# package: org.apache.derby.catalog
+
+org/apache/derby/catalog/SequencePreallocator.java
+
 # package: org.apache.derby.drda
 
 org/apache/derby/drda/NetServlet.java