1818package org .apache .omid .transaction ;
1919
2020import org .apache .phoenix .thirdparty .com .google .common .base .Optional ;
21-
22-
21+ import org . slf4j . Logger ;
22+ import org . slf4j . LoggerFactory ;
2323import org .apache .commons .collections4 .map .LRUMap ;
2424import org .apache .hadoop .hbase .Cell ;
2525import org .apache .hadoop .hbase .CellUtil ;
26+ import org .apache .hadoop .hbase .KeyValue ;
27+ import org .apache .hadoop .hbase .KeyValueUtil ;
28+ import org .apache .hadoop .hbase .Cell .Type ;
2629import org .apache .hadoop .hbase .client .Get ;
2730import org .apache .hadoop .hbase .client .Result ;
2831import org .apache .hadoop .hbase .filter .Filter ;
3134
3235import org .apache .hadoop .hbase .util .Bytes ;
3336
34-
3537import java .io .IOException ;
38+ import java .lang .invoke .MethodHandle ;
39+ import java .lang .invoke .MethodHandles ;
40+ import java .lang .invoke .MethodType ;
41+ import java .lang .reflect .Method ;
3642import java .util .HashMap ;
3743
3844import java .util .List ;
4147
4248public class TransactionVisibilityFilterBase extends FilterBase {
4349
50+ private static final Logger LOG = LoggerFactory .getLogger (TransactionVisibilityFilterBase .class );
51+
4452 // optional sub-filter to apply to visible cells
4553 private final Filter userFilter ;
4654 private final SnapshotFilterImpl snapshotFilter ;
@@ -51,6 +59,31 @@ public class TransactionVisibilityFilterBase extends FilterBase {
5159 // So no need to keep row name
5260 private final Map <ImmutableBytesWritable , Long > familyDeletionCache ;
5361
62+ // Using reflection to avoid adding compatibility modules.
63+ private static final Method removedFilterRowKeyMethod ;
64+ private static final MethodHandle removedSuperFilterRowKeyMethod ;
65+ static {
66+ Method tmpFilterRowKeyMethod ;
67+ try {
68+ tmpFilterRowKeyMethod = FilterBase .class .getMethod ("filterRowKey" , byte [].class , int .class , int .class );
69+ } catch (Exception e ) {
70+ LOG .info ("Could not get filterRowKey method handle by reflection. This is normal for HBase 3.x" , e );
71+ tmpFilterRowKeyMethod = null ;
72+ }
73+ removedFilterRowKeyMethod = tmpFilterRowKeyMethod ;
74+
75+ MethodHandle tmpRemovedSuperFilterRowKeyMethod ;
76+ try {
77+ tmpRemovedSuperFilterRowKeyMethod = MethodHandles .lookup ().findSpecial (FilterBase .class , "filterRowKey" ,
78+ MethodType .methodType (boolean .class , byte [].class , int .class , int .class ),
79+ TransactionVisibilityFilterBase .class );
80+ } catch (Exception e ) {
81+ LOG .info ("Could not get super.filterRowKey method handle by reflection. This is normal for HBase 3.x" , e );
82+ tmpRemovedSuperFilterRowKeyMethod = null ;
83+ }
84+ removedSuperFilterRowKeyMethod = tmpRemovedSuperFilterRowKeyMethod ;
85+ }
86+
5487 public TransactionVisibilityFilterBase (Filter cellFilter ,
5588 SnapshotFilterImpl snapshotFilter ,
5689 HBaseTransaction hbaseTransaction ) {
@@ -65,8 +98,9 @@ public TransactionVisibilityFilterBase(Filter cellFilter,
6598 /**
6699 * This deprecated method is implemented for backwards compatibility reasons.
67100 * use {@link TransactionVisibilityFilterBase#filterCell(Cell)}
101+ *
102+ * No @Override so that it compiles with HBase 3.x
68103 */
69- @ Override
70104 public ReturnCode filterKeyValue (Cell cell ) throws IOException {
71105 return filterCell (cell );
72106 }
@@ -202,16 +236,38 @@ public boolean filterRow() throws IOException {
202236 return super .filterRow ();
203237 }
204238
205- /**
239+ /**
206240 * This deprecated method is implemented for backwards compatibility reasons.
207241 * use {@link TransactionVisibilityFilterBase#filterRowKey(Cell)}
242+ *
243+ * No @Override so that it compiles with HBase 3.x
208244 */
209- @ Override
210245 public boolean filterRowKey (byte [] buffer , int offset , int length ) throws IOException {
246+ // Even though this is deprecated, this is the actual implementation that filterRowKey(Cell)
247+ // calls in FilterBase in HBase 2, so we cannot call filterRowKey(Cell), because that would
248+ // cause infinite recursion
249+ if (removedFilterRowKeyMethod == null ) {
250+ // This should never happen, this can only get called from HBase 2.x and
251+ // the reflected method is public.
252+ throw new UnsupportedOperationException ("Called from Hbase 2, but could net get Method handle" );
253+ }
211254 if (userFilter != null ) {
212- return userFilter .filterRowKey (buffer , offset , length );
255+ try {
256+ return (boolean ) (removedFilterRowKeyMethod .invoke (userFilter , buffer , offset , length ));
257+ } catch (Exception e ) {
258+ throw new UnsupportedOperationException (e );
259+ }
260+ }
261+ if (removedSuperFilterRowKeyMethod == null ) {
262+ // This should never happen, this can only get called from HBase 2.x and
263+ // the reflected method is public.
264+ throw new UnsupportedOperationException ("Called from Hbase 2, but could net get super method handle" );
265+ }
266+ try {
267+ return (boolean ) (removedSuperFilterRowKeyMethod .invoke (this , buffer , offset , length ));
268+ } catch (Throwable e ) {
269+ throw new UnsupportedOperationException (e );
213270 }
214- return super .filterRowKey (buffer , offset , length );
215271 }
216272
217273 @ Override
@@ -271,4 +327,5 @@ public byte[] toByteArray() throws IOException {
271327 public Filter getInnerFilter () {
272328 return userFilter ;
273329 }
330+
274331}
0 commit comments