Impala
Impalaistheopensource,nativeanalyticdatabaseforApacheHadoop.
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros
DescriptorTable.java
Go to the documentation of this file.
1 // Copyright 2012 Cloudera Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 package com.cloudera.impala.analysis;
16 
17 import java.util.Collection;
18 import java.util.HashMap;
19 import java.util.HashSet;
20 import java.util.List;
21 
24 import com.cloudera.impala.common.IdGenerator;
25 import com.cloudera.impala.thrift.TDescriptorTable;
26 import com.google.common.base.Preconditions;
27 import com.google.common.collect.Lists;
28 import com.google.common.collect.Maps;
29 import com.google.common.collect.Sets;
30 
36 public class DescriptorTable {
37  private final HashMap<TupleId, TupleDescriptor> tupleDescs_ = Maps.newHashMap();
38  private final HashMap<SlotId, SlotDescriptor> slotDescs_ = Maps.newHashMap();
39  private final IdGenerator<TupleId> tupleIdGenerator_ = TupleId.createGenerator();
40  private final IdGenerator<SlotId> slotIdGenerator_ = SlotId.createGenerator();
41  // List of referenced tables with no associated TupleDescriptor to ship to the BE.
42  // For example, the output table of an insert query.
43  private final List<Table> referencedTables_ = Lists.newArrayList();
44  // For each table, the set of partitions that are referenced by at least one scan range.
45  private final HashMap<Table, HashSet<Long>> referencedPartitionsPerTable_ =
46  Maps.newHashMap();
47 
48  public TupleDescriptor createTupleDescriptor(String debugName) {
49  TupleDescriptor d = new TupleDescriptor(tupleIdGenerator_.getNextId(), debugName);
50  tupleDescs_.put(d.getId(), d);
51  return d;
52  }
53 
58  public TupleDescriptor copyTupleDescriptor(TupleId srcId, String debugName) {
59  TupleDescriptor d = new TupleDescriptor(tupleIdGenerator_.getNextId(), debugName);
60  tupleDescs_.put(d.getId(), d);
61  // create copies of slots
62  TupleDescriptor src = tupleDescs_.get(srcId);
63  for (SlotDescriptor slot: src.getSlots()) {
64  copySlotDescriptor(d, slot);
65  }
66  d.computeMemLayout();
67  Preconditions.checkState(d.getByteSize() == src.getByteSize());
68  return d;
69  }
70 
72  SlotDescriptor result = new SlotDescriptor(slotIdGenerator_.getNextId(), d);
73  d.addSlot(result);
74  slotDescs_.put(result.getId(), result);
75  return result;
76  }
77 
82  SlotDescriptor result = new SlotDescriptor(slotIdGenerator_.getNextId(), dest, src);
83  dest.addSlot(result);
84  slotDescs_.put(result.getId(), result);
85  return result;
86  }
87 
88  public TupleDescriptor getTupleDesc(TupleId id) { return tupleDescs_.get(id); }
89  public SlotDescriptor getSlotDesc(SlotId id) { return slotDescs_.get(id); }
90  public Collection<TupleDescriptor> getTupleDescs() { return tupleDescs_.values(); }
91  public Collection<SlotDescriptor> getSlotDescs() { return slotDescs_.values(); }
92  public TupleId getMaxTupleId() { return tupleIdGenerator_.getMaxId(); }
93  public SlotId getMaxSlotId() { return slotIdGenerator_.getMaxId(); }
94 
95  public void addReferencedTable(Table table) {
96  referencedTables_.add(table);
97  }
98 
103  private HashSet<Long> getReferencedPartitions(Table table) {
104  HashSet<Long> refPartitions = referencedPartitionsPerTable_.get(table);
105  if (refPartitions == null) {
106  refPartitions = new HashSet<Long>();
107  referencedPartitionsPerTable_.put(table, refPartitions);
108  }
109  return refPartitions;
110  }
111 
116  public void addReferencedPartition(Table table, long partitionId) {
117  getReferencedPartitions(table).add(partitionId);
118  }
119 
123  public void markSlotsMaterialized(List<SlotId> ids) {
124  for (SlotId id: ids) {
125  getSlotDesc(id).setIsMaterialized(true);
126  }
127  }
128 
132  public List<SlotId> getTupleSlotIds(List<SlotId> slotIds, TupleId tupleId) {
133  List<SlotId> result = Lists.newArrayList();
134  for (SlotId id: slotIds) {
135  if (getSlotDesc(id).getParent().getId().equals(tupleId)) result.add(id);
136  }
137  return result;
138  }
139 
140  // Computes physical layout parameters of all descriptors.
141  // Call this only after the last descriptor was added.
142  // Test-only.
143  public void computeMemLayout() {
144  for (TupleDescriptor d: tupleDescs_.values()) {
145  d.computeMemLayout();
146  }
147  }
148 
149  public TDescriptorTable toThrift() {
150  TDescriptorTable result = new TDescriptorTable();
151  HashSet<Table> referencedTbls = Sets.newHashSet();
152  HashSet<Table> allPartitionsTbls = Sets.newHashSet();
153  for (TupleDescriptor tupleDesc: tupleDescs_.values()) {
154  // inline view of a non-constant select has a non-materialized tuple descriptor
155  // in the descriptor table just for type checking, which we need to skip
156  if (tupleDesc.isMaterialized()) {
157  result.addToTupleDescriptors(tupleDesc.toThrift());
158  Table table = tupleDesc.getTable();
159  if (table != null && !(table instanceof View)) referencedTbls.add(table);
160  for (SlotDescriptor slotD: tupleDesc.getSlots()) {
161  result.addToSlotDescriptors(slotD.toThrift());
162  }
163  }
164  }
165  for (Table table: referencedTables_) {
166  referencedTbls.add(table);
167  // We don't know which partitions are needed for INSERT, so include them all.
168  allPartitionsTbls.add(table);
169  }
170  for (Table tbl: referencedTbls) {
171  HashSet<Long> referencedPartitions = null; // null means include all partitions.
172  if (!allPartitionsTbls.contains(tbl)) {
173  referencedPartitions = getReferencedPartitions(tbl);
174  }
175  result.addToTableDescriptors(tbl.toThriftDescriptor(referencedPartitions));
176  }
177  return result;
178  }
179 
180  public String debugString() {
181  StringBuilder out = new StringBuilder();
182  out.append("tuples:\n");
183  for (TupleDescriptor desc: tupleDescs_.values()) {
184  out.append(desc.debugString() + "\n");
185  }
186  return out.toString();
187  }
188 }
void addReferencedPartition(Table table, long partitionId)
final HashMap< Table, HashSet< Long > > referencedPartitionsPerTable_
List< SlotId > getTupleSlotIds(List< SlotId > slotIds, TupleId tupleId)
TupleDescriptor copyTupleDescriptor(TupleId srcId, String debugName)
final IdGenerator< TupleId > tupleIdGenerator_
TupleDescriptor createTupleDescriptor(String debugName)
Collection< TupleDescriptor > getTupleDescs()
final IdGenerator< SlotId > slotIdGenerator_
Collection< SlotDescriptor > getSlotDescs()
SlotDescriptor copySlotDescriptor(TupleDescriptor dest, SlotDescriptor src)
HashSet< Long > getReferencedPartitions(Table table)
final HashMap< TupleId, TupleDescriptor > tupleDescs_
final HashMap< SlotId, SlotDescriptor > slotDescs_
SlotDescriptor addSlotDescriptor(TupleDescriptor d)