001/**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements.  See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership.  The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License.  You may obtain a copy of the License at
009 *
010 *     http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS,
014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015 * See the License for the specific language governing permissions and
016 * limitations under the License.
017 */
018package org.apache.hadoop.hbase.regionserver.querymatcher;
019
020import java.util.TreeSet;
021import static org.junit.Assert.assertEquals;
022
023import java.io.IOException;
024import org.apache.hadoop.hbase.CellComparator;
025import org.apache.hadoop.hbase.CellComparatorImpl;
026import org.apache.hadoop.hbase.HBaseClassTestRule;
027import org.apache.hadoop.hbase.KeyValue;
028import org.apache.hadoop.hbase.regionserver.querymatcher.DeleteTracker.DeleteResult;
029import org.apache.hadoop.hbase.regionserver.querymatcher.ScanQueryMatcher.MatchCode;
030import org.apache.hadoop.hbase.testclassification.RegionServerTests;
031import org.apache.hadoop.hbase.testclassification.SmallTests;
032import org.apache.hadoop.hbase.util.Bytes;
033import org.junit.ClassRule;
034import org.junit.Test;
035import org.junit.experimental.categories.Category;
036
037
038@Category({ RegionServerTests.class, SmallTests.class })
039public class TestNewVersionBehaviorTracker {
040
041  @ClassRule
042  public static final HBaseClassTestRule CLASS_RULE =
043      HBaseClassTestRule.forClass(TestNewVersionBehaviorTracker.class);
044
045  private final byte[] col0 = Bytes.toBytes("col0");
046  private final byte[] col1 = Bytes.toBytes("col1");
047  private final byte[] col2 = Bytes.toBytes("col2");
048  private final byte[] col3 = Bytes.toBytes("col3");
049  private final byte[] col4 = Bytes.toBytes("col4");
050  private final byte[] row = Bytes.toBytes("row");
051  private final byte[] family = Bytes.toBytes("family");
052  private final byte[] value = Bytes.toBytes("value");
053  private final CellComparator comparator = CellComparatorImpl.COMPARATOR;
054
055  @Test
056  public void testColumns() throws IOException {
057    TreeSet<byte[]> trackedColumns = new TreeSet<byte[]>(Bytes.BYTES_COMPARATOR);
058    trackedColumns.add(col1);
059    trackedColumns.add(col3);
060
061    NewVersionBehaviorTracker tracker =
062        new NewVersionBehaviorTracker(trackedColumns, comparator, 1, 3, 3, 10000);
063
064    KeyValue keyValue = new KeyValue(row, family, col0, 20000, KeyValue.Type.Put, value);
065    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
066    assertEquals(MatchCode.SEEK_NEXT_COL, tracker.checkColumn(keyValue, keyValue.getTypeByte()));
067
068    keyValue = new KeyValue(row, family, col1, 20000, KeyValue.Type.Put, value);
069    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
070    assertEquals(MatchCode.INCLUDE, tracker.checkColumn(keyValue, keyValue.getTypeByte()));
071
072    keyValue = new KeyValue(row, family, col2, 20000, KeyValue.Type.Put, value);
073    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
074    assertEquals(MatchCode.SEEK_NEXT_COL, tracker.checkColumn(keyValue, keyValue.getTypeByte()));
075
076    keyValue = new KeyValue(row, family, col3, 20000, KeyValue.Type.Put, value);
077    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
078    assertEquals(MatchCode.INCLUDE, tracker.checkColumn(keyValue, keyValue.getTypeByte()));
079
080    keyValue = new KeyValue(row, family, col4, 20000, KeyValue.Type.Put, value);
081    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
082    assertEquals(MatchCode.SEEK_NEXT_ROW, tracker.checkColumn(keyValue, keyValue.getTypeByte()));
083  }
084
085  @Test
086  public void testMaxVersionMask() {
087    NewVersionBehaviorTracker tracker =
088        new NewVersionBehaviorTracker(null, comparator, 1, 3, 3, 10000);
089
090    KeyValue keyValue = new KeyValue(row, family, col1, 20000, KeyValue.Type.Put, value);
091    keyValue.setTimestamp(20000);
092    keyValue.setSequenceId(1000);
093    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
094    keyValue.setTimestamp(19999);
095    keyValue.setSequenceId(999);
096    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
097    keyValue.setTimestamp(19999);
098    keyValue.setSequenceId(998);
099    assertEquals(DeleteResult.VERSION_MASKED, tracker.isDeleted(keyValue));
100    keyValue.setTimestamp(19998);
101    keyValue.setSequenceId(997);
102    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
103    keyValue.setTimestamp(19997);
104    keyValue.setSequenceId(996);
105    assertEquals(DeleteResult.VERSION_MASKED, tracker.isDeleted(keyValue));
106
107    keyValue = new KeyValue(row, family, col2, 20000, KeyValue.Type.Put, value);
108    keyValue.setTimestamp(20000);
109    keyValue.setSequenceId(1000);
110    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
111    keyValue.setTimestamp(19999);
112    keyValue.setSequenceId(1002);
113    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
114    keyValue.setTimestamp(19999);
115    keyValue.setSequenceId(1001);
116    assertEquals(DeleteResult.VERSION_MASKED, tracker.isDeleted(keyValue));
117    keyValue.setTimestamp(19998);
118    keyValue.setSequenceId(1003);
119    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
120    keyValue.setTimestamp(19997);
121    keyValue.setSequenceId(1004);
122    assertEquals(DeleteResult.VERSION_MASKED, tracker.isDeleted(keyValue));
123  }
124
125  @Test
126  public void testVersionsDelete() {
127    NewVersionBehaviorTracker tracker =
128        new NewVersionBehaviorTracker(null, comparator, 1, 3, 3, 10000);
129    KeyValue put = new KeyValue(row, family, col1, 20000, KeyValue.Type.Put, value);
130    KeyValue delete = new KeyValue(row, family, col1, 20000, KeyValue.Type.DeleteColumn, value);
131    delete.setSequenceId(1000);
132    delete.setTimestamp(20000);
133    tracker.add(delete);
134    put.setSequenceId(1001);
135    put.setTimestamp(19999);
136    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(put));
137    put.setSequenceId(999);
138    put.setTimestamp(19998);
139    assertEquals(DeleteResult.COLUMN_DELETED, tracker.isDeleted(put));
140
141    delete = new KeyValue(row, family, col2, 20000, KeyValue.Type.DeleteColumn, value);
142    delete.setSequenceId(1002);
143    delete.setTimestamp(20000);
144    tracker.add(delete);
145    put = new KeyValue(row, family, col2, 20000, KeyValue.Type.Put, value);
146    put.setSequenceId(1001);
147    put.setTimestamp(19999);
148    assertEquals(DeleteResult.COLUMN_DELETED, tracker.isDeleted(put));
149    put.setSequenceId(999);
150    put.setTimestamp(19998);
151    assertEquals(DeleteResult.COLUMN_DELETED, tracker.isDeleted(put));
152  }
153
154  @Test
155  public void testVersionDelete() {
156    NewVersionBehaviorTracker tracker =
157        new NewVersionBehaviorTracker(null, comparator, 1, 3, 3, 10000);
158    KeyValue put = new KeyValue(row, family, col1, 20000, KeyValue.Type.Put, value);
159    KeyValue delete = new KeyValue(row, family, col1, 20000, KeyValue.Type.Delete, value);
160    delete.setSequenceId(1000);
161    delete.setTimestamp(20000);
162    tracker.add(delete);
163    put.setSequenceId(1001);
164    put.setTimestamp(20000);
165    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(put));
166    put.setSequenceId(999);
167    put.setTimestamp(20000);
168    assertEquals(DeleteResult.VERSION_DELETED, tracker.isDeleted(put));
169
170    delete = new KeyValue(row, family, col2, 20000, KeyValue.Type.Delete, value);
171    delete.setSequenceId(1002);
172    delete.setTimestamp(20000);
173    tracker.add(delete);
174    put = new KeyValue(row, family, col2, 20000, KeyValue.Type.Put, value);
175    put.setSequenceId(1001);
176    put.setTimestamp(20000);
177    assertEquals(DeleteResult.VERSION_DELETED, tracker.isDeleted(put));
178    put.setSequenceId(999);
179    put.setTimestamp(20000);
180    assertEquals(DeleteResult.VERSION_DELETED, tracker.isDeleted(put));
181    put.setSequenceId(1002);
182    put.setTimestamp(19999);
183    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(put));
184    put.setSequenceId(998);
185    put.setTimestamp(19999);
186    assertEquals(DeleteResult.VERSION_MASKED, tracker.isDeleted(put));
187  }
188
189  @Test
190  public void testFamilyVersionsDelete() {
191    NewVersionBehaviorTracker tracker =
192        new NewVersionBehaviorTracker(null, comparator, 1, 3, 3, 10000);
193
194    KeyValue delete = new KeyValue(row, family, null, 20000, KeyValue.Type.DeleteFamily, value);
195    delete.setSequenceId(1000);
196    delete.setTimestamp(20000);
197
198    KeyValue put = new KeyValue(row, family, col1, 20000, KeyValue.Type.Put, value);
199    tracker.add(delete);
200    put.setSequenceId(1001);
201    put.setTimestamp(20000);
202    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(put));
203    put.setSequenceId(999);
204    put.setTimestamp(19998);
205    assertEquals(DeleteResult.COLUMN_DELETED, tracker.isDeleted(put));
206
207    put = new KeyValue(row, family, col2, 20000, KeyValue.Type.Put, value);
208    put.setSequenceId(998);
209    put.setTimestamp(19999);
210    assertEquals(DeleteResult.COLUMN_DELETED, tracker.isDeleted(put));
211    put.setSequenceId(999);
212    put.setTimestamp(19998);
213    assertEquals(DeleteResult.COLUMN_DELETED, tracker.isDeleted(put));
214  }
215
216  @Test
217  public void testFamilyVersionDelete() {
218    NewVersionBehaviorTracker tracker =
219        new NewVersionBehaviorTracker(null, comparator, 1, 3, 3, 10000);
220
221    KeyValue delete = new KeyValue(row, family, null, 20000, KeyValue.Type.DeleteFamilyVersion,
222        value);
223    delete.setSequenceId(1000);
224    delete.setTimestamp(20000);
225    tracker.add(delete);
226
227    KeyValue put = new KeyValue(row, family, col1, 20000, KeyValue.Type.Put, value);
228    put.setSequenceId(1001);
229    put.setTimestamp(20000);
230    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(put));
231    put.setSequenceId(999);
232    put.setTimestamp(20000);
233    assertEquals(DeleteResult.VERSION_DELETED, tracker.isDeleted(put));
234
235    put = new KeyValue(row, family, col2, 20000, KeyValue.Type.Put, value);
236    put.setSequenceId(1001);
237    put.setTimestamp(20000);
238    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(put));
239    put.setSequenceId(999);
240    put.setTimestamp(20000);
241    assertEquals(DeleteResult.VERSION_DELETED, tracker.isDeleted(put));
242    put.setSequenceId(1002);
243    put.setTimestamp(19999);
244    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(put));
245    put.setSequenceId(998);
246    put.setTimestamp(19999);
247    assertEquals(DeleteResult.VERSION_MASKED, tracker.isDeleted(put));
248  }
249
250  @Test
251  public void testMinVersionsAndTTL() throws IOException {
252    NewVersionBehaviorTracker tracker =
253        new NewVersionBehaviorTracker(null, comparator, 1, 3, 3, 30000);
254
255    KeyValue keyValue = new KeyValue(row, family, col1, 20000, KeyValue.Type.Put, value);
256    keyValue.setTimestamp(20000);
257    keyValue.setSequenceId(1000);
258    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
259    assertEquals(MatchCode.INCLUDE_AND_SEEK_NEXT_COL,
260        tracker.checkVersions(keyValue, keyValue.getTimestamp(), keyValue.getTypeByte(), false));
261    keyValue.setTimestamp(19999);
262    keyValue.setSequenceId(999);
263    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
264    assertEquals(
265        MatchCode.SEEK_NEXT_COL,
266        tracker.checkVersions(keyValue, keyValue.getTimestamp(), keyValue.getTypeByte(), false));
267    keyValue.setTimestamp(19999);
268    keyValue.setSequenceId(998);
269    assertEquals(DeleteResult.VERSION_MASKED, tracker.isDeleted(keyValue));
270    assertEquals(MatchCode.SEEK_NEXT_COL,
271        tracker.checkVersions(keyValue, keyValue.getTimestamp(), keyValue.getTypeByte(), false));
272    keyValue.setTimestamp(19998);
273    keyValue.setSequenceId(997);
274    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
275    assertEquals(MatchCode.SEEK_NEXT_COL,
276        tracker.checkVersions(keyValue, keyValue.getTimestamp(), keyValue.getTypeByte(), false));
277    keyValue.setTimestamp(19997);
278    keyValue.setSequenceId(996);
279    assertEquals(DeleteResult.VERSION_MASKED, tracker.isDeleted(keyValue));
280    assertEquals(MatchCode.SEEK_NEXT_COL,
281        tracker.checkVersions(keyValue, keyValue.getTimestamp(), keyValue.getTypeByte(), false));
282
283    keyValue = new KeyValue(row, family, col2, 20000, KeyValue.Type.Put, value);
284    keyValue.setTimestamp(20000);
285    keyValue.setSequenceId(1000);
286    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
287    assertEquals(MatchCode.INCLUDE_AND_SEEK_NEXT_COL,
288        tracker.checkVersions(keyValue, keyValue.getTimestamp(), keyValue.getTypeByte(), false));
289    keyValue.setTimestamp(19999);
290    keyValue.setSequenceId(1002);
291    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
292    assertEquals(MatchCode.SEEK_NEXT_COL,
293        tracker.checkVersions(keyValue, keyValue.getTimestamp(), keyValue.getTypeByte(), false));
294    keyValue.setTimestamp(19999);
295    keyValue.setSequenceId(1001);
296    assertEquals(DeleteResult.VERSION_MASKED, tracker.isDeleted(keyValue));
297    assertEquals(MatchCode.SEEK_NEXT_COL,
298        tracker.checkVersions(keyValue, keyValue.getTimestamp(), keyValue.getTypeByte(), false));
299    keyValue.setTimestamp(19998);
300    keyValue.setSequenceId(1003);
301    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
302    assertEquals(MatchCode.SEEK_NEXT_COL,
303        tracker.checkVersions(keyValue, keyValue.getTimestamp(), keyValue.getTypeByte(), false));
304    keyValue.setTimestamp(19997);
305    keyValue.setSequenceId(1004);
306    assertEquals(DeleteResult.VERSION_MASKED, tracker.isDeleted(keyValue));
307    assertEquals(MatchCode.SEEK_NEXT_COL,
308        tracker.checkVersions(keyValue, keyValue.getTimestamp(), keyValue.getTypeByte(), false));
309  }
310}