View Javadoc

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