View Javadoc

1   /*
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  
16  package org.apache.hadoop.hbase.coprocessor;
17  
18  import java.io.IOException;
19  import java.util.List;
20  import java.util.NavigableSet;
21  
22  import org.apache.hadoop.classification.InterfaceAudience;
23  import org.apache.hadoop.classification.InterfaceStability;
24  import org.apache.hadoop.fs.FileSystem;
25  import org.apache.hadoop.fs.Path;
26  import org.apache.hadoop.hbase.Cell;
27  import org.apache.hadoop.hbase.Coprocessor;
28  import org.apache.hadoop.hbase.HBaseInterfaceAudience;
29  import org.apache.hadoop.hbase.HRegionInfo;
30  import org.apache.hadoop.hbase.KeyValue;
31  import org.apache.hadoop.hbase.client.Append;
32  import org.apache.hadoop.hbase.client.Delete;
33  import org.apache.hadoop.hbase.client.Durability;
34  import org.apache.hadoop.hbase.client.Get;
35  import org.apache.hadoop.hbase.client.Increment;
36  import org.apache.hadoop.hbase.client.Mutation;
37  import org.apache.hadoop.hbase.client.Put;
38  import org.apache.hadoop.hbase.client.Result;
39  import org.apache.hadoop.hbase.client.Scan;
40  import org.apache.hadoop.hbase.filter.ByteArrayComparable;
41  import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
42  import org.apache.hadoop.hbase.io.FSDataInputStreamWrapper;
43  import org.apache.hadoop.hbase.io.Reference;
44  import org.apache.hadoop.hbase.io.hfile.CacheConfig;
45  import org.apache.hadoop.hbase.regionserver.DeleteTracker;
46  import org.apache.hadoop.hbase.regionserver.HRegion;
47  import org.apache.hadoop.hbase.regionserver.HRegion.Operation;
48  import org.apache.hadoop.hbase.regionserver.InternalScanner;
49  import org.apache.hadoop.hbase.regionserver.KeyValueScanner;
50  import org.apache.hadoop.hbase.regionserver.MiniBatchOperationInProgress;
51  import org.apache.hadoop.hbase.regionserver.OperationStatus;
52  import org.apache.hadoop.hbase.regionserver.RegionScanner;
53  import org.apache.hadoop.hbase.regionserver.ScanType;
54  import org.apache.hadoop.hbase.regionserver.Store;
55  import org.apache.hadoop.hbase.regionserver.StoreFile;
56  import org.apache.hadoop.hbase.regionserver.StoreFileScanner;
57  import org.apache.hadoop.hbase.regionserver.compactions.CompactionRequest;
58  import org.apache.hadoop.hbase.regionserver.wal.HLogKey;
59  import org.apache.hadoop.hbase.regionserver.wal.WALEdit;
60  import org.apache.hadoop.hbase.util.Pair;
61  
62  import com.google.common.collect.ImmutableList;
63  
64  /**
65   * Coprocessors implement this interface to observe and mediate client actions
66   * on the region.
67   */
68  @InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.COPROC)
69  @InterfaceStability.Evolving
70  public interface RegionObserver extends Coprocessor {
71  
72    /** Mutation type for postMutationBeforeWAL hook */
73    public enum MutationType {
74      APPEND, INCREMENT
75    }
76  
77    /**
78     * Called before the region is reported as open to the master.
79     * @param c the environment provided by the region server
80     * @throws IOException if an error occurred on the coprocessor
81     */
82    void preOpen(final ObserverContext<RegionCoprocessorEnvironment> c) throws IOException;
83  
84    /**
85     * Called after the region is reported as open to the master.
86     * @param c the environment provided by the region server
87     */
88    void postOpen(final ObserverContext<RegionCoprocessorEnvironment> c);
89  
90    /**
91     * Called after the log replay on the region is over.
92     * @param c the environment provided by the region server
93     */
94    void postLogReplay(final ObserverContext<RegionCoprocessorEnvironment> c);
95  
96    /**
97     * Called before a memstore is flushed to disk and prior to creating the scanner to read from
98     * the memstore.  To override or modify how a memstore is flushed,
99     * implementing classes can return a new scanner to provide the KeyValues to be
100    * stored into the new {@code StoreFile} or null to perform the default processing.
101    * Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no
102    * effect in this hook.
103    * @param c the environment provided by the region server
104    * @param store the store being flushed
105    * @param memstoreScanner the scanner for the memstore that is flushed
106    * @param s the base scanner, if not {@code null}, from previous RegionObserver in the chain
107    * @return the scanner to use during the flush.  {@code null} if the default implementation
108    * is to be used.
109    * @throws IOException if an error occurred on the coprocessor
110    */
111   InternalScanner preFlushScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
112       final Store store, final KeyValueScanner memstoreScanner, final InternalScanner s)
113       throws IOException;
114 
115   /**
116    * Called before the memstore is flushed to disk.
117    * @param c the environment provided by the region server
118    * @throws IOException if an error occurred on the coprocessor
119    * @deprecated use {@link #preFlush(ObserverContext, Store, InternalScanner)} instead
120    */
121   void preFlush(final ObserverContext<RegionCoprocessorEnvironment> c) throws IOException;
122 
123   /**
124    * Called before a Store's memstore is flushed to disk.
125    * @param c the environment provided by the region server
126    * @param store the store where compaction is being requested
127    * @param scanner the scanner over existing data used in the store file
128    * @return the scanner to use during compaction.  Should not be {@code null}
129    * unless the implementation is writing new store files on its own.
130    * @throws IOException if an error occurred on the coprocessor
131    */
132   InternalScanner preFlush(final ObserverContext<RegionCoprocessorEnvironment> c, final Store store,
133       final InternalScanner scanner) throws IOException;
134 
135   /**
136    * Called after the memstore is flushed to disk.
137    * @param c the environment provided by the region server
138    * @throws IOException if an error occurred on the coprocessor
139    * @deprecated use {@link #preFlush(ObserverContext, Store, InternalScanner)} instead.
140    */
141   void postFlush(final ObserverContext<RegionCoprocessorEnvironment> c) throws IOException;
142 
143   /**
144    * Called after a Store's memstore is flushed to disk.
145    * @param c the environment provided by the region server
146    * @param store the store being flushed
147    * @param resultFile the new store file written out during compaction
148    * @throws IOException if an error occurred on the coprocessor
149    */
150   void postFlush(final ObserverContext<RegionCoprocessorEnvironment> c, final Store store,
151       final StoreFile resultFile) throws IOException;
152 
153   /**
154    * Called prior to selecting the {@link StoreFile StoreFiles} to compact from the list of
155    * available candidates. To alter the files used for compaction, you may mutate the passed in list
156    * of candidates.
157    * @param c the environment provided by the region server
158    * @param store the store where compaction is being requested
159    * @param candidates the store files currently available for compaction
160    * @param request custom compaction request
161    * @throws IOException if an error occurred on the coprocessor
162    */
163   void preCompactSelection(final ObserverContext<RegionCoprocessorEnvironment> c,
164       final Store store, final List<StoreFile> candidates, final CompactionRequest request)
165       throws IOException;
166 
167   /**
168    * Called prior to selecting the {@link StoreFile}s to compact from the list of available
169    * candidates. To alter the files used for compaction, you may mutate the passed in list of
170    * candidates.
171    * @param c the environment provided by the region server
172    * @param store the store where compaction is being requested
173    * @param candidates the store files currently available for compaction
174    * @throws IOException if an error occurred on the coprocessor
175    * @deprecated Use {@link #preCompactSelection(ObserverContext, Store, List, CompactionRequest)}
176    *             instead
177    */
178   @Deprecated
179   void preCompactSelection(final ObserverContext<RegionCoprocessorEnvironment> c,
180       final Store store, final List<StoreFile> candidates) throws IOException;
181 
182   /**
183    * Called after the {@link StoreFile}s to compact have been selected from the available
184    * candidates.
185    * @param c the environment provided by the region server
186    * @param store the store being compacted
187    * @param selected the store files selected to compact
188    * @param request custom compaction request
189    */
190   void postCompactSelection(final ObserverContext<RegionCoprocessorEnvironment> c,
191       final Store store, final ImmutableList<StoreFile> selected, CompactionRequest request);
192 
193   /**
194    * Called after the {@link StoreFile}s to compact have been selected from the available
195    * candidates.
196    * @param c the environment provided by the region server
197    * @param store the store being compacted
198    * @param selected the store files selected to compact
199    * @deprecated use {@link #postCompactSelection(ObserverContext, Store, ImmutableList,
200    *             CompactionRequest)} instead.
201    */
202   @Deprecated
203   void postCompactSelection(final ObserverContext<RegionCoprocessorEnvironment> c,
204       final Store store, final ImmutableList<StoreFile> selected);
205 
206   /**
207    * Called prior to writing the {@link StoreFile}s selected for compaction into a new
208    * {@code StoreFile}. To override or modify the compaction process, implementing classes have two
209    * options:
210    * <ul>
211    * <li>Wrap the provided {@link InternalScanner} with a custom implementation that is returned
212    * from this method. The custom scanner can then inspect {@link KeyValue}s from the wrapped
213    * scanner, applying its own policy to what gets written.</li>
214    * <li>Call {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} and provide a
215    * custom implementation for writing of new {@link StoreFile}s. <strong>Note: any implementations
216    * bypassing core compaction using this approach must write out new store files themselves or the
217    * existing data will no longer be available after compaction.</strong></li>
218    * </ul>
219    * @param c the environment provided by the region server
220    * @param store the store being compacted
221    * @param scanner the scanner over existing data used in the store file rewriting
222    * @param scanType type of Scan
223    * @param request the requested compaction
224    * @return the scanner to use during compaction. Should not be {@code null} unless the
225    *         implementation is writing new store files on its own.
226    * @throws IOException if an error occurred on the coprocessor
227    */
228   InternalScanner preCompact(final ObserverContext<RegionCoprocessorEnvironment> c,
229       final Store store, final InternalScanner scanner, final ScanType scanType,
230       CompactionRequest request) throws IOException;
231 
232   /**
233    * Called prior to writing the {@link StoreFile}s selected for compaction into a new
234    * {@code StoreFile}. To override or modify the compaction process, implementing classes have two
235    * options:
236    * <ul>
237    * <li>Wrap the provided {@link InternalScanner} with a custom implementation that is returned
238    * from this method. The custom scanner can then inspect {@link KeyValue}s from the wrapped
239    * scanner, applying its own policy to what gets written.</li>
240    * <li>Call {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} and provide a
241    * custom implementation for writing of new {@link StoreFile}s. <strong>Note: any implementations
242    * bypassing core compaction using this approach must write out new store files themselves or the
243    * existing data will no longer be available after compaction.</strong></li>
244    * </ul>
245    * @param c the environment provided by the region server
246    * @param store the store being compacted
247    * @param scanner the scanner over existing data used in the store file rewriting
248    * @param scanType type of Scan
249    * @return the scanner to use during compaction. Should not be {@code null} unless the
250    *         implementation is writing new store files on its own.
251    * @throws IOException if an error occurred on the coprocessor
252    * @deprecated use
253    *             {@link #preCompact(ObserverContext, Store, InternalScanner,
254    *             ScanType, CompactionRequest)} instead
255    */
256   @Deprecated
257   InternalScanner preCompact(final ObserverContext<RegionCoprocessorEnvironment> c,
258       final Store store, final InternalScanner scanner, final ScanType scanType) throws IOException;
259 
260   /**
261    * Called prior to writing the {@link StoreFile}s selected for compaction into a new
262    * {@code StoreFile} and prior to creating the scanner used to read the input files. To override
263    * or modify the compaction process, implementing classes can return a new scanner to provide the
264    * KeyValues to be stored into the new {@code StoreFile} or null to perform the default
265    * processing. Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no
266    * effect in this hook.
267    * @param c the environment provided by the region server
268    * @param store the store being compacted
269    * @param scanners the list {@link StoreFileScanner}s to be read from
270    * @param scanType the {@link ScanType} indicating whether this is a major or minor compaction
271    * @param earliestPutTs timestamp of the earliest put that was found in any of the involved store
272    *          files
273    * @param s the base scanner, if not {@code null}, from previous RegionObserver in the chain
274    * @param request the requested compaction
275    * @return the scanner to use during compaction. {@code null} if the default implementation is to
276    *         be used.
277    * @throws IOException if an error occurred on the coprocessor
278    */
279   InternalScanner preCompactScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
280       final Store store, List<? extends KeyValueScanner> scanners, final ScanType scanType,
281       final long earliestPutTs, final InternalScanner s, CompactionRequest request)
282       throws IOException;
283 
284   /**
285    * Called prior to writing the {@link StoreFile}s selected for compaction into a new
286    * {@code StoreFile} and prior to creating the scanner used to read the input files. To override
287    * or modify the compaction process, implementing classes can return a new scanner to provide the
288    * KeyValues to be stored into the new {@code StoreFile} or null to perform the default
289    * processing. Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no
290    * effect in this hook.
291    * @param c the environment provided by the region server
292    * @param store the store being compacted
293    * @param scanners the list {@link StoreFileScanner}s to be read from
294    * @param scanType the {@link ScanType} indicating whether this is a major or minor compaction
295    * @param earliestPutTs timestamp of the earliest put that was found in any of the involved store
296    *          files
297    * @param s the base scanner, if not {@code null}, from previous RegionObserver in the chain
298    * @return the scanner to use during compaction. {@code null} if the default implementation is to
299    *         be used.
300    * @throws IOException if an error occurred on the coprocessor
301    * @deprecated Use
302    *             {@link #preCompactScannerOpen(ObserverContext, Store, List, ScanType, long,
303    *             InternalScanner, CompactionRequest)} instead.
304    */
305   @Deprecated
306   InternalScanner preCompactScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
307       final Store store, List<? extends KeyValueScanner> scanners, final ScanType scanType,
308       final long earliestPutTs, final InternalScanner s) throws IOException;
309 
310   /**
311    * Called after compaction has completed and the new store file has been moved in to place.
312    * @param c the environment provided by the region server
313    * @param store the store being compacted
314    * @param resultFile the new store file written out during compaction
315    * @param request the requested compaction
316    * @throws IOException if an error occurred on the coprocessor
317    */
318   void postCompact(final ObserverContext<RegionCoprocessorEnvironment> c, final Store store,
319       StoreFile resultFile, CompactionRequest request) throws IOException;
320 
321   /**
322    * Called after compaction has completed and the new store file has been moved in to place.
323    * @param c the environment provided by the region server
324    * @param store the store being compacted
325    * @param resultFile the new store file written out during compaction
326    * @throws IOException if an error occurred on the coprocessor
327    * @deprecated Use {@link #postCompact(ObserverContext, Store, StoreFile, CompactionRequest)}
328    *             instead
329    */
330   @Deprecated
331   void postCompact(final ObserverContext<RegionCoprocessorEnvironment> c, final Store store,
332       StoreFile resultFile) throws IOException;
333 
334   /**
335    * Called before the region is split.
336    * @param c the environment provided by the region server
337    * (e.getRegion() returns the parent region)
338    * @throws IOException if an error occurred on the coprocessor
339    * @deprecated Use preSplit(
340    *    final ObserverContext<RegionCoprocessorEnvironment> c, byte[] splitRow)
341    */
342   void preSplit(final ObserverContext<RegionCoprocessorEnvironment> c) throws IOException;
343 
344   /**
345    * Called before the region is split.
346    * @param c the environment provided by the region server
347    * (e.getRegion() returns the parent region)
348    * @throws IOException if an error occurred on the coprocessor
349    */
350   void preSplit(final ObserverContext<RegionCoprocessorEnvironment> c, byte[] splitRow)
351       throws IOException;
352 
353   /**
354    * Called after the region is split.
355    * @param c the environment provided by the region server
356    * (e.getRegion() returns the parent region)
357    * @param l the left daughter region
358    * @param r the right daughter region
359    * @throws IOException if an error occurred on the coprocessor
360    * @deprecated Use postCompleteSplit() instead
361    */
362   void postSplit(final ObserverContext<RegionCoprocessorEnvironment> c, final HRegion l,
363       final HRegion r) throws IOException;
364 
365   /**
366    * This will be called before PONR step as part of split transaction. Calling
367    * {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} rollback the split
368    * @param ctx
369    * @param splitKey
370    * @param metaEntries
371    * @throws IOException
372    */
373   void preSplitBeforePONR(final ObserverContext<RegionCoprocessorEnvironment> ctx,
374       byte[] splitKey, List<Mutation> metaEntries) throws IOException;
375 
376   
377   /**
378    * This will be called after PONR step as part of split transaction
379    * Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no
380    * effect in this hook.
381    * @param ctx
382    * @throws IOException
383    */
384   void preSplitAfterPONR(final ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException;
385   
386   /**
387    * This will be called before the roll back of the split region is completed 
388    * @param ctx
389    * @throws IOException
390    */
391   void preRollBackSplit(final ObserverContext<RegionCoprocessorEnvironment> ctx) throws IOException;
392 
393   /**
394    * This will be called after the roll back of the split region is completed
395    * @param ctx
396    * @throws IOException
397    */
398   void postRollBackSplit(final ObserverContext<RegionCoprocessorEnvironment> ctx)
399     throws IOException;
400 
401   /**
402    * Called after any split request is processed.  This will be called irrespective of success or
403    * failure of the split.
404    * @param ctx
405    * @throws IOException
406    */
407   void postCompleteSplit(final ObserverContext<RegionCoprocessorEnvironment> ctx)
408     throws IOException;
409   /**
410    * Called before the region is reported as closed to the master.
411    * @param c the environment provided by the region server
412    * @param abortRequested true if the region server is aborting
413    * @throws IOException 
414    */
415   void preClose(final ObserverContext<RegionCoprocessorEnvironment> c,
416       boolean abortRequested) throws IOException;
417 
418   /**
419    * Called after the region is reported as closed to the master.
420    * @param c the environment provided by the region server
421    * @param abortRequested true if the region server is aborting
422    */
423   void postClose(final ObserverContext<RegionCoprocessorEnvironment> c,
424       boolean abortRequested);
425 
426   /**
427    * Called before a client makes a GetClosestRowBefore request.
428    * <p>
429    * Call CoprocessorEnvironment#bypass to skip default actions
430    * <p>
431    * Call CoprocessorEnvironment#complete to skip any subsequent chained
432    * coprocessors
433    * @param c the environment provided by the region server
434    * @param row the row
435    * @param family the family
436    * @param result The result to return to the client if default processing
437    * is bypassed. Can be modified. Will not be used if default processing
438    * is not bypassed.
439    * @throws IOException if an error occurred on the coprocessor
440    */
441   void preGetClosestRowBefore(final ObserverContext<RegionCoprocessorEnvironment> c,
442       final byte [] row, final byte [] family, final Result result)
443     throws IOException;
444 
445   /**
446    * Called after a client makes a GetClosestRowBefore request.
447    * <p>
448    * Call CoprocessorEnvironment#complete to skip any subsequent chained
449    * coprocessors
450    * @param c the environment provided by the region server
451    * @param row the row
452    * @param family the desired family
453    * @param result the result to return to the client, modify as necessary
454    * @throws IOException if an error occurred on the coprocessor
455    */
456   void postGetClosestRowBefore(final ObserverContext<RegionCoprocessorEnvironment> c,
457       final byte [] row, final byte [] family, final Result result)
458     throws IOException;
459 
460   /**
461    * Called before the client performs a Get
462    * <p>
463    * Call CoprocessorEnvironment#bypass to skip default actions
464    * <p>
465    * Call CoprocessorEnvironment#complete to skip any subsequent chained
466    * coprocessors
467    * @param c the environment provided by the region server
468    * @param get the Get request
469    * @param result The result to return to the client if default processing
470    * is bypassed. Can be modified. Will not be used if default processing
471    * is not bypassed.
472    * @throws IOException if an error occurred on the coprocessor
473    */
474   void preGetOp(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get,
475       final List<Cell> result)
476     throws IOException;
477 
478   /**
479    * WARNING: please override preGetOp instead of this method.  This is to maintain some
480    * compatibility and to ease the transition from 0.94 -> 0.96.
481    */
482   @Deprecated
483   void preGet(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get,
484       final List<KeyValue> result)
485     throws IOException;
486 
487   /**
488    * Called after the client performs a Get
489    * <p>
490    * Call CoprocessorEnvironment#complete to skip any subsequent chained
491    * coprocessors
492    * @param c the environment provided by the region server
493    * @param get the Get request
494    * @param result the result to return to the client, modify as necessary
495    * @throws IOException if an error occurred on the coprocessor
496    */
497   void postGetOp(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get,
498       final List<Cell> result)
499     throws IOException;
500 
501   /**
502    * WARNING: please override postGetOp instead of this method.  This is to maintain some
503    * compatibility and to ease the transition from 0.94 -> 0.96.
504    */
505   @Deprecated
506   void postGet(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get,
507       final List<KeyValue> result)
508     throws IOException;
509 
510   /**
511    * Called before the client tests for existence using a Get.
512    * <p>
513    * Call CoprocessorEnvironment#bypass to skip default actions
514    * <p>
515    * Call CoprocessorEnvironment#complete to skip any subsequent chained
516    * coprocessors
517    * @param c the environment provided by the region server
518    * @param get the Get request
519    * @param exists
520    * @return the value to return to the client if bypassing default processing
521    * @throws IOException if an error occurred on the coprocessor
522    */
523   boolean preExists(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get,
524       final boolean exists)
525     throws IOException;
526 
527   /**
528    * Called after the client tests for existence using a Get.
529    * <p>
530    * Call CoprocessorEnvironment#complete to skip any subsequent chained
531    * coprocessors
532    * @param c the environment provided by the region server
533    * @param get the Get request
534    * @param exists the result returned by the region server
535    * @return the result to return to the client
536    * @throws IOException if an error occurred on the coprocessor
537    */
538   boolean postExists(final ObserverContext<RegionCoprocessorEnvironment> c, final Get get,
539       final boolean exists)
540     throws IOException;
541 
542   /**
543    * Called before the client stores a value.
544    * <p>
545    * Call CoprocessorEnvironment#bypass to skip default actions
546    * <p>
547    * Call CoprocessorEnvironment#complete to skip any subsequent chained
548    * coprocessors
549    * @param c the environment provided by the region server
550    * @param put The Put object
551    * @param edit The WALEdit object that will be written to the wal
552    * @param durability Persistence guarantee for this Put
553    * @throws IOException if an error occurred on the coprocessor
554    */
555   void prePut(final ObserverContext<RegionCoprocessorEnvironment> c, 
556       final Put put, final WALEdit edit, final Durability durability)
557     throws IOException;
558 
559   /**
560    * Called after the client stores a value.
561    * <p>
562    * Call CoprocessorEnvironment#complete to skip any subsequent chained
563    * coprocessors
564    * @param c the environment provided by the region server
565    * @param put The Put object
566    * @param edit The WALEdit object for the wal
567    * @param durability Persistence guarantee for this Put
568    * @throws IOException if an error occurred on the coprocessor
569    */
570   void postPut(final ObserverContext<RegionCoprocessorEnvironment> c, 
571       final Put put, final WALEdit edit, final Durability durability)
572     throws IOException;
573 
574   /**
575    * Called before the client deletes a value.
576    * <p>
577    * Call CoprocessorEnvironment#bypass to skip default actions
578    * <p>
579    * Call CoprocessorEnvironment#complete to skip any subsequent chained
580    * coprocessors
581    * @param c the environment provided by the region server
582    * @param delete The Delete object
583    * @param edit The WALEdit object for the wal
584    * @param durability Persistence guarantee for this Delete
585    * @throws IOException if an error occurred on the coprocessor
586    */
587   void preDelete(final ObserverContext<RegionCoprocessorEnvironment> c, 
588       final Delete delete, final WALEdit edit, final Durability durability)
589     throws IOException;
590 
591   /**
592    * Called after the client deletes a value.
593    * <p>
594    * Call CoprocessorEnvironment#complete to skip any subsequent chained
595    * coprocessors
596    * @param c the environment provided by the region server
597    * @param delete The Delete object
598    * @param edit The WALEdit object for the wal
599    * @param durability Persistence guarantee for this Delete
600    * @throws IOException if an error occurred on the coprocessor
601    */
602   void postDelete(final ObserverContext<RegionCoprocessorEnvironment> c,
603       final Delete delete, final WALEdit edit, final Durability durability)
604     throws IOException;
605   
606   /**
607    * This will be called for every batch mutation operation happening at the server. This will be
608    * called after acquiring the locks on the mutating rows and after applying the proper timestamp
609    * for each Mutation at the server. The batch may contain Put/Delete. By setting OperationStatus
610    * of Mutations ({@link MiniBatchOperationInProgress#setOperationStatus(int, OperationStatus)}),
611    * {@link RegionObserver} can make HRegion to skip these Mutations.
612    * @param c the environment provided by the region server
613    * @param miniBatchOp batch of Mutations getting applied to region.
614    * @throws IOException if an error occurred on the coprocessor
615    */
616   void preBatchMutate(final ObserverContext<RegionCoprocessorEnvironment> c,
617       final MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException;
618 
619   /**
620    * This will be called after applying a batch of Mutations on a region. The Mutations are added to
621    * memstore and WAL.
622    * @param c the environment provided by the region server
623    * @param miniBatchOp batch of Mutations applied to region.
624    * @throws IOException if an error occurred on the coprocessor
625    */
626   void postBatchMutate(final ObserverContext<RegionCoprocessorEnvironment> c,
627       final MiniBatchOperationInProgress<Mutation> miniBatchOp) throws IOException;
628 
629   /**
630    * This will be called for region operations where read lock is acquired in
631    * {@link HRegion#startRegionOperation()}.
632    * @param ctx
633    * @param operation The operation is about to be taken on the region
634    * @throws IOException
635    */
636   void postStartRegionOperation(final ObserverContext<RegionCoprocessorEnvironment> ctx,
637       Operation operation) throws IOException;
638 
639   /**
640    * Called after releasing read lock in {@link HRegion#closeRegionOperation(Operation)}.
641    * @param ctx
642    * @param operation
643    * @throws IOException
644    */
645   void postCloseRegionOperation(final ObserverContext<RegionCoprocessorEnvironment> ctx,
646       Operation operation) throws IOException;
647 
648   /**
649    * Called after the completion of batch put/delete and will be called even if the batch operation
650    * fails
651    * @param ctx
652    * @param miniBatchOp 
653    * @param success true if batch operation is successful otherwise false.
654    * @throws IOException
655    */
656   void postBatchMutateIndispensably(final ObserverContext<RegionCoprocessorEnvironment> ctx,
657       MiniBatchOperationInProgress<Mutation> miniBatchOp, final boolean success) throws IOException;
658 
659   /**
660    * Called before checkAndPut
661    * <p>
662    * Call CoprocessorEnvironment#bypass to skip default actions
663    * <p>
664    * Call CoprocessorEnvironment#complete to skip any subsequent chained
665    * coprocessors
666    * @param c the environment provided by the region server
667    * @param row row to check
668    * @param family column family
669    * @param qualifier column qualifier
670    * @param compareOp the comparison operation
671    * @param comparator the comparator
672    * @param put data to put if check succeeds
673    * @param result 
674    * @return the return value to return to client if bypassing default
675    * processing
676    * @throws IOException if an error occurred on the coprocessor
677    */
678   boolean preCheckAndPut(final ObserverContext<RegionCoprocessorEnvironment> c,
679       final byte [] row, final byte [] family, final byte [] qualifier,
680       final CompareOp compareOp, final ByteArrayComparable comparator,
681       final Put put, final boolean result)
682     throws IOException;
683 
684   /**
685    * Called after checkAndPut
686    * <p>
687    * Call CoprocessorEnvironment#complete to skip any subsequent chained
688    * coprocessors
689    * @param c the environment provided by the region server
690    * @param row row to check
691    * @param family column family
692    * @param qualifier column qualifier
693    * @param compareOp the comparison operation
694    * @param comparator the comparator
695    * @param put data to put if check succeeds
696    * @param result from the checkAndPut
697    * @return the possibly transformed return value to return to client
698    * @throws IOException if an error occurred on the coprocessor
699    */
700   boolean postCheckAndPut(final ObserverContext<RegionCoprocessorEnvironment> c,
701       final byte [] row, final byte [] family, final byte [] qualifier,
702       final CompareOp compareOp, final ByteArrayComparable comparator,
703       final Put put, final boolean result)
704     throws IOException;
705 
706   /**
707    * Called before checkAndDelete
708    * <p>
709    * Call CoprocessorEnvironment#bypass to skip default actions
710    * <p>
711    * Call CoprocessorEnvironment#complete to skip any subsequent chained
712    * coprocessors
713    * @param c the environment provided by the region server
714    * @param row row to check
715    * @param family column family
716    * @param qualifier column qualifier
717    * @param compareOp the comparison operation
718    * @param comparator the comparator
719    * @param delete delete to commit if check succeeds
720    * @param result 
721    * @return the value to return to client if bypassing default processing
722    * @throws IOException if an error occurred on the coprocessor
723    */
724   boolean preCheckAndDelete(final ObserverContext<RegionCoprocessorEnvironment> c,
725       final byte [] row, final byte [] family, final byte [] qualifier,
726       final CompareOp compareOp, final ByteArrayComparable comparator,
727       final Delete delete, final boolean result)
728     throws IOException;
729 
730   /**
731    * Called after checkAndDelete
732    * <p>
733    * Call CoprocessorEnvironment#complete to skip any subsequent chained
734    * coprocessors
735    * @param c the environment provided by the region server
736    * @param row row to check
737    * @param family column family
738    * @param qualifier column qualifier
739    * @param compareOp the comparison operation
740    * @param comparator the comparator
741    * @param delete delete to commit if check succeeds
742    * @param result from the CheckAndDelete
743    * @return the possibly transformed returned value to return to client
744    * @throws IOException if an error occurred on the coprocessor
745    */
746   boolean postCheckAndDelete(final ObserverContext<RegionCoprocessorEnvironment> c,
747       final byte [] row, final byte [] family, final byte [] qualifier,
748       final CompareOp compareOp, final ByteArrayComparable comparator,
749       final Delete delete, final boolean result)
750     throws IOException;
751 
752   /**
753    * Called before incrementColumnValue
754    * <p>
755    * Call CoprocessorEnvironment#bypass to skip default actions
756    * <p>
757    * Call CoprocessorEnvironment#complete to skip any subsequent chained
758    * coprocessors
759    * @param c the environment provided by the region server
760    * @param row row to check
761    * @param family column family
762    * @param qualifier column qualifier
763    * @param amount long amount to increment
764    * @param writeToWAL true if the change should be written to the WAL
765    * @return value to return to the client if bypassing default processing
766    * @throws IOException if an error occurred on the coprocessor
767    * @deprecated This hook is no longer called by the RegionServer
768    */
769   @Deprecated
770   long preIncrementColumnValue(final ObserverContext<RegionCoprocessorEnvironment> c,
771       final byte [] row, final byte [] family, final byte [] qualifier,
772       final long amount, final boolean writeToWAL)
773     throws IOException;
774 
775   /**
776    * Called after incrementColumnValue
777    * <p>
778    * Call CoprocessorEnvironment#complete to skip any subsequent chained
779    * coprocessors
780    * @param c the environment provided by the region server
781    * @param row row to check
782    * @param family column family
783    * @param qualifier column qualifier
784    * @param amount long amount to increment
785    * @param writeToWAL true if the change should be written to the WAL
786    * @param result the result returned by incrementColumnValue
787    * @return the result to return to the client
788    * @throws IOException if an error occurred on the coprocessor
789    * @deprecated This hook is no longer called by the RegionServer
790    */
791   @Deprecated
792   long postIncrementColumnValue(final ObserverContext<RegionCoprocessorEnvironment> c,
793       final byte [] row, final byte [] family, final byte [] qualifier,
794       final long amount, final boolean writeToWAL, final long result)
795     throws IOException;
796 
797   /**
798    * Called before Append
799    * <p>
800    * Call CoprocessorEnvironment#bypass to skip default actions
801    * <p>
802    * Call CoprocessorEnvironment#complete to skip any subsequent chained
803    * coprocessors
804    * @param c the environment provided by the region server
805    * @param append Append object
806    * @return result to return to the client if bypassing default processing
807    * @throws IOException if an error occurred on the coprocessor
808    */
809   Result preAppend(final ObserverContext<RegionCoprocessorEnvironment> c,
810       final Append append)
811     throws IOException;
812 
813   /**
814    * Called after Append
815    * <p>
816    * Call CoprocessorEnvironment#complete to skip any subsequent chained
817    * coprocessors
818    * @param c the environment provided by the region server
819    * @param append Append object
820    * @param result the result returned by increment
821    * @return the result to return to the client
822    * @throws IOException if an error occurred on the coprocessor
823    */
824   Result postAppend(final ObserverContext<RegionCoprocessorEnvironment> c,
825       final Append append, final Result result)
826     throws IOException;
827 
828   /**
829    * Called before Increment
830    * <p>
831    * Call CoprocessorEnvironment#bypass to skip default actions
832    * <p>
833    * Call CoprocessorEnvironment#complete to skip any subsequent chained
834    * coprocessors
835    * @param c the environment provided by the region server
836    * @param increment increment object
837    * @return result to return to the client if bypassing default processing
838    * @throws IOException if an error occurred on the coprocessor
839    */
840   Result preIncrement(final ObserverContext<RegionCoprocessorEnvironment> c,
841       final Increment increment)
842     throws IOException;
843 
844   /**
845    * Called after increment
846    * <p>
847    * Call CoprocessorEnvironment#complete to skip any subsequent chained
848    * coprocessors
849    * @param c the environment provided by the region server
850    * @param increment increment object
851    * @param result the result returned by increment
852    * @return the result to return to the client
853    * @throws IOException if an error occurred on the coprocessor
854    */
855   Result postIncrement(final ObserverContext<RegionCoprocessorEnvironment> c,
856       final Increment increment, final Result result)
857     throws IOException;
858 
859   /**
860    * Called before the client opens a new scanner.
861    * <p>
862    * Call CoprocessorEnvironment#bypass to skip default actions
863    * <p>
864    * Call CoprocessorEnvironment#complete to skip any subsequent chained
865    * coprocessors
866    * @param c the environment provided by the region server
867    * @param scan the Scan specification
868    * @param s if not null, the base scanner
869    * @return an RegionScanner instance to use instead of the base scanner if
870    * overriding default behavior, null otherwise
871    * @throws IOException if an error occurred on the coprocessor
872    */
873   RegionScanner preScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
874       final Scan scan, final RegionScanner s)
875     throws IOException;
876 
877   /**
878    * Called before a store opens a new scanner.
879    * This hook is called when a "user" scanner is opened.
880    * <p>
881    * See {@link #preFlushScannerOpen(ObserverContext, Store, KeyValueScanner, InternalScanner)}
882    * and {@link #preCompactScannerOpen(ObserverContext,
883    *  Store, List, ScanType, long, InternalScanner)}
884    * to override scanners created for flushes or compactions, resp.
885    * <p>
886    * Call CoprocessorEnvironment#complete to skip any subsequent chained
887    * coprocessors.
888    * Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no
889    * effect in this hook.
890    * @param c the environment provided by the region server
891    * @param store the store being scanned
892    * @param scan the Scan specification
893    * @param targetCols columns to be used in the scanner
894    * @param s the base scanner, if not {@code null}, from previous RegionObserver in the chain
895    * @return a KeyValueScanner instance to use or {@code null} to use the default implementation
896    * @throws IOException if an error occurred on the coprocessor
897    */
898   KeyValueScanner preStoreScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
899       final Store store, final Scan scan, final NavigableSet<byte[]> targetCols,
900       final KeyValueScanner s) throws IOException;
901 
902   /**
903    * Called after the client opens a new scanner.
904    * <p>
905    * Call CoprocessorEnvironment#complete to skip any subsequent chained
906    * coprocessors
907    * @param c the environment provided by the region server
908    * @param scan the Scan specification
909    * @param s if not null, the base scanner
910    * @return the scanner instance to use
911    * @throws IOException if an error occurred on the coprocessor
912    */
913   RegionScanner postScannerOpen(final ObserverContext<RegionCoprocessorEnvironment> c,
914       final Scan scan, final RegionScanner s)
915     throws IOException;
916 
917   /**
918    * Called before the client asks for the next row on a scanner.
919    * <p>
920    * Call CoprocessorEnvironment#bypass to skip default actions
921    * <p>
922    * Call CoprocessorEnvironment#complete to skip any subsequent chained
923    * coprocessors
924    * @param c the environment provided by the region server
925    * @param s the scanner
926    * @param result The result to return to the client if default processing
927    * is bypassed. Can be modified. Will not be returned if default processing
928    * is not bypassed.
929    * @param limit the maximum number of results to return
930    * @param hasNext the 'has more' indication
931    * @return 'has more' indication that should be sent to client
932    * @throws IOException if an error occurred on the coprocessor
933    */
934   boolean preScannerNext(final ObserverContext<RegionCoprocessorEnvironment> c,
935       final InternalScanner s, final List<Result> result,
936       final int limit, final boolean hasNext)
937     throws IOException;
938 
939   /**
940    * Called after the client asks for the next row on a scanner.
941    * <p>
942    * Call CoprocessorEnvironment#complete to skip any subsequent chained
943    * coprocessors
944    * @param c the environment provided by the region server
945    * @param s the scanner
946    * @param result the result to return to the client, can be modified
947    * @param limit the maximum number of results to return
948    * @param hasNext the 'has more' indication
949    * @return 'has more' indication that should be sent to client
950    * @throws IOException if an error occurred on the coprocessor
951    */
952   boolean postScannerNext(final ObserverContext<RegionCoprocessorEnvironment> c,
953       final InternalScanner s, final List<Result> result, final int limit,
954       final boolean hasNext)
955     throws IOException;
956 
957   /**
958    * This will be called by the scan flow when the current scanned row is being filtered out by the
959    * filter. The filter may be filtering out the row via any of the below scenarios
960    * <ol>
961    * <li>
962    * <code>boolean filterRowKey(byte [] buffer, int offset, int length)</code> returning true</li>
963    * <li>
964    * <code>boolean filterRow()</code> returning true</li>
965    * <li>
966    * <code>void filterRow(List<KeyValue> kvs)</code> removing all the kvs from the passed List</li>
967    * </ol>
968    * @param c the environment provided by the region server
969    * @param s the scanner
970    * @param currentRow The current rowkey which got filtered out
971    * @param offset offset to rowkey
972    * @param length length of rowkey
973    * @param hasMore the 'has more' indication
974    * @return whether more rows are available for the scanner or not
975    * @throws IOException
976    */
977   boolean postScannerFilterRow(final ObserverContext<RegionCoprocessorEnvironment> c,
978       final InternalScanner s, final byte[] currentRow, final int offset, final short length,
979       final boolean hasMore) throws IOException;
980   
981   /**
982    * Called before the client closes a scanner.
983    * <p>
984    * Call CoprocessorEnvironment#bypass to skip default actions
985    * <p>
986    * Call CoprocessorEnvironment#complete to skip any subsequent chained
987    * coprocessors
988    * @param c the environment provided by the region server
989    * @param s the scanner
990    * @throws IOException if an error occurred on the coprocessor
991    */
992   void preScannerClose(final ObserverContext<RegionCoprocessorEnvironment> c,
993       final InternalScanner s)
994     throws IOException;
995 
996   /**
997    * Called after the client closes a scanner.
998    * <p>
999    * Call CoprocessorEnvironment#complete to skip any subsequent chained
1000    * coprocessors
1001    * @param c the environment provided by the region server
1002    * @param s the scanner
1003    * @throws IOException if an error occurred on the coprocessor
1004    */
1005   void postScannerClose(final ObserverContext<RegionCoprocessorEnvironment> c,
1006       final InternalScanner s)
1007     throws IOException;
1008 
1009   /**
1010    * Called before a {@link org.apache.hadoop.hbase.regionserver.wal.WALEdit}
1011    * replayed for this region.
1012    *
1013    * @param ctx
1014    * @param info
1015    * @param logKey
1016    * @param logEdit
1017    * @throws IOException
1018    */
1019   void preWALRestore(final ObserverContext<RegionCoprocessorEnvironment> ctx,
1020       HRegionInfo info, HLogKey logKey, WALEdit logEdit) throws IOException;
1021 
1022   /**
1023    * Called after a {@link org.apache.hadoop.hbase.regionserver.wal.WALEdit}
1024    * replayed for this region.
1025    *
1026    * @param ctx
1027    * @param info
1028    * @param logKey
1029    * @param logEdit
1030    * @throws IOException
1031    */
1032   void postWALRestore(final ObserverContext<RegionCoprocessorEnvironment> ctx,
1033       HRegionInfo info, HLogKey logKey, WALEdit logEdit) throws IOException;
1034 
1035   /**
1036    * Called before bulkLoadHFile. Users can create a StoreFile instance to
1037    * access the contents of a HFile.
1038    *
1039    * @param ctx
1040    * @param familyPaths pairs of { CF, HFile path } submitted for bulk load. Adding
1041    * or removing from this list will add or remove HFiles to be bulk loaded.
1042    * @throws IOException
1043    */
1044   void preBulkLoadHFile(final ObserverContext<RegionCoprocessorEnvironment> ctx,
1045     List<Pair<byte[], String>> familyPaths) throws IOException;
1046 
1047   /**
1048    * Called after bulkLoadHFile.
1049    *
1050    * @param ctx
1051    * @param familyPaths pairs of { CF, HFile path } submitted for bulk load
1052    * @param hasLoaded whether the bulkLoad was successful
1053    * @return the new value of hasLoaded
1054    * @throws IOException
1055    */
1056   boolean postBulkLoadHFile(final ObserverContext<RegionCoprocessorEnvironment> ctx,
1057     List<Pair<byte[], String>> familyPaths, boolean hasLoaded) throws IOException;
1058 
1059   /**
1060    * Called before creation of Reader for a store file.
1061    * Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no
1062    * effect in this hook.
1063    * 
1064    * @param ctx the environment provided by the region server
1065    * @param fs fileystem to read from
1066    * @param p path to the file
1067    * @param in {@link FSDataInputStreamWrapper}
1068    * @param size Full size of the file
1069    * @param cacheConf
1070    * @param r original reference file. This will be not null only when reading a split file.
1071    * @param reader the base reader, if not {@code null}, from previous RegionObserver in the chain
1072    * @return a Reader instance to use instead of the base reader if overriding
1073    * default behavior, null otherwise
1074    * @throws IOException
1075    */
1076   StoreFile.Reader preStoreFileReaderOpen(final ObserverContext<RegionCoprocessorEnvironment> ctx,
1077       final FileSystem fs, final Path p, final FSDataInputStreamWrapper in, long size,
1078       final CacheConfig cacheConf, final Reference r, StoreFile.Reader reader) throws IOException;
1079 
1080   /**
1081    * Called after the creation of Reader for a store file.
1082    * 
1083    * @param ctx the environment provided by the region server
1084    * @param fs fileystem to read from
1085    * @param p path to the file
1086    * @param in {@link FSDataInputStreamWrapper}
1087    * @param size Full size of the file
1088    * @param cacheConf
1089    * @param r original reference file. This will be not null only when reading a split file.
1090    * @param reader the base reader instance
1091    * @return The reader to use
1092    * @throws IOException
1093    */
1094   StoreFile.Reader postStoreFileReaderOpen(final ObserverContext<RegionCoprocessorEnvironment> ctx,
1095       final FileSystem fs, final Path p, final FSDataInputStreamWrapper in, long size,
1096       final CacheConfig cacheConf, final Reference r, StoreFile.Reader reader) throws IOException;
1097 
1098   /**
1099    * Called after a new cell has been created during an increment operation, but before
1100    * it is committed to the WAL or memstore.
1101    * Calling {@link org.apache.hadoop.hbase.coprocessor.ObserverContext#bypass()} has no
1102    * effect in this hook.
1103    * @param ctx the environment provided by the region server
1104    * @param opType the operation type
1105    * @param mutation the current mutation
1106    * @param oldCell old cell containing previous value
1107    * @param newCell the new cell containing the computed value
1108    * @return the new cell, possibly changed
1109    * @throws IOException
1110    */
1111   Cell postMutationBeforeWAL(ObserverContext<RegionCoprocessorEnvironment> ctx,
1112       MutationType opType, Mutation mutation, Cell oldCell, Cell newCell) throws IOException;
1113 
1114   /**
1115    * Called after the ScanQueryMatcher creates ScanDeleteTracker. Implementing
1116    * this hook would help in creating customised DeleteTracker and returning
1117    * the newly created DeleteTracker
1118    *
1119    * @param ctx the environment provided by the region server
1120    * @param delTracker the deleteTracker that is created by the QueryMatcher
1121    * @return the Delete Tracker
1122    * @throws IOException
1123    */
1124   DeleteTracker postInstantiateDeleteTracker(
1125       final ObserverContext<RegionCoprocessorEnvironment> ctx, DeleteTracker delTracker)
1126       throws IOException;
1127 }