diff options
Diffstat (limited to 'src/main/java/com/amazon/carbonado/layout')
5 files changed, 200 insertions, 24 deletions
diff --git a/src/main/java/com/amazon/carbonado/layout/Layout.java b/src/main/java/com/amazon/carbonado/layout/Layout.java index b6c6c0d..7aea758 100644 --- a/src/main/java/com/amazon/carbonado/layout/Layout.java +++ b/src/main/java/com/amazon/carbonado/layout/Layout.java @@ -18,6 +18,7 @@ package com.amazon.carbonado.layout;
+import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
@@ -32,6 +33,7 @@ import org.apache.commons.logging.LogFactory; import org.cojen.util.SoftValuedHashMap;
+import com.amazon.carbonado.CorruptEncodingException;
import com.amazon.carbonado.Cursor;
import com.amazon.carbonado.FetchException;
import com.amazon.carbonado.FetchNoneException;
@@ -131,22 +133,36 @@ public class Layout { private final LayoutFactory mLayoutFactory;
private final StoredLayout mStoredLayout;
+ private final LayoutOptions mOptions;
private transient List<LayoutProperty> mAllProperties;
/**
* Creates a Layout around an existing storable.
*/
- Layout(LayoutFactory factory, StoredLayout storedLayout) {
+ Layout(LayoutFactory factory, StoredLayout storedLayout) throws CorruptEncodingException {
mLayoutFactory = factory;
mStoredLayout = storedLayout;
+
+ byte[] extra = storedLayout.getExtraData();
+ if (extra == null) {
+ mOptions = null;
+ } else {
+ mOptions = new LayoutOptions();
+ try {
+ mOptions.decode(extra);
+ } catch (IOException e) {
+ throw new CorruptEncodingException(e);
+ }
+ mOptions.readOnly();
+ }
}
/**
* Copies layout information into freshly prepared storables. Call insert
* (on this class) to persist them.
*/
- Layout(LayoutFactory factory, StorableInfo<?> info, long layoutID) {
+ Layout(LayoutFactory factory, StorableInfo<?> info, LayoutOptions options, long layoutID) {
mLayoutFactory = factory;
StoredLayout storedLayout = factory.mLayoutStorage.prepare();
@@ -168,6 +184,14 @@ public class Layout { // Can't get host, no big deal.
}
+ if (options == null) {
+ mOptions = null;
+ } else {
+ options.readOnly();
+ storedLayout.setExtraData(options.encode());
+ mOptions = options;
+ }
+
Collection<? extends StorableProperty<?>> properties = info.getAllProperties().values();
List<LayoutProperty> list = new ArrayList<LayoutProperty>(properties.size());
int ordinal = 0;
@@ -269,6 +293,15 @@ public class Layout { }
/**
+ * Returns additional options, or null if none.
+ *
+ * @return read-only object or null
+ */
+ public LayoutOptions getOptions() {
+ return mOptions;
+ }
+
+ /**
* Returns the layout for a particular generation of this layout's type.
*
* @throws FetchNoneException if generation not found
diff --git a/src/main/java/com/amazon/carbonado/layout/LayoutFactory.java b/src/main/java/com/amazon/carbonado/layout/LayoutFactory.java index 1b2f0fc..54b6933 100644 --- a/src/main/java/com/amazon/carbonado/layout/LayoutFactory.java +++ b/src/main/java/com/amazon/carbonado/layout/LayoutFactory.java @@ -87,6 +87,23 @@ public class LayoutFactory implements LayoutCapability { public Layout layoutFor(Class<? extends Storable> type)
throws FetchException, PersistException
{
+ return layoutFor(type, null);
+ }
+
+ /**
+ * Returns the layout matching the current definition of the given type.
+ *
+ * @throws PersistException if type represents a new generation, but
+ * persisting this information failed
+ */
+ public Layout layoutFor(Class<? extends Storable> type, LayoutOptions options)
+ throws FetchException, PersistException
+ {
+ if (options != null) {
+ // Make side-effect consistently applied.
+ options.readOnly();
+ }
+
synchronized (this) {
if (mReconstructed != null) {
Layout layout = mReconstructed.get(type);
@@ -120,10 +137,10 @@ public class LayoutFactory implements LayoutCapability { for (int i=0; i<HASH_MULTIPLIERS.length; i++) {
// Generate an identifier which has a high likelyhood of being unique.
- long layoutID = mixInHash(0L, info, HASH_MULTIPLIERS[i]);
+ long layoutID = mixInHash(0L, info, options, HASH_MULTIPLIERS[i]);
// Initially use for comparison purposes.
- newLayout = new Layout(this, info, layoutID);
+ newLayout = new Layout(this, info, options, layoutID);
StoredLayout storedLayout = mLayoutStorage.prepare();
storedLayout.setLayoutID(layoutID);
@@ -262,8 +279,10 @@ public class LayoutFactory implements LayoutCapability { * Creates a long hash code that attempts to mix in all relevant layout
* elements.
*/
- private long mixInHash(long hash, StorableInfo<?> info, int multiplier) {
+ private long mixInHash(long hash, StorableInfo<?> info, LayoutOptions options, int multiplier)
+ {
hash = mixInHash(hash, info.getStorableType().getName(), multiplier);
+ hash = mixInHash(hash, options, multiplier);
for (StorableProperty<?> property : info.getAllProperties().values()) {
if (!property.isJoin()) {
@@ -314,6 +333,18 @@ public class LayoutFactory implements LayoutCapability { return hash;
}
+ private long mixInHash(long hash, LayoutOptions options, int multiplier) {
+ if (options != null) {
+ byte[] data = options.encode();
+ if (data != null) {
+ for (int b : data) {
+ hash = hash * multiplier + (b & 0xff);
+ }
+ }
+ }
+ return hash;
+ }
+
/**
* Returns an annotation hash code using a algorithm similar to the
* default. The difference is in the handling of class and enum values. The
diff --git a/src/main/java/com/amazon/carbonado/layout/LayoutOptions.java b/src/main/java/com/amazon/carbonado/layout/LayoutOptions.java new file mode 100644 index 0000000..1e57407 --- /dev/null +++ b/src/main/java/com/amazon/carbonado/layout/LayoutOptions.java @@ -0,0 +1,131 @@ +/*
+ * Copyright 2009 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.layout;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Extra options encoded with a Storable layout.
+ *
+ * @author Brian S O'Neill
+ */
+public class LayoutOptions {
+ /**
+ * Data is compression algorithm name, encoded by DataOutput.writeUTF.
+ */
+ static final byte COMPRESSION_TYPE = 1;
+
+ private final Map<Byte, Object> mData;
+
+ private boolean mReadOnly;
+
+ public LayoutOptions() {
+ mData = new HashMap<Byte, Object>(1);
+ }
+
+ /**
+ * @return null if not compressed
+ */
+ public synchronized String getCompressionType() {
+ return (String) mData.get(COMPRESSION_TYPE);
+ }
+
+ /**
+ * @param type null if not compressed
+ */
+ public void setCompressionType(String type) {
+ put(COMPRESSION_TYPE, type);
+ }
+
+ private synchronized void put(byte op, Object value) {
+ if (mReadOnly) {
+ throw new IllegalStateException("Options are read only");
+ }
+ if (value == null) {
+ mData.remove(op);
+ } else {
+ mData.put(op, value);
+ }
+ }
+
+ synchronized void readOnly() {
+ mReadOnly = true;
+ }
+
+ /**
+ * @return null if empty
+ */
+ synchronized byte[] encode() {
+ if (mData.isEmpty()) {
+ return null;
+ }
+
+ try {
+ ByteArrayOutputStream bout = new ByteArrayOutputStream();
+ DataOutputStream dout = new DataOutputStream(bout);
+
+ for (Map.Entry<Byte, Object> entry : mData.entrySet()) {
+ switch (entry.getKey()) {
+ default:
+ break;
+ case COMPRESSION_TYPE:
+ dout.write(COMPRESSION_TYPE);
+ dout.writeUTF((String) entry.getValue());
+ }
+ }
+
+ dout.close();
+ return bout.toByteArray();
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ /**
+ * @param source can be null if empty
+ */
+ synchronized void decode(byte[] source) throws IOException {
+ mData.clear();
+
+ if (source == null || source.length == 0) {
+ return;
+ }
+
+ ByteArrayInputStream bin = new ByteArrayInputStream(source);
+ DataInputStream din = new DataInputStream(bin);
+
+ while (bin.available() > 0) {
+ byte op = din.readByte();
+ switch (op) {
+ default:
+ throw new IOException("Unknown extra data type: " + op);
+ case COMPRESSION_TYPE:
+ mData.put(COMPRESSION_TYPE, din.readUTF());
+ break;
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/amazon/carbonado/layout/StoredLayout.java b/src/main/java/com/amazon/carbonado/layout/StoredLayout.java index ea3c1ec..0ed8ffa 100644 --- a/src/main/java/com/amazon/carbonado/layout/StoredLayout.java +++ b/src/main/java/com/amazon/carbonado/layout/StoredLayout.java @@ -42,21 +42,18 @@ import com.amazon.carbonado.Version; @Alias("CARBONADO_LAYOUT")
public interface StoredLayout extends Storable<StoredLayout>, Unevolvable {
long getLayoutID();
-
void setLayoutID(long typeID);
/**
* Storable type name is a fully qualified Java class name.
*/
String getStorableTypeName();
-
void setStorableTypeName(String typeName);
/**
* Generation of storable, where 0 represents the first generation.
*/
int getGeneration();
-
void setGeneration(int generation);
/**
@@ -64,7 +61,6 @@ public interface StoredLayout extends Storable<StoredLayout>, Unevolvable { * created.
*/
long getCreationTimestamp();
-
void setCreationTimestamp(long timestamp);
/**
@@ -72,7 +68,6 @@ public interface StoredLayout extends Storable<StoredLayout>, Unevolvable { */
@Nullable
String getCreationUser();
-
void setCreationUser(String user);
/**
@@ -80,7 +75,6 @@ public interface StoredLayout extends Storable<StoredLayout>, Unevolvable { */
@Nullable
String getCreationHost();
-
void setCreationHost(String host);
/**
@@ -89,7 +83,6 @@ public interface StoredLayout extends Storable<StoredLayout>, Unevolvable { */
@Version
int getVersionNumber();
-
void setVersionNumber(int version);
/**
@@ -100,6 +93,5 @@ public interface StoredLayout extends Storable<StoredLayout>, Unevolvable { */
@Nullable
byte[] getExtraData();
-
void setExtraData(byte[] data);
}
diff --git a/src/main/java/com/amazon/carbonado/layout/StoredLayoutProperty.java b/src/main/java/com/amazon/carbonado/layout/StoredLayoutProperty.java index 0777f10..b98a2a7 100644 --- a/src/main/java/com/amazon/carbonado/layout/StoredLayoutProperty.java +++ b/src/main/java/com/amazon/carbonado/layout/StoredLayoutProperty.java @@ -42,7 +42,6 @@ import com.amazon.carbonado.Version; @Alias("CARBONADO_LAYOUT_PROPERTY")
public interface StoredLayoutProperty extends Storable<StoredLayoutProperty>, Unevolvable {
long getLayoutID();
-
void setLayoutID(long typeID);
/**
@@ -50,32 +49,27 @@ public interface StoredLayoutProperty extends Storable<StoredLayoutProperty>, Un * layout.
*/
int getOrdinal();
-
void setOrdinal(int ordinal);
String getPropertyName();
-
void setPropertyName(String name);
/**
* Property type descriptor is a Java type descriptor.
*/
String getPropertyTypeDescriptor();
-
void setPropertyTypeDescriptor(String type);
/**
* Returns true of property value can be set to null.
*/
boolean isNullable();
-
void setNullable(boolean nullable);
/**
* Returns true if property is a member of the primary key.
*/
boolean isPrimaryKeyMember();
-
void setPrimaryKeyMember(boolean pk);
/**
@@ -83,7 +77,6 @@ public interface StoredLayoutProperty extends Storable<StoredLayoutProperty>, Un * Storable.
*/
boolean isVersion();
-
void setVersion(boolean version);
/**
@@ -92,7 +85,6 @@ public interface StoredLayoutProperty extends Storable<StoredLayoutProperty>, Un */
@Nullable
String getAdapterTypeName();
-
void setAdapterTypeName(String name);
/**
@@ -100,7 +92,6 @@ public interface StoredLayoutProperty extends Storable<StoredLayoutProperty>, Un */
@Nullable
String getAdapterParams();
-
void setAdapterParams(String params);
/**
@@ -109,7 +100,6 @@ public interface StoredLayoutProperty extends Storable<StoredLayoutProperty>, Un */
@Version
int getVersionNumber();
-
void setVersionNumber(int version);
/**
@@ -120,6 +110,5 @@ public interface StoredLayoutProperty extends Storable<StoredLayoutProperty>, Un */
@Nullable
byte[] getExtraData();
-
void setExtraData(byte[] data);
}
|