1 /*
2 * Copyright 2010 The Apache Software Foundation
3 *
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 */
19
20 package org.apache.hadoop.hbase.filter;
21
22 import org.apache.hadoop.hbase.KeyValue;
23
24 import java.util.List;
25 import java.util.ArrayList;
26
27 /**
28 * Abstract base class to help you implement new Filters. Common "ignore" or NOOP type
29 * methods can go here, helping to reduce boiler plate in an ever-expanding filter
30 * library.
31 *
32 * If you could instantiate FilterBase, it would end up being a "null" filter -
33 * that is one that never filters anything.
34 */
35 public abstract class FilterBase implements Filter {
36
37 /**
38 * Filters that are purely stateless and do nothing in their reset() methods can inherit
39 * this null/empty implementation.
40 *
41 * @inheritDoc
42 */
43 @Override
44 public void reset() {
45 }
46
47 /**
48 * Filters that do not filter by row key can inherit this implementation that
49 * never filters anything. (ie: returns false).
50 *
51 * @inheritDoc
52 */
53 @Override
54 public boolean filterRowKey(byte [] buffer, int offset, int length) {
55 return false;
56 }
57
58 /**
59 * Filters that never filter all remaining can inherit this implementation that
60 * never stops the filter early.
61 *
62 * @inheritDoc
63 */
64 @Override
65 public boolean filterAllRemaining() {
66 return false;
67 }
68
69 /**
70 * Filters that dont filter by key value can inherit this implementation that
71 * includes all KeyValues.
72 *
73 * @inheritDoc
74 */
75 @Override
76 public ReturnCode filterKeyValue(KeyValue ignored) {
77 return ReturnCode.INCLUDE;
78 }
79
80 /**
81 * By default no transformation takes place
82 *
83 * @inheritDoc
84 */
85 @Override
86 public KeyValue transform(KeyValue v) {
87 return v;
88 }
89
90 /**
91 * Filters that never filter by modifying the returned List of KeyValues can
92 * inherit this implementation that does nothing.
93 *
94 * @inheritDoc
95 */
96 @Override
97 public void filterRow(List<KeyValue> ignored) {
98 }
99
100 /**
101 * Fitlers that never filter by modifying the returned List of KeyValues can
102 * inherit this implementation that does nothing.
103 *
104 * @inheritDoc
105 */
106 @Override
107 public boolean hasFilterRow() {
108 return false;
109 }
110
111 /**
112 * Filters that never filter by rows based on previously gathered state from
113 * {@link #filterKeyValue(KeyValue)} can inherit this implementation that
114 * never filters a row.
115 *
116 * @inheritDoc
117 */
118 @Override
119 public boolean filterRow() {
120 return false;
121 }
122
123 /**
124 * Filters that are not sure which key must be next seeked to, can inherit
125 * this implementation that, by default, returns a null KeyValue.
126 *
127 * @inheritDoc
128 */
129 public KeyValue getNextKeyHint(KeyValue currentKV) {
130 return null;
131 }
132
133 /**
134 * Check that given column family is essential for filter to check row. Most
135 * filters always return true here. But some could have more sophisticated
136 * logic which could significantly reduce scanning process by not even
137 * touching columns until we are 100% sure that it's data is needed in result.
138 *
139 * By default, we require all scan's column families to be present. Our
140 * subclasses may be more precise.
141 */
142 public boolean isFamilyEssential(byte[] name) {
143 return true;
144 }
145
146 /**
147 * Check that given column family is essential for filter to check row.
148 * This accommodates Filter implementation which didn't have this capability
149 *
150 * @param filter
151 * @param name column family name
152 * @return whether column family is essential
153 */
154 public static boolean isFamilyEssential(Filter filter, byte[] name) {
155 return (!(filter instanceof FilterBase) || ((FilterBase) filter).isFamilyEssential(name)) &&
156 (!(filter instanceof FilterList) || ((FilterList) filter).isFamilyEssential(name));
157 }
158
159 /**
160 * Given the filter's arguments it constructs the filter
161 * <p>
162 * @param filterArguments the filter's arguments
163 * @return constructed filter object
164 */
165 public static Filter createFilterFromArguments(ArrayList<byte []> filterArguments) {
166 throw new IllegalArgumentException("This method has not been implemented");
167 }
168
169 /**
170 * Return filter's info for debugging and logging purpose.
171 */
172 public String toString() {
173 return this.getClass().getSimpleName();
174 }
175 }