001/*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.client;
019
020import java.util.Arrays;
021import java.util.Collection;
022import java.util.Comparator;
023import java.util.Iterator;
024import java.util.Map;
025import java.util.Optional;
026import java.util.Set;
027import java.util.stream.Collectors;
028import java.util.stream.Stream;
029import org.apache.hadoop.hbase.HConstants;
030import org.apache.hadoop.hbase.TableName;
031import org.apache.hadoop.hbase.util.Bytes;
032import org.apache.yetus.audience.InterfaceAudience;
033
034/**
035 * TableDescriptor contains the details about an HBase table such as the descriptors of all the
036 * column families, is the table a catalog table, <code> hbase:meta </code>, if the table is read
037 * only, the maximum size of the memstore, when the region split should occur, coprocessors
038 * associated with it etc...
039 */
040@InterfaceAudience.Public
041public interface TableDescriptor {
042
043  @InterfaceAudience.Private
044  Comparator<TableDescriptor> COMPARATOR = getComparator(ColumnFamilyDescriptor.COMPARATOR);
045
046  @InterfaceAudience.Private
047  Comparator<TableDescriptor> COMPARATOR_IGNORE_REPLICATION =
048    getComparator(ColumnFamilyDescriptor.COMPARATOR_IGNORE_REPLICATION);
049
050  static Comparator<TableDescriptor>
051    getComparator(Comparator<ColumnFamilyDescriptor> cfComparator) {
052    return (TableDescriptor lhs, TableDescriptor rhs) -> {
053      int result = lhs.getTableName().compareTo(rhs.getTableName());
054      if (result != 0) {
055        return result;
056      }
057      Collection<ColumnFamilyDescriptor> lhsFamilies = Arrays.asList(lhs.getColumnFamilies());
058      Collection<ColumnFamilyDescriptor> rhsFamilies = Arrays.asList(rhs.getColumnFamilies());
059      result = Integer.compare(lhsFamilies.size(), rhsFamilies.size());
060      if (result != 0) {
061        return result;
062      }
063
064      for (Iterator<ColumnFamilyDescriptor> it = lhsFamilies.iterator(),
065          it2 = rhsFamilies.iterator(); it.hasNext();) {
066        result = cfComparator.compare(it.next(), it2.next());
067        if (result != 0) {
068          return result;
069        }
070      }
071      // punt on comparison for ordering, just calculate difference
072      return Integer.compare(lhs.getValues().hashCode(), rhs.getValues().hashCode());
073    };
074  }
075
076  /**
077   * Returns the count of the column families of the table.
078   * @return Count of column families of the table
079   */
080  int getColumnFamilyCount();
081
082  /**
083   * Return the list of attached co-processor represented
084   * @return The list of CoprocessorDescriptor
085   */
086  Collection<CoprocessorDescriptor> getCoprocessorDescriptors();
087
088  /**
089   * Return the list of attached co-processor represented by their name className
090   * @return The list of co-processors classNames
091   * @deprecated As of release 2.0.0, this will be removed in HBase 3.0.0. Use
092   *             {@link #getCoprocessorDescriptors()} instead
093   */
094  @Deprecated
095  default Collection<String> getCoprocessors() {
096    return getCoprocessorDescriptors().stream().map(CoprocessorDescriptor::getClassName)
097      .collect(Collectors.toList());
098  }
099
100  /**
101   * Returns the durability setting for the table.
102   * @return durability setting for the table.
103   */
104  Durability getDurability();
105
106  /**
107   * Returns an unmodifiable collection of all the {@link ColumnFamilyDescriptor} of all the column
108   * families of the table.
109   * @return An array of {@link ColumnFamilyDescriptor} of all the column families.
110   */
111  ColumnFamilyDescriptor[] getColumnFamilies();
112
113  /**
114   * Returns all the column family names of the current table. The map of TableDescriptor contains
115   * mapping of family name to ColumnDescriptor. This returns all the keys of the family map which
116   * represents the column family names of the table.
117   * @return Immutable sorted set of the keys of the families.
118   */
119  Set<byte[]> getColumnFamilyNames();
120
121  /**
122   * Returns the ColumnDescriptor for a specific column family with name as specified by the
123   * parameter column.
124   * @param name Column family name
125   * @return Column descriptor for the passed family name or the family on passed in column.
126   */
127  ColumnFamilyDescriptor getColumnFamily(final byte[] name);
128
129  /**
130   * This gets the class associated with the flush policy which determines the stores need to be
131   * flushed when flushing a region. The class used by default is defined in
132   * org.apache.hadoop.hbase.regionserver.FlushPolicy.
133   * @return the class name of the flush policy for this table. If this returns null, the default
134   *         flush policy is used.
135   */
136  String getFlushPolicyClassName();
137
138  /**
139   * Returns the maximum size upto which a region can grow to after which a region split is
140   * triggered. The region size is represented by the size of the biggest store file in that region.
141   * @return max hregion size for table, -1 if not set.
142   */
143  long getMaxFileSize();
144
145  /**
146   * Returns the size of the memstore after which a flush to filesystem is triggered.
147   * @return memory cache flush size for each hregion, -1 if not set.
148   */
149  long getMemStoreFlushSize();
150
151  // TODO: Currently this is used RPC scheduling only. Make it more generic than this; allow it
152  // to also be priority when scheduling procedures that pertain to this table scheduling first
153  // those tables with the highest priority (From Yi Liang over on HBASE-18109).
154  int getPriority();
155
156  /** Returns Returns the configured replicas per region */
157  int getRegionReplication();
158
159  /**
160   * This gets the class associated with the region split policy which determines when a region
161   * split should occur. The class used by default is defined in
162   * org.apache.hadoop.hbase.regionserver.RegionSplitPolicy
163   * @return the class name of the region split policy for this table. If this returns null, the
164   *         default split policy is used.
165   */
166  String getRegionSplitPolicyClassName();
167
168  /**
169   * Get the name of the table
170   */
171  TableName getTableName();
172
173  /**
174   * Get the owner name as a string.
175   * @deprecated since 2.0.0 and will be removed in 3.0.0.
176   * @see <a href="https://issues.apache.org/jira/browse/HBASE-15583">HBASE-15583</a>
177   */
178  @Deprecated
179  String getOwnerString();
180
181  /**
182   * Getter for accessing the metadata associated with the key.
183   * @param key The key.
184   * @return A clone value. Null if no mapping for the key
185   */
186  Bytes getValue(Bytes key);
187
188  /**
189   * Getter for accessing the metadata associated with the key.
190   * @param key The key.
191   * @return A clone value. Null if no mapping for the key
192   */
193  byte[] getValue(byte[] key);
194
195  /**
196   * Getter for accessing the metadata associated with the key.
197   * @param key The key.
198   * @return Null if no mapping for the key
199   */
200  String getValue(String key);
201
202  /** Returns Getter for fetching an unmodifiable map. */
203  Map<Bytes, Bytes> getValues();
204
205  /**
206   * Check if the table has an attached co-processor represented by the name className
207   * @param classNameToMatch - Class name of the co-processor
208   * @return true of the table has a co-processor className
209   */
210  boolean hasCoprocessor(String classNameToMatch);
211
212  /**
213   * Checks to see if this table contains the given column family
214   * @param name Family name or column name.
215   * @return true if the table contains the specified family name
216   */
217  boolean hasColumnFamily(final byte[] name);
218
219  /** Returns true if the read-replicas memstore replication is enabled. */
220  boolean hasRegionMemStoreReplication();
221
222  /**
223   * Check if the compaction enable flag of the table is true. If flag is false then no minor/major
224   * compactions will be done in real.
225   * @return true if table compaction enabled
226   */
227  boolean isCompactionEnabled();
228
229  /**
230   * Check if the split enable flag of the table is true. If flag is false then no region split will
231   * be done.
232   * @return true if table region split enabled
233   */
234  boolean isSplitEnabled();
235
236  /**
237   * Check if the merge enable flag of the table is true. If flag is false then no region merge will
238   * be done.
239   * @return true if table region merge enabled
240   */
241  boolean isMergeEnabled();
242
243  /**
244   * Checks if this table is <code> hbase:meta </code> region.
245   * @return true if this table is <code> hbase:meta </code> region
246   */
247  boolean isMetaRegion();
248
249  /**
250   * Checks if the table is a <code>hbase:meta</code> table
251   * @return true if table is <code> hbase:meta </code> region.
252   */
253  boolean isMetaTable();
254
255  /**
256   * Check if normalization enable flag of the table is true. If flag is false then region
257   * normalizer won't attempt to normalize this table.
258   * @return true if region normalization is enabled for this table
259   */
260  boolean isNormalizationEnabled();
261
262  /**
263   * Check if there is the target region count. If so, the normalize plan will be calculated based
264   * on the target region count.
265   * @return target region count after normalize done
266   */
267  int getNormalizerTargetRegionCount();
268
269  /**
270   * Check if there is the target region size. If so, the normalize plan will be calculated based on
271   * the target region size.
272   * @return target region size after normalize done
273   */
274  long getNormalizerTargetRegionSize();
275
276  /**
277   * Check if the readOnly flag of the table is set. If the readOnly flag is set then the contents
278   * of the table can only be read from but not modified.
279   * @return true if all columns in the table should be read only
280   */
281  boolean isReadOnly();
282
283  /**
284   * The HDFS erasure coding policy for a table. This will be set on the data dir of the table, and
285   * is an alternative to normal replication which takes less space at the cost of locality.
286   * @return the current policy, or null if undefined
287   */
288  default String getErasureCodingPolicy() {
289    return null;
290  }
291
292  /**
293   * Returns Name of this table and then a map of all of the column family descriptors (with only
294   * the non-default column family attributes)
295   */
296  String toStringCustomizedValues();
297
298  /**
299   * Check if any of the table's cfs' replication scope are set to
300   * {@link HConstants#REPLICATION_SCOPE_GLOBAL}.
301   * @return {@code true} if we have, otherwise {@code false}.
302   */
303  default boolean hasGlobalReplicationScope() {
304    return Stream.of(getColumnFamilies())
305      .anyMatch(cf -> cf.getScope() == HConstants.REPLICATION_SCOPE_GLOBAL);
306  }
307
308  /**
309   * Check if the table's cfs' replication scope matched with the replication state
310   * @param enabled replication state
311   * @return true if matched, otherwise false
312   */
313  default boolean matchReplicationScope(boolean enabled) {
314    boolean hasEnabled = false;
315    boolean hasDisabled = false;
316
317    for (ColumnFamilyDescriptor cf : getColumnFamilies()) {
318      if (cf.getScope() != HConstants.REPLICATION_SCOPE_GLOBAL) {
319        hasDisabled = true;
320      } else {
321        hasEnabled = true;
322      }
323    }
324
325    if (hasEnabled && hasDisabled) {
326      return false;
327    }
328    if (hasEnabled) {
329      return enabled;
330    }
331    return !enabled;
332  }
333
334  /**
335   * Get the region server group this table belongs to. The regions of this table will be placed
336   * only on the region servers within this group. If not present, will be placed on
337   * {@link org.apache.hadoop.hbase.rsgroup.RSGroupInfo#DEFAULT_GROUP}.
338   */
339  Optional<String> getRegionServerGroup();
340}