1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.filter;
19
20 import com.google.common.base.Preconditions;
21 import com.google.protobuf.InvalidProtocolBufferException;
22 import org.apache.hadoop.hbase.classification.InterfaceAudience;
23 import org.apache.hadoop.hbase.classification.InterfaceStability;
24 import org.apache.hadoop.hbase.Cell;
25 import org.apache.hadoop.hbase.exceptions.DeserializationException;
26 import org.apache.hadoop.hbase.protobuf.generated.FilterProtos;
27
28 import java.util.ArrayList;
29 import java.util.List;
30 import java.util.TreeSet;
31
32
33
34
35
36
37
38
39
40
41 @InterfaceAudience.Public
42 @InterfaceStability.Stable
43 public class TimestampsFilter extends FilterBase {
44
45 TreeSet<Long> timestamps;
46 private static final int MAX_LOG_TIMESTAMPS = 5;
47
48
49
50 long minTimeStamp = Long.MAX_VALUE;
51
52
53
54
55
56
57
58
59 public TimestampsFilter(List<Long> timestamps) {
60 for (Long timestamp : timestamps) {
61 Preconditions.checkArgument(timestamp >= 0, "must be positive %s", timestamp);
62 }
63 this.timestamps = new TreeSet<Long>(timestamps);
64 init();
65 }
66
67
68
69
70 public List<Long> getTimestamps() {
71 List<Long> list = new ArrayList<Long>(timestamps.size());
72 list.addAll(timestamps);
73 return list;
74 }
75
76 private void init() {
77 if (this.timestamps.size() > 0) {
78 minTimeStamp = this.timestamps.first();
79 }
80 }
81
82
83
84
85
86 public long getMin() {
87 return minTimeStamp;
88 }
89
90 @Override
91 public ReturnCode filterKeyValue(Cell v) {
92 if (this.timestamps.contains(v.getTimestamp())) {
93 return ReturnCode.INCLUDE;
94 } else if (v.getTimestamp() < minTimeStamp) {
95
96
97 return ReturnCode.NEXT_COL;
98 }
99 return ReturnCode.SKIP;
100 }
101
102
103
104 @Override
105 public Cell transformCell(Cell v) {
106 return v;
107 }
108
109 public static Filter createFilterFromArguments(ArrayList<byte []> filterArguments) {
110 ArrayList<Long> timestamps = new ArrayList<Long>();
111 for (int i = 0; i<filterArguments.size(); i++) {
112 long timestamp = ParseFilter.convertByteArrayToLong(filterArguments.get(i));
113 timestamps.add(timestamp);
114 }
115 return new TimestampsFilter(timestamps);
116 }
117
118
119
120
121 public byte [] toByteArray() {
122 FilterProtos.TimestampsFilter.Builder builder =
123 FilterProtos.TimestampsFilter.newBuilder();
124 builder.addAllTimestamps(this.timestamps);
125 return builder.build().toByteArray();
126 }
127
128
129
130
131
132
133
134 public static TimestampsFilter parseFrom(final byte [] pbBytes)
135 throws DeserializationException {
136 FilterProtos.TimestampsFilter proto;
137 try {
138 proto = FilterProtos.TimestampsFilter.parseFrom(pbBytes);
139 } catch (InvalidProtocolBufferException e) {
140 throw new DeserializationException(e);
141 }
142 return new TimestampsFilter(proto.getTimestampsList());
143 }
144
145
146
147
148
149
150 boolean areSerializedFieldsEqual(Filter o) {
151 if (o == this) return true;
152 if (!(o instanceof TimestampsFilter)) return false;
153
154 TimestampsFilter other = (TimestampsFilter)o;
155 return this.getTimestamps().equals(other.getTimestamps());
156 }
157
158 @Override
159 public String toString() {
160 return toString(MAX_LOG_TIMESTAMPS);
161 }
162
163 protected String toString(int maxTimestamps) {
164 StringBuilder tsList = new StringBuilder();
165
166 int count = 0;
167 for (Long ts : this.timestamps) {
168 if (count >= maxTimestamps) {
169 break;
170 }
171 ++count;
172 tsList.append(ts.toString());
173 if (count < this.timestamps.size() && count < maxTimestamps) {
174 tsList.append(", ");
175 }
176 }
177
178 return String.format("%s (%d/%d): [%s]", this.getClass().getSimpleName(),
179 count, this.timestamps.size(), tsList.toString());
180 }
181 }