1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.regionserver.querymatcher;
20
21 import java.util.SortedSet;
22 import java.util.TreeSet;
23
24 import org.apache.hadoop.hbase.classification.InterfaceAudience;
25 import org.apache.hadoop.hbase.regionserver.DeleteTracker;
26 import org.apache.hadoop.hbase.Cell;
27 import org.apache.hadoop.hbase.KeyValue;
28 import org.apache.hadoop.hbase.util.Bytes;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44 @InterfaceAudience.Private
45 public class ScanDeleteTracker implements DeleteTracker {
46
47 protected boolean hasFamilyStamp = false;
48 protected long familyStamp = 0L;
49 protected SortedSet<Long> familyVersionStamps = new TreeSet<Long>();
50 protected byte[] deleteBuffer = null;
51 protected int deleteOffset = 0;
52 protected int deleteLength = 0;
53 protected byte deleteType = 0;
54 protected long deleteTimestamp = 0L;
55
56
57
58
59
60
61
62 @Override
63 public void add(Cell cell) {
64 long timestamp = cell.getTimestamp();
65 int qualifierOffset = cell.getQualifierOffset();
66 int qualifierLength = cell.getQualifierLength();
67 byte type = cell.getTypeByte();
68 if (!hasFamilyStamp || timestamp > familyStamp) {
69 if (type == KeyValue.Type.DeleteFamily.getCode()) {
70 hasFamilyStamp = true;
71 familyStamp = timestamp;
72 return;
73 } else if (type == KeyValue.Type.DeleteFamilyVersion.getCode()) {
74 familyVersionStamps.add(timestamp);
75 return;
76 }
77
78 if (deleteBuffer != null && type < deleteType) {
79
80 if (Bytes.equals(deleteBuffer, deleteOffset, deleteLength, cell.getQualifierArray(),
81 qualifierOffset, qualifierLength)) {
82 return;
83 }
84 }
85
86 deleteBuffer = cell.getQualifierArray();
87 deleteOffset = qualifierOffset;
88 deleteLength = qualifierLength;
89 deleteType = type;
90 deleteTimestamp = timestamp;
91 }
92
93 }
94
95
96
97
98
99
100 @Override
101 public DeleteResult isDeleted(Cell cell) {
102 long timestamp = cell.getTimestamp();
103 int qualifierOffset = cell.getQualifierOffset();
104 int qualifierLength = cell.getQualifierLength();
105 if (hasFamilyStamp && timestamp <= familyStamp) {
106 return DeleteResult.FAMILY_DELETED;
107 }
108
109 if (familyVersionStamps.contains(Long.valueOf(timestamp))) {
110 return DeleteResult.FAMILY_VERSION_DELETED;
111 }
112
113 if (deleteBuffer != null) {
114 int ret = Bytes.compareTo(deleteBuffer, deleteOffset, deleteLength, cell.getQualifierArray(),
115 qualifierOffset, qualifierLength);
116
117 if (ret == 0) {
118 if (deleteType == KeyValue.Type.DeleteColumn.getCode()) {
119 return DeleteResult.COLUMN_DELETED;
120 }
121
122
123 if (timestamp == deleteTimestamp) {
124 return DeleteResult.VERSION_DELETED;
125 }
126
127 assert timestamp < deleteTimestamp;
128
129
130 deleteBuffer = null;
131 } else if (ret < 0) {
132
133 deleteBuffer = null;
134 } else {
135 throw new IllegalStateException("isDelete failed: deleteBuffer="
136 + Bytes.toStringBinary(deleteBuffer, deleteOffset, deleteLength) + ", qualifier="
137 + Bytes.toStringBinary(cell.getQualifierArray(), qualifierOffset, qualifierLength)
138 + ", timestamp=" + timestamp + ", comparison result: " + ret);
139 }
140 }
141
142 return DeleteResult.NOT_DELETED;
143 }
144
145 @Override
146 public boolean isEmpty() {
147 return deleteBuffer == null && !hasFamilyStamp && familyVersionStamps.isEmpty();
148 }
149
150 @Override
151
152 public void reset() {
153 hasFamilyStamp = false;
154 familyStamp = 0L;
155 familyVersionStamps.clear();
156 deleteBuffer = null;
157 }
158
159 @Override
160
161 public void update() {
162 this.reset();
163 }
164 }