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 static org.junit.Assert.assertEquals;
021
022import java.io.IOException;
023import java.util.TreeSet;
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@Category({ RegionServerTests.class, SmallTests.class })
038public class TestNewVersionBehaviorTracker {
039
040  @ClassRule
041  public static final HBaseClassTestRule CLASS_RULE =
042    HBaseClassTestRule.forClass(TestNewVersionBehaviorTracker.class);
043
044  private final byte[] col0 = Bytes.toBytes("col0");
045  private final byte[] col1 = Bytes.toBytes("col1");
046  private final byte[] col2 = Bytes.toBytes("col2");
047  private final byte[] col3 = Bytes.toBytes("col3");
048  private final byte[] col4 = Bytes.toBytes("col4");
049  private final byte[] row = Bytes.toBytes("row");
050  private final byte[] family = Bytes.toBytes("family");
051  private final byte[] value = Bytes.toBytes("value");
052  private final CellComparator comparator = CellComparatorImpl.COMPARATOR;
053
054  @Test
055  public void testColumns() throws IOException {
056    TreeSet<byte[]> trackedColumns = new TreeSet<byte[]>(Bytes.BYTES_COMPARATOR);
057    trackedColumns.add(col1);
058    trackedColumns.add(col3);
059
060    NewVersionBehaviorTracker tracker =
061      new NewVersionBehaviorTracker(trackedColumns, comparator, 1, 3, 3, 10000);
062
063    KeyValue keyValue = new KeyValue(row, family, col0, 20000, KeyValue.Type.Put, value);
064    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
065    assertEquals(MatchCode.SEEK_NEXT_COL, tracker.checkColumn(keyValue, keyValue.getTypeByte()));
066
067    keyValue = new KeyValue(row, family, col1, 20000, KeyValue.Type.Put, value);
068    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
069    assertEquals(MatchCode.INCLUDE, tracker.checkColumn(keyValue, keyValue.getTypeByte()));
070
071    keyValue = new KeyValue(row, family, col2, 20000, KeyValue.Type.Put, value);
072    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
073    assertEquals(MatchCode.SEEK_NEXT_COL, tracker.checkColumn(keyValue, keyValue.getTypeByte()));
074
075    keyValue = new KeyValue(row, family, col3, 20000, KeyValue.Type.Put, value);
076    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
077    assertEquals(MatchCode.INCLUDE, tracker.checkColumn(keyValue, keyValue.getTypeByte()));
078
079    keyValue = new KeyValue(row, family, col4, 20000, KeyValue.Type.Put, value);
080    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
081    assertEquals(MatchCode.SEEK_NEXT_ROW, tracker.checkColumn(keyValue, keyValue.getTypeByte()));
082  }
083
084  @Test
085  public void testMaxVersionMask() {
086    NewVersionBehaviorTracker tracker =
087      new NewVersionBehaviorTracker(null, comparator, 1, 3, 3, 10000);
088
089    KeyValue keyValue = new KeyValue(row, family, col1, 20000, KeyValue.Type.Put, value);
090    keyValue.setTimestamp(20000);
091    keyValue.setSequenceId(1000);
092    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
093    keyValue.setTimestamp(19999);
094    keyValue.setSequenceId(999);
095    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
096    keyValue.setTimestamp(19999);
097    keyValue.setSequenceId(998);
098    assertEquals(DeleteResult.VERSION_MASKED, tracker.isDeleted(keyValue));
099    keyValue.setTimestamp(19998);
100    keyValue.setSequenceId(997);
101    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
102    keyValue.setTimestamp(19997);
103    keyValue.setSequenceId(996);
104    assertEquals(DeleteResult.VERSION_MASKED, tracker.isDeleted(keyValue));
105
106    keyValue = new KeyValue(row, family, col2, 20000, KeyValue.Type.Put, value);
107    keyValue.setTimestamp(20000);
108    keyValue.setSequenceId(1000);
109    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
110    keyValue.setTimestamp(19999);
111    keyValue.setSequenceId(1002);
112    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
113    keyValue.setTimestamp(19999);
114    keyValue.setSequenceId(1001);
115    assertEquals(DeleteResult.VERSION_MASKED, tracker.isDeleted(keyValue));
116    keyValue.setTimestamp(19998);
117    keyValue.setSequenceId(1003);
118    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
119    keyValue.setTimestamp(19997);
120    keyValue.setSequenceId(1004);
121    assertEquals(DeleteResult.VERSION_MASKED, tracker.isDeleted(keyValue));
122  }
123
124  @Test
125  public void testVersionsDelete() {
126    NewVersionBehaviorTracker tracker =
127      new NewVersionBehaviorTracker(null, comparator, 1, 3, 3, 10000);
128    KeyValue put = new KeyValue(row, family, col1, 20000, KeyValue.Type.Put, value);
129    KeyValue delete = new KeyValue(row, family, col1, 20000, KeyValue.Type.DeleteColumn, value);
130    delete.setSequenceId(1000);
131    delete.setTimestamp(20000);
132    tracker.add(delete);
133    put.setSequenceId(1001);
134    put.setTimestamp(19999);
135    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(put));
136    put.setSequenceId(999);
137    put.setTimestamp(19998);
138    assertEquals(DeleteResult.COLUMN_DELETED, tracker.isDeleted(put));
139
140    delete = new KeyValue(row, family, col2, 20000, KeyValue.Type.DeleteColumn, value);
141    delete.setSequenceId(1002);
142    delete.setTimestamp(20000);
143    tracker.add(delete);
144    put = new KeyValue(row, family, col2, 20000, KeyValue.Type.Put, value);
145    put.setSequenceId(1001);
146    put.setTimestamp(19999);
147    assertEquals(DeleteResult.COLUMN_DELETED, tracker.isDeleted(put));
148    put.setSequenceId(999);
149    put.setTimestamp(19998);
150    assertEquals(DeleteResult.COLUMN_DELETED, tracker.isDeleted(put));
151  }
152
153  @Test
154  public void testVersionDelete() {
155    NewVersionBehaviorTracker tracker =
156      new NewVersionBehaviorTracker(null, comparator, 1, 3, 3, 10000);
157    KeyValue put = new KeyValue(row, family, col1, 20000, KeyValue.Type.Put, value);
158    KeyValue delete = new KeyValue(row, family, col1, 20000, KeyValue.Type.Delete, value);
159    delete.setSequenceId(1000);
160    delete.setTimestamp(20000);
161    tracker.add(delete);
162    put.setSequenceId(1001);
163    put.setTimestamp(20000);
164    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(put));
165    put.setSequenceId(999);
166    put.setTimestamp(20000);
167    assertEquals(DeleteResult.VERSION_DELETED, tracker.isDeleted(put));
168
169    delete = new KeyValue(row, family, col2, 20000, KeyValue.Type.Delete, value);
170    delete.setSequenceId(1002);
171    delete.setTimestamp(20000);
172    tracker.add(delete);
173    put = new KeyValue(row, family, col2, 20000, KeyValue.Type.Put, value);
174    put.setSequenceId(1001);
175    put.setTimestamp(20000);
176    assertEquals(DeleteResult.VERSION_DELETED, tracker.isDeleted(put));
177    put.setSequenceId(999);
178    put.setTimestamp(20000);
179    assertEquals(DeleteResult.VERSION_DELETED, tracker.isDeleted(put));
180    put.setSequenceId(1002);
181    put.setTimestamp(19999);
182    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(put));
183    put.setSequenceId(998);
184    put.setTimestamp(19999);
185    assertEquals(DeleteResult.VERSION_MASKED, tracker.isDeleted(put));
186  }
187
188  @Test
189  public void testFamilyVersionsDelete() {
190    NewVersionBehaviorTracker tracker =
191      new NewVersionBehaviorTracker(null, comparator, 1, 3, 3, 10000);
192
193    KeyValue delete = new KeyValue(row, family, null, 20000, KeyValue.Type.DeleteFamily, value);
194    delete.setSequenceId(1000);
195    delete.setTimestamp(20000);
196
197    KeyValue put = new KeyValue(row, family, col1, 20000, KeyValue.Type.Put, value);
198    tracker.add(delete);
199    put.setSequenceId(1001);
200    put.setTimestamp(20000);
201    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(put));
202    put.setSequenceId(999);
203    put.setTimestamp(19998);
204    assertEquals(DeleteResult.COLUMN_DELETED, tracker.isDeleted(put));
205
206    put = new KeyValue(row, family, col2, 20000, KeyValue.Type.Put, value);
207    put.setSequenceId(998);
208    put.setTimestamp(19999);
209    assertEquals(DeleteResult.COLUMN_DELETED, tracker.isDeleted(put));
210    put.setSequenceId(999);
211    put.setTimestamp(19998);
212    assertEquals(DeleteResult.COLUMN_DELETED, tracker.isDeleted(put));
213  }
214
215  @Test
216  public void testFamilyVersionDelete() {
217    NewVersionBehaviorTracker tracker =
218      new NewVersionBehaviorTracker(null, comparator, 1, 3, 3, 10000);
219
220    KeyValue delete =
221      new KeyValue(row, family, null, 20000, KeyValue.Type.DeleteFamilyVersion, value);
222    delete.setSequenceId(1000);
223    delete.setTimestamp(20000);
224    tracker.add(delete);
225
226    KeyValue put = new KeyValue(row, family, col1, 20000, KeyValue.Type.Put, value);
227    put.setSequenceId(1001);
228    put.setTimestamp(20000);
229    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(put));
230    put.setSequenceId(999);
231    put.setTimestamp(20000);
232    assertEquals(DeleteResult.VERSION_DELETED, tracker.isDeleted(put));
233
234    put = new KeyValue(row, family, col2, 20000, KeyValue.Type.Put, value);
235    put.setSequenceId(1001);
236    put.setTimestamp(20000);
237    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(put));
238    put.setSequenceId(999);
239    put.setTimestamp(20000);
240    assertEquals(DeleteResult.VERSION_DELETED, tracker.isDeleted(put));
241    put.setSequenceId(1002);
242    put.setTimestamp(19999);
243    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(put));
244    put.setSequenceId(998);
245    put.setTimestamp(19999);
246    assertEquals(DeleteResult.VERSION_MASKED, tracker.isDeleted(put));
247  }
248
249  @Test
250  public void testMinVersionsAndTTL() throws IOException {
251    NewVersionBehaviorTracker tracker =
252      new NewVersionBehaviorTracker(null, comparator, 1, 3, 3, 30000);
253
254    KeyValue keyValue = new KeyValue(row, family, col1, 20000, KeyValue.Type.Put, value);
255    keyValue.setTimestamp(20000);
256    keyValue.setSequenceId(1000);
257    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
258    assertEquals(MatchCode.INCLUDE_AND_SEEK_NEXT_COL,
259      tracker.checkVersions(keyValue, keyValue.getTimestamp(), keyValue.getTypeByte(), false));
260    keyValue.setTimestamp(19999);
261    keyValue.setSequenceId(999);
262    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
263    assertEquals(MatchCode.SEEK_NEXT_COL,
264      tracker.checkVersions(keyValue, keyValue.getTimestamp(), keyValue.getTypeByte(), false));
265    keyValue.setTimestamp(19999);
266    keyValue.setSequenceId(998);
267    assertEquals(DeleteResult.VERSION_MASKED, tracker.isDeleted(keyValue));
268    assertEquals(MatchCode.SEEK_NEXT_COL,
269      tracker.checkVersions(keyValue, keyValue.getTimestamp(), keyValue.getTypeByte(), false));
270    keyValue.setTimestamp(19998);
271    keyValue.setSequenceId(997);
272    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
273    assertEquals(MatchCode.SEEK_NEXT_COL,
274      tracker.checkVersions(keyValue, keyValue.getTimestamp(), keyValue.getTypeByte(), false));
275    keyValue.setTimestamp(19997);
276    keyValue.setSequenceId(996);
277    assertEquals(DeleteResult.VERSION_MASKED, tracker.isDeleted(keyValue));
278    assertEquals(MatchCode.SEEK_NEXT_COL,
279      tracker.checkVersions(keyValue, keyValue.getTimestamp(), keyValue.getTypeByte(), false));
280
281    keyValue = new KeyValue(row, family, col2, 20000, KeyValue.Type.Put, value);
282    keyValue.setTimestamp(20000);
283    keyValue.setSequenceId(1000);
284    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
285    assertEquals(MatchCode.INCLUDE_AND_SEEK_NEXT_COL,
286      tracker.checkVersions(keyValue, keyValue.getTimestamp(), keyValue.getTypeByte(), false));
287    keyValue.setTimestamp(19999);
288    keyValue.setSequenceId(1002);
289    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
290    assertEquals(MatchCode.SEEK_NEXT_COL,
291      tracker.checkVersions(keyValue, keyValue.getTimestamp(), keyValue.getTypeByte(), false));
292    keyValue.setTimestamp(19999);
293    keyValue.setSequenceId(1001);
294    assertEquals(DeleteResult.VERSION_MASKED, tracker.isDeleted(keyValue));
295    assertEquals(MatchCode.SEEK_NEXT_COL,
296      tracker.checkVersions(keyValue, keyValue.getTimestamp(), keyValue.getTypeByte(), false));
297    keyValue.setTimestamp(19998);
298    keyValue.setSequenceId(1003);
299    assertEquals(DeleteResult.NOT_DELETED, tracker.isDeleted(keyValue));
300    assertEquals(MatchCode.SEEK_NEXT_COL,
301      tracker.checkVersions(keyValue, keyValue.getTimestamp(), keyValue.getTypeByte(), false));
302    keyValue.setTimestamp(19997);
303    keyValue.setSequenceId(1004);
304    assertEquals(DeleteResult.VERSION_MASKED, tracker.isDeleted(keyValue));
305    assertEquals(MatchCode.SEEK_NEXT_COL,
306      tracker.checkVersions(keyValue, keyValue.getTimestamp(), keyValue.getTypeByte(), false));
307  }
308}