1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one
3  * or more contributor license agreements.  See the NOTICE file
4  * distributed with this work for additional information
5  * regarding copyright ownership.  The ASF licenses this file
6  * to you under the Apache License, Version 2.0 (the
7  * "License"); you may not use this file except in compliance
8  * with the License.  You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18 package org.apache.hadoop.hbase.regionserver;
19 
20 import java.io.IOException;
21 import java.util.Collection;
22 import java.util.List;
23 import java.util.Map;
24 
25 import org.apache.hadoop.hbase.Cell;
26 import org.apache.hadoop.hbase.HBaseInterfaceAudience;
27 import org.apache.hadoop.hbase.HDFSBlocksDistribution;
28 import org.apache.hadoop.hbase.HRegionInfo;
29 import org.apache.hadoop.hbase.HTableDescriptor;
30 import org.apache.hadoop.hbase.classification.InterfaceAudience;
31 import org.apache.hadoop.hbase.classification.InterfaceStability;
32 import org.apache.hadoop.hbase.client.Append;
33 import org.apache.hadoop.hbase.client.Delete;
34 import org.apache.hadoop.hbase.client.Get;
35 import org.apache.hadoop.hbase.client.Increment;
36 import org.apache.hadoop.hbase.client.IsolationLevel;
37 import org.apache.hadoop.hbase.client.Mutation;
38 import org.apache.hadoop.hbase.client.Put;
39 import org.apache.hadoop.hbase.client.Result;
40 import org.apache.hadoop.hbase.client.RowMutations;
41 import org.apache.hadoop.hbase.client.Scan;
42 import org.apache.hadoop.hbase.conf.ConfigurationObserver;
43 import org.apache.hadoop.hbase.exceptions.FailedSanityCheckException;
44 import org.apache.hadoop.hbase.filter.ByteArrayComparable;
45 import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
46 import org.apache.hadoop.hbase.protobuf.generated.AdminProtos.GetRegionInfoResponse.CompactionState;
47 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.CoprocessorServiceCall;
48 import org.apache.hadoop.hbase.util.Pair;
49 import org.apache.hadoop.hbase.wal.WALSplitter.MutationReplay;
50 
51 import com.google.common.annotations.VisibleForTesting;
52 import com.google.protobuf.Message;
53 import com.google.protobuf.RpcController;
54 import com.google.protobuf.Service;
55 
56 /**
57  * Regions store data for a certain region of a table.  It stores all columns
58  * for each row. A given table consists of one or more Regions.
59  *
60  * <p>An Region is defined by its table and its key extent.
61  *
62  * <p>Locking at the Region level serves only one purpose: preventing the
63  * region from being closed (and consequently split) while other operations
64  * are ongoing. Each row level operation obtains both a row lock and a region
65  * read lock for the duration of the operation. While a scanner is being
66  * constructed, getScanner holds a read lock. If the scanner is successfully
67  * constructed, it holds a read lock until it is closed. A close takes out a
68  * write lock and consequently will block for ongoing operations and will block
69  * new operations from starting while the close is in progress.
70  */
71 @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC)
72 @InterfaceStability.Evolving
73 public interface Region extends ConfigurationObserver {
74 
75   ///////////////////////////////////////////////////////////////////////////
76   // Region state
77 
78   /** @return region information for this region */
getRegionInfo()79   HRegionInfo getRegionInfo();
80 
81   /** @return table descriptor for this region */
getTableDesc()82   HTableDescriptor getTableDesc();
83 
84   /** @return true if region is available (not closed and not closing) */
isAvailable()85   boolean isAvailable();
86 
87   /** @return true if region is closed */
isClosed()88   boolean isClosed();
89 
90   /** @return True if closing process has started */
isClosing()91   boolean isClosing();
92 
93   /** @return True if region is in recovering state */
isRecovering()94   boolean isRecovering();
95 
96   /** @return True if region is read only */
isReadOnly()97   boolean isReadOnly();
98 
99   /**
100    * Return the list of Stores managed by this region
101    * <p>Use with caution.  Exposed for use of fixup utilities.
102    * @return a list of the Stores managed by this region
103    */
getStores()104   List<Store> getStores();
105 
106   /**
107    * Return the Store for the given family
108    * <p>Use with caution.  Exposed for use of fixup utilities.
109    * @return the Store for the given family
110    */
getStore(byte[] family)111   Store getStore(byte[] family);
112 
113   /** @return list of store file names for the given families */
getStoreFileList(byte [][] columns)114   List<String> getStoreFileList(byte [][] columns);
115 
116   /**
117    * Check the region's underlying store files, open the files that have not
118    * been opened yet, and remove the store file readers for store files no
119    * longer available.
120    * @throws IOException
121    */
refreshStoreFiles()122   boolean refreshStoreFiles() throws IOException;
123 
124   /** @return the latest sequence number that was read from storage when this region was opened */
getOpenSeqNum()125   long getOpenSeqNum();
126 
127   /** @return the max sequence id of flushed data on this region; no edit in memory will have
128    * a sequence id that is less that what is returned here.
129    */
getMaxFlushedSeqId()130   long getMaxFlushedSeqId();
131 
132   /** @return the oldest flushed sequence id for the given family; can be beyond
133    * {@link #getMaxFlushedSeqId()} in case where we've flushed a subset of a regions column
134    * families
135    * @deprecated Since version 1.2.0. Exposes too much about our internals; shutting it down.
136    * Do not use.
137    */
138   @VisibleForTesting
139   @Deprecated
getOldestSeqIdOfStore(byte[] familyName)140   public long getOldestSeqIdOfStore(byte[] familyName);
141 
142   /**
143    * This can be used to determine the last time all files of this region were major compacted.
144    * @param majorCompactioOnly Only consider HFile that are the result of major compaction
145    * @return the timestamp of the oldest HFile for all stores of this region
146    */
getOldestHfileTs(boolean majorCompactioOnly)147   long getOldestHfileTs(boolean majorCompactioOnly) throws IOException;
148 
149   /**
150    * @return map of column family names to max sequence id that was read from storage when this
151    * region was opened
152    */
getMaxStoreSeqId()153   public Map<byte[], Long> getMaxStoreSeqId();
154 
155   /** @return true if loading column families on demand by default */
isLoadingCfsOnDemandDefault()156   boolean isLoadingCfsOnDemandDefault();
157 
158   /** @return readpoint considering given IsolationLevel */
getReadpoint(IsolationLevel isolationLevel)159   long getReadpoint(IsolationLevel isolationLevel);
160 
161   /**
162    * @return The earliest time a store in the region was flushed. All
163    *         other stores in the region would have been flushed either at, or
164    *         after this time.
165    */
getEarliestFlushTimeForAllStores()166   long getEarliestFlushTimeForAllStores();
167 
168   ///////////////////////////////////////////////////////////////////////////
169   // Metrics
170 
171   /** @return read requests count for this region */
getReadRequestsCount()172   long getReadRequestsCount();
173 
174   /**
175    * Update the read request count for this region
176    * @param i increment
177    */
updateReadRequestsCount(long i)178   void updateReadRequestsCount(long i);
179 
180   /** @return write request count for this region */
getWriteRequestsCount()181   long getWriteRequestsCount();
182 
183   /**
184    * Update the write request count for this region
185    * @param i increment
186    */
updateWriteRequestsCount(long i)187   void updateWriteRequestsCount(long i);
188 
189   /** @return memstore size for this region, in bytes */
getMemstoreSize()190   long getMemstoreSize();
191 
192   /** @return the number of mutations processed bypassing the WAL */
getNumMutationsWithoutWAL()193   long getNumMutationsWithoutWAL();
194 
195   /** @return the size of data processed bypassing the WAL, in bytes */
getDataInMemoryWithoutWAL()196   long getDataInMemoryWithoutWAL();
197 
198   /** @return the number of blocked requests */
getBlockedRequestsCount()199   long getBlockedRequestsCount();
200 
201   /** @return the number of checkAndMutate guards that passed */
getCheckAndMutateChecksPassed()202   long getCheckAndMutateChecksPassed();
203 
204   /** @return the number of failed checkAndMutate guards */
getCheckAndMutateChecksFailed()205   long getCheckAndMutateChecksFailed();
206 
207   /** @return the MetricsRegion for this region */
getMetrics()208   MetricsRegion getMetrics();
209 
210   /** @return the block distribution for all Stores managed by this region */
getHDFSBlocksDistribution()211   HDFSBlocksDistribution getHDFSBlocksDistribution();
212 
213   ///////////////////////////////////////////////////////////////////////////
214   // Locking
215 
216   // Region read locks
217 
218   /**
219    * Operation enum is used in {@link Region#startRegionOperation} to provide context for
220    * various checks before any region operation begins.
221    */
222   enum Operation {
223     ANY, GET, PUT, DELETE, SCAN, APPEND, INCREMENT, SPLIT_REGION, MERGE_REGION, BATCH_MUTATE,
224     REPLAY_BATCH_MUTATE, COMPACT_REGION, REPLAY_EVENT
225   }
226 
227   /**
228    * This method needs to be called before any public call that reads or
229    * modifies data.
230    * Acquires a read lock and checks if the region is closing or closed.
231    * <p>{@link #closeRegionOperation} MUST then always be called after
232    * the operation has completed, whether it succeeded or failed.
233    * @throws IOException
234    */
startRegionOperation()235   void startRegionOperation() throws IOException;
236 
237   /**
238    * This method needs to be called before any public call that reads or
239    * modifies data.
240    * Acquires a read lock and checks if the region is closing or closed.
241    * <p>{@link #closeRegionOperation} MUST then always be called after
242    * the operation has completed, whether it succeeded or failed.
243    * @param op The operation is about to be taken on the region
244    * @throws IOException
245    */
startRegionOperation(Operation op)246   void startRegionOperation(Operation op) throws IOException;
247 
248   /**
249    * Closes the region operation lock.
250    * @throws IOException
251    */
closeRegionOperation()252   void closeRegionOperation() throws IOException;
253 
254   // Row write locks
255 
256   /**
257    * Row lock held by a given thread.
258    * One thread may acquire multiple locks on the same row simultaneously.
259    * The locks must be released by calling release() from the same thread.
260    */
261   public interface RowLock {
262     /**
263      * Release the given lock.  If there are no remaining locks held by the current thread
264      * then unlock the row and allow other threads to acquire the lock.
265      * @throws IllegalArgumentException if called by a different thread than the lock owning
266      *     thread
267      */
release()268     void release();
269   }
270 
271   /**
272    * Tries to acquire a lock on the given row.
273    * @param waitForLock if true, will block until the lock is available.
274    *        Otherwise, just tries to obtain the lock and returns
275    *        false if unavailable.
276    * @return the row lock if acquired,
277    *   null if waitForLock was false and the lock was not acquired
278    * @throws IOException if waitForLock was true and the lock could not be acquired after waiting
279    */
getRowLock(byte[] row, boolean waitForLock)280   RowLock getRowLock(byte[] row, boolean waitForLock) throws IOException;
281 
282   /**
283    * If the given list of row locks is not null, releases all locks.
284    */
releaseRowLocks(List<RowLock> rowLocks)285   void releaseRowLocks(List<RowLock> rowLocks);
286 
287   ///////////////////////////////////////////////////////////////////////////
288   // Region operations
289 
290   /**
291    * Perform one or more append operations on a row.
292    * @param append
293    * @param nonceGroup
294    * @param nonce
295    * @return result of the operation
296    * @throws IOException
297    */
append(Append append, long nonceGroup, long nonce)298   Result append(Append append, long nonceGroup, long nonce) throws IOException;
299 
300   /**
301    * Perform a batch of mutations.
302    * <p>
303    * Note this supports only Put and Delete mutations and will ignore other types passed.
304    * @param mutations the list of mutations
305    * @param nonceGroup
306    * @param nonce
307    * @return an array of OperationStatus which internally contains the
308    *         OperationStatusCode and the exceptionMessage if any.
309    * @throws IOException
310    */
batchMutate(Mutation[] mutations, long nonceGroup, long nonce)311   OperationStatus[] batchMutate(Mutation[] mutations, long nonceGroup, long nonce)
312       throws IOException;
313 
314   /**
315    * Replay a batch of mutations.
316    * @param mutations mutations to replay.
317    * @param replaySeqId
318    * @return an array of OperationStatus which internally contains the
319    *         OperationStatusCode and the exceptionMessage if any.
320    * @throws IOException
321    */
batchReplay(MutationReplay[] mutations, long replaySeqId)322    OperationStatus[] batchReplay(MutationReplay[] mutations, long replaySeqId) throws IOException;
323 
324   /**
325    * Atomically checks if a row/family/qualifier value matches the expected val
326    * If it does, it performs the row mutations.  If the passed value is null, t
327    * is for the lack of column (ie: non-existence)
328    * @param row to check
329    * @param family column family to check
330    * @param qualifier column qualifier to check
331    * @param compareOp the comparison operator
332    * @param comparator
333    * @param mutation
334    * @param writeToWAL
335    * @return true if mutation was applied, false otherwise
336    * @throws IOException
337    */
checkAndMutate(byte [] row, byte [] family, byte [] qualifier, CompareOp compareOp, ByteArrayComparable comparator, Mutation mutation, boolean writeToWAL)338   boolean checkAndMutate(byte [] row, byte [] family, byte [] qualifier, CompareOp compareOp,
339       ByteArrayComparable comparator, Mutation mutation, boolean writeToWAL) throws IOException;
340 
341   /**
342    * Atomically checks if a row/family/qualifier value matches the expected val
343    * If it does, it performs the row mutations.  If the passed value is null, t
344    * is for the lack of column (ie: non-existence)
345    * @param row to check
346    * @param family column family to check
347    * @param qualifier column qualifier to check
348    * @param compareOp the comparison operator
349    * @param comparator
350    * @param mutations
351    * @param writeToWAL
352    * @return true if mutation was applied, false otherwise
353    * @throws IOException
354    */
checkAndRowMutate(byte [] row, byte [] family, byte [] qualifier, CompareOp compareOp, ByteArrayComparable comparator, RowMutations mutations, boolean writeToWAL)355   boolean checkAndRowMutate(byte [] row, byte [] family, byte [] qualifier, CompareOp compareOp,
356       ByteArrayComparable comparator, RowMutations mutations, boolean writeToWAL)
357       throws IOException;
358 
359   /**
360    * Deletes the specified cells/row.
361    * @param delete
362    * @throws IOException
363    */
delete(Delete delete)364   void delete(Delete delete) throws IOException;
365 
366   /**
367    * Do a get based on the get parameter.
368    * @param get query parameters
369    * @return result of the operation
370    */
get(Get get)371   Result get(Get get) throws IOException;
372 
373   /**
374    * Do a get based on the get parameter.
375    * @param get query parameters
376    * @param withCoprocessor invoke coprocessor or not. We don't want to
377    * always invoke cp.
378    * @return list of cells resulting from the operation
379    */
get(Get get, boolean withCoprocessor)380   List<Cell> get(Get get, boolean withCoprocessor) throws IOException;
381 
382   /**
383    * Return all the data for the row that matches <i>row</i> exactly,
384    * or the one that immediately preceeds it, at or immediately before
385    * <i>ts</i>.
386    * @param row
387    * @param family
388    * @return result of the operation
389    * @throws IOException
390    */
getClosestRowBefore(byte[] row, byte[] family)391   Result getClosestRowBefore(byte[] row, byte[] family) throws IOException;
392 
393   /**
394    * Return an iterator that scans over the HRegion, returning the indicated
395    * columns and rows specified by the {@link Scan}.
396    * <p>
397    * This Iterator must be closed by the caller.
398    *
399    * @param scan configured {@link Scan}
400    * @return RegionScanner
401    * @throws IOException read exceptions
402    */
getScanner(Scan scan)403   RegionScanner getScanner(Scan scan) throws IOException;
404 
405   /**
406    * Return an iterator that scans over the HRegion, returning the indicated columns and rows
407    * specified by the {@link Scan}. The scanner will also include the additional scanners passed
408    * along with the scanners for the specified Scan instance. Should be careful with the usage to
409    * pass additional scanners only within this Region
410    * <p>
411    * This Iterator must be closed by the caller.
412    *
413    * @param scan configured {@link Scan}
414    * @param additionalScanners Any additional scanners to be used
415    * @return RegionScanner
416    * @throws IOException read exceptions
417    */
getScanner(Scan scan, List<KeyValueScanner> additionalScanners)418   RegionScanner getScanner(Scan scan, List<KeyValueScanner> additionalScanners) throws IOException;
419 
420   /**
421    * Perform one or more increment operations on a row.
422    * @param increment
423    * @param nonceGroup
424    * @param nonce
425    * @return result of the operation
426    * @throws IOException
427    */
increment(Increment increment, long nonceGroup, long nonce)428   Result increment(Increment increment, long nonceGroup, long nonce) throws IOException;
429 
430   /**
431    * Performs multiple mutations atomically on a single row. Currently
432    * {@link Put} and {@link Delete} are supported.
433    *
434    * @param mutations object that specifies the set of mutations to perform atomically
435    * @throws IOException
436    */
mutateRow(RowMutations mutations)437   void mutateRow(RowMutations mutations) throws IOException;
438 
439   /**
440    * Perform atomic mutations within the region.
441    *
442    * @param mutations The list of mutations to perform.
443    * <code>mutations</code> can contain operations for multiple rows.
444    * Caller has to ensure that all rows are contained in this region.
445    * @param rowsToLock Rows to lock
446    * @param nonceGroup Optional nonce group of the operation (client Id)
447    * @param nonce Optional nonce of the operation (unique random id to ensure "more idempotence")
448    * If multiple rows are locked care should be taken that
449    * <code>rowsToLock</code> is sorted in order to avoid deadlocks.
450    * @throws IOException
451    */
mutateRowsWithLocks(Collection<Mutation> mutations, Collection<byte[]> rowsToLock, long nonceGroup, long nonce)452   void mutateRowsWithLocks(Collection<Mutation> mutations, Collection<byte[]> rowsToLock,
453       long nonceGroup, long nonce) throws IOException;
454 
455   /**
456    * Performs atomic multiple reads and writes on a given row.
457    *
458    * @param processor The object defines the reads and writes to a row.
459    */
processRowsWithLocks(RowProcessor<?,?> processor)460   void processRowsWithLocks(RowProcessor<?,?> processor) throws IOException;
461 
462   /**
463    * Performs atomic multiple reads and writes on a given row.
464    *
465    * @param processor The object defines the reads and writes to a row.
466    * @param nonceGroup Optional nonce group of the operation (client Id)
467    * @param nonce Optional nonce of the operation (unique random id to ensure "more idempotence")
468    */
processRowsWithLocks(RowProcessor<?,?> processor, long nonceGroup, long nonce)469   void processRowsWithLocks(RowProcessor<?,?> processor, long nonceGroup, long nonce)
470       throws IOException;
471 
472   /**
473    * Performs atomic multiple reads and writes on a given row.
474    *
475    * @param processor The object defines the reads and writes to a row.
476    * @param timeout The timeout of the processor.process() execution
477    *                Use a negative number to switch off the time bound
478    * @param nonceGroup Optional nonce group of the operation (client Id)
479    * @param nonce Optional nonce of the operation (unique random id to ensure "more idempotence")
480    */
processRowsWithLocks(RowProcessor<?,?> processor, long timeout, long nonceGroup, long nonce)481   void processRowsWithLocks(RowProcessor<?,?> processor, long timeout, long nonceGroup, long nonce)
482       throws IOException;
483 
484   /**
485    * Puts some data in the table.
486    * @param put
487    * @throws IOException
488    */
put(Put put)489   void put(Put put) throws IOException;
490 
491   /**
492    * Listener class to enable callers of
493    * bulkLoadHFile() to perform any necessary
494    * pre/post processing of a given bulkload call
495    */
496   interface BulkLoadListener {
497 
498     /**
499      * Called before an HFile is actually loaded
500      * @param family family being loaded to
501      * @param srcPath path of HFile
502      * @return final path to be used for actual loading
503      * @throws IOException
504      */
prepareBulkLoad(byte[] family, String srcPath)505     String prepareBulkLoad(byte[] family, String srcPath) throws IOException;
506 
507     /**
508      * Called after a successful HFile load
509      * @param family family being loaded to
510      * @param srcPath path of HFile
511      * @throws IOException
512      */
doneBulkLoad(byte[] family, String srcPath)513     void doneBulkLoad(byte[] family, String srcPath) throws IOException;
514 
515     /**
516      * Called after a failed HFile load
517      * @param family family being loaded to
518      * @param srcPath path of HFile
519      * @throws IOException
520      */
failedBulkLoad(byte[] family, String srcPath)521     void failedBulkLoad(byte[] family, String srcPath) throws IOException;
522   }
523 
524   /**
525    * Attempts to atomically load a group of hfiles.  This is critical for loading
526    * rows with multiple column families atomically.
527    *
528    * @param familyPaths List of Pair&lt;byte[] column family, String hfilePath&gt;
529    * @param bulkLoadListener Internal hooks enabling massaging/preparation of a
530    * file about to be bulk loaded
531    * @param assignSeqId
532    * @return true if successful, false if failed recoverably
533    * @throws IOException if failed unrecoverably.
534    */
bulkLoadHFiles(Collection<Pair<byte[], String>> familyPaths, boolean assignSeqId, BulkLoadListener bulkLoadListener)535   boolean bulkLoadHFiles(Collection<Pair<byte[], String>> familyPaths, boolean assignSeqId,
536       BulkLoadListener bulkLoadListener) throws IOException;
537 
538   ///////////////////////////////////////////////////////////////////////////
539   // Coprocessors
540 
541   /** @return the coprocessor host */
getCoprocessorHost()542   RegionCoprocessorHost getCoprocessorHost();
543 
544   /**
545    * Executes a single protocol buffer coprocessor endpoint {@link Service} method using
546    * the registered protocol handlers.  {@link Service} implementations must be registered via the
547    * {@link Region#registerService(com.google.protobuf.Service)}
548    * method before they are available.
549    *
550    * @param controller an {@code RpcContoller} implementation to pass to the invoked service
551    * @param call a {@code CoprocessorServiceCall} instance identifying the service, method,
552    *     and parameters for the method invocation
553    * @return a protocol buffer {@code Message} instance containing the method's result
554    * @throws IOException if no registered service handler is found or an error
555    *     occurs during the invocation
556    * @see org.apache.hadoop.hbase.regionserver.Region#registerService(com.google.protobuf.Service)
557    */
execService(RpcController controller, CoprocessorServiceCall call)558   Message execService(RpcController controller, CoprocessorServiceCall call) throws IOException;
559 
560   /**
561    * Registers a new protocol buffer {@link Service} subclass as a coprocessor endpoint to
562    * be available for handling
563    * {@link Region#execService(com.google.protobuf.RpcController,
564    *    org.apache.hadoop.hbase.protobuf.generated.ClientProtos.CoprocessorServiceCall)}} calls.
565    *
566    * <p>
567    * Only a single instance may be registered per region for a given {@link Service} subclass (the
568    * instances are keyed on {@link com.google.protobuf.Descriptors.ServiceDescriptor#getFullName()}.
569    * After the first registration, subsequent calls with the same service name will fail with
570    * a return value of {@code false}.
571    * </p>
572    * @param instance the {@code Service} subclass instance to expose as a coprocessor endpoint
573    * @return {@code true} if the registration was successful, {@code false}
574    * otherwise
575    */
registerService(Service instance)576   boolean registerService(Service instance);
577 
578   ///////////////////////////////////////////////////////////////////////////
579   // RowMutation processor support
580 
581   /**
582    * Check the collection of families for validity.
583    * @param families
584    * @throws NoSuchColumnFamilyException
585    */
checkFamilies(Collection<byte[]> families)586   void checkFamilies(Collection<byte[]> families) throws NoSuchColumnFamilyException;
587 
588   /**
589    * Check the collection of families for valid timestamps
590    * @param familyMap
591    * @param now current timestamp
592    * @throws FailedSanityCheckException
593    */
checkTimestamps(Map<byte[], List<Cell>> familyMap, long now)594   void checkTimestamps(Map<byte[], List<Cell>> familyMap, long now)
595       throws FailedSanityCheckException;
596 
597   /**
598    * Prepare a delete for a row mutation processor
599    * @param delete The passed delete is modified by this method. WARNING!
600    * @throws IOException
601    */
prepareDelete(Delete delete)602   void prepareDelete(Delete delete) throws IOException;
603 
604   /**
605    * Set up correct timestamps in the KVs in Delete object.
606    * <p>Caller should have the row and region locks.
607    * @param mutation
608    * @param familyCellMap
609    * @param now
610    * @throws IOException
611    */
prepareDeleteTimestamps(Mutation mutation, Map<byte[], List<Cell>> familyCellMap, byte[] now)612   void prepareDeleteTimestamps(Mutation mutation, Map<byte[], List<Cell>> familyCellMap,
613       byte[] now) throws IOException;
614 
615   /**
616    * Replace any cell timestamps set to HConstants#LATEST_TIMESTAMP with the
617    * provided current timestamp.
618    * @param values
619    * @param now
620    */
updateCellTimestamps(final Iterable<List<Cell>> values, final byte[] now)621   void updateCellTimestamps(final Iterable<List<Cell>> values, final byte[] now)
622       throws IOException;
623 
624   ///////////////////////////////////////////////////////////////////////////
625   // Flushes, compactions, splits, etc.
626   // Wizards only, please
627 
628   interface FlushResult {
629     enum Result {
630       FLUSHED_NO_COMPACTION_NEEDED,
631       FLUSHED_COMPACTION_NEEDED,
632       // Special case where a flush didn't run because there's nothing in the memstores. Used when
633       // bulk loading to know when we can still load even if a flush didn't happen.
634       CANNOT_FLUSH_MEMSTORE_EMPTY,
635       CANNOT_FLUSH
636     }
637 
638     /** @return the detailed result code */
getResult()639     Result getResult();
640 
641     /** @return true if the memstores were flushed, else false */
isFlushSucceeded()642     boolean isFlushSucceeded();
643 
644     /** @return True if the flush requested a compaction, else false */
isCompactionNeeded()645     boolean isCompactionNeeded();
646   }
647 
648   /**
649    * Flush the cache.
650    *
651    * <p>When this method is called the cache will be flushed unless:
652    * <ol>
653    *   <li>the cache is empty</li>
654    *   <li>the region is closed.</li>
655    *   <li>a flush is already in progress</li>
656    *   <li>writes are disabled</li>
657    * </ol>
658    *
659    * <p>This method may block for some time, so it should not be called from a
660    * time-sensitive thread.
661    * @param force whether we want to force a flush of all stores
662    * @return FlushResult indicating whether the flush was successful or not and if
663    * the region needs compacting
664    *
665    * @throws IOException general io exceptions
666    * because a snapshot was not properly persisted.
667    */
flush(boolean force)668   FlushResult flush(boolean force) throws IOException;
669 
670   /**
671    * Synchronously compact all stores in the region.
672    * <p>This operation could block for a long time, so don't call it from a
673    * time-sensitive thread.
674    * <p>Note that no locks are taken to prevent possible conflicts between
675    * compaction and splitting activities. The regionserver does not normally compact
676    * and split in parallel. However by calling this method you may introduce
677    * unexpected and unhandled concurrency. Don't do this unless you know what
678    * you are doing.
679    *
680    * @param majorCompaction True to force a major compaction regardless of thresholds
681    * @throws IOException
682    */
compact(final boolean majorCompaction)683   void compact(final boolean majorCompaction) throws IOException;
684 
685   /**
686    * Trigger major compaction on all stores in the region.
687    * <p>
688    * Compaction will be performed asynchronously to this call by the RegionServer's
689    * CompactSplitThread. See also {@link Store#triggerMajorCompaction()}
690    * @throws IOException
691    */
triggerMajorCompaction()692   void triggerMajorCompaction() throws IOException;
693 
694   /**
695    * @return if a given region is in compaction now.
696    */
getCompactionState()697   CompactionState getCompactionState();
698 
699   /** Wait for all current flushes and compactions of the region to complete */
waitForFlushesAndCompactions()700   void waitForFlushesAndCompactions();
701 
702 }
703