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