Repository navigation
Expand file tree
/
Copy pathKeySet.java
More file actions
213 lines (187 loc) · 6.04 KB
/
Copy pathKeySet.java
File metadata and controls
213 lines (187 loc) · 6.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
/*
* Copyright 2017 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.google.cloud.spanner;
import com.google.common.collect.ImmutableList;
import java.io.Serializable;
import java.util.Objects;
/**
* Defines a collection of Cloud Spanner keys and/or key ranges. All the keys are expected to be in
* the same table or index. The keys need not be sorted in any particular way.
*
* <p>If the same key is specified multiple times in the set (for example if two ranges, two keys,
* or a key and a range overlap), the Cloud Spanner backend behaves as if the key were only
* specified once. However, the {@code KeySet} object itself does not perform any de-duplication.
*
* <p>{@code KeySet} instances are immutable.
*/
public final class KeySet implements Serializable {
private static final long serialVersionUID = -542201151451064347L;
private final boolean all;
private final ImmutableList<Key> keys;
private final ImmutableList<KeyRange> ranges;
private KeySet(boolean all, ImmutableList<Key> keys, ImmutableList<KeyRange> ranges) {
this.all = all;
this.keys = keys;
this.ranges = ranges;
}
/**
* Creates a key set containing a single key. {@code key} should contain exactly as many elements
* as there are columns in the primary or index key with this this key set is used.
*/
public static KeySet singleKey(Key key) {
return new KeySet(false, ImmutableList.of(key), ImmutableList.<KeyRange>of());
}
/**
* Creates a key set containing a single range. See {@link KeyRange} for details of how to specify
* ranges.
*/
public static KeySet range(KeyRange range) {
return new KeySet(false, ImmutableList.<Key>of(), ImmutableList.of(range));
}
/**
* Creates a key set that covers all keys where the first {@code prefix.size()} components match
* {@code prefix} exactly.
*/
public static KeySet prefixRange(Key prefix) {
return range(KeyRange.prefix(prefix));
}
/** Creates a key set that will retrieve all rows of a table or index. */
public static KeySet all() {
return new KeySet(true, ImmutableList.<Key>of(), ImmutableList.<KeyRange>of());
}
/** Returns a new builder that can be used to construct a key set. */
public static Builder newBuilder() {
return new Builder();
}
/** Builder for {@link KeySet} instances. */
public static class Builder {
private boolean all;
private ImmutableList.Builder<Key> keys;
private ImmutableList.Builder<KeyRange> ranges;
private Builder() {}
private Builder(KeySet set) {
all = set.all;
if (!set.keys.isEmpty()) {
keys = ImmutableList.<Key>builder().addAll(set.keys);
}
if (!set.ranges.isEmpty()) {
ranges = ImmutableList.<KeyRange>builder().addAll(set.ranges);
}
}
/**
* Adds a key to the key set. {@code key} should contain exactly as many elements as there are
* columns in the primary or index key with this this key set is used.
*/
public Builder addKey(Key key) {
if (keys == null) {
keys = ImmutableList.builder();
}
keys.add(key);
return this;
}
/** Adds a range to the key set. See {@link KeyRange} for details of how to specify ranges. */
public Builder addRange(KeyRange range) {
if (ranges == null) {
ranges = ImmutableList.builder();
}
ranges.add(range);
return this;
}
/** Makes the key set retrieve all rows of a table or index. */
public Builder setAll() {
all = true;
return this;
}
public KeySet build() {
return new KeySet(
all,
keys != null ? keys.build() : ImmutableList.<Key>of(),
ranges != null ? ranges.build() : ImmutableList.<KeyRange>of());
}
}
/** Returns the keys in this set. */
public Iterable<Key> getKeys() {
// Design note: returns Iterable<> rather than List<> since future internal representations
// may not maintain a List<Key> internally, but rather decode the rep and reconstruct Keys on
// the fly.
return keys;
}
/** Returns the ranges in this set. */
public Iterable<KeyRange> getRanges() {
return ranges;
}
/** Indicates whether the set will retrieve all rows in a table or index. */
public boolean isAll() {
return all;
}
/** Returns a builder initialized with the contents of this set. */
public Builder toBuilder() {
return new Builder(this);
}
void toString(StringBuilder b) {
b.append('{');
int size = 0;
if (all) {
++size;
b.append("<all>");
}
for (Key key : keys) {
if (size++ > 0) {
b.append(',');
}
key.toString(b);
}
for (KeyRange range : ranges) {
if (size++ > 0) {
b.append(',');
}
range.toString(b);
}
b.append('}');
}
@Override
public String toString() {
StringBuilder b = new StringBuilder();
toString(b);
return b.toString();
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
KeySet that = (KeySet) o;
return all == that.all && keys.equals(that.keys) && ranges.equals(that.ranges);
}
@Override
public int hashCode() {
return Objects.hash(all, keys, ranges);
}
void appendToProto(com.google.spanner.v1.KeySet.Builder proto) {
for (Key key : keys) {
proto.addKeys(key.toProto());
}
for (KeyRange range : ranges) {
proto.addRanges(range.toProto());
}
if (all) {
proto.setAll(true);
}
}
}