Skip to content

Commit 1526d45

Browse files
igorbernstein2pongad
authored andcommitted
---
yaml --- r: 9101 b: refs/heads/master c: c1608a8 h: refs/heads/master i: 9099: 86dc2a6
1 parent e6813c6 commit 1526d45

7 files changed

Lines changed: 265 additions & 6 deletions

File tree

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: 8366a39a940f4941926cd232662cf2eb36945b1f
2+
refs/heads/master: c1608a8a37eca8192659963501b2e0db36eb2b35
33
refs/heads/travis: 47e4fee4fd5af9b2a8ce46f23c72ec95f9b195b2
44
refs/heads/gh-pages: 8e9b065ba06cd7a4af306aaea1010aade81670e0
55
refs/tags/0.0.9: 22f1839238f66c39e67ed4dfdcd273b1ae2e8444

trunk/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/Filters.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -351,6 +351,15 @@ public Filter regex(@Nonnull ByteString regex) {
351351
return new SimpleFilter(RowFilter.newBuilder().setRowKeyRegexFilter(regex).build());
352352
}
353353

354+
/**
355+
* Matches only cells from rows whose keys equal the value. In other words, passes through the
356+
* entire row when the key matches, and otherwise produces an empty row.
357+
*/
358+
public Filter exactMatch(@Nonnull String value) {
359+
Preconditions.checkNotNull(value);
360+
return exactMatch(ByteString.copyFromUtf8(value));
361+
}
362+
354363
/**
355364
* Matches only cells from rows whose keys equal the value. In other words, passes through the
356365
* entire row when the key matches, and otherwise produces an empty row.
@@ -423,6 +432,12 @@ public Filter regex(@Nonnull ByteString regex) {
423432
return new SimpleFilter(RowFilter.newBuilder().setColumnQualifierRegexFilter(regex).build());
424433
}
425434

435+
/** Matches only cells from columns whose qualifiers equal the value. */
436+
public Filter exactMatch(@Nonnull String value) {
437+
Preconditions.checkNotNull(value);
438+
return exactMatch(ByteString.copyFromUtf8(value));
439+
}
440+
426441
/** Matches only cells from columns whose qualifiers equal the value. */
427442
public Filter exactMatch(@Nonnull ByteString value) {
428443
Preconditions.checkNotNull(value);
@@ -561,6 +576,12 @@ public Filter regex(@Nonnull String regex) {
561576
return regex(ByteString.copyFromUtf8(regex));
562577
}
563578

579+
/** Matches only cells with values that match the given value. */
580+
public Filter exactMatch(@Nonnull String value) {
581+
Preconditions.checkNotNull(value);
582+
return exactMatch(ByteString.copyFromUtf8(value));
583+
}
584+
564585
/** Matches only cells with values that match the given value. */
565586
public Filter exactMatch(@Nonnull ByteString value) {
566587
Preconditions.checkNotNull(value);

trunk/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/Query.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,14 @@ public Query rowKey(ByteString key) {
5656
return this;
5757
}
5858

59+
public Query prefix(ByteString prefix) {
60+
return range(ByteStringRange.prefix(prefix));
61+
}
62+
63+
public Query prefix(String prefix) {
64+
return range(ByteStringRange.prefix(prefix));
65+
}
66+
5967
/**
6068
* Adds a range to be looked up.
6169
*

trunk/google-cloud-bigtable/src/main/java/com/google/cloud/bigtable/data/v2/models/Range.java

Lines changed: 146 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616
package com.google.cloud.bigtable.data.v2.models;
1717

1818
import com.google.api.core.InternalExtensionOnly;
19+
import com.google.common.base.Objects;
1920
import com.google.common.base.Preconditions;
2021
import com.google.protobuf.ByteString;
22+
import com.google.protobuf.UnsafeByteOperations;
2123
import javax.annotation.Nonnull;
2224

2325
/**
@@ -197,25 +199,65 @@ public R of(String startClosed, String endOpen) {
197199
}
198200

199201
/** Creates a new {@link Range} with the specified exclusive start and the current end. */
200-
public R startOpen(String start) {
202+
public R startOpen(@Nonnull String start) {
201203
return startOpen(wrap(start));
202204
}
203205

204206
/** Creates a new {@link Range} with the specified inclusive start and the current end. */
205-
public R startClosed(String start) {
207+
public R startClosed(@Nonnull String start) {
206208
return startClosed(wrap(start));
207209
}
208210

209211
/** Creates a new {@link Range} with the specified exclusive end and the current start. */
210-
public R endOpen(String end) {
212+
public R endOpen(@Nonnull String end) {
211213
return endOpen(wrap(end));
212214
}
213215

214216
/** Creates a new {@link Range} with the specified inclusive end and the current start. */
215-
public R endClosed(String end) {
217+
public R endClosed(@Nonnull String end) {
216218
return endClosed(wrap(end));
217219
}
218220

221+
@Override
222+
public R startOpen(@Nonnull ByteString start) {
223+
Preconditions.checkNotNull(start);
224+
if (start.isEmpty()) {
225+
return startUnbounded();
226+
} else {
227+
return super.startOpen(start);
228+
}
229+
}
230+
231+
@Override
232+
public R startClosed(@Nonnull ByteString start) {
233+
Preconditions.checkNotNull(start);
234+
if (start.isEmpty()) {
235+
return startUnbounded();
236+
} else {
237+
return super.startClosed(start);
238+
}
239+
}
240+
241+
@Override
242+
public R endOpen(@Nonnull ByteString end) {
243+
Preconditions.checkNotNull(end);
244+
if (end.isEmpty()) {
245+
return endUnbounded();
246+
} else {
247+
return super.endOpen(end);
248+
}
249+
}
250+
251+
@Override
252+
public R endClosed(@Nonnull ByteString end) {
253+
Preconditions.checkNotNull(end);
254+
if (end.isEmpty()) {
255+
return endUnbounded();
256+
} else {
257+
return super.endClosed(end);
258+
}
259+
}
260+
219261
@SuppressWarnings("unchecked")
220262
@Override
221263
protected R clone() {
@@ -244,10 +286,79 @@ public static TimestampRange create(long closedStart, long openEnd) {
244286
private TimestampRange(BoundType startBound, Long start, BoundType endBound, Long end) {
245287
super(startBound, start, endBound, end);
246288
}
289+
290+
@Override
291+
public boolean equals(Object o) {
292+
if (this == o) {
293+
return true;
294+
}
295+
if (o == null || getClass() != o.getClass()) {
296+
return false;
297+
}
298+
TimestampRange range = (TimestampRange) o;
299+
300+
if (getStartBound() != range.getStartBound() || getEndBound() != range.getEndBound()) {
301+
return false;
302+
}
303+
if (getStartBound() != BoundType.UNBOUNDED && !Objects.equal(getStart(), range.getStart())) {
304+
return false;
305+
}
306+
if (getEndBound() != BoundType.UNBOUNDED && !Objects.equal(getEnd(), range.getEnd())) {
307+
return false;
308+
}
309+
return true;
310+
}
311+
312+
@Override
313+
public int hashCode() {
314+
return Objects.hashCode(
315+
getStartBound(),
316+
getStartBound() == BoundType.UNBOUNDED ? null : getStart(),
317+
getEndBound(),
318+
getEndBound() == BoundType.UNBOUNDED ? null : getEnd());
319+
}
247320
}
248321

249322
/** Concrete Range for ByteStrings */
250323
public static final class ByteStringRange extends AbstractByteStringRange<ByteStringRange> {
324+
public static ByteStringRange prefix(String prefix) {
325+
return prefix(ByteString.copyFromUtf8(prefix));
326+
}
327+
328+
public static ByteStringRange prefix(ByteString prefix) {
329+
if (prefix.isEmpty()) {
330+
return unbounded();
331+
}
332+
333+
int offset = prefix.size() - 1;
334+
int curByte = 0xFF;
335+
336+
while (offset >= 0) {
337+
curByte = prefix.byteAt(offset) & 0xFF;
338+
if (curByte != 0xFF) {
339+
break;
340+
}
341+
offset--;
342+
}
343+
344+
if (offset < 0) {
345+
// We got an 0xFFFF... (only FFs) stopRow value which is
346+
// the last possible prefix before the end of the table.
347+
// So set it to stop at the 'end of the table'
348+
return unbounded().startClosed(prefix);
349+
}
350+
351+
ByteString endPrefix = offset == 0 ? ByteString.EMPTY : prefix.substring(0, offset);
352+
ByteString endSuffix = UnsafeByteOperations.unsafeWrap(new byte[] {(byte) (curByte + 1)});
353+
ByteString end = endPrefix.concat(endSuffix);
354+
355+
ByteStringRange range = ByteStringRange.unbounded().startClosed(prefix);
356+
if (!end.isEmpty()) {
357+
range.endOpen(end);
358+
}
359+
return range;
360+
}
361+
251362
public static ByteStringRange unbounded() {
252363
return new ByteStringRange(BoundType.UNBOUNDED, null, BoundType.UNBOUNDED, null);
253364
}
@@ -265,5 +376,36 @@ private ByteStringRange(
265376
BoundType startBound, ByteString start, BoundType endBound, ByteString end) {
266377
super(startBound, start, endBound, end);
267378
}
379+
380+
@Override
381+
public boolean equals(Object o) {
382+
if (this == o) {
383+
return true;
384+
}
385+
if (o == null || getClass() != o.getClass()) {
386+
return false;
387+
}
388+
ByteStringRange range = (ByteStringRange) o;
389+
390+
if (getStartBound() != range.getStartBound() || getEndBound() != range.getEndBound()) {
391+
return false;
392+
}
393+
if (getStartBound() != BoundType.UNBOUNDED && !Objects.equal(getStart(), range.getStart())) {
394+
return false;
395+
}
396+
if (getEndBound() != BoundType.UNBOUNDED && !Objects.equal(getEnd(), range.getEnd())) {
397+
return false;
398+
}
399+
return true;
400+
}
401+
402+
@Override
403+
public int hashCode() {
404+
return Objects.hashCode(
405+
getStartBound(),
406+
getStartBound() == BoundType.UNBOUNDED ? null : getStart(),
407+
getEndBound(),
408+
getEndBound() == BoundType.UNBOUNDED ? null : getEnd());
409+
}
268410
}
269411
}

trunk/google-cloud-bigtable/src/test/java/com/google/cloud/bigtable/data/v2/models/FiltersTest.java

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,16 @@ public void keyExactMatchTest() {
182182
assertThat(actualFilter).isEqualTo(expectedFilter);
183183
}
184184

185+
@Test
186+
public void keyExactMatchStringTest() {
187+
RowFilter actualFilter = FILTERS.key().exactMatch(".*").toProto();
188+
189+
RowFilter expectedFilter =
190+
RowFilter.newBuilder().setRowKeyRegexFilter(ByteString.copyFromUtf8("\\.\\*")).build();
191+
192+
assertThat(actualFilter).isEqualTo(expectedFilter);
193+
}
194+
185195
@Test
186196
public void keySampleTest() {
187197
RowFilter actualFilter = FILTERS.key().sample(0.3).toProto();
@@ -246,6 +256,18 @@ public void qualifierExactMatchTest() {
246256
assertThat(actualFilter).isEqualTo(expectedFilter);
247257
}
248258

259+
@Test
260+
public void qualifierExactStringMatchTest() {
261+
RowFilter actualFilter = FILTERS.qualifier().exactMatch("^hi").toProto();
262+
263+
RowFilter expectedFilter =
264+
RowFilter.newBuilder()
265+
.setColumnQualifierRegexFilter(ByteString.copyFromUtf8("\\^hi"))
266+
.build();
267+
268+
assertThat(actualFilter).isEqualTo(expectedFilter);
269+
}
270+
249271
@Test
250272
public void qualifierRangeInFamilyClosedOpen() {
251273
RowFilter actualFilter =
@@ -370,6 +392,18 @@ public void valueExactMatch() {
370392
assertThat(actualFilter).isEqualTo(expectedFilter);
371393
}
372394

395+
@Test
396+
public void valueExactStringMatch() {
397+
RowFilter actualFilter = FILTERS.value().exactMatch("some[0-9]regex").toProto();
398+
399+
RowFilter expectedFilter =
400+
RowFilter.newBuilder()
401+
.setValueRegexFilter(ByteString.copyFromUtf8("some\\[0\\-9\\]regex"))
402+
.build();
403+
404+
assertThat(actualFilter).isEqualTo(expectedFilter);
405+
}
406+
373407
@Test
374408
public void valueRangeClosedOpen() {
375409
RowFilter actualFilter = FILTERS.value().range().startClosed("begin").endOpen("end").toProto();

0 commit comments

Comments
 (0)