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 org.apache.hadoop.hbase.CellComparatorImpl; 023import org.apache.hadoop.hbase.KeyValue; 024import org.apache.hadoop.hbase.regionserver.querymatcher.DeleteTracker.DeleteResult; 025import org.apache.hadoop.hbase.testclassification.RegionServerTests; 026import org.apache.hadoop.hbase.testclassification.SmallTests; 027import org.apache.hadoop.hbase.util.Bytes; 028import org.junit.jupiter.api.BeforeEach; 029import org.junit.jupiter.api.Tag; 030import org.junit.jupiter.api.Test; 031 032@Tag(RegionServerTests.TAG) 033@Tag(SmallTests.TAG) 034public class TestScanDeleteTracker { 035 036 private ScanDeleteTracker sdt; 037 038 private long timestamp = 10L; 039 040 @BeforeEach 041 public void setUp() throws Exception { 042 sdt = new ScanDeleteTracker(CellComparatorImpl.COMPARATOR); 043 } 044 045 @Test 046 public void testDeletedByDelete() { 047 KeyValue kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"), Bytes.toBytes("qualifier"), 048 timestamp, KeyValue.Type.Delete); 049 sdt.add(kv); 050 DeleteResult ret = sdt.isDeleted(kv); 051 assertEquals(DeleteResult.VERSION_DELETED, ret); 052 } 053 054 @Test 055 public void testDeletedByDeleteColumn() { 056 KeyValue kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"), Bytes.toBytes("qualifier"), 057 timestamp, KeyValue.Type.DeleteColumn); 058 sdt.add(kv); 059 timestamp -= 5; 060 kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"), Bytes.toBytes("qualifier"), 061 timestamp, KeyValue.Type.DeleteColumn); 062 DeleteResult ret = sdt.isDeleted(kv); 063 assertEquals(DeleteResult.COLUMN_DELETED, ret); 064 } 065 066 @Test 067 public void testDeletedByDeleteFamily() { 068 KeyValue kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"), Bytes.toBytes("qualifier"), 069 timestamp, KeyValue.Type.DeleteFamily); 070 sdt.add(kv); 071 timestamp -= 5; 072 kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"), Bytes.toBytes("qualifier"), 073 timestamp, KeyValue.Type.DeleteColumn); 074 DeleteResult ret = sdt.isDeleted(kv); 075 assertEquals(DeleteResult.FAMILY_DELETED, ret); 076 } 077 078 @Test 079 public void testDeletedByDeleteFamilyVersion() { 080 byte[] qualifier1 = Bytes.toBytes("qualifier1"); 081 byte[] qualifier2 = Bytes.toBytes("qualifier2"); 082 byte[] qualifier3 = Bytes.toBytes("qualifier3"); 083 byte[] qualifier4 = Bytes.toBytes("qualifier4"); 084 KeyValue kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"), null, timestamp, 085 KeyValue.Type.DeleteFamilyVersion); 086 sdt.add(kv); 087 kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"), qualifier1, timestamp, 088 KeyValue.Type.DeleteFamilyVersion); 089 DeleteResult ret = sdt.isDeleted(kv); 090 assertEquals(DeleteResult.FAMILY_VERSION_DELETED, ret); 091 kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"), qualifier2, timestamp, 092 KeyValue.Type.DeleteFamilyVersion); 093 ret = sdt.isDeleted(kv); 094 assertEquals(DeleteResult.FAMILY_VERSION_DELETED, ret); 095 kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"), qualifier3, timestamp, 096 KeyValue.Type.DeleteFamilyVersion); 097 ret = sdt.isDeleted(kv); 098 assertEquals(DeleteResult.FAMILY_VERSION_DELETED, ret); 099 kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"), qualifier4, timestamp, 100 KeyValue.Type.DeleteFamilyVersion); 101 ret = sdt.isDeleted(kv); 102 assertEquals(DeleteResult.FAMILY_VERSION_DELETED, ret); 103 kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"), qualifier1, timestamp + 3, 104 KeyValue.Type.DeleteFamilyVersion); 105 ret = sdt.isDeleted(kv); 106 assertEquals(DeleteResult.NOT_DELETED, ret); 107 kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"), qualifier2, timestamp - 2, 108 KeyValue.Type.DeleteFamilyVersion); 109 ret = sdt.isDeleted(kv); 110 assertEquals(DeleteResult.NOT_DELETED, ret); 111 kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"), qualifier3, timestamp - 5, 112 KeyValue.Type.DeleteFamilyVersion); 113 ret = sdt.isDeleted(kv); 114 assertEquals(DeleteResult.NOT_DELETED, ret); 115 kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"), qualifier4, timestamp + 8, 116 KeyValue.Type.DeleteFamilyVersion); 117 ret = sdt.isDeleted(kv); 118 assertEquals(DeleteResult.NOT_DELETED, ret); 119 } 120 121 @Test 122 public void testDeleteDeleteColumn() { 123 byte[] qualifier = Bytes.toBytes("qualifier"); 124 KeyValue kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"), qualifier, timestamp, 125 KeyValue.Type.Delete); 126 sdt.add(kv); 127 128 timestamp -= 5; 129 kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"), qualifier, timestamp, 130 KeyValue.Type.DeleteColumn); 131 sdt.add(kv); 132 133 timestamp -= 5; 134 kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"), qualifier, timestamp, 135 KeyValue.Type.DeleteColumn); 136 DeleteResult ret = sdt.isDeleted(kv); 137 assertEquals(DeleteResult.COLUMN_DELETED, ret); 138 } 139 140 @Test 141 public void testDeleteColumnDelete() { 142 byte[] qualifier = Bytes.toBytes("qualifier"); 143 KeyValue kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"), qualifier, timestamp, 144 KeyValue.Type.DeleteColumn); 145 sdt.add(kv); 146 147 qualifier = Bytes.toBytes("qualifier1"); 148 kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"), qualifier, timestamp, 149 KeyValue.Type.Delete); 150 sdt.add(kv); 151 152 DeleteResult ret = sdt.isDeleted(kv); 153 assertEquals(DeleteResult.VERSION_DELETED, ret); 154 } 155 156 // Testing new way where we save the Delete in case of a Delete for specific 157 // ts, could have just added the last line to the first test, but rather keep 158 // them separated 159 @Test 160 public void testDeleteKeepDelete() { 161 byte[] qualifier = Bytes.toBytes("qualifier"); 162 KeyValue kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"), qualifier, timestamp, 163 KeyValue.Type.Delete); 164 sdt.add(kv); 165 sdt.isDeleted(kv); 166 assertEquals(false, sdt.isEmpty()); 167 } 168 169 @Test 170 public void testDeleteKeepVersionZero() { 171 byte[] qualifier = Bytes.toBytes("qualifier"); 172 173 long deleteTimestamp = 10; 174 long valueTimestamp = 0; 175 176 sdt.reset(); 177 KeyValue kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"), qualifier, deleteTimestamp, 178 KeyValue.Type.Delete); 179 sdt.add(kv); 180 kv = new KeyValue(Bytes.toBytes("row"), Bytes.toBytes("f"), qualifier, valueTimestamp, 181 KeyValue.Type.Delete); 182 DeleteResult ret = sdt.isDeleted(kv); 183 assertEquals(DeleteResult.NOT_DELETED, ret); 184 } 185}