From 8809341248c62b15b78d7e6d8e06ab2ec3793c8e Mon Sep 17 00:00:00 2001 From: "Brian S. O'Neill" Date: Wed, 28 Mar 2007 22:00:24 +0000 Subject: Merged 1.2-dev to trunk. --- .../sequence/AbstractSequenceValueProducer.java | 79 +++++ .../carbonado/sequence/SequenceCapability.java | 38 +++ .../carbonado/sequence/SequenceValueGenerator.java | 321 +++++++++++++++++++++ .../carbonado/sequence/SequenceValueProducer.java | 103 +++++++ .../sequence/SequenceValueProducerPool.java | 77 +++++ .../amazon/carbonado/sequence/StoredSequence.java | 70 +++++ .../amazon/carbonado/sequence/package-info.java | 26 ++ 7 files changed, 714 insertions(+) create mode 100644 src/main/java/com/amazon/carbonado/sequence/AbstractSequenceValueProducer.java create mode 100644 src/main/java/com/amazon/carbonado/sequence/SequenceCapability.java create mode 100644 src/main/java/com/amazon/carbonado/sequence/SequenceValueGenerator.java create mode 100644 src/main/java/com/amazon/carbonado/sequence/SequenceValueProducer.java create mode 100644 src/main/java/com/amazon/carbonado/sequence/SequenceValueProducerPool.java create mode 100644 src/main/java/com/amazon/carbonado/sequence/StoredSequence.java create mode 100644 src/main/java/com/amazon/carbonado/sequence/package-info.java (limited to 'src/main/java/com/amazon/carbonado/sequence') diff --git a/src/main/java/com/amazon/carbonado/sequence/AbstractSequenceValueProducer.java b/src/main/java/com/amazon/carbonado/sequence/AbstractSequenceValueProducer.java new file mode 100644 index 0000000..8deb3d7 --- /dev/null +++ b/src/main/java/com/amazon/carbonado/sequence/AbstractSequenceValueProducer.java @@ -0,0 +1,79 @@ +/* + * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * Licensed 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 com.amazon.carbonado.sequence; + +import java.math.BigInteger; + +import com.amazon.carbonado.PersistException; + +/** + * + * + * @author Brian S O'Neill + */ +public abstract class AbstractSequenceValueProducer implements SequenceValueProducer { + protected AbstractSequenceValueProducer() { + } + + public int nextIntValue() throws PersistException { + return (int) nextLongValue(); + } + + public String nextDecimalValue() throws PersistException { + return nextNumericalValue(10, 0); + } + + public String nextNumericalValue(int radix, int minLength) throws PersistException { + long next = nextLongValue(); + String str; + + if (next >= 0) { + str = Long.toString(next, radix); + } else { + // Use BigInteger to print negative values as positive by expanding + // precision to 72 bits + + byte[] bytes = new byte[9]; + bytes[8] = (byte) (next & 0xff); + bytes[7] = (byte) ((next >>= 8) & 0xff); + bytes[6] = (byte) ((next >>= 8) & 0xff); + bytes[5] = (byte) ((next >>= 8) & 0xff); + bytes[4] = (byte) ((next >>= 8) & 0xff); + bytes[3] = (byte) ((next >>= 8) & 0xff); + bytes[2] = (byte) ((next >>= 8) & 0xff); + bytes[1] = (byte) ((next >>= 8) & 0xff); + //bytes[0] = 0; + + str = new BigInteger(bytes).toString(radix); + } + + int pad = minLength - str.length(); + + if (pad > 0) { + StringBuilder b = new StringBuilder(minLength); + while (--pad >= 0) { + b.append('0'); + } + b.append(str); + str = b.toString(); + } + + return str; + } +} diff --git a/src/main/java/com/amazon/carbonado/sequence/SequenceCapability.java b/src/main/java/com/amazon/carbonado/sequence/SequenceCapability.java new file mode 100644 index 0000000..0e26eec --- /dev/null +++ b/src/main/java/com/amazon/carbonado/sequence/SequenceCapability.java @@ -0,0 +1,38 @@ +/* + * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * Licensed 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 com.amazon.carbonado.sequence; + +import com.amazon.carbonado.RepositoryException; +import com.amazon.carbonado.capability.Capability; + +/** + * Capability to use sequences. + * + * @author bcastill + * + */ +public interface SequenceCapability extends Capability { + + /** + * Retrieve and/or generate a SequenceValueProducer for the given name. + * + * @param name sequence name + */ + SequenceValueProducer getSequenceValueProducer(String name) throws RepositoryException; +} diff --git a/src/main/java/com/amazon/carbonado/sequence/SequenceValueGenerator.java b/src/main/java/com/amazon/carbonado/sequence/SequenceValueGenerator.java new file mode 100644 index 0000000..1371a32 --- /dev/null +++ b/src/main/java/com/amazon/carbonado/sequence/SequenceValueGenerator.java @@ -0,0 +1,321 @@ +/* + * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * Licensed 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 com.amazon.carbonado.sequence; + +import com.amazon.carbonado.FetchException; +import com.amazon.carbonado.PersistException; +import com.amazon.carbonado.Repository; +import com.amazon.carbonado.RepositoryException; +import com.amazon.carbonado.Storage; +import com.amazon.carbonado.Transaction; + +/** + * General purpose implementation of a sequence value generator. + * + * @author Brian S O'Neill + * @author bcastill + * @see com.amazon.carbonado.Sequence + * @see StoredSequence + */ +public class SequenceValueGenerator extends AbstractSequenceValueProducer { + public static final int DEFAULT_RESERVE_AMOUNT = 100; + public static final int DEFAULT_INITIAL_VALUE = 1; + public static final int DEFAULT_INCREMENT = 1; + + private final Repository mRepository; + private final Storage mStorage; + private final StoredSequence mStoredSequence; + private final int mIncrement; + private final int mReserveAmount; + + private boolean mHasReservedValues; + private long mNextValue; + + /** + * Construct a new SequenceValueGenerator which might create persistent + * sequence data if it does not exist. The initial sequence value is one, + * and the increment is one. + * + * @param repo repository to persist sequence data + * @param name name of sequence + */ + public SequenceValueGenerator(Repository repo, String name) + throws RepositoryException + { + this(repo, name, DEFAULT_INITIAL_VALUE, DEFAULT_INCREMENT); + } + + /** + * Construct a new SequenceValueGenerator which might create persistent + * sequence data if it does not exist. + * + * @param repo repository to persist sequence data + * @param name name of sequence + * @param initialValue initial sequence value, if sequence needs to be created + * @param increment amount to increment sequence by + */ + public SequenceValueGenerator(Repository repo, String name, long initialValue, int increment) + throws RepositoryException + { + this(repo, name, initialValue, increment, DEFAULT_RESERVE_AMOUNT); + } + + /** + * Construct a new SequenceValueGenerator which might create persistent + * sequence data if it does not exist. + * + * @param repo repository to persist sequence data + * @param name name of sequence + * @param initialValue initial sequence value, if sequence needs to be created + * @param increment amount to increment sequence by + * @param reserveAmount amount of sequence values to reserve + */ + public SequenceValueGenerator(Repository repo, String name, + long initialValue, int increment, int reserveAmount) + throws RepositoryException + { + if (repo == null || name == null || increment < 1 || reserveAmount < 1) { + throw new IllegalArgumentException(); + } + + mRepository = repo; + + mIncrement = increment; + mReserveAmount = reserveAmount; + + mStorage = repo.storageFor(StoredSequence.class); + + mStoredSequence = mStorage.prepare(); + mStoredSequence.setName(name); + + Transaction txn = repo.enterTopTransaction(null); + txn.setForUpdate(true); + try { + if (!mStoredSequence.tryLoad()) { + // Create a new sequence. + + mStoredSequence.setInitialValue(initialValue); + // Start as small as possible to allow signed long comparisons to work. + mStoredSequence.setNextValue(Long.MIN_VALUE); + + // Try to transfer values from a deprecated sequence. + com.amazon.carbonado.spi.StoredSequence oldSequence; + try { + oldSequence = repo + .storageFor(com.amazon.carbonado.spi.StoredSequence.class).prepare(); + oldSequence.setName(name); + if (oldSequence.tryLoad()) { + mStoredSequence.setInitialValue(oldSequence.getInitialValue()); + mStoredSequence.setNextValue(oldSequence.getNextValue()); + } else { + oldSequence = null; + } + } catch (RepositoryException e) { + // Okay, perhaps no old sequence. + oldSequence = null; + } + + if (mStoredSequence.tryInsert()) { + if (oldSequence != null) { + try { + // Get rid of deprecated sequence. + oldSequence.tryDelete(); + } catch (RepositoryException e) { + // Oh well. + } + } + } else { + // A race condition likely. Load again. + mStoredSequence.load(); + } + } + txn.commit(); + } finally { + txn.exit(); + } + } + + /** + * Reset the sequence. + * + * @param initialValue first value produced by sequence + */ + public void reset(int initialValue) throws FetchException, PersistException { + synchronized (mStoredSequence) { + Transaction txn = mRepository.enterTopTransaction(null); + txn.setForUpdate(true); + try { + boolean doUpdate = mStoredSequence.tryLoad(); + mStoredSequence.setInitialValue(initialValue); + // Start as small as possible to allow signed long comparisons to work. + mStoredSequence.setNextValue(Long.MIN_VALUE); + if (doUpdate) { + mStoredSequence.update(); + } else { + mStoredSequence.insert(); + } + txn.commit(); + mHasReservedValues = false; + } finally { + txn.exit(); + } + } + } + + /** + * Returns the next value from the sequence, which may wrap negative if all + * positive values are exhausted. When sequence wraps back to initial + * value, the sequence is fully exhausted, and an exception is thrown to + * indicate this. + * + *

Note: this method throws PersistException even for fetch failures + * since this method is called by insert operations. Insert operations can + * only throw a PersistException. + * + * @throws PersistException for fetch/persist failure or if sequence is exhausted. + */ + public long nextLongValue() throws PersistException { + try { + synchronized (mStoredSequence) { + return nextUnadjustedValue() + Long.MIN_VALUE + mStoredSequence.getInitialValue(); + } + } catch (FetchException e) { + throw e.toPersistException(); + } + } + + /** + * Returns the next value from the sequence, which may wrap negative if all + * positive values are exhausted. When sequence wraps back to initial + * value, the sequence is fully exhausted, and an exception is thrown to + * indicate this. + * + *

Note: this method throws PersistException even for fetch failures + * since this method is called by insert operations. Insert operations can + * only throw a PersistException. + * + * @throws PersistException for fetch/persist failure or if sequence is + * exhausted for int values. + */ + public int nextIntValue() throws PersistException { + try { + synchronized (mStoredSequence) { + long initial = mStoredSequence.getInitialValue(); + if (initial >= 0x100000000L) { + throw new PersistException + ("Sequence initial value too large to support 32-bit ints: " + + mStoredSequence.getName() + ", initial: " + initial); + } + long next = nextUnadjustedValue(); + if (next >= Long.MIN_VALUE + 0x100000000L) { + // Everytime we throw this exception, a long sequence value + // has been lost. This seems fairly benign. + throw new PersistException + ("Sequence exhausted for 32-bit ints: " + mStoredSequence.getName() + + ", next: " + (next + Long.MIN_VALUE + initial)); + } + return (int) (next + Long.MIN_VALUE + initial); + } + } catch (FetchException e) { + throw e.toPersistException(); + } + } + + /** + * Allow any unused reserved values to be returned for re-use. If the + * repository is shared by other processes, then reserved values might not + * be returnable. + * + *

This method should be called during the shutdown process of a + * repository, although calling it does not invalidate this + * SequenceValueGenerator. If getNextValue is called again, it will reserve + * values again. + * + * @return true if reserved values were returned + */ + public boolean returnReservedValues() throws FetchException, PersistException { + synchronized (mStoredSequence) { + if (mHasReservedValues) { + Transaction txn = mRepository.enterTopTransaction(null); + txn.setForUpdate(true); + try { + // Compare known StoredSequence with current persistent + // one. If same, then reserved values can be returned. + StoredSequence current = mStorage.prepare(); + current.setName(mStoredSequence.getName()); + if (current.tryLoad() && current.equals(mStoredSequence)) { + mStoredSequence.setNextValue(mNextValue + mIncrement); + mStoredSequence.update(); + txn.commit(); + mHasReservedValues = false; + return true; + } + } finally { + txn.exit(); + } + } + } + return false; + } + + // Assumes caller has synchronized on mStoredSequence + private long nextUnadjustedValue() throws FetchException, PersistException { + if (mHasReservedValues) { + long next = mNextValue + mIncrement; + mNextValue = next; + if (next < mStoredSequence.getNextValue()) { + return next; + } + mHasReservedValues = false; + } + + Transaction txn = mRepository.enterTopTransaction(null); + txn.setForUpdate(true); + try { + // Assume that StoredSequence is stale, so reload. + mStoredSequence.load(); + long next = mStoredSequence.getNextValue(); + long nextStored = next + mReserveAmount * mIncrement; + + if (next >= 0 && nextStored < 0) { + // Wrapped around. There might be just a few values left. + long avail = (Long.MAX_VALUE - next) / mIncrement; + if (avail > 0) { + nextStored = next + avail * mIncrement; + } else { + // Throw a PersistException since sequences are applied during + // insert operations, and inserts can only throw PersistExceptions. + throw new PersistException + ("Sequence exhausted: " + mStoredSequence.getName()); + } + } + + mStoredSequence.setNextValue(nextStored); + mStoredSequence.update(); + + txn.commit(); + + mNextValue = next; + mHasReservedValues = true; + return next; + } finally { + txn.exit(); + } + } +} diff --git a/src/main/java/com/amazon/carbonado/sequence/SequenceValueProducer.java b/src/main/java/com/amazon/carbonado/sequence/SequenceValueProducer.java new file mode 100644 index 0000000..5f7fa03 --- /dev/null +++ b/src/main/java/com/amazon/carbonado/sequence/SequenceValueProducer.java @@ -0,0 +1,103 @@ +/* + * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * Licensed 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 com.amazon.carbonado.sequence; + +import com.amazon.carbonado.FetchException; +import com.amazon.carbonado.PersistException; + +/** + * Produces values for sequences. + * + * @author Brian S O'Neill + * @author bcastill + * @see com.amazon.carbonado.Sequence + */ +public interface SequenceValueProducer { + /** + * Returns the next value from the sequence, which may wrap negative if all + * positive values are exhausted. When sequence wraps back to initial + * value, the sequence is fully exhausted, and an exception is thrown to + * indicate this. + * + *

Note: this method throws PersistException even for fetch failures + * since this method is called by insert operations. Insert operations can + * only throw a PersistException. + * + * @throws PersistException for fetch/persist failure or if sequence is exhausted. + */ + public long nextLongValue() throws PersistException; + + /** + * Returns the next value from the sequence, which may wrap negative if all + * positive values are exhausted. When sequence wraps back to initial + * value, the sequence is fully exhausted, and an exception is thrown to + * indicate this. + * + *

Note: this method throws PersistException even for fetch failures + * since this method is called by insert operations. Insert operations can + * only throw a PersistException. + * + * @throws PersistException for fetch/persist failure or if sequence is + * exhausted for int values. + */ + public int nextIntValue() throws PersistException; + + /** + * Returns the next decimal string value from the sequence, which remains + * positive. When sequence wraps back to initial value, the sequence is + * fully exhausted, and an exception is thrown to indicate this. + * + *

Note: this method throws PersistException even for fetch failures + * since this method is called by insert operations. Insert operations can + * only throw a PersistException. + * + * @throws PersistException for fetch/persist failure or if sequence is exhausted. + */ + public String nextDecimalValue() throws PersistException; + + /** + * Returns the next numerical string value from the sequence, which remains + * positive. When sequence wraps back to initial value, the sequence is + * fully exhausted, and an exception is thrown to indicate this. + * + *

Note: this method throws PersistException even for fetch failures + * since this method is called by insert operations. Insert operations can + * only throw a PersistException. + * + * @param radix use 2 for binary, 10 for decimal, 16 for hex. Max is 36. + * @param minLength ensure string is at least this long (padded with zeros if + * necessary) to ensure proper string sort + * @throws PersistException for fetch/persist failure or if sequence is exhausted. + */ + public String nextNumericalValue(int radix, int minLength) throws PersistException; + + /** + * Allow any unused reserved values to be returned for re-use. If the + * repository is shared by other processes, then reserved values might not + * be returnable. + * + *

This method should be called during the shutdown process of a + * repository, although calling it does not invalidate this + * SequenceValueGenerator. If getNextValue is called again, it will reserve + * values again. + * + * @return true if reserved values were returned + */ + public boolean returnReservedValues() throws FetchException, PersistException; +} diff --git a/src/main/java/com/amazon/carbonado/sequence/SequenceValueProducerPool.java b/src/main/java/com/amazon/carbonado/sequence/SequenceValueProducerPool.java new file mode 100644 index 0000000..9b9cb8c --- /dev/null +++ b/src/main/java/com/amazon/carbonado/sequence/SequenceValueProducerPool.java @@ -0,0 +1,77 @@ +/* + * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * Licensed 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 com.amazon.carbonado.sequence; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import com.amazon.carbonado.RepositoryException; +import com.amazon.carbonado.util.AbstractPool; + +/** + * A concurrent pool of strongly referenced {@link SequenceValueProducer} + * instances mapped by name. SequenceValueProducer instances are lazily created + * and pooled. + * + * @author bcastill + * @author Brian S O'Neill + */ +public abstract class SequenceValueProducerPool + extends AbstractPool +{ + public SequenceValueProducerPool() { + } + + /** + * Returns a SequenceValueProducer instance for the given name, which is + * lazily created and pooled. If multiple threads are requesting upon the + * same name concurrently, at most one thread attempts to lazily create the + * SequenceValueProducer. The others wait for it to become available. + * + * @param name name of sequence + */ + public SequenceValueProducer get(String name) throws RepositoryException { + return (SequenceValueProducer) super.get(name); + } + + /** + * Returns reserved values for all {@link SequenceValueProducer}s. + * + * @param log optional log to report errors; uses default log if null + */ + public void returnReservedValues(Log log) { + for (SequenceValueProducer producer : values()) { + try { + producer.returnReservedValues(); + } catch (RepositoryException e) { + if (log == null) { + log = LogFactory.getLog(SequenceValueProducerPool.class); + } + log.error(e.getMessage(), e); + } + } + } + + protected final SequenceValueProducer create(String name) throws RepositoryException { + return createSequenceValueProducer(name); + } + + protected abstract SequenceValueProducer createSequenceValueProducer(String name) + throws RepositoryException; +} diff --git a/src/main/java/com/amazon/carbonado/sequence/StoredSequence.java b/src/main/java/com/amazon/carbonado/sequence/StoredSequence.java new file mode 100644 index 0000000..3fa770e --- /dev/null +++ b/src/main/java/com/amazon/carbonado/sequence/StoredSequence.java @@ -0,0 +1,70 @@ +/* + * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * Licensed 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 com.amazon.carbonado.sequence; + +import com.amazon.carbonado.Alias; +import com.amazon.carbonado.Authoritative; +import com.amazon.carbonado.Independent; +import com.amazon.carbonado.PrimaryKey; +import com.amazon.carbonado.Storable; +import com.amazon.carbonado.Version; + +/** + * Stores data for {@link SequenceValueGenerator}. To use with JDBC repository, + * create a table like so: + * + *

+ * CREATE TABLE CARBONADO_SEQUENCE (
+ *     NAME           VARCHAR(100) PRIMARY KEY,
+ *     INITIAL_VALUE  BIGINT       NOT NULL,
+ *     NEXT_VALUE     BIGINT       NOT NULL
+ * )
+ * 
+ * + * @author Brian S O'Neill + */ +@PrimaryKey("name") +@Authoritative +@Independent +@Alias("CARBONADO_SEQUENCE") +public interface StoredSequence extends Storable { + @Alias("NAME") + String getName(); + void setName(String name); + + /** + * Returns the initial value for the sequence. + */ + @Alias("INITIAL_VALUE") + long getInitialValue(); + void setInitialValue(long value); + + /** + * Returns the pre-adjusted next value of the sequence. This value is + * initially Long.MIN_VALUE, and it increments up to Long.MAX_VALUE. The actual + * next value for the sequence is: (getNextValue() + Long.MIN_VALUE + getInitialValue()). + */ + @Alias("NEXT_VALUE") + long getNextValue(); + void setNextValue(long value); + + @Version + int getVersion(); + void setVersion(int version); +} diff --git a/src/main/java/com/amazon/carbonado/sequence/package-info.java b/src/main/java/com/amazon/carbonado/sequence/package-info.java new file mode 100644 index 0000000..d464166 --- /dev/null +++ b/src/main/java/com/amazon/carbonado/sequence/package-info.java @@ -0,0 +1,26 @@ +/* + * Copyright 2006 Amazon Technologies, Inc. or its affiliates. + * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks + * of Amazon Technologies, Inc. or its affiliates. All rights reserved. + * + * Licensed 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. + */ + +/** + * Support for generating sequences of values, intended for creating surrogate + * keys. Most repository implementations support sequences already, but direct + * control over sequences might be desired. + * + * @see com.amazon.carbonado.Sequence + */ +package com.amazon.carbonado.sequence; -- cgit v1.2.3