commit b0e19779910dc5e33320d31c288ae23d38d160bd Author: Alan Gates Date: Thu Mar 19 08:58:13 2015 -0700 HIVE-10010 Reworked SharedStorageDescriptor to be much simpler and work better when users copy it. diff --git itests/hive-unit/src/test/java/org/apache/hadoop/hive/metastore/hbase/TestHBaseMetastoreSql.java itests/hive-unit/src/test/java/org/apache/hadoop/hive/metastore/hbase/TestHBaseMetastoreSql.java index 7be0357..676c389 100644 --- itests/hive-unit/src/test/java/org/apache/hadoop/hive/metastore/hbase/TestHBaseMetastoreSql.java +++ itests/hive-unit/src/test/java/org/apache/hadoop/hive/metastore/hbase/TestHBaseMetastoreSql.java @@ -79,7 +79,7 @@ public void database() throws Exception { Assert.assertEquals(0, rsp.getResponseCode()); } - @Ignore + @Test public void table() throws Exception { driver.run("create table tbl (c int)"); CommandProcessorResponse rsp = driver.run("insert into table tbl values (3)"); @@ -92,7 +92,7 @@ public void table() throws Exception { Assert.assertEquals(0, rsp.getResponseCode()); } - @Ignore + @Test public void partitionedTable() throws Exception { driver.run("create table parttbl (c int) partitioned by (ds string)"); CommandProcessorResponse rsp = @@ -113,8 +113,11 @@ public void partitionedTable() throws Exception { Assert.assertEquals(0, rsp.getResponseCode()); rsp = driver.run("alter table parttbl touch partition (ds = 'whenever')"); Assert.assertEquals(0, rsp.getResponseCode()); + // TODO - Can't do this until getPartitionsByExpr implemented + /* rsp = driver.run("alter table parttbl drop partition (ds = 'whenever')"); Assert.assertEquals(0, rsp.getResponseCode()); + */ rsp = driver.run("select * from parttbl"); Assert.assertEquals(0, rsp.getResponseCode()); rsp = driver.run("select * from parttbl where ds = 'today'"); diff --git metastore/src/java/org/apache/hadoop/hive/metastore/hbase/SharedStorageDescriptor.java metastore/src/java/org/apache/hadoop/hive/metastore/hbase/SharedStorageDescriptor.java index f5e9168..d772dca 100644 --- metastore/src/java/org/apache/hadoop/hive/metastore/hbase/SharedStorageDescriptor.java +++ metastore/src/java/org/apache/hadoop/hive/metastore/hbase/SharedStorageDescriptor.java @@ -27,751 +27,225 @@ import org.apache.hadoop.hive.metastore.api.StorageDescriptor; import java.util.ArrayList; -import java.util.Collection; import java.util.Iterator; import java.util.List; -import java.util.Map; /** * A {@link org.apache.hadoop.hive.metastore.api.StorageDescriptor} with most of it's content - * shared. Location and parameters are left alone, everything else is redirected to a shared - * reference in the cache. + * shallow copied from the underlying storage descriptor. Location and parameters are left alone. + * To avoid issues when users change the contents, all lists and nested structures (cols, serde, + * buckets, sortCols, and skewed) are deep copied when they are accessed for reading or writing. + * (It has to be done on read as well because there's no way to guarantee the user won't change the + * nested structure or list, which would result in changing every storage descriptor sharing that + * structure.) Users wishing better performance can call setReadyOnly(), which will prevent the + * copies. */ public class SharedStorageDescriptor extends StorageDescriptor { static final private Log LOG = LogFactory.getLog(SharedStorageDescriptor.class.getName()); - private StorageDescriptor shared; - private boolean copied = false; - private CopyOnWriteColList colList = null; - private CopyOnWriteOrderList orderList = null; - private CopyOnWriteBucketList bucketList = null; + private boolean colsCopied = false; + private boolean serdeCopied = false; + private boolean bucketsCopied = false; + private boolean sortCopied = false; + private boolean skewedCopied = false; SharedStorageDescriptor() { } - public SharedStorageDescriptor(SharedStorageDescriptor that) { - this.setLocation(that.getLocation()); - this.setParameters(that.getParameters()); - this.shared = that.shared; + void setShared(StorageDescriptor shared) { + if (shared.getCols() != null) super.setCols(shared.getCols()); + // Skip location + if (shared.getInputFormat() != null) super.setInputFormat(shared.getInputFormat()); + if (shared.getOutputFormat() != null) super.setOutputFormat(shared.getOutputFormat()); + super.setCompressed(shared.isCompressed()); + super.setNumBuckets(shared.getNumBuckets()); + if (shared.getSerdeInfo() != null) super.setSerdeInfo(shared.getSerdeInfo()); + if (shared.getBucketCols() != null) super.setBucketCols(shared.getBucketCols()); + if (shared.getSortCols() != null) super.setSortCols(shared.getSortCols()); + // skip parameters + if (shared.getSkewedInfo() != null) super.setSkewedInfo(shared.getSkewedInfo()); + super.setStoredAsSubDirectories(shared.isStoredAsSubDirectories()); } - @Override - public StorageDescriptor deepCopy() { - return new SharedStorageDescriptor(this); + /** + * Promise that you'll only use this shared storage descriptor in a read only mode. + * This prevents the copies of the nested structures and lists when reading them. However, the + * caller must not change the structures or lists returned to it, as this will change all + * storage descriptor sharing that list. + */ + public void setReadOnly() { + colsCopied = serdeCopied = bucketsCopied = sortCopied = skewedCopied = true; } @Override - public boolean isSetCols() { - return shared.isSetCols(); + public void addToCols(FieldSchema fs) { + copyCols(); + super.addToCols(fs); } @Override public List getCols() { - return copied ? shared.getCols() : ( - shared.getCols() == null ? null : copyCols(shared.getCols())); - } - - @Override - public int getColsSize() { - return shared.getColsSize(); - } - - @Override - public Iterator getColsIterator() { - return shared.getColsIterator(); + copyCols(); + return super.getCols(); } @Override public void setCols(List cols) { - copyOnWrite(); - shared.setCols(cols); - } - - @Override - public void addToCols(FieldSchema fs) { - copyOnWrite(); - shared.addToCols(fs); + colsCopied = true; + super.setCols(cols); } @Override public void unsetCols() { - copyOnWrite(); - shared.unsetCols(); + colsCopied = true; + super.unsetCols(); } @Override - public boolean isSetInputFormat() { - return shared.isSetInputFormat(); - } - - @Override - public String getInputFormat() { - return shared.getInputFormat(); - } - - @Override - public void setInputFormat(String inputFormat) { - copyOnWrite(); - shared.setInputFormat(inputFormat); - } - - @Override - public void unsetInputFormat() { - copyOnWrite(); - shared.unsetInputFormat(); - } - - @Override - public boolean isSetOutputFormat() { - return shared.isSetOutputFormat(); - } - - @Override - public String getOutputFormat() { - return shared.getOutputFormat(); - } - - @Override - public void setOutputFormat(String outputFormat) { - copyOnWrite(); - shared.setOutputFormat(outputFormat); - } - - @Override - public void unsetOutputFormat() { - copyOnWrite(); - shared.unsetOutputFormat(); - } - - @Override - public boolean isSetCompressed() { - return shared.isSetCompressed(); - } - - @Override - public boolean isCompressed() { - return shared.isCompressed(); - } - - @Override - public void setCompressed(boolean isCompressed) { - copyOnWrite(); - shared.setCompressed(isCompressed); - } - - @Override - public void unsetCompressed() { - copyOnWrite(); - shared.unsetCompressed(); - } - - @Override - public boolean isSetNumBuckets() { - return shared.isSetNumBuckets(); - } - - @Override - public int getNumBuckets() { - return shared.getNumBuckets(); - } - - @Override - public void setNumBuckets(int numBuckets) { - copyOnWrite(); - shared.setNumBuckets(numBuckets); - } - - @Override - public void unsetNumBuckets() { - copyOnWrite(); - shared.unsetNumBuckets(); + public Iterator getColsIterator() { + copyCols(); + return super.getColsIterator(); } - @Override - public boolean isSetSerdeInfo() { - return shared.isSetSerdeInfo(); + private void copyCols() { + if (!colsCopied) { + colsCopied = true; + if (super.getCols() != null) { + List cols = new ArrayList(super.getColsSize()); + for (FieldSchema fs : super.getCols()) cols.add(new FieldSchema(fs)); + super.setCols(cols); + } + } } @Override public SerDeInfo getSerdeInfo() { - return copied ? shared.getSerdeInfo() : ( - shared.getSerdeInfo() == null ? null : new SerDeInfoWrapper(shared.getSerdeInfo())); + copySerde(); + return super.getSerdeInfo(); } @Override public void setSerdeInfo(SerDeInfo serdeInfo) { - copyOnWrite(); - shared.setSerdeInfo(serdeInfo); + serdeCopied = true; + super.setSerdeInfo(serdeInfo); } @Override public void unsetSerdeInfo() { - copyOnWrite(); - shared.unsetSerdeInfo(); - } - - @Override - public boolean isSetBucketCols() { - return shared.isSetBucketCols(); + serdeCopied = true; + super.unsetSerdeInfo(); } - @Override - public List getBucketCols() { - return copied ? shared.getBucketCols() : ( - shared.getBucketCols() == null ? null : copyBucketCols(shared.getBucketCols())); - } - - @Override - public int getBucketColsSize() { - return shared.getBucketColsSize(); + private void copySerde() { + if (!serdeCopied) { + serdeCopied = true; + if (super.getSerdeInfo() != null) super.setSerdeInfo(new SerDeInfo(super.getSerdeInfo())); + } } @Override - public Iterator getBucketColsIterator() { - return shared.getBucketColsIterator(); + public void addToBucketCols(String bucket) { + copyBucketCols(); + super.addToBucketCols(bucket); } @Override - public void setBucketCols(List bucketCols) { - copyOnWrite(); - shared.setBucketCols(bucketCols); + public List getBucketCols() { + copyBucketCols(); + return super.getBucketCols(); } @Override - public void addToBucketCols(String bucketCol) { - copyOnWrite(); - shared.addToBucketCols(bucketCol); + public void setBucketCols(List buckets) { + bucketsCopied = true; + super.setBucketCols(buckets); } @Override public void unsetBucketCols() { - copyOnWrite(); - shared.unsetBucketCols(); + bucketsCopied = true; + super.unsetBucketCols(); } @Override - public boolean isSetSortCols() { - return shared.isSetSortCols(); + public Iterator getBucketColsIterator() { + copyBucketCols(); + return super.getBucketColsIterator(); } - @Override - public List getSortCols() { - return copied ? shared.getSortCols() : ( - shared.getSortCols() == null ? null : copySort(shared.getSortCols())); + private void copyBucketCols() { + if (!bucketsCopied) { + bucketsCopied = true; + if (super.getBucketCols() != null) { + List buckets = new ArrayList(super.getBucketColsSize()); + for (String bucket : super.getBucketCols()) buckets.add(bucket); + super.setBucketCols(buckets); + } + } } @Override - public int getSortColsSize() { - return shared.getSortColsSize(); + public void addToSortCols(Order sort) { + copySort(); + super.addToSortCols(sort); } @Override - public Iterator getSortColsIterator() { - return shared.getSortColsIterator(); + public List getSortCols() { + copySort(); + return super.getSortCols(); } @Override - public void setSortCols(List sortCols) { - copyOnWrite(); - shared.setSortCols(sortCols); + public void setSortCols(List sorts) { + sortCopied = true; + super.setSortCols(sorts); } @Override - public void addToSortCols(Order sortCol) { - copyOnWrite(); - shared.addToSortCols(sortCol); + public void unsetSortCols() { + sortCopied = true; + super.unsetSortCols(); } @Override - public void unsetSortCols() { - copyOnWrite(); - shared.unsetSortCols(); + public Iterator getSortColsIterator() { + copySort(); + return super.getSortColsIterator(); } - @Override - public boolean isSetSkewedInfo() { - return shared.isSetSkewedInfo(); + private void copySort() { + if (!sortCopied) { + sortCopied = true; + if (super.getSortCols() != null) { + List sortCols = new ArrayList(super.getSortColsSize()); + for (Order sortCol : super.getSortCols()) sortCols.add(new Order(sortCol)); + super.setSortCols(sortCols); + } + } } @Override public SkewedInfo getSkewedInfo() { - return copied ? shared.getSkewedInfo() : ( - shared.getSkewedInfo() == null ? null : new SkewWrapper(shared.getSkewedInfo())); + copySkewed(); + return super.getSkewedInfo(); } @Override public void setSkewedInfo(SkewedInfo skewedInfo) { - copyOnWrite(); - shared.setSkewedInfo(skewedInfo); + skewedCopied = true; + super.setSkewedInfo(skewedInfo); } @Override public void unsetSkewedInfo() { - copyOnWrite(); - shared.unsetSkewedInfo(); - } - - @Override - public boolean isSetStoredAsSubDirectories() { - return shared.isSetStoredAsSubDirectories(); - } - - @Override - public boolean isStoredAsSubDirectories() { - return shared.isStoredAsSubDirectories(); - } - - @Override - public void setStoredAsSubDirectories(boolean sasd) { - copyOnWrite(); - shared.setStoredAsSubDirectories(sasd); - } - - @Override - public void unsetStoredAsSubDirectories() { - copyOnWrite(); - shared.unsetStoredAsSubDirectories(); + skewedCopied = true; + super.unsetSkewedInfo(); } - void setShared(StorageDescriptor sd) { - shared = sd; - } - - StorageDescriptor getShared() { - return shared; - } - - private void copyOnWrite() { - if (!copied) { - shared = new StorageDescriptor(shared); - copied = true; - } - } - - private class SerDeInfoWrapper extends SerDeInfo { - - SerDeInfoWrapper(SerDeInfo serde) { - super(serde); - } - - @Override - public void setName(String name) { - copyOnWrite(); - shared.getSerdeInfo().setName(name); - } - - @Override - public void unsetName() { - copyOnWrite(); - shared.getSerdeInfo().unsetName(); - } - - @Override - public void setSerializationLib(String lib) { - copyOnWrite(); - shared.getSerdeInfo().setSerializationLib(lib); - } - - @Override - public void unsetSerializationLib() { - copyOnWrite(); - shared.getSerdeInfo().unsetSerializationLib(); - } - - @Override - public void setParameters(Map parameters) { - copyOnWrite(); - shared.getSerdeInfo().setParameters(parameters); - } - - @Override - public void unsetParameters() { - copyOnWrite(); - shared.getSerdeInfo().unsetParameters(); - } - - @Override - public void putToParameters(String key, String value) { - copyOnWrite(); - shared.getSerdeInfo().putToParameters(key, value); + private void copySkewed() { + if (!skewedCopied) { + skewedCopied = true; + if (super.getSkewedInfo() != null) super.setSkewedInfo(new SkewedInfo(super.getSkewedInfo())); } } - - private class SkewWrapper extends SkewedInfo { - SkewWrapper(SkewedInfo skew) { - super(skew); - } - - @Override - public void setSkewedColNames(List skewedColNames) { - copyOnWrite(); - shared.getSkewedInfo().setSkewedColNames(skewedColNames); - } - - @Override - public void unsetSkewedColNames() { - copyOnWrite(); - shared.getSkewedInfo().unsetSkewedColNames(); - } - - @Override - public void addToSkewedColNames(String skewCol) { - copyOnWrite(); - shared.getSkewedInfo().addToSkewedColNames(skewCol); - } - - @Override - public void setSkewedColValues(List> skewedColValues) { - copyOnWrite(); - shared.getSkewedInfo().setSkewedColValues(skewedColValues); - } - - @Override - public void unsetSkewedColValues() { - copyOnWrite(); - shared.getSkewedInfo().unsetSkewedColValues(); - } - - @Override - public void addToSkewedColValues(List skewedColValue) { - copyOnWrite(); - shared.getSkewedInfo().addToSkewedColValues(skewedColValue); - } - - @Override - public void setSkewedColValueLocationMaps(Map, String> maps) { - copyOnWrite(); - shared.getSkewedInfo().setSkewedColValueLocationMaps(maps); - } - - @Override - public void unsetSkewedColValueLocationMaps() { - copyOnWrite(); - shared.getSkewedInfo().unsetSkewedColValueLocationMaps(); - } - - @Override - public void putToSkewedColValueLocationMaps(List key, String value) { - copyOnWrite(); - shared.getSkewedInfo().putToSkewedColValueLocationMaps(key, value); - } - } - - private CopyOnWriteOrderList copySort(List sort) { - if (orderList == null) { - orderList = new CopyOnWriteOrderList(sort.size()); - for (int i = 0; i < sort.size(); i++) { - orderList.secretAdd(new OrderWrapper(i, sort.get(i))); - } - } - return orderList; - } - - private class CopyOnWriteOrderList extends ArrayList { - - CopyOnWriteOrderList(int size) { - super(size); - } - - private void secretAdd(OrderWrapper order) { - super.add(order); - } - - @Override - public boolean add(Order t) { - copyOnWrite(); - return shared.getSortCols().add(t); - } - - @Override - public boolean remove(Object o) { - copyOnWrite(); - return shared.getSortCols().remove(o); - } - - @Override - public boolean addAll(Collection c) { - copyOnWrite(); - return shared.getSortCols().addAll(c); - } - - @Override - public boolean addAll(int index, Collection c) { - copyOnWrite(); - return shared.getSortCols().addAll(c); - } - - @Override - public boolean removeAll(Collection c) { - copyOnWrite(); - return shared.getSortCols().removeAll(c); - } - - @Override - public boolean retainAll(Collection c) { - copyOnWrite(); - return shared.getSortCols().retainAll(c); - } - - @Override - public void clear() { - copyOnWrite(); - shared.getSortCols().clear(); - } - - @Override - public Order set(int index, Order element) { - copyOnWrite(); - return shared.getSortCols().set(index, element); - } - - @Override - public void add(int index, Order element) { - copyOnWrite(); - shared.getSortCols().add(index, element); - } - - @Override - public Order remove(int index) { - copyOnWrite(); - return shared.getSortCols().remove(index); - } - } - - private class OrderWrapper extends Order { - final private int pos; - - OrderWrapper(int pos, Order order) { - super(order); - this.pos = pos; - } - - @Override - public void setCol(String col) { - copyOnWrite(); - shared.getSortCols().get(pos).setCol(col); - } - - @Override - public void unsetCol() { - copyOnWrite(); - shared.getSortCols().get(pos).unsetCol(); - } - - @Override - public void setOrder(int order) { - copyOnWrite(); - shared.getSortCols().get(pos).setOrder(order); - } - - @Override - public void unsetOrder() { - copyOnWrite(); - shared.getSortCols().get(pos).unsetOrder(); - } - } - - private CopyOnWriteColList copyCols(List cols) { - if (colList == null) { - colList = new CopyOnWriteColList(cols.size()); - for (int i = 0; i < cols.size(); i++) { - colList.secretAdd(new FieldSchemaWrapper(i, cols.get(i))); - } - } - return colList; - } - - private class CopyOnWriteColList extends ArrayList { - - CopyOnWriteColList(int size) { - super(size); - } - - private void secretAdd(FieldSchemaWrapper col) { - super.add(col); - } - - @Override - public boolean add(FieldSchema t) { - copyOnWrite(); - return shared.getCols().add(t); - } - - @Override - public boolean remove(Object o) { - copyOnWrite(); - return shared.getCols().remove(o); - } - - @Override - public boolean addAll(Collection c) { - copyOnWrite(); - return shared.getCols().addAll(c); - } - - @Override - public boolean addAll(int index, Collection c) { - copyOnWrite(); - return shared.getCols().addAll(c); - } - - @Override - public boolean removeAll(Collection c) { - copyOnWrite(); - return shared.getCols().removeAll(c); - } - - @Override - public boolean retainAll(Collection c) { - copyOnWrite(); - return shared.getCols().retainAll(c); - } - - @Override - public void clear() { - copyOnWrite(); - shared.getCols().clear(); - } - - @Override - public FieldSchema set(int index, FieldSchema element) { - copyOnWrite(); - return shared.getCols().set(index, element); - } - - @Override - public void add(int index, FieldSchema element) { - copyOnWrite(); - shared.getCols().add(index, element); - } - - @Override - public FieldSchema remove(int index) { - copyOnWrite(); - return shared.getCols().remove(index); - } - } - - private class FieldSchemaWrapper extends FieldSchema { - final private int pos; - - FieldSchemaWrapper(int pos, FieldSchema col) { - super(col); - this.pos = pos; - } - - @Override - public void setName(String name) { - copyOnWrite(); - shared.getCols().get(pos).setName(name); - } - - @Override - public void unsetName() { - copyOnWrite(); - shared.getCols().get(pos).unsetName(); - } - - @Override - public void setType(String type) { - copyOnWrite(); - shared.getCols().get(pos).setType(type); - } - - @Override - public void unsetType() { - copyOnWrite(); - shared.getCols().get(pos).unsetType(); - } - - @Override - public void setComment(String comment) { - copyOnWrite(); - shared.getCols().get(pos).setComment(comment); - } - - @Override - public void unsetComment() { - copyOnWrite(); - shared.getCols().get(pos).unsetComment(); - } - } - - private CopyOnWriteBucketList copyBucketCols(List cols) { - if (bucketList == null) { - bucketList = new CopyOnWriteBucketList(cols); - } - return bucketList; - } - - private class CopyOnWriteBucketList extends ArrayList { - - CopyOnWriteBucketList(Collection c) { - super(c); - } - - private void secretAdd(String col) { - super.add(col); - } - - @Override - public boolean add(String t) { - copyOnWrite(); - return shared.getBucketCols().add(t); - } - - @Override - public boolean remove(Object o) { - copyOnWrite(); - return shared.getBucketCols().remove(o); - } - - @Override - public boolean addAll(Collection c) { - copyOnWrite(); - return shared.getBucketCols().addAll(c); - } - - @Override - public boolean addAll(int index, Collection c) { - copyOnWrite(); - return shared.getBucketCols().addAll(c); - } - - @Override - public boolean removeAll(Collection c) { - copyOnWrite(); - return shared.getBucketCols().removeAll(c); - } - - @Override - public boolean retainAll(Collection c) { - copyOnWrite(); - return shared.getBucketCols().retainAll(c); - } - - @Override - public void clear() { - copyOnWrite(); - shared.getBucketCols().clear(); - } - - @Override - public String set(int index, String element) { - copyOnWrite(); - return shared.getBucketCols().set(index, element); - } - - @Override - public void add(int index, String element) { - copyOnWrite(); - shared.getBucketCols().add(index, element); - } - - @Override - public String remove(int index) { - copyOnWrite(); - return shared.getBucketCols().remove(index); - } - } - } diff --git metastore/src/test/org/apache/hadoop/hive/metastore/hbase/TestSharedStorageDescriptor.java metastore/src/test/org/apache/hadoop/hive/metastore/hbase/TestSharedStorageDescriptor.java index c9d1eef..fdfb6d1 100644 --- metastore/src/test/org/apache/hadoop/hive/metastore/hbase/TestSharedStorageDescriptor.java +++ metastore/src/test/org/apache/hadoop/hive/metastore/hbase/TestSharedStorageDescriptor.java @@ -20,6 +20,7 @@ import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.hadoop.hive.metastore.api.FieldSchema; import org.apache.hadoop.hive.metastore.api.Order; import org.apache.hadoop.hive.metastore.api.SerDeInfo; import org.apache.hadoop.hive.metastore.api.SkewedInfo; @@ -27,6 +28,8 @@ import org.junit.Assert; import org.junit.Test; +import java.util.ArrayList; +import java.util.Iterator; import java.util.List; @@ -38,30 +41,6 @@ @Test - public void location() { - StorageDescriptor sd = new StorageDescriptor(); - SharedStorageDescriptor ssd = new SharedStorageDescriptor(); - ssd.setLocation("here"); - ssd.setShared(sd); - ssd.setLocation("there"); - Assert.assertTrue(sd == ssd.getShared()); - } - - @Test - public void changeOnInputFormat() { - StorageDescriptor sd = new StorageDescriptor(); - sd.setInputFormat("input"); - SharedStorageDescriptor ssd = new SharedStorageDescriptor(); - ssd.setShared(sd); - Assert.assertEquals("input", ssd.getInputFormat()); - ssd.setInputFormat("different"); - Assert.assertFalse(sd == ssd.getShared()); - Assert.assertEquals("input", sd.getInputFormat()); - Assert.assertEquals("different", ssd.getInputFormat()); - Assert.assertEquals("input", sd.getInputFormat()); - } - - @Test public void changeOnSerde() { StorageDescriptor sd = new StorageDescriptor(); SerDeInfo serde = new SerDeInfo(); @@ -69,32 +48,33 @@ public void changeOnSerde() { sd.setSerdeInfo(serde); SharedStorageDescriptor ssd = new SharedStorageDescriptor(); ssd.setShared(sd); - Assert.assertEquals("serde", ssd.getSerdeInfo().getName()); ssd.getSerdeInfo().setName("different"); - Assert.assertFalse(sd == ssd.getShared()); + Assert.assertFalse(sd.getSerdeInfo() == ssd.getSerdeInfo()); Assert.assertEquals("serde", serde.getName()); Assert.assertEquals("different", ssd.getSerdeInfo().getName()); Assert.assertEquals("serde", sd.getSerdeInfo().getName()); } @Test - public void multipleChangesDontCauseMultipleCopies() { + public void changeOnSkewed() { + StorageDescriptor sd = new StorageDescriptor(); + SkewedInfo skew = new SkewedInfo(); + sd.setSkewedInfo(skew); + SharedStorageDescriptor ssd = new SharedStorageDescriptor(); + ssd.setShared(sd); + ssd.setSkewedInfo(new SkewedInfo()); + Assert.assertFalse(sd.getSkewedInfo() == ssd.getSkewedInfo()); + } + + @Test + public void changeOnUnset() { StorageDescriptor sd = new StorageDescriptor(); - sd.setInputFormat("input"); - sd.setOutputFormat("output"); + SkewedInfo skew = new SkewedInfo(); + sd.setSkewedInfo(skew); SharedStorageDescriptor ssd = new SharedStorageDescriptor(); ssd.setShared(sd); - Assert.assertEquals("input", ssd.getInputFormat()); - ssd.setInputFormat("different"); - Assert.assertFalse(sd == ssd.getShared()); - Assert.assertEquals("input", sd.getInputFormat()); - Assert.assertEquals("different", ssd.getInputFormat()); - StorageDescriptor keep = ssd.getShared(); - ssd.setOutputFormat("different_output"); - Assert.assertEquals("different", ssd.getInputFormat()); - Assert.assertEquals("different_output", ssd.getOutputFormat()); - Assert.assertEquals("output", sd.getOutputFormat()); - Assert.assertTrue(keep == ssd.getShared()); + ssd.unsetSkewedInfo(); + Assert.assertFalse(sd.getSkewedInfo() == ssd.getSkewedInfo()); } @Test @@ -103,25 +83,71 @@ public void changeOrder() { sd.addToSortCols(new Order("fred", 1)); SharedStorageDescriptor ssd = new SharedStorageDescriptor(); ssd.setShared(sd); - Assert.assertEquals(1, ssd.getSortCols().get(0).getOrder()); ssd.getSortCols().get(0).setOrder(2); - Assert.assertFalse(sd == ssd.getShared()); + Assert.assertFalse(sd.getSortCols() == ssd.getSortCols()); Assert.assertEquals(2, ssd.getSortCols().get(0).getOrder()); Assert.assertEquals(1, sd.getSortCols().get(0).getOrder()); } @Test - public void changeOrderList() { + public void unsetOrder() { StorageDescriptor sd = new StorageDescriptor(); sd.addToSortCols(new Order("fred", 1)); SharedStorageDescriptor ssd = new SharedStorageDescriptor(); ssd.setShared(sd); - Assert.assertEquals(1, ssd.getSortCols().get(0).getOrder()); - List list = ssd.getSortCols(); - list.add(new Order("bob", 2)); - Assert.assertFalse(sd == ssd.getShared()); - Assert.assertEquals(2, ssd.getSortColsSize()); + ssd.unsetSortCols(); + Assert.assertFalse(sd.getSortCols() == ssd.getSortCols()); + Assert.assertEquals(0, ssd.getSortColsSize()); Assert.assertEquals(1, sd.getSortColsSize()); } + @Test + public void changeBucketList() { + StorageDescriptor sd = new StorageDescriptor(); + sd.addToBucketCols(new String("fred")); + SharedStorageDescriptor ssd = new SharedStorageDescriptor(); + ssd.setShared(sd); + List list = ssd.getBucketCols(); + list.add(new String("bob")); + Assert.assertFalse(sd.getBucketCols() == ssd.getBucketCols()); + Assert.assertEquals(2, ssd.getBucketColsSize()); + Assert.assertEquals(1, sd.getBucketColsSize()); + } + + @Test + public void addToColList() { + StorageDescriptor sd = new StorageDescriptor(); + sd.addToCols(new FieldSchema("fred", "string", "")); + SharedStorageDescriptor ssd = new SharedStorageDescriptor(); + ssd.setShared(sd); + ssd.addToCols(new FieldSchema("joe", "int", "")); + Assert.assertFalse(sd.getCols() == ssd.getCols()); + Assert.assertEquals(2, ssd.getColsSize()); + Assert.assertEquals(1, sd.getColsSize()); + } + + @Test + public void colIterator() { + StorageDescriptor sd = new StorageDescriptor(); + sd.addToCols(new FieldSchema("fred", "string", "")); + SharedStorageDescriptor ssd = new SharedStorageDescriptor(); + ssd.setShared(sd); + Iterator iter = ssd.getColsIterator(); + Assert.assertTrue(iter.hasNext()); + Assert.assertEquals("fred", iter.next().getName()); + Assert.assertFalse(sd.getCols() == ssd.getCols()); + } + + @Test + public void setReadOnly() { + StorageDescriptor sd = new StorageDescriptor(); + sd.addToCols(new FieldSchema("fred", "string", "")); + SharedStorageDescriptor ssd = new SharedStorageDescriptor(); + ssd.setShared(sd); + ssd.setReadOnly(); + List cols = ssd.getCols(); + Assert.assertEquals(1, cols.size()); + Assert.assertTrue(sd.getCols() == ssd.getCols()); + } + }