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