|
20 | 20 | import org.apache.fluss.bucketing.BucketingFunction; |
21 | 21 | import org.apache.fluss.client.metadata.MetadataUpdater; |
22 | 22 | import org.apache.fluss.client.table.getter.PartitionGetter; |
23 | | -import org.apache.fluss.exception.LeaderNotAvailableException; |
24 | 23 | import org.apache.fluss.exception.PartitionNotExistException; |
25 | | -import org.apache.fluss.exception.TableNotPartitionedException; |
26 | 24 | import org.apache.fluss.metadata.DataLakeFormat; |
27 | | -import org.apache.fluss.metadata.PhysicalTablePath; |
28 | 25 | import org.apache.fluss.metadata.TableBucket; |
29 | 26 | import org.apache.fluss.metadata.TableInfo; |
30 | | -import org.apache.fluss.metadata.TablePath; |
31 | | -import org.apache.fluss.record.DefaultValueRecordBatch; |
32 | | -import org.apache.fluss.record.ValueRecord; |
33 | | -import org.apache.fluss.record.ValueRecordReadContext; |
34 | 27 | import org.apache.fluss.row.InternalRow; |
35 | 28 | import org.apache.fluss.row.decode.RowDecoder; |
36 | 29 | import org.apache.fluss.row.encode.KeyEncoder; |
37 | 30 | import org.apache.fluss.row.encode.ValueDecoder; |
38 | | -import org.apache.fluss.rpc.gateway.TabletServerGateway; |
39 | | -import org.apache.fluss.rpc.messages.FullScanRequest; |
40 | | -import org.apache.fluss.rpc.messages.FullScanResponse; |
41 | | -import org.apache.fluss.rpc.protocol.Errors; |
42 | 31 | import org.apache.fluss.types.DataType; |
43 | 32 | import org.apache.fluss.types.RowType; |
44 | 33 |
|
45 | 34 | import javax.annotation.Nullable; |
46 | 35 |
|
47 | | -import java.nio.ByteBuffer; |
48 | | -import java.util.ArrayList; |
49 | 36 | import java.util.Collections; |
50 | | -import java.util.HashSet; |
51 | | -import java.util.List; |
52 | | -import java.util.Optional; |
53 | 37 | import java.util.concurrent.CompletableFuture; |
54 | 38 |
|
55 | 39 | import static org.apache.fluss.client.utils.ClientUtils.getPartitionId; |
|
58 | 42 | /** |
59 | 43 | * Client-side lookuper implementation for primary-key tables. |
60 | 44 | * |
61 | | - * <p>This class supports single-key lookups as well as bounded, point-in-time snapshot reads that |
62 | | - * return all current values of a KV table (and per-partition for partitioned tables). Snapshot |
63 | | - * reads are executed via the FULL_SCAN RPC and aggregate results across the leaders of all buckets |
64 | | - * on each target server. |
| 45 | + * <p>This class supports single-key lookups. For any scan semantics (full scan, limited scan, or |
| 46 | + * snapshot-by-id), use the Scan API instead. |
65 | 47 | */ |
66 | 48 | class PrimaryKeyLookuper implements Lookuper { |
67 | 49 |
|
@@ -185,124 +167,4 @@ public CompletableFuture<LookupResult> lookup(InternalRow lookupKey) { |
185 | 167 | * |
186 | 168 | * @return a future with an unordered list of current rows |
187 | 169 | */ |
188 | | - @Override |
189 | | - public CompletableFuture<List<InternalRow>> snapshotAll() { |
190 | | - if (tableInfo.isPartitioned()) { |
191 | | - CompletableFuture<List<InternalRow>> result = new CompletableFuture<>(); |
192 | | - result.completeExceptionally( |
193 | | - new TableNotPartitionedException( |
194 | | - "Table is partitioned. Please use snapshotAllPartition(partitionName).")); |
195 | | - |
196 | | - return result; |
197 | | - } |
198 | | - |
199 | | - return executeFullScan(Optional.empty()); |
200 | | - } |
201 | | - |
202 | | - /** |
203 | | - * Returns all current values for the specified partition of a partitioned primary-key table |
204 | | - * using a point-in-time snapshot. |
205 | | - * |
206 | | - * @param partitionName the partition identifier (for example, a date string) |
207 | | - * @return a future with an unordered list of current rows in the partition |
208 | | - */ |
209 | | - @Override |
210 | | - public CompletableFuture<List<InternalRow>> snapshotAllPartition(String partitionName) { |
211 | | - if (!tableInfo.isPartitioned()) { |
212 | | - CompletableFuture<List<InternalRow>> result = new CompletableFuture<>(); |
213 | | - result.completeExceptionally( |
214 | | - new TableNotPartitionedException( |
215 | | - "Table is not partitioned. Please use snapshotAll().")); |
216 | | - return result; |
217 | | - } |
218 | | - |
219 | | - // Resolve partition id from name |
220 | | - TablePath tablePath = tableInfo.getTablePath(); |
221 | | - PhysicalTablePath physicalTablePath = PhysicalTablePath.of(tablePath, partitionName); |
222 | | - |
223 | | - try { |
224 | | - metadataUpdater.checkAndUpdatePartitionMetadata(physicalTablePath); |
225 | | - } catch (PartitionNotExistException e) { |
226 | | - CompletableFuture<List<InternalRow>> result = new CompletableFuture<>(); |
227 | | - result.completeExceptionally(e); |
228 | | - return result; |
229 | | - } |
230 | | - |
231 | | - Optional<Long> partitionId = metadataUpdater.getPartitionId(physicalTablePath); |
232 | | - return executeFullScan(partitionId); |
233 | | - } |
234 | | - |
235 | | - /** |
236 | | - * Decodes and aggregates FULL_SCAN RPC responses into a list of rows. |
237 | | - * |
238 | | - * <p>Throws a mapped client exception if any response contains an error. |
239 | | - * |
240 | | - * @param responseFutures futures of server responses per target leader node |
241 | | - * @return aggregated, unordered rows |
242 | | - */ |
243 | | - private List<InternalRow> decodeFullScanResponses( |
244 | | - List<CompletableFuture<FullScanResponse>> responseFutures) { |
245 | | - List<InternalRow> out = new ArrayList<>(); |
246 | | - for (CompletableFuture<FullScanResponse> responseFuture : responseFutures) { |
247 | | - FullScanResponse response = responseFuture.join(); |
248 | | - |
249 | | - if (response.hasErrorCode() && response.getErrorCode() != Errors.NONE.code()) { |
250 | | - Errors err = Errors.forCode(response.getErrorCode()); |
251 | | - throw err.exception( |
252 | | - response.hasErrorMessage() ? response.getErrorMessage() : err.message()); |
253 | | - } |
254 | | - |
255 | | - if (response.hasRecords()) { |
256 | | - ByteBuffer buffer = ByteBuffer.wrap(response.getRecords()); |
257 | | - DefaultValueRecordBatch values = DefaultValueRecordBatch.pointToByteBuffer(buffer); |
258 | | - |
259 | | - ValueRecordReadContext context = |
260 | | - new ValueRecordReadContext(kvValueDecoder.getRowDecoder()); |
261 | | - for (ValueRecord record : values.records(context)) { |
262 | | - out.add(record.getRow()); |
263 | | - } |
264 | | - } |
265 | | - } |
266 | | - return out; |
267 | | - } |
268 | | - |
269 | | - private CompletableFuture<List<InternalRow>> executeFullScan(Optional<Long> partitionIdOpt) { |
270 | | - Long partitionId = partitionIdOpt.orElse(null); |
271 | | - long tableId = tableInfo.getTableId(); |
272 | | - int numBuckets = tableInfo.getNumBuckets(); |
273 | | - |
274 | | - // Find leader tablet/servers for this table/partition |
275 | | - HashSet<Integer> leaderServers = new HashSet<>(); |
276 | | - for (int bucketId = 0; bucketId < numBuckets; bucketId++) { |
277 | | - TableBucket tableBucket = new TableBucket(tableId, partitionId, bucketId); |
278 | | - |
279 | | - // ensure metadata for this bucket is present |
280 | | - metadataUpdater.checkAndUpdateMetadata(tableInfo.getTablePath(), tableBucket); |
281 | | - int leader = metadataUpdater.leaderFor(tableBucket); |
282 | | - leaderServers.add(leader); |
283 | | - } |
284 | | - |
285 | | - List<CompletableFuture<FullScanResponse>> responseFutures = new ArrayList<>(); |
286 | | - for (int leader : leaderServers) { |
287 | | - TabletServerGateway gateway = metadataUpdater.newTabletServerClientForNode(leader); |
288 | | - if (gateway == null) { |
289 | | - CompletableFuture<List<InternalRow>> result = new CompletableFuture<>(); |
290 | | - result.completeExceptionally( |
291 | | - new LeaderNotAvailableException( |
292 | | - "Leader server " + leader + " is not found in metadata cache.")); |
293 | | - return result; |
294 | | - } |
295 | | - |
296 | | - FullScanRequest request = new FullScanRequest(); |
297 | | - request.setTableId(tableId); |
298 | | - |
299 | | - if (partitionId != null) { |
300 | | - request.setPartitionId(partitionId); |
301 | | - } |
302 | | - responseFutures.add(gateway.fullScan(request)); |
303 | | - } |
304 | | - // Decode all responses and aggregate rows |
305 | | - return CompletableFuture.allOf(responseFutures.toArray(new CompletableFuture[0])) |
306 | | - .thenApply(v -> decodeFullScanResponses(responseFutures)); |
307 | | - } |
308 | 170 | } |
0 commit comments