Published site at 278625312047a2100f4dbb2d2eaa4e2219d00e14.
[hbase-site.git] / apidocs / src-html / org / apache / hadoop / hbase / filter / FilterList.Operator.html
1 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
2 <html lang="en">
3 <head>
4 <title>Source code</title>
5 <link rel="stylesheet" type="text/css" href="../../../../../../stylesheet.css" title="Style">
6 </head>
7 <body>
8 <div class="sourceContainer">
9 <pre><span class="sourceLineNo">001</span>/**<a name="line.1"></a>
10 <span class="sourceLineNo">002</span> *<a name="line.2"></a>
11 <span class="sourceLineNo">003</span> * Licensed to the Apache Software Foundation (ASF) under one<a name="line.3"></a>
12 <span class="sourceLineNo">004</span> * or more contributor license agreements. See the NOTICE file<a name="line.4"></a>
13 <span class="sourceLineNo">005</span> * distributed with this work for additional information<a name="line.5"></a>
14 <span class="sourceLineNo">006</span> * regarding copyright ownership. The ASF licenses this file<a name="line.6"></a>
15 <span class="sourceLineNo">007</span> * to you under the Apache License, Version 2.0 (the<a name="line.7"></a>
16 <span class="sourceLineNo">008</span> * "License"); you may not use this file except in compliance<a name="line.8"></a>
17 <span class="sourceLineNo">009</span> * with the License. You may obtain a copy of the License at<a name="line.9"></a>
18 <span class="sourceLineNo">010</span> *<a name="line.10"></a>
19 <span class="sourceLineNo">011</span> * http://www.apache.org/licenses/LICENSE-2.0<a name="line.11"></a>
20 <span class="sourceLineNo">012</span> *<a name="line.12"></a>
21 <span class="sourceLineNo">013</span> * Unless required by applicable law or agreed to in writing, software<a name="line.13"></a>
22 <span class="sourceLineNo">014</span> * distributed under the License is distributed on an "AS IS" BASIS,<a name="line.14"></a>
23 <span class="sourceLineNo">015</span> * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<a name="line.15"></a>
24 <span class="sourceLineNo">016</span> * See the License for the specific language governing permissions and<a name="line.16"></a>
25 <span class="sourceLineNo">017</span> * limitations under the License.<a name="line.17"></a>
26 <span class="sourceLineNo">018</span> */<a name="line.18"></a>
27 <span class="sourceLineNo">019</span>package org.apache.hadoop.hbase.filter;<a name="line.19"></a>
28 <span class="sourceLineNo">020</span><a name="line.20"></a>
29 <span class="sourceLineNo">021</span>import java.io.IOException;<a name="line.21"></a>
30 <span class="sourceLineNo">022</span>import java.util.ArrayList;<a name="line.22"></a>
31 <span class="sourceLineNo">023</span>import java.util.Arrays;<a name="line.23"></a>
32 <span class="sourceLineNo">024</span>import java.util.List;<a name="line.24"></a>
33 <span class="sourceLineNo">025</span><a name="line.25"></a>
34 <span class="sourceLineNo">026</span>import org.apache.hadoop.hbase.Cell;<a name="line.26"></a>
35 <span class="sourceLineNo">027</span>import org.apache.hadoop.hbase.CellComparator;<a name="line.27"></a>
36 <span class="sourceLineNo">028</span>import org.apache.hadoop.hbase.CellUtil;<a name="line.28"></a>
37 <span class="sourceLineNo">029</span>import org.apache.hadoop.hbase.classification.InterfaceAudience;<a name="line.29"></a>
38 <span class="sourceLineNo">030</span>import org.apache.hadoop.hbase.classification.InterfaceStability;<a name="line.30"></a>
39 <span class="sourceLineNo">031</span>import org.apache.hadoop.hbase.exceptions.DeserializationException;<a name="line.31"></a>
40 <span class="sourceLineNo">032</span>import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;<a name="line.32"></a>
41 <span class="sourceLineNo">033</span>import org.apache.hadoop.hbase.shaded.protobuf.generated.FilterProtos;<a name="line.33"></a>
42 <span class="sourceLineNo">034</span>import org.apache.hadoop.hbase.shaded.com.google.protobuf.InvalidProtocolBufferException;<a name="line.34"></a>
43 <span class="sourceLineNo">035</span><a name="line.35"></a>
44 <span class="sourceLineNo">036</span>/**<a name="line.36"></a>
45 <span class="sourceLineNo">037</span> * Implementation of {@link Filter} that represents an ordered List of Filters<a name="line.37"></a>
46 <span class="sourceLineNo">038</span> * which will be evaluated with a specified boolean operator {@link Operator#MUST_PASS_ALL}<a name="line.38"></a>
47 <span class="sourceLineNo">039</span> * (&lt;code&gt;AND&lt;/code&gt;) or {@link Operator#MUST_PASS_ONE} (&lt;code&gt;OR&lt;/code&gt;).<a name="line.39"></a>
48 <span class="sourceLineNo">040</span> * Since you can use Filter Lists as children of Filter Lists, you can create a<a name="line.40"></a>
49 <span class="sourceLineNo">041</span> * hierarchy of filters to be evaluated.<a name="line.41"></a>
50 <span class="sourceLineNo">042</span> *<a name="line.42"></a>
51 <span class="sourceLineNo">043</span> * &lt;br&gt;<a name="line.43"></a>
52 <span class="sourceLineNo">044</span> * {@link Operator#MUST_PASS_ALL} evaluates lazily: evaluation stops as soon as one filter does<a name="line.44"></a>
53 <span class="sourceLineNo">045</span> * not include the KeyValue.<a name="line.45"></a>
54 <span class="sourceLineNo">046</span> *<a name="line.46"></a>
55 <span class="sourceLineNo">047</span> * &lt;br&gt;<a name="line.47"></a>
56 <span class="sourceLineNo">048</span> * {@link Operator#MUST_PASS_ONE} evaluates non-lazily: all filters are always evaluated.<a name="line.48"></a>
57 <span class="sourceLineNo">049</span> *<a name="line.49"></a>
58 <span class="sourceLineNo">050</span> * &lt;br&gt;<a name="line.50"></a>
59 <span class="sourceLineNo">051</span> * Defaults to {@link Operator#MUST_PASS_ALL}.<a name="line.51"></a>
60 <span class="sourceLineNo">052</span> */<a name="line.52"></a>
61 <span class="sourceLineNo">053</span>@InterfaceAudience.Public<a name="line.53"></a>
62 <span class="sourceLineNo">054</span>@InterfaceStability.Stable<a name="line.54"></a>
63 <span class="sourceLineNo">055</span>final public class FilterList extends FilterBase {<a name="line.55"></a>
64 <span class="sourceLineNo">056</span> /** set operator */<a name="line.56"></a>
65 <span class="sourceLineNo">057</span> @InterfaceAudience.Public<a name="line.57"></a>
66 <span class="sourceLineNo">058</span> @InterfaceStability.Stable<a name="line.58"></a>
67 <span class="sourceLineNo">059</span> public static enum Operator {<a name="line.59"></a>
68 <span class="sourceLineNo">060</span> /** !AND */<a name="line.60"></a>
69 <span class="sourceLineNo">061</span> MUST_PASS_ALL,<a name="line.61"></a>
70 <span class="sourceLineNo">062</span> /** !OR */<a name="line.62"></a>
71 <span class="sourceLineNo">063</span> MUST_PASS_ONE<a name="line.63"></a>
72 <span class="sourceLineNo">064</span> }<a name="line.64"></a>
73 <span class="sourceLineNo">065</span><a name="line.65"></a>
74 <span class="sourceLineNo">066</span> private static final int MAX_LOG_FILTERS = 5;<a name="line.66"></a>
75 <span class="sourceLineNo">067</span> private Operator operator = Operator.MUST_PASS_ALL;<a name="line.67"></a>
76 <span class="sourceLineNo">068</span> private final List&lt;Filter&gt; filters;<a name="line.68"></a>
77 <span class="sourceLineNo">069</span> private Filter seekHintFilter = null;<a name="line.69"></a>
78 <span class="sourceLineNo">070</span><a name="line.70"></a>
79 <span class="sourceLineNo">071</span> /** Reference Cell used by {@link #transformCell(Cell)} for validation purpose. */<a name="line.71"></a>
80 <span class="sourceLineNo">072</span> private Cell referenceCell = null;<a name="line.72"></a>
81 <span class="sourceLineNo">073</span><a name="line.73"></a>
82 <span class="sourceLineNo">074</span> /**<a name="line.74"></a>
83 <span class="sourceLineNo">075</span> * When filtering a given Cell in {@link #filterKeyValue(Cell)},<a name="line.75"></a>
84 <span class="sourceLineNo">076</span> * this stores the transformed Cell to be returned by {@link #transformCell(Cell)}.<a name="line.76"></a>
85 <span class="sourceLineNo">077</span> *<a name="line.77"></a>
86 <span class="sourceLineNo">078</span> * Individual filters transformation are applied only when the filter includes the Cell.<a name="line.78"></a>
87 <span class="sourceLineNo">079</span> * Transformations are composed in the order specified by {@link #filters}.<a name="line.79"></a>
88 <span class="sourceLineNo">080</span> */<a name="line.80"></a>
89 <span class="sourceLineNo">081</span> private Cell transformedCell = null;<a name="line.81"></a>
90 <span class="sourceLineNo">082</span><a name="line.82"></a>
91 <span class="sourceLineNo">083</span> /**<a name="line.83"></a>
92 <span class="sourceLineNo">084</span> * Constructor that takes a set of {@link Filter}s. The default operator<a name="line.84"></a>
93 <span class="sourceLineNo">085</span> * MUST_PASS_ALL is assumed.<a name="line.85"></a>
94 <span class="sourceLineNo">086</span> * All filters are cloned to internal list.<a name="line.86"></a>
95 <span class="sourceLineNo">087</span> * @param rowFilters list of filters<a name="line.87"></a>
96 <span class="sourceLineNo">088</span> */<a name="line.88"></a>
97 <span class="sourceLineNo">089</span> public FilterList(final List&lt;Filter&gt; rowFilters) {<a name="line.89"></a>
98 <span class="sourceLineNo">090</span> reversed = getReversed(rowFilters, reversed);<a name="line.90"></a>
99 <span class="sourceLineNo">091</span> this.filters = new ArrayList&lt;&gt;(rowFilters);<a name="line.91"></a>
100 <span class="sourceLineNo">092</span> }<a name="line.92"></a>
101 <span class="sourceLineNo">093</span><a name="line.93"></a>
102 <span class="sourceLineNo">094</span> /**<a name="line.94"></a>
103 <span class="sourceLineNo">095</span> * Constructor that takes a var arg number of {@link Filter}s. The fefault operator<a name="line.95"></a>
104 <span class="sourceLineNo">096</span> * MUST_PASS_ALL is assumed.<a name="line.96"></a>
105 <span class="sourceLineNo">097</span> * @param rowFilters<a name="line.97"></a>
106 <span class="sourceLineNo">098</span> */<a name="line.98"></a>
107 <span class="sourceLineNo">099</span> public FilterList(final Filter... rowFilters) {<a name="line.99"></a>
108 <span class="sourceLineNo">100</span> this(Arrays.asList(rowFilters));<a name="line.100"></a>
109 <span class="sourceLineNo">101</span> }<a name="line.101"></a>
110 <span class="sourceLineNo">102</span><a name="line.102"></a>
111 <span class="sourceLineNo">103</span> /**<a name="line.103"></a>
112 <span class="sourceLineNo">104</span> * Constructor that takes an operator.<a name="line.104"></a>
113 <span class="sourceLineNo">105</span> *<a name="line.105"></a>
114 <span class="sourceLineNo">106</span> * @param operator Operator to process filter set with.<a name="line.106"></a>
115 <span class="sourceLineNo">107</span> */<a name="line.107"></a>
116 <span class="sourceLineNo">108</span> public FilterList(final Operator operator) {<a name="line.108"></a>
117 <span class="sourceLineNo">109</span> this.operator = operator;<a name="line.109"></a>
118 <span class="sourceLineNo">110</span> this.filters = new ArrayList&lt;&gt;();<a name="line.110"></a>
119 <span class="sourceLineNo">111</span> }<a name="line.111"></a>
120 <span class="sourceLineNo">112</span><a name="line.112"></a>
121 <span class="sourceLineNo">113</span> /**<a name="line.113"></a>
122 <span class="sourceLineNo">114</span> * Constructor that takes a set of {@link Filter}s and an operator.<a name="line.114"></a>
123 <span class="sourceLineNo">115</span> *<a name="line.115"></a>
124 <span class="sourceLineNo">116</span> * @param operator Operator to process filter set with.<a name="line.116"></a>
125 <span class="sourceLineNo">117</span> * @param rowFilters Set of row filters.<a name="line.117"></a>
126 <span class="sourceLineNo">118</span> */<a name="line.118"></a>
127 <span class="sourceLineNo">119</span> public FilterList(final Operator operator, final List&lt;Filter&gt; rowFilters) {<a name="line.119"></a>
128 <span class="sourceLineNo">120</span> this(rowFilters);<a name="line.120"></a>
129 <span class="sourceLineNo">121</span> this.operator = operator;<a name="line.121"></a>
130 <span class="sourceLineNo">122</span> }<a name="line.122"></a>
131 <span class="sourceLineNo">123</span><a name="line.123"></a>
132 <span class="sourceLineNo">124</span> /**<a name="line.124"></a>
133 <span class="sourceLineNo">125</span> * Constructor that takes a var arg number of {@link Filter}s and an operator.<a name="line.125"></a>
134 <span class="sourceLineNo">126</span> *<a name="line.126"></a>
135 <span class="sourceLineNo">127</span> * @param operator Operator to process filter set with.<a name="line.127"></a>
136 <span class="sourceLineNo">128</span> * @param rowFilters Filters to use<a name="line.128"></a>
137 <span class="sourceLineNo">129</span> */<a name="line.129"></a>
138 <span class="sourceLineNo">130</span> public FilterList(final Operator operator, final Filter... rowFilters) {<a name="line.130"></a>
139 <span class="sourceLineNo">131</span> this(rowFilters);<a name="line.131"></a>
140 <span class="sourceLineNo">132</span> this.operator = operator;<a name="line.132"></a>
141 <span class="sourceLineNo">133</span> }<a name="line.133"></a>
142 <span class="sourceLineNo">134</span><a name="line.134"></a>
143 <span class="sourceLineNo">135</span> /**<a name="line.135"></a>
144 <span class="sourceLineNo">136</span> * Get the operator.<a name="line.136"></a>
145 <span class="sourceLineNo">137</span> *<a name="line.137"></a>
146 <span class="sourceLineNo">138</span> * @return operator<a name="line.138"></a>
147 <span class="sourceLineNo">139</span> */<a name="line.139"></a>
148 <span class="sourceLineNo">140</span> public Operator getOperator() {<a name="line.140"></a>
149 <span class="sourceLineNo">141</span> return operator;<a name="line.141"></a>
150 <span class="sourceLineNo">142</span> }<a name="line.142"></a>
151 <span class="sourceLineNo">143</span><a name="line.143"></a>
152 <span class="sourceLineNo">144</span> /**<a name="line.144"></a>
153 <span class="sourceLineNo">145</span> * Get the filters.<a name="line.145"></a>
154 <span class="sourceLineNo">146</span> *<a name="line.146"></a>
155 <span class="sourceLineNo">147</span> * @return filters<a name="line.147"></a>
156 <span class="sourceLineNo">148</span> */<a name="line.148"></a>
157 <span class="sourceLineNo">149</span> public List&lt;Filter&gt; getFilters() {<a name="line.149"></a>
158 <span class="sourceLineNo">150</span> return filters;<a name="line.150"></a>
159 <span class="sourceLineNo">151</span> }<a name="line.151"></a>
160 <span class="sourceLineNo">152</span><a name="line.152"></a>
161 <span class="sourceLineNo">153</span> private int size() {<a name="line.153"></a>
162 <span class="sourceLineNo">154</span> return filters.size();<a name="line.154"></a>
163 <span class="sourceLineNo">155</span> }<a name="line.155"></a>
164 <span class="sourceLineNo">156</span><a name="line.156"></a>
165 <span class="sourceLineNo">157</span> private boolean isEmpty() {<a name="line.157"></a>
166 <span class="sourceLineNo">158</span> return filters.isEmpty();<a name="line.158"></a>
167 <span class="sourceLineNo">159</span> }<a name="line.159"></a>
168 <span class="sourceLineNo">160</span><a name="line.160"></a>
169 <span class="sourceLineNo">161</span> private static boolean getReversed(List&lt;Filter&gt; rowFilters, boolean defaultValue) {<a name="line.161"></a>
170 <span class="sourceLineNo">162</span> boolean rval = defaultValue;<a name="line.162"></a>
171 <span class="sourceLineNo">163</span> boolean isFirst = true;<a name="line.163"></a>
172 <span class="sourceLineNo">164</span> for (Filter f : rowFilters) {<a name="line.164"></a>
173 <span class="sourceLineNo">165</span> if (isFirst) {<a name="line.165"></a>
174 <span class="sourceLineNo">166</span> rval = f.isReversed();<a name="line.166"></a>
175 <span class="sourceLineNo">167</span> isFirst = false;<a name="line.167"></a>
176 <span class="sourceLineNo">168</span> continue;<a name="line.168"></a>
177 <span class="sourceLineNo">169</span> }<a name="line.169"></a>
178 <span class="sourceLineNo">170</span> if (rval != f.isReversed()) {<a name="line.170"></a>
179 <span class="sourceLineNo">171</span> throw new IllegalArgumentException("Filters in the list must have the same reversed flag");<a name="line.171"></a>
180 <span class="sourceLineNo">172</span> }<a name="line.172"></a>
181 <span class="sourceLineNo">173</span> }<a name="line.173"></a>
182 <span class="sourceLineNo">174</span> return rval;<a name="line.174"></a>
183 <span class="sourceLineNo">175</span> }<a name="line.175"></a>
184 <span class="sourceLineNo">176</span> private static void checkReversed(List&lt;Filter&gt; rowFilters, boolean expected) {<a name="line.176"></a>
185 <span class="sourceLineNo">177</span> for (Filter filter : rowFilters) {<a name="line.177"></a>
186 <span class="sourceLineNo">178</span> if (expected != filter.isReversed()) {<a name="line.178"></a>
187 <span class="sourceLineNo">179</span> throw new IllegalArgumentException(<a name="line.179"></a>
188 <span class="sourceLineNo">180</span> "Filters in the list must have the same reversed flag, expected="<a name="line.180"></a>
189 <span class="sourceLineNo">181</span> + expected);<a name="line.181"></a>
190 <span class="sourceLineNo">182</span> }<a name="line.182"></a>
191 <span class="sourceLineNo">183</span> }<a name="line.183"></a>
192 <span class="sourceLineNo">184</span> }<a name="line.184"></a>
193 <span class="sourceLineNo">185</span><a name="line.185"></a>
194 <span class="sourceLineNo">186</span> public void addFilter(List&lt;Filter&gt; filters) {<a name="line.186"></a>
195 <span class="sourceLineNo">187</span> checkReversed(filters, isReversed());<a name="line.187"></a>
196 <span class="sourceLineNo">188</span> this.filters.addAll(filters);<a name="line.188"></a>
197 <span class="sourceLineNo">189</span> }<a name="line.189"></a>
198 <span class="sourceLineNo">190</span><a name="line.190"></a>
199 <span class="sourceLineNo">191</span> /**<a name="line.191"></a>
200 <span class="sourceLineNo">192</span> * Add a filter.<a name="line.192"></a>
201 <span class="sourceLineNo">193</span> *<a name="line.193"></a>
202 <span class="sourceLineNo">194</span> * @param filter another filter<a name="line.194"></a>
203 <span class="sourceLineNo">195</span> */<a name="line.195"></a>
204 <span class="sourceLineNo">196</span> public void addFilter(Filter filter) {<a name="line.196"></a>
205 <span class="sourceLineNo">197</span> addFilter(Arrays.asList(filter));<a name="line.197"></a>
206 <span class="sourceLineNo">198</span> }<a name="line.198"></a>
207 <span class="sourceLineNo">199</span><a name="line.199"></a>
208 <span class="sourceLineNo">200</span> @Override<a name="line.200"></a>
209 <span class="sourceLineNo">201</span> public void reset() throws IOException {<a name="line.201"></a>
210 <span class="sourceLineNo">202</span> int listize = filters.size();<a name="line.202"></a>
211 <span class="sourceLineNo">203</span> for (int i = 0; i &lt; listize; i++) {<a name="line.203"></a>
212 <span class="sourceLineNo">204</span> filters.get(i).reset();<a name="line.204"></a>
213 <span class="sourceLineNo">205</span> }<a name="line.205"></a>
214 <span class="sourceLineNo">206</span> seekHintFilter = null;<a name="line.206"></a>
215 <span class="sourceLineNo">207</span> }<a name="line.207"></a>
216 <span class="sourceLineNo">208</span><a name="line.208"></a>
217 <span class="sourceLineNo">209</span> @Override<a name="line.209"></a>
218 <span class="sourceLineNo">210</span> public boolean filterRowKey(byte[] rowKey, int offset, int length) throws IOException {<a name="line.210"></a>
219 <span class="sourceLineNo">211</span> if (isEmpty()) {<a name="line.211"></a>
220 <span class="sourceLineNo">212</span> return super.filterRowKey(rowKey, offset, length);<a name="line.212"></a>
221 <span class="sourceLineNo">213</span> }<a name="line.213"></a>
222 <span class="sourceLineNo">214</span> boolean flag = this.operator == Operator.MUST_PASS_ONE;<a name="line.214"></a>
223 <span class="sourceLineNo">215</span> int listize = filters.size();<a name="line.215"></a>
224 <span class="sourceLineNo">216</span> for (int i = 0; i &lt; listize; i++) {<a name="line.216"></a>
225 <span class="sourceLineNo">217</span> Filter filter = filters.get(i);<a name="line.217"></a>
226 <span class="sourceLineNo">218</span> if (this.operator == Operator.MUST_PASS_ALL) {<a name="line.218"></a>
227 <span class="sourceLineNo">219</span> if (filter.filterAllRemaining() ||<a name="line.219"></a>
228 <span class="sourceLineNo">220</span> filter.filterRowKey(rowKey, offset, length)) {<a name="line.220"></a>
229 <span class="sourceLineNo">221</span> flag = true;<a name="line.221"></a>
230 <span class="sourceLineNo">222</span> }<a name="line.222"></a>
231 <span class="sourceLineNo">223</span> } else if (this.operator == Operator.MUST_PASS_ONE) {<a name="line.223"></a>
232 <span class="sourceLineNo">224</span> if (!filter.filterAllRemaining() &amp;&amp;<a name="line.224"></a>
233 <span class="sourceLineNo">225</span> !filter.filterRowKey(rowKey, offset, length)) {<a name="line.225"></a>
234 <span class="sourceLineNo">226</span> flag = false;<a name="line.226"></a>
235 <span class="sourceLineNo">227</span> }<a name="line.227"></a>
236 <span class="sourceLineNo">228</span> }<a name="line.228"></a>
237 <span class="sourceLineNo">229</span> }<a name="line.229"></a>
238 <span class="sourceLineNo">230</span> return flag;<a name="line.230"></a>
239 <span class="sourceLineNo">231</span> }<a name="line.231"></a>
240 <span class="sourceLineNo">232</span><a name="line.232"></a>
241 <span class="sourceLineNo">233</span> @Override<a name="line.233"></a>
242 <span class="sourceLineNo">234</span> public boolean filterRowKey(Cell firstRowCell) throws IOException {<a name="line.234"></a>
243 <span class="sourceLineNo">235</span> if (isEmpty()) {<a name="line.235"></a>
244 <span class="sourceLineNo">236</span> return super.filterRowKey(firstRowCell);<a name="line.236"></a>
245 <span class="sourceLineNo">237</span> }<a name="line.237"></a>
246 <span class="sourceLineNo">238</span> boolean flag = this.operator == Operator.MUST_PASS_ONE;<a name="line.238"></a>
247 <span class="sourceLineNo">239</span> int listize = filters.size();<a name="line.239"></a>
248 <span class="sourceLineNo">240</span> for (int i = 0; i &lt; listize; i++) {<a name="line.240"></a>
249 <span class="sourceLineNo">241</span> Filter filter = filters.get(i);<a name="line.241"></a>
250 <span class="sourceLineNo">242</span> if (this.operator == Operator.MUST_PASS_ALL) {<a name="line.242"></a>
251 <span class="sourceLineNo">243</span> if (filter.filterAllRemaining() || filter.filterRowKey(firstRowCell)) {<a name="line.243"></a>
252 <span class="sourceLineNo">244</span> flag = true;<a name="line.244"></a>
253 <span class="sourceLineNo">245</span> }<a name="line.245"></a>
254 <span class="sourceLineNo">246</span> } else if (this.operator == Operator.MUST_PASS_ONE) {<a name="line.246"></a>
255 <span class="sourceLineNo">247</span> if (!filter.filterAllRemaining() &amp;&amp; !filter.filterRowKey(firstRowCell)) {<a name="line.247"></a>
256 <span class="sourceLineNo">248</span> flag = false;<a name="line.248"></a>
257 <span class="sourceLineNo">249</span> }<a name="line.249"></a>
258 <span class="sourceLineNo">250</span> }<a name="line.250"></a>
259 <span class="sourceLineNo">251</span> }<a name="line.251"></a>
260 <span class="sourceLineNo">252</span> return flag;<a name="line.252"></a>
261 <span class="sourceLineNo">253</span> }<a name="line.253"></a>
262 <span class="sourceLineNo">254</span><a name="line.254"></a>
263 <span class="sourceLineNo">255</span> @Override<a name="line.255"></a>
264 <span class="sourceLineNo">256</span> public boolean filterAllRemaining() throws IOException {<a name="line.256"></a>
265 <span class="sourceLineNo">257</span> if (isEmpty()) {<a name="line.257"></a>
266 <span class="sourceLineNo">258</span> return super.filterAllRemaining();<a name="line.258"></a>
267 <span class="sourceLineNo">259</span> }<a name="line.259"></a>
268 <span class="sourceLineNo">260</span> int listize = filters.size();<a name="line.260"></a>
269 <span class="sourceLineNo">261</span> for (int i = 0; i &lt; listize; i++) {<a name="line.261"></a>
270 <span class="sourceLineNo">262</span> if (filters.get(i).filterAllRemaining()) {<a name="line.262"></a>
271 <span class="sourceLineNo">263</span> if (operator == Operator.MUST_PASS_ALL) {<a name="line.263"></a>
272 <span class="sourceLineNo">264</span> return true;<a name="line.264"></a>
273 <span class="sourceLineNo">265</span> }<a name="line.265"></a>
274 <span class="sourceLineNo">266</span> } else {<a name="line.266"></a>
275 <span class="sourceLineNo">267</span> if (operator == Operator.MUST_PASS_ONE) {<a name="line.267"></a>
276 <span class="sourceLineNo">268</span> return false;<a name="line.268"></a>
277 <span class="sourceLineNo">269</span> }<a name="line.269"></a>
278 <span class="sourceLineNo">270</span> }<a name="line.270"></a>
279 <span class="sourceLineNo">271</span> }<a name="line.271"></a>
280 <span class="sourceLineNo">272</span> return operator == Operator.MUST_PASS_ONE;<a name="line.272"></a>
281 <span class="sourceLineNo">273</span> }<a name="line.273"></a>
282 <span class="sourceLineNo">274</span><a name="line.274"></a>
283 <span class="sourceLineNo">275</span> @Override<a name="line.275"></a>
284 <span class="sourceLineNo">276</span> public Cell transformCell(Cell c) throws IOException {<a name="line.276"></a>
285 <span class="sourceLineNo">277</span> if (isEmpty()) {<a name="line.277"></a>
286 <span class="sourceLineNo">278</span> return super.transformCell(c);<a name="line.278"></a>
287 <span class="sourceLineNo">279</span> }<a name="line.279"></a>
288 <span class="sourceLineNo">280</span> if (!CellUtil.equals(c, referenceCell)) {<a name="line.280"></a>
289 <span class="sourceLineNo">281</span> throw new IllegalStateException("Reference Cell: " + this.referenceCell + " does not match: "<a name="line.281"></a>
290 <span class="sourceLineNo">282</span> + c);<a name="line.282"></a>
291 <span class="sourceLineNo">283</span> }<a name="line.283"></a>
292 <span class="sourceLineNo">284</span> return this.transformedCell;<a name="line.284"></a>
293 <span class="sourceLineNo">285</span> }<a name="line.285"></a>
294 <span class="sourceLineNo">286</span><a name="line.286"></a>
295 <span class="sourceLineNo">287</span> @Override<a name="line.287"></a>
296 <span class="sourceLineNo">288</span> @edu.umd.cs.findbugs.annotations.SuppressWarnings(value="SF_SWITCH_FALLTHROUGH",<a name="line.288"></a>
297 <span class="sourceLineNo">289</span> justification="Intentional")<a name="line.289"></a>
298 <span class="sourceLineNo">290</span> public ReturnCode filterKeyValue(Cell c) throws IOException {<a name="line.290"></a>
299 <span class="sourceLineNo">291</span> if (isEmpty()) {<a name="line.291"></a>
300 <span class="sourceLineNo">292</span> return ReturnCode.INCLUDE;<a name="line.292"></a>
301 <span class="sourceLineNo">293</span> }<a name="line.293"></a>
302 <span class="sourceLineNo">294</span> this.referenceCell = c;<a name="line.294"></a>
303 <span class="sourceLineNo">295</span><a name="line.295"></a>
304 <span class="sourceLineNo">296</span> // Accumulates successive transformation of every filter that includes the Cell:<a name="line.296"></a>
305 <span class="sourceLineNo">297</span> Cell transformed = c;<a name="line.297"></a>
306 <span class="sourceLineNo">298</span><a name="line.298"></a>
307 <span class="sourceLineNo">299</span> ReturnCode rc = operator == Operator.MUST_PASS_ONE?<a name="line.299"></a>
308 <span class="sourceLineNo">300</span> ReturnCode.SKIP: ReturnCode.INCLUDE;<a name="line.300"></a>
309 <span class="sourceLineNo">301</span> int listize = filters.size();<a name="line.301"></a>
310 <span class="sourceLineNo">302</span> /*<a name="line.302"></a>
311 <span class="sourceLineNo">303</span> * When all filters in a MUST_PASS_ONE FilterList return a SEEK_USING_NEXT_HINT code,<a name="line.303"></a>
312 <span class="sourceLineNo">304</span> * we should return SEEK_NEXT_USING_HINT from the FilterList to utilize the lowest seek value.<a name="line.304"></a>
313 <span class="sourceLineNo">305</span> * <a name="line.305"></a>
314 <span class="sourceLineNo">306</span> * The following variable tracks whether any of the Filters returns ReturnCode other than<a name="line.306"></a>
315 <span class="sourceLineNo">307</span> * SEEK_NEXT_USING_HINT for MUST_PASS_ONE FilterList, in which case the optimization would<a name="line.307"></a>
316 <span class="sourceLineNo">308</span> * be skipped.<a name="line.308"></a>
317 <span class="sourceLineNo">309</span> */<a name="line.309"></a>
318 <span class="sourceLineNo">310</span> boolean seenNonHintReturnCode = false;<a name="line.310"></a>
319 <span class="sourceLineNo">311</span> for (int i = 0; i &lt; listize; i++) {<a name="line.311"></a>
320 <span class="sourceLineNo">312</span> Filter filter = filters.get(i);<a name="line.312"></a>
321 <span class="sourceLineNo">313</span> if (operator == Operator.MUST_PASS_ALL) {<a name="line.313"></a>
322 <span class="sourceLineNo">314</span> if (filter.filterAllRemaining()) {<a name="line.314"></a>
323 <span class="sourceLineNo">315</span> return ReturnCode.NEXT_ROW;<a name="line.315"></a>
324 <span class="sourceLineNo">316</span> }<a name="line.316"></a>
325 <span class="sourceLineNo">317</span> ReturnCode code = filter.filterKeyValue(c);<a name="line.317"></a>
326 <span class="sourceLineNo">318</span> switch (code) {<a name="line.318"></a>
327 <span class="sourceLineNo">319</span> // Override INCLUDE and continue to evaluate.<a name="line.319"></a>
328 <span class="sourceLineNo">320</span> case INCLUDE_AND_NEXT_COL:<a name="line.320"></a>
329 <span class="sourceLineNo">321</span> rc = ReturnCode.INCLUDE_AND_NEXT_COL; // FindBugs SF_SWITCH_FALLTHROUGH<a name="line.321"></a>
330 <span class="sourceLineNo">322</span> case INCLUDE:<a name="line.322"></a>
331 <span class="sourceLineNo">323</span> transformed = filter.transformCell(transformed);<a name="line.323"></a>
332 <span class="sourceLineNo">324</span> continue;<a name="line.324"></a>
333 <span class="sourceLineNo">325</span> case SEEK_NEXT_USING_HINT:<a name="line.325"></a>
334 <span class="sourceLineNo">326</span> seekHintFilter = filter;<a name="line.326"></a>
335 <span class="sourceLineNo">327</span> return code;<a name="line.327"></a>
336 <span class="sourceLineNo">328</span> default:<a name="line.328"></a>
337 <span class="sourceLineNo">329</span> return code;<a name="line.329"></a>
338 <span class="sourceLineNo">330</span> }<a name="line.330"></a>
339 <span class="sourceLineNo">331</span> } else if (operator == Operator.MUST_PASS_ONE) {<a name="line.331"></a>
340 <span class="sourceLineNo">332</span> if (filter.filterAllRemaining()) {<a name="line.332"></a>
341 <span class="sourceLineNo">333</span> seenNonHintReturnCode = true;<a name="line.333"></a>
342 <span class="sourceLineNo">334</span> continue;<a name="line.334"></a>
343 <span class="sourceLineNo">335</span> }<a name="line.335"></a>
344 <span class="sourceLineNo">336</span><a name="line.336"></a>
345 <span class="sourceLineNo">337</span> ReturnCode localRC = filter.filterKeyValue(c);<a name="line.337"></a>
346 <span class="sourceLineNo">338</span> if (localRC != ReturnCode.SEEK_NEXT_USING_HINT) {<a name="line.338"></a>
347 <span class="sourceLineNo">339</span> seenNonHintReturnCode = true;<a name="line.339"></a>
348 <span class="sourceLineNo">340</span> }<a name="line.340"></a>
349 <span class="sourceLineNo">341</span> switch (localRC) {<a name="line.341"></a>
350 <span class="sourceLineNo">342</span> case INCLUDE:<a name="line.342"></a>
351 <span class="sourceLineNo">343</span> if (rc != ReturnCode.INCLUDE_AND_NEXT_COL) {<a name="line.343"></a>
352 <span class="sourceLineNo">344</span> rc = ReturnCode.INCLUDE;<a name="line.344"></a>
353 <span class="sourceLineNo">345</span> }<a name="line.345"></a>
354 <span class="sourceLineNo">346</span> transformed = filter.transformCell(transformed);<a name="line.346"></a>
355 <span class="sourceLineNo">347</span> break;<a name="line.347"></a>
356 <span class="sourceLineNo">348</span> case INCLUDE_AND_NEXT_COL:<a name="line.348"></a>
357 <span class="sourceLineNo">349</span> rc = ReturnCode.INCLUDE_AND_NEXT_COL;<a name="line.349"></a>
358 <span class="sourceLineNo">350</span> transformed = filter.transformCell(transformed);<a name="line.350"></a>
359 <span class="sourceLineNo">351</span> // must continue here to evaluate all filters<a name="line.351"></a>
360 <span class="sourceLineNo">352</span> break;<a name="line.352"></a>
361 <span class="sourceLineNo">353</span> case NEXT_ROW:<a name="line.353"></a>
362 <span class="sourceLineNo">354</span> break;<a name="line.354"></a>
363 <span class="sourceLineNo">355</span> case SKIP:<a name="line.355"></a>
364 <span class="sourceLineNo">356</span> break;<a name="line.356"></a>
365 <span class="sourceLineNo">357</span> case NEXT_COL:<a name="line.357"></a>
366 <span class="sourceLineNo">358</span> break;<a name="line.358"></a>
367 <span class="sourceLineNo">359</span> case SEEK_NEXT_USING_HINT:<a name="line.359"></a>
368 <span class="sourceLineNo">360</span> break;<a name="line.360"></a>
369 <span class="sourceLineNo">361</span> default:<a name="line.361"></a>
370 <span class="sourceLineNo">362</span> throw new IllegalStateException("Received code is not valid.");<a name="line.362"></a>
371 <span class="sourceLineNo">363</span> }<a name="line.363"></a>
372 <span class="sourceLineNo">364</span> }<a name="line.364"></a>
373 <span class="sourceLineNo">365</span> }<a name="line.365"></a>
374 <span class="sourceLineNo">366</span><a name="line.366"></a>
375 <span class="sourceLineNo">367</span> // Save the transformed Cell for transform():<a name="line.367"></a>
376 <span class="sourceLineNo">368</span> this.transformedCell = transformed;<a name="line.368"></a>
377 <span class="sourceLineNo">369</span><a name="line.369"></a>
378 <span class="sourceLineNo">370</span> /*<a name="line.370"></a>
379 <span class="sourceLineNo">371</span> * The seenNonHintReturnCode flag is intended only for Operator.MUST_PASS_ONE branch.<a name="line.371"></a>
380 <span class="sourceLineNo">372</span> * If we have seen non SEEK_NEXT_USING_HINT ReturnCode, respect that ReturnCode.<a name="line.372"></a>
381 <span class="sourceLineNo">373</span> */<a name="line.373"></a>
382 <span class="sourceLineNo">374</span> if (operator == Operator.MUST_PASS_ONE &amp;&amp; !seenNonHintReturnCode) {<a name="line.374"></a>
383 <span class="sourceLineNo">375</span> return ReturnCode.SEEK_NEXT_USING_HINT;<a name="line.375"></a>
384 <span class="sourceLineNo">376</span> }<a name="line.376"></a>
385 <span class="sourceLineNo">377</span> return rc;<a name="line.377"></a>
386 <span class="sourceLineNo">378</span> }<a name="line.378"></a>
387 <span class="sourceLineNo">379</span><a name="line.379"></a>
388 <span class="sourceLineNo">380</span> /**<a name="line.380"></a>
389 <span class="sourceLineNo">381</span> * Filters that never filter by modifying the returned List of Cells can<a name="line.381"></a>
390 <span class="sourceLineNo">382</span> * inherit this implementation that does nothing.<a name="line.382"></a>
391 <span class="sourceLineNo">383</span> *<a name="line.383"></a>
392 <span class="sourceLineNo">384</span> * {@inheritDoc}<a name="line.384"></a>
393 <span class="sourceLineNo">385</span> */<a name="line.385"></a>
394 <span class="sourceLineNo">386</span> @Override<a name="line.386"></a>
395 <span class="sourceLineNo">387</span> public void filterRowCells(List&lt;Cell&gt; cells) throws IOException {<a name="line.387"></a>
396 <span class="sourceLineNo">388</span> int listize = filters.size();<a name="line.388"></a>
397 <span class="sourceLineNo">389</span> for (int i = 0; i &lt; listize; i++) {<a name="line.389"></a>
398 <span class="sourceLineNo">390</span> filters.get(i).filterRowCells(cells);<a name="line.390"></a>
399 <span class="sourceLineNo">391</span> }<a name="line.391"></a>
400 <span class="sourceLineNo">392</span> }<a name="line.392"></a>
401 <span class="sourceLineNo">393</span><a name="line.393"></a>
402 <span class="sourceLineNo">394</span> @Override<a name="line.394"></a>
403 <span class="sourceLineNo">395</span> public boolean hasFilterRow() {<a name="line.395"></a>
404 <span class="sourceLineNo">396</span> int listize = filters.size();<a name="line.396"></a>
405 <span class="sourceLineNo">397</span> for (int i = 0; i &lt; listize; i++) {<a name="line.397"></a>
406 <span class="sourceLineNo">398</span> if (filters.get(i).hasFilterRow()) {<a name="line.398"></a>
407 <span class="sourceLineNo">399</span> return true;<a name="line.399"></a>
408 <span class="sourceLineNo">400</span> }<a name="line.400"></a>
409 <span class="sourceLineNo">401</span> }<a name="line.401"></a>
410 <span class="sourceLineNo">402</span> return false;<a name="line.402"></a>
411 <span class="sourceLineNo">403</span> }<a name="line.403"></a>
412 <span class="sourceLineNo">404</span><a name="line.404"></a>
413 <span class="sourceLineNo">405</span> @Override<a name="line.405"></a>
414 <span class="sourceLineNo">406</span> public boolean filterRow() throws IOException {<a name="line.406"></a>
415 <span class="sourceLineNo">407</span> if (isEmpty()) {<a name="line.407"></a>
416 <span class="sourceLineNo">408</span> return super.filterRow();<a name="line.408"></a>
417 <span class="sourceLineNo">409</span> }<a name="line.409"></a>
418 <span class="sourceLineNo">410</span> int listize = filters.size();<a name="line.410"></a>
419 <span class="sourceLineNo">411</span> for (int i = 0; i &lt; listize; i++) {<a name="line.411"></a>
420 <span class="sourceLineNo">412</span> Filter filter = filters.get(i);<a name="line.412"></a>
421 <span class="sourceLineNo">413</span> if (operator == Operator.MUST_PASS_ALL) {<a name="line.413"></a>
422 <span class="sourceLineNo">414</span> if (filter.filterRow()) {<a name="line.414"></a>
423 <span class="sourceLineNo">415</span> return true;<a name="line.415"></a>
424 <span class="sourceLineNo">416</span> }<a name="line.416"></a>
425 <span class="sourceLineNo">417</span> } else if (operator == Operator.MUST_PASS_ONE) {<a name="line.417"></a>
426 <span class="sourceLineNo">418</span> if (!filter.filterRow()) {<a name="line.418"></a>
427 <span class="sourceLineNo">419</span> return false;<a name="line.419"></a>
428 <span class="sourceLineNo">420</span> }<a name="line.420"></a>
429 <span class="sourceLineNo">421</span> }<a name="line.421"></a>
430 <span class="sourceLineNo">422</span> }<a name="line.422"></a>
431 <span class="sourceLineNo">423</span> return operator == Operator.MUST_PASS_ONE;<a name="line.423"></a>
432 <span class="sourceLineNo">424</span> }<a name="line.424"></a>
433 <span class="sourceLineNo">425</span><a name="line.425"></a>
434 <span class="sourceLineNo">426</span> /**<a name="line.426"></a>
435 <span class="sourceLineNo">427</span> * @return The filter serialized using pb<a name="line.427"></a>
436 <span class="sourceLineNo">428</span> */<a name="line.428"></a>
437 <span class="sourceLineNo">429</span> public byte[] toByteArray() throws IOException {<a name="line.429"></a>
438 <span class="sourceLineNo">430</span> FilterProtos.FilterList.Builder builder =<a name="line.430"></a>
439 <span class="sourceLineNo">431</span> FilterProtos.FilterList.newBuilder();<a name="line.431"></a>
440 <span class="sourceLineNo">432</span> builder.setOperator(FilterProtos.FilterList.Operator.valueOf(operator.name()));<a name="line.432"></a>
441 <span class="sourceLineNo">433</span> int listize = filters.size();<a name="line.433"></a>
442 <span class="sourceLineNo">434</span> for (int i = 0; i &lt; listize; i++) {<a name="line.434"></a>
443 <span class="sourceLineNo">435</span> builder.addFilters(ProtobufUtil.toFilter(filters.get(i)));<a name="line.435"></a>
444 <span class="sourceLineNo">436</span> }<a name="line.436"></a>
445 <span class="sourceLineNo">437</span> return builder.build().toByteArray();<a name="line.437"></a>
446 <span class="sourceLineNo">438</span> }<a name="line.438"></a>
447 <span class="sourceLineNo">439</span><a name="line.439"></a>
448 <span class="sourceLineNo">440</span> /**<a name="line.440"></a>
449 <span class="sourceLineNo">441</span> * @param pbBytes A pb serialized {@link FilterList} instance<a name="line.441"></a>
450 <span class="sourceLineNo">442</span> * @return An instance of {@link FilterList} made from &lt;code&gt;bytes&lt;/code&gt;<a name="line.442"></a>
451 <span class="sourceLineNo">443</span> * @throws DeserializationException<a name="line.443"></a>
452 <span class="sourceLineNo">444</span> * @see #toByteArray<a name="line.444"></a>
453 <span class="sourceLineNo">445</span> */<a name="line.445"></a>
454 <span class="sourceLineNo">446</span> public static FilterList parseFrom(final byte [] pbBytes)<a name="line.446"></a>
455 <span class="sourceLineNo">447</span> throws DeserializationException {<a name="line.447"></a>
456 <span class="sourceLineNo">448</span> FilterProtos.FilterList proto;<a name="line.448"></a>
457 <span class="sourceLineNo">449</span> try {<a name="line.449"></a>
458 <span class="sourceLineNo">450</span> proto = FilterProtos.FilterList.parseFrom(pbBytes);<a name="line.450"></a>
459 <span class="sourceLineNo">451</span> } catch (InvalidProtocolBufferException e) {<a name="line.451"></a>
460 <span class="sourceLineNo">452</span> throw new DeserializationException(e);<a name="line.452"></a>
461 <span class="sourceLineNo">453</span> }<a name="line.453"></a>
462 <span class="sourceLineNo">454</span><a name="line.454"></a>
463 <span class="sourceLineNo">455</span> List&lt;Filter&gt; rowFilters = new ArrayList&lt;Filter&gt;(proto.getFiltersCount());<a name="line.455"></a>
464 <span class="sourceLineNo">456</span> try {<a name="line.456"></a>
465 <span class="sourceLineNo">457</span> List&lt;FilterProtos.Filter&gt; filtersList = proto.getFiltersList();<a name="line.457"></a>
466 <span class="sourceLineNo">458</span> int listSize = filtersList.size();<a name="line.458"></a>
467 <span class="sourceLineNo">459</span> for (int i = 0; i &lt; listSize; i++) {<a name="line.459"></a>
468 <span class="sourceLineNo">460</span> rowFilters.add(ProtobufUtil.toFilter(filtersList.get(i)));<a name="line.460"></a>
469 <span class="sourceLineNo">461</span> }<a name="line.461"></a>
470 <span class="sourceLineNo">462</span> } catch (IOException ioe) {<a name="line.462"></a>
471 <span class="sourceLineNo">463</span> throw new DeserializationException(ioe);<a name="line.463"></a>
472 <span class="sourceLineNo">464</span> }<a name="line.464"></a>
473 <span class="sourceLineNo">465</span> return new FilterList(Operator.valueOf(proto.getOperator().name()),rowFilters);<a name="line.465"></a>
474 <span class="sourceLineNo">466</span> }<a name="line.466"></a>
475 <span class="sourceLineNo">467</span><a name="line.467"></a>
476 <span class="sourceLineNo">468</span> /**<a name="line.468"></a>
477 <span class="sourceLineNo">469</span> * @param other<a name="line.469"></a>
478 <span class="sourceLineNo">470</span> * @return true if and only if the fields of the filter that are serialized<a name="line.470"></a>
479 <span class="sourceLineNo">471</span> * are equal to the corresponding fields in other. Used for testing.<a name="line.471"></a>
480 <span class="sourceLineNo">472</span> */<a name="line.472"></a>
481 <span class="sourceLineNo">473</span> boolean areSerializedFieldsEqual(Filter other) {<a name="line.473"></a>
482 <span class="sourceLineNo">474</span> if (other == this) return true;<a name="line.474"></a>
483 <span class="sourceLineNo">475</span> if (!(other instanceof FilterList)) return false;<a name="line.475"></a>
484 <span class="sourceLineNo">476</span><a name="line.476"></a>
485 <span class="sourceLineNo">477</span> FilterList o = (FilterList)other;<a name="line.477"></a>
486 <span class="sourceLineNo">478</span> return this.getOperator().equals(o.getOperator()) &amp;&amp;<a name="line.478"></a>
487 <span class="sourceLineNo">479</span> ((this.getFilters() == o.getFilters())<a name="line.479"></a>
488 <span class="sourceLineNo">480</span> || this.getFilters().equals(o.getFilters()));<a name="line.480"></a>
489 <span class="sourceLineNo">481</span> }<a name="line.481"></a>
490 <span class="sourceLineNo">482</span><a name="line.482"></a>
491 <span class="sourceLineNo">483</span> @Override<a name="line.483"></a>
492 <span class="sourceLineNo">484</span> public Cell getNextCellHint(Cell currentCell) throws IOException {<a name="line.484"></a>
493 <span class="sourceLineNo">485</span> if (isEmpty()) {<a name="line.485"></a>
494 <span class="sourceLineNo">486</span> return super.getNextCellHint(currentCell);<a name="line.486"></a>
495 <span class="sourceLineNo">487</span> }<a name="line.487"></a>
496 <span class="sourceLineNo">488</span> Cell keyHint = null;<a name="line.488"></a>
497 <span class="sourceLineNo">489</span> if (operator == Operator.MUST_PASS_ALL) {<a name="line.489"></a>
498 <span class="sourceLineNo">490</span> keyHint = seekHintFilter.getNextCellHint(currentCell);<a name="line.490"></a>
499 <span class="sourceLineNo">491</span> return keyHint;<a name="line.491"></a>
500 <span class="sourceLineNo">492</span> }<a name="line.492"></a>
501 <span class="sourceLineNo">493</span><a name="line.493"></a>
502 <span class="sourceLineNo">494</span> // If any condition can pass, we need to keep the min hint<a name="line.494"></a>
503 <span class="sourceLineNo">495</span> int listize = filters.size();<a name="line.495"></a>
504 <span class="sourceLineNo">496</span> for (int i = 0; i &lt; listize; i++) {<a name="line.496"></a>
505 <span class="sourceLineNo">497</span> if (filters.get(i).filterAllRemaining()) {<a name="line.497"></a>
506 <span class="sourceLineNo">498</span> continue;<a name="line.498"></a>
507 <span class="sourceLineNo">499</span> }<a name="line.499"></a>
508 <span class="sourceLineNo">500</span> Cell curKeyHint = filters.get(i).getNextCellHint(currentCell);<a name="line.500"></a>
509 <span class="sourceLineNo">501</span> if (curKeyHint == null) {<a name="line.501"></a>
510 <span class="sourceLineNo">502</span> // If we ever don't have a hint and this is must-pass-one, then no hint<a name="line.502"></a>
511 <span class="sourceLineNo">503</span> return null;<a name="line.503"></a>
512 <span class="sourceLineNo">504</span> }<a name="line.504"></a>
513 <span class="sourceLineNo">505</span> // If this is the first hint we find, set it<a name="line.505"></a>
514 <span class="sourceLineNo">506</span> if (keyHint == null) {<a name="line.506"></a>
515 <span class="sourceLineNo">507</span> keyHint = curKeyHint;<a name="line.507"></a>
516 <span class="sourceLineNo">508</span> continue;<a name="line.508"></a>
517 <span class="sourceLineNo">509</span> }<a name="line.509"></a>
518 <span class="sourceLineNo">510</span> if (CellComparator.COMPARATOR.compare(keyHint, curKeyHint) &gt; 0) {<a name="line.510"></a>
519 <span class="sourceLineNo">511</span> keyHint = curKeyHint;<a name="line.511"></a>
520 <span class="sourceLineNo">512</span> }<a name="line.512"></a>
521 <span class="sourceLineNo">513</span> }<a name="line.513"></a>
522 <span class="sourceLineNo">514</span> return keyHint;<a name="line.514"></a>
523 <span class="sourceLineNo">515</span> }<a name="line.515"></a>
524 <span class="sourceLineNo">516</span><a name="line.516"></a>
525 <span class="sourceLineNo">517</span> @Override<a name="line.517"></a>
526 <span class="sourceLineNo">518</span> public boolean isFamilyEssential(byte[] name) throws IOException {<a name="line.518"></a>
527 <span class="sourceLineNo">519</span> if (isEmpty()) {<a name="line.519"></a>
528 <span class="sourceLineNo">520</span> return super.isFamilyEssential(name);<a name="line.520"></a>
529 <span class="sourceLineNo">521</span> }<a name="line.521"></a>
530 <span class="sourceLineNo">522</span> int listize = filters.size();<a name="line.522"></a>
531 <span class="sourceLineNo">523</span> for (int i = 0; i &lt; listize; i++) {<a name="line.523"></a>
532 <span class="sourceLineNo">524</span> if (filters.get(i).isFamilyEssential(name)) {<a name="line.524"></a>
533 <span class="sourceLineNo">525</span> return true;<a name="line.525"></a>
534 <span class="sourceLineNo">526</span> }<a name="line.526"></a>
535 <span class="sourceLineNo">527</span> }<a name="line.527"></a>
536 <span class="sourceLineNo">528</span> return false;<a name="line.528"></a>
537 <span class="sourceLineNo">529</span> }<a name="line.529"></a>
538 <span class="sourceLineNo">530</span><a name="line.530"></a>
539 <span class="sourceLineNo">531</span> @Override<a name="line.531"></a>
540 <span class="sourceLineNo">532</span> public void setReversed(boolean reversed) {<a name="line.532"></a>
541 <span class="sourceLineNo">533</span> int listize = filters.size();<a name="line.533"></a>
542 <span class="sourceLineNo">534</span> for (int i = 0; i &lt; listize; i++) {<a name="line.534"></a>
543 <span class="sourceLineNo">535</span> filters.get(i).setReversed(reversed);<a name="line.535"></a>
544 <span class="sourceLineNo">536</span> }<a name="line.536"></a>
545 <span class="sourceLineNo">537</span> this.reversed = reversed;<a name="line.537"></a>
546 <span class="sourceLineNo">538</span> }<a name="line.538"></a>
547 <span class="sourceLineNo">539</span><a name="line.539"></a>
548 <span class="sourceLineNo">540</span> @Override<a name="line.540"></a>
549 <span class="sourceLineNo">541</span> public String toString() {<a name="line.541"></a>
550 <span class="sourceLineNo">542</span> return toString(MAX_LOG_FILTERS);<a name="line.542"></a>
551 <span class="sourceLineNo">543</span> }<a name="line.543"></a>
552 <span class="sourceLineNo">544</span><a name="line.544"></a>
553 <span class="sourceLineNo">545</span> protected String toString(int maxFilters) {<a name="line.545"></a>
554 <span class="sourceLineNo">546</span> int endIndex = this.filters.size() &lt; maxFilters<a name="line.546"></a>
555 <span class="sourceLineNo">547</span> ? this.filters.size() : maxFilters;<a name="line.547"></a>
556 <span class="sourceLineNo">548</span> return String.format("%s %s (%d/%d): %s",<a name="line.548"></a>
557 <span class="sourceLineNo">549</span> this.getClass().getSimpleName(),<a name="line.549"></a>
558 <span class="sourceLineNo">550</span> this.operator == Operator.MUST_PASS_ALL ? "AND" : "OR",<a name="line.550"></a>
559 <span class="sourceLineNo">551</span> endIndex,<a name="line.551"></a>
560 <span class="sourceLineNo">552</span> this.filters.size(),<a name="line.552"></a>
561 <span class="sourceLineNo">553</span> this.filters.subList(0, endIndex).toString());<a name="line.553"></a>
562 <span class="sourceLineNo">554</span> }<a name="line.554"></a>
563 <span class="sourceLineNo">555</span>}<a name="line.555"></a>
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624 </pre>
625 </div>
626 </body>
627 </html>