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