/** * 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.hadoop.hive.metastore.partition.spec; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.hadoop.hive.metastore.api.MetaException; import org.apache.hadoop.hive.metastore.api.Partition; import org.apache.hadoop.hive.metastore.api.PartitionSpec; import java.util.ArrayList; import java.util.List; import java.util.Map; /** * Implementation of PartitionSpecProxy that composes a list of PartitionSpecProxy. */ public class CompositePartitionSpecProxy extends PartitionSpecProxy { private String dbName; private String tableName; private List<PartitionSpec> partitionSpecs; private List<PartitionSpecProxy> partitionSpecProxies; private int size = 0; protected CompositePartitionSpecProxy(List<PartitionSpec> partitionSpecs) { this.partitionSpecs = partitionSpecs; if (partitionSpecs.isEmpty()) { dbName = null; tableName = null; } else { dbName = partitionSpecs.get(0).getDbName(); tableName = partitionSpecs.get(0).getTableName(); this.partitionSpecProxies = new ArrayList<PartitionSpecProxy>(partitionSpecs.size()); for (PartitionSpec partitionSpec : partitionSpecs) { PartitionSpecProxy partitionSpecProxy = Factory.get(partitionSpec); this.partitionSpecProxies.add(partitionSpecProxy); size += partitionSpecProxy.size(); } } // Assert class-invariant. assert isValid() : "Invalid CompositePartitionSpecProxy!"; } protected CompositePartitionSpecProxy(String dbName, String tableName, List<PartitionSpec> partitionSpecs) { this.dbName = dbName; this.tableName = tableName; this.partitionSpecs = partitionSpecs; this.partitionSpecProxies = new ArrayList<PartitionSpecProxy>(partitionSpecs.size()); for (PartitionSpec partitionSpec : partitionSpecs) { this.partitionSpecProxies.add(PartitionSpecProxy.Factory.get(partitionSpec)); } // Assert class-invariant. assert isValid() : "Invalid CompositePartitionSpecProxy!"; } private boolean isValid() { for (PartitionSpecProxy partitionSpecProxy : partitionSpecProxies) { if (partitionSpecProxy instanceof CompositePartitionSpecProxy) { return false; } } return true; } @Override public int size() { return size; } /** * Iterator to iterate over all Partitions, across all PartitionSpecProxy instances within the Composite. */ public static class Iterator implements PartitionIterator { private CompositePartitionSpecProxy composite; private List<PartitionSpecProxy> partitionSpecProxies; private int index = -1; // Index into partitionSpecs. private PartitionIterator iterator = null; public Iterator(CompositePartitionSpecProxy composite) { this.composite = composite; this.partitionSpecProxies = composite.partitionSpecProxies; if (this.partitionSpecProxies != null && !this.partitionSpecProxies.isEmpty()) { this.index = 0; this.iterator = this.partitionSpecProxies.get(this.index).getPartitionIterator(); } } @Override public boolean hasNext() { if (iterator == null) { return false; } if (iterator.hasNext()) { return true; } while ( ++index < partitionSpecProxies.size() && !(iterator = partitionSpecProxies.get(index).getPartitionIterator()).hasNext()); return index < partitionSpecProxies.size() && iterator.hasNext(); } @Override public Partition next() { if (iterator.hasNext()) return iterator.next(); while (++index < partitionSpecProxies.size() && !(iterator = partitionSpecProxies.get(index).getPartitionIterator()).hasNext()); return index == partitionSpecProxies.size()? null : iterator.next(); } @Override public void remove() { iterator.remove(); } @Override public Partition getCurrent() { return iterator.getCurrent(); } @Override public String getDbName() { return composite.dbName; } @Override public String getTableName() { return composite.tableName; } @Override public Map<String, String> getParameters() { return iterator.getParameters(); } @Override public void setParameters(Map<String, String> parameters) { iterator.setParameters(parameters); } @Override public String getLocation() { return iterator.getLocation(); } @Override public void putToParameters(String key, String value) { iterator.putToParameters(key, value); } @Override public void setCreateTime(long time) { iterator.setCreateTime(time); } } @Override public void setDbName(String dbName) { this.dbName = dbName; for (PartitionSpecProxy partSpecProxy : partitionSpecProxies) { partSpecProxy.setDbName(dbName); } } @Override public void setTableName(String tableName) { this.tableName = tableName; for (PartitionSpecProxy partSpecProxy : partitionSpecProxies) { partSpecProxy.setTableName(tableName); } } @Override public String getDbName() { return dbName; } @Override public String getTableName() { return tableName; } @Override public PartitionIterator getPartitionIterator() { return new Iterator(this); } @Override public List<PartitionSpec> toPartitionSpec() { return partitionSpecs; } @Override public void setRootLocation(String rootLocation) throws MetaException { for (PartitionSpecProxy partSpecProxy : partitionSpecProxies) { partSpecProxy.setRootLocation(rootLocation); } } }