HBASE-24456 : Create ImmutableScan and use it for CustomizedScanInfoBuilder (#1818)
Signed-off-by: Anoop Sam John <anoopsamjohn@apache.org> Signed-off-by: Duo Zhang <zhangduo@apache.org>
This commit is contained in:
parent
59031ab661
commit
61a7468df7
|
@ -0,0 +1,542 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you 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 org.apache.hadoop.hbase.client;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.NavigableSet;
|
||||||
|
import org.apache.hadoop.hbase.exceptions.DeserializationException;
|
||||||
|
import org.apache.hadoop.hbase.filter.Filter;
|
||||||
|
import org.apache.hadoop.hbase.io.TimeRange;
|
||||||
|
import org.apache.hadoop.hbase.security.access.Permission;
|
||||||
|
import org.apache.hadoop.hbase.security.visibility.Authorizations;
|
||||||
|
import org.apache.hadoop.hbase.util.Bytes;
|
||||||
|
import org.apache.yetus.audience.InterfaceAudience;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Immutable version of Scan
|
||||||
|
*/
|
||||||
|
@InterfaceAudience.Private
|
||||||
|
public final class ImmutableScan extends Scan {
|
||||||
|
|
||||||
|
private final Scan delegateScan;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create Immutable instance of Scan from given Scan object
|
||||||
|
*
|
||||||
|
* @param scan Copy all values from Scan
|
||||||
|
*/
|
||||||
|
public ImmutableScan(Scan scan) {
|
||||||
|
this.delegateScan = scan;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan addFamily(byte[] family) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to addFamily");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan addColumn(byte[] family, byte[] qualifier) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to addColumn");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setTimeRange(long minStamp, long maxStamp) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to setTimeRange");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Deprecated
|
||||||
|
@Override
|
||||||
|
public Scan setTimeStamp(long timestamp) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to setTimeStamp");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setTimestamp(long timestamp) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to setTimestamp");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setColumnFamilyTimeRange(byte[] cf, long minStamp, long maxStamp) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"ImmutableScan does not allow access to setColumnFamilyTimeRange");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan withStartRow(byte[] startRow) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to withStartRow");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan withStartRow(byte[] startRow, boolean inclusive) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to withStartRow");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan withStopRow(byte[] stopRow) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to withStopRow");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan withStopRow(byte[] stopRow, boolean inclusive) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to withStopRow");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setRowPrefixFilter(byte[] rowPrefix) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"ImmutableScan does not allow access to setRowPrefixFilter");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan readAllVersions() {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"ImmutableScan does not allow access to readAllVersions");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan readVersions(int versions) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to readVersions");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setBatch(int batch) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to setBatch");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setMaxResultsPerColumnFamily(int limit) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"ImmutableScan does not allow access to setMaxResultsPerColumnFamily");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setRowOffsetPerColumnFamily(int offset) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"ImmutableScan does not allow access to setRowOffsetPerColumnFamily");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setCaching(int caching) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to setCaching");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setMaxResultSize(long maxResultSize) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"ImmutableScan does not allow access to setMaxResultSize");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setFilter(Filter filter) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to setFilter");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setFamilyMap(Map<byte[], NavigableSet<byte[]>> familyMap) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to setFamilyMap");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setCacheBlocks(boolean cacheBlocks) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"ImmutableScan does not allow access to setCacheBlocks");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setReversed(boolean reversed) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to setReversed");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setAllowPartialResults(final boolean allowPartialResults) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"ImmutableScan does not allow access to setAllowPartialResults");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setLoadColumnFamiliesOnDemand(boolean value) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"ImmutableScan does not allow access to setLoadColumnFamiliesOnDemand");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setRaw(boolean raw) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to setRaw");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public Scan setSmall(boolean small) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to setSmall");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setAttribute(String name, byte[] value) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to setAttribute");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setId(String id) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to setId");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setAuthorizations(Authorizations authorizations) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"ImmutableScan does not allow access to setAuthorizations");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setACL(Map<String, Permission> perms) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to setACL");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setACL(String user, Permission perms) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to setACL");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setConsistency(Consistency consistency) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"ImmutableScan does not allow access to setConsistency");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setReplicaId(int id) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to setReplicaId");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setIsolationLevel(IsolationLevel level) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"ImmutableScan does not allow access to setIsolationLevel");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setPriority(int priority) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to setPriority");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setScanMetricsEnabled(final boolean enabled) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"ImmutableScan does not allow access to setScanMetricsEnabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public Scan setAsyncPrefetch(boolean asyncPrefetch) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"ImmutableScan does not allow access to setAsyncPrefetch");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setLimit(int limit) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to setLimit");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setOneRowLimit() {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"ImmutableScan does not allow access to setOneRowLimit");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setReadType(ReadType readType) {
|
||||||
|
throw new UnsupportedOperationException("ImmutableScan does not allow access to setReadType");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Scan setMvccReadPoint(long mvccReadPoint) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"ImmutableScan does not allow access to setMvccReadPoint");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
Scan resetMvccReadPoint() {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"ImmutableScan does not allow access to resetMvccReadPoint");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Scan setNeedCursorResult(boolean needCursorResult) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"ImmutableScan does not allow access to setNeedCursorResult");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getMaxResultSize() {
|
||||||
|
return this.delegateScan.getMaxResultSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<byte[], NavigableSet<byte[]>> getFamilyMap() {
|
||||||
|
return Collections.unmodifiableMap(this.delegateScan.getFamilyMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int numFamilies() {
|
||||||
|
return this.delegateScan.numFamilies();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasFamilies() {
|
||||||
|
return this.delegateScan.hasFamilies();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[][] getFamilies() {
|
||||||
|
final byte[][] families = this.delegateScan.getFamilies();
|
||||||
|
byte[][] cloneFamilies = new byte[families.length][];
|
||||||
|
for (int i = 0; i < families.length; i++) {
|
||||||
|
cloneFamilies[i] = Bytes.copy(families[i]);
|
||||||
|
}
|
||||||
|
return cloneFamilies;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getStartRow() {
|
||||||
|
final byte[] startRow = this.delegateScan.getStartRow();
|
||||||
|
return Bytes.copy(startRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean includeStartRow() {
|
||||||
|
return this.delegateScan.includeStartRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getStopRow() {
|
||||||
|
final byte[] stopRow = this.delegateScan.getStopRow();
|
||||||
|
return Bytes.copy(stopRow);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean includeStopRow() {
|
||||||
|
return this.delegateScan.includeStopRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxVersions() {
|
||||||
|
return this.delegateScan.getMaxVersions();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getBatch() {
|
||||||
|
return this.delegateScan.getBatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMaxResultsPerColumnFamily() {
|
||||||
|
return this.delegateScan.getMaxResultsPerColumnFamily();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRowOffsetPerColumnFamily() {
|
||||||
|
return this.delegateScan.getRowOffsetPerColumnFamily();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getCaching() {
|
||||||
|
return this.delegateScan.getCaching();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TimeRange getTimeRange() {
|
||||||
|
return this.delegateScan.getTimeRange();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Filter getFilter() {
|
||||||
|
return this.delegateScan.getFilter();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasFilter() {
|
||||||
|
return this.delegateScan.hasFilter();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getCacheBlocks() {
|
||||||
|
return this.delegateScan.getCacheBlocks();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isReversed() {
|
||||||
|
return this.delegateScan.isReversed();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean getAllowPartialResults() {
|
||||||
|
return this.delegateScan.getAllowPartialResults();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getACL() {
|
||||||
|
final byte[] acl = this.delegateScan.getACL();
|
||||||
|
return Bytes.copy(acl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> getFingerprint() {
|
||||||
|
return Collections.unmodifiableMap(this.delegateScan.getFingerprint());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> toMap(int maxCols) {
|
||||||
|
return Collections.unmodifiableMap(this.delegateScan.toMap(maxCols));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isRaw() {
|
||||||
|
return this.delegateScan.isRaw();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@Deprecated
|
||||||
|
public boolean isSmall() {
|
||||||
|
return this.delegateScan.isSmall();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isScanMetricsEnabled() {
|
||||||
|
return this.delegateScan.isScanMetricsEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean isAsyncPrefetch() {
|
||||||
|
return this.delegateScan.isAsyncPrefetch();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getLimit() {
|
||||||
|
return this.delegateScan.getLimit();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ReadType getReadType() {
|
||||||
|
return this.delegateScan.getReadType();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
long getMvccReadPoint() {
|
||||||
|
return this.delegateScan.getMvccReadPoint();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isNeedCursorResult() {
|
||||||
|
return this.delegateScan.isNeedCursorResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getAttribute(String name) {
|
||||||
|
final byte[] attribute = this.delegateScan.getAttribute(name);
|
||||||
|
return Bytes.copy(attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Consistency getConsistency() {
|
||||||
|
return this.delegateScan.getConsistency();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public long getAttributeSize() {
|
||||||
|
return this.delegateScan.getAttributeSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, byte[]> getAttributesMap() {
|
||||||
|
return Collections.unmodifiableMap(this.delegateScan.getAttributesMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean getLoadColumnFamiliesOnDemandValue() {
|
||||||
|
return this.delegateScan.getLoadColumnFamiliesOnDemandValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getPriority() {
|
||||||
|
return this.delegateScan.getPriority();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<byte[], TimeRange> getColumnFamilyTimeRange() {
|
||||||
|
return Collections.unmodifiableMap(this.delegateScan.getColumnFamilyTimeRange());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getReplicaId() {
|
||||||
|
return this.delegateScan.getReplicaId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean doLoadColumnFamiliesOnDemand() {
|
||||||
|
return this.delegateScan.doLoadColumnFamiliesOnDemand();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getId() {
|
||||||
|
return this.delegateScan.getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isGetScan() {
|
||||||
|
return this.delegateScan.isGetScan();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public IsolationLevel getIsolationLevel() {
|
||||||
|
return this.delegateScan.getIsolationLevel();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Authorizations getAuthorizations() throws DeserializationException {
|
||||||
|
return this.delegateScan.getAuthorizations();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString(int maxCols) {
|
||||||
|
return this.delegateScan.toString(maxCols);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return this.delegateScan.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> toMap() {
|
||||||
|
return Collections.unmodifiableMap(this.delegateScan.toMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toJSON(int maxCols) throws IOException {
|
||||||
|
return this.delegateScan.toJSON(maxCols);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toJSON() throws IOException {
|
||||||
|
return this.delegateScan.toJSON();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,392 @@
|
||||||
|
/*
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
* or more contributor license agreements. See the NOTICE file
|
||||||
|
* distributed with this work for additional information
|
||||||
|
* regarding copyright ownership. The ASF licenses this file
|
||||||
|
* to you 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 org.apache.hadoop.hbase.client;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.apache.commons.lang3.builder.EqualsBuilder;
|
||||||
|
import org.apache.hadoop.hbase.HBaseClassTestRule;
|
||||||
|
import org.apache.hadoop.hbase.filter.Filter;
|
||||||
|
import org.apache.hadoop.hbase.filter.FilterList;
|
||||||
|
import org.apache.hadoop.hbase.security.access.Permission;
|
||||||
|
import org.apache.hadoop.hbase.security.visibility.Authorizations;
|
||||||
|
import org.apache.hadoop.hbase.testclassification.ClientTests;
|
||||||
|
import org.apache.hadoop.hbase.testclassification.SmallTests;
|
||||||
|
import org.apache.hadoop.hbase.util.Bytes;
|
||||||
|
import org.junit.ClassRule;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.experimental.categories.Category;
|
||||||
|
import org.mockito.Mockito;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Small tests for ImmutableScan
|
||||||
|
*/
|
||||||
|
@Category({ ClientTests.class, SmallTests.class })
|
||||||
|
public class TestImmutableScan {
|
||||||
|
|
||||||
|
@ClassRule
|
||||||
|
public static final HBaseClassTestRule CLASS_RULE =
|
||||||
|
HBaseClassTestRule.forClass(TestImmutableScan.class);
|
||||||
|
|
||||||
|
private static final Logger LOG = LoggerFactory.getLogger(TestImmutableScan.class);
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testScanCopyConstructor() throws Exception {
|
||||||
|
Scan scan = new Scan();
|
||||||
|
|
||||||
|
scan.addColumn(Bytes.toBytes("cf"), Bytes.toBytes("q"))
|
||||||
|
.setACL("test_user2", new Permission(Permission.Action.READ))
|
||||||
|
.setAllowPartialResults(true)
|
||||||
|
.setAsyncPrefetch(false)
|
||||||
|
.setAttribute("test_key", Bytes.toBytes("test_value"))
|
||||||
|
.setAuthorizations(new Authorizations("test_label"))
|
||||||
|
.setBatch(10)
|
||||||
|
.setCacheBlocks(false)
|
||||||
|
.setCaching(10)
|
||||||
|
.setConsistency(Consistency.TIMELINE)
|
||||||
|
.setFilter(new FilterList())
|
||||||
|
.setId("scan_copy_constructor")
|
||||||
|
.setIsolationLevel(IsolationLevel.READ_COMMITTED)
|
||||||
|
.setLimit(100)
|
||||||
|
.setLoadColumnFamiliesOnDemand(false)
|
||||||
|
.setMaxResultSize(100)
|
||||||
|
.setMaxResultsPerColumnFamily(1000)
|
||||||
|
.readVersions(9999)
|
||||||
|
.setMvccReadPoint(5)
|
||||||
|
.setNeedCursorResult(true)
|
||||||
|
.setPriority(1)
|
||||||
|
.setRaw(true)
|
||||||
|
.setReplicaId(3)
|
||||||
|
.setReversed(true)
|
||||||
|
.setRowOffsetPerColumnFamily(5)
|
||||||
|
.setRowPrefixFilter(Bytes.toBytes("row_"))
|
||||||
|
.setScanMetricsEnabled(true)
|
||||||
|
.setSmall(true)
|
||||||
|
.setReadType(Scan.ReadType.STREAM)
|
||||||
|
.withStartRow(Bytes.toBytes("row_1"))
|
||||||
|
.withStopRow(Bytes.toBytes("row_2"))
|
||||||
|
.setTimeRange(0, 13);
|
||||||
|
|
||||||
|
// create a copy of existing scan object
|
||||||
|
Scan scanCopy = new ImmutableScan(scan);
|
||||||
|
|
||||||
|
// validate fields of copied scan object match with the original scan object
|
||||||
|
assertArrayEquals(scan.getACL(), scanCopy.getACL());
|
||||||
|
assertEquals(scan.getAllowPartialResults(), scanCopy.getAllowPartialResults());
|
||||||
|
assertArrayEquals(scan.getAttribute("test_key"), scanCopy.getAttribute("test_key"));
|
||||||
|
assertEquals(scan.getAttributeSize(), scanCopy.getAttributeSize());
|
||||||
|
assertEquals(scan.getAttributesMap(), scanCopy.getAttributesMap());
|
||||||
|
assertEquals(scan.getAuthorizations().getLabels(), scanCopy.getAuthorizations().getLabels());
|
||||||
|
assertEquals(scan.getBatch(), scanCopy.getBatch());
|
||||||
|
assertEquals(scan.getCacheBlocks(), scanCopy.getCacheBlocks());
|
||||||
|
assertEquals(scan.getCaching(), scanCopy.getCaching());
|
||||||
|
assertEquals(scan.getConsistency(), scanCopy.getConsistency());
|
||||||
|
assertEquals(scan.getFamilies().length, scanCopy.getFamilies().length);
|
||||||
|
assertArrayEquals(scan.getFamilies()[0], scanCopy.getFamilies()[0]);
|
||||||
|
assertEquals(scan.getFamilyMap(), scanCopy.getFamilyMap());
|
||||||
|
assertEquals(scan.getFilter(), scanCopy.getFilter());
|
||||||
|
assertEquals(scan.getId(), scanCopy.getId());
|
||||||
|
assertEquals(scan.getIsolationLevel(), scanCopy.getIsolationLevel());
|
||||||
|
assertEquals(scan.getLimit(), scanCopy.getLimit());
|
||||||
|
assertEquals(scan.getLoadColumnFamiliesOnDemandValue(),
|
||||||
|
scanCopy.getLoadColumnFamiliesOnDemandValue());
|
||||||
|
assertEquals(scan.getMaxResultSize(), scanCopy.getMaxResultSize());
|
||||||
|
assertEquals(scan.getMaxResultsPerColumnFamily(), scanCopy.getMaxResultsPerColumnFamily());
|
||||||
|
assertEquals(scan.getMaxVersions(), scanCopy.getMaxVersions());
|
||||||
|
assertEquals(scan.getMvccReadPoint(), scanCopy.getMvccReadPoint());
|
||||||
|
assertEquals(scan.getPriority(), scanCopy.getPriority());
|
||||||
|
assertEquals(scan.getReadType(), scanCopy.getReadType());
|
||||||
|
assertEquals(scan.getReplicaId(), scanCopy.getReplicaId());
|
||||||
|
assertEquals(scan.getRowOffsetPerColumnFamily(), scanCopy.getRowOffsetPerColumnFamily());
|
||||||
|
assertArrayEquals(scan.getStartRow(), scanCopy.getStartRow());
|
||||||
|
assertArrayEquals(scan.getStopRow(), scanCopy.getStopRow());
|
||||||
|
assertEquals(scan.getTimeRange(), scanCopy.getTimeRange());
|
||||||
|
assertEquals(scan.getFingerprint(), scanCopy.getFingerprint());
|
||||||
|
assertEquals(scan.toMap(1), scanCopy.toMap(1));
|
||||||
|
assertEquals(scan.toString(2), scanCopy.toString(2));
|
||||||
|
assertEquals(scan.toJSON(2), scanCopy.toJSON(2));
|
||||||
|
|
||||||
|
LOG.debug("Compare all getters of scan and scanCopy.");
|
||||||
|
compareGetters(scan, scanCopy);
|
||||||
|
|
||||||
|
testUnmodifiableSetters(scanCopy);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void testUnmodifiableSetters(Scan scanCopy) throws IOException {
|
||||||
|
try {
|
||||||
|
scanCopy.setFilter(Mockito.mock(Filter.class));
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setFilter", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.addFamily(new byte[] { 0, 1 });
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to addFamily", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.addColumn(new byte[] { 0, 1 }, new byte[] { 2, 3 });
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to addColumn", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setTimeRange(1L, 2L);
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setTimeRange", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setTimestamp(1L);
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setTimestamp", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setColumnFamilyTimeRange(new byte[] { 0 }, 1L, 2L);
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setColumnFamilyTimeRange",
|
||||||
|
e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.withStopRow(new byte[] { 1, 2 });
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to withStopRow", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setRowPrefixFilter(new byte[] { 1, 2 });
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setRowPrefixFilter", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.readAllVersions();
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to readAllVersions", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setBatch(1);
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setBatch", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setRowOffsetPerColumnFamily(1);
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setRowOffsetPerColumnFamily",
|
||||||
|
e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setCaching(1);
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setCaching",
|
||||||
|
e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setLoadColumnFamiliesOnDemand(true);
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setLoadColumnFamiliesOnDemand",
|
||||||
|
e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setRaw(true);
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setRaw", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setAuthorizations(new Authorizations("test"));
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setAuthorizations", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setACL("user1", new Permission(Permission.Action.READ));
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setACL", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setReplicaId(12);
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setReplicaId", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setReadType(Scan.ReadType.STREAM);
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setReadType", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setOneRowLimit();
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setOneRowLimit", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setNeedCursorResult(false);
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setNeedCursorResult", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.resetMvccReadPoint();
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to resetMvccReadPoint", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setMvccReadPoint(1L);
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setMvccReadPoint", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setIsolationLevel(IsolationLevel.READ_UNCOMMITTED);
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setIsolationLevel", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setPriority(10);
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setPriority", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setConsistency(Consistency.TIMELINE);
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setConsistency", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setCacheBlocks(true);
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setCacheBlocks", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setAllowPartialResults(true);
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setAllowPartialResults",
|
||||||
|
e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setId("id");
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setId", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setMaxResultSize(100);
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setMaxResultSize", e.getMessage());
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
scanCopy.setMaxResultsPerColumnFamily(100);
|
||||||
|
throw new RuntimeException("Should not reach here");
|
||||||
|
} catch (UnsupportedOperationException e) {
|
||||||
|
assertEquals("ImmutableScan does not allow access to setMaxResultsPerColumnFamily",
|
||||||
|
e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void compareGetters(Scan scan, Scan scanCopy) {
|
||||||
|
Method[] methods = Scan.class.getMethods();
|
||||||
|
for (Method method : methods) {
|
||||||
|
if (isGetter(method)) {
|
||||||
|
LOG.debug("Comparing return values of method: {}", method);
|
||||||
|
try {
|
||||||
|
Object obj1;
|
||||||
|
Object obj2;
|
||||||
|
switch (method.getName()) {
|
||||||
|
case "toMap": {
|
||||||
|
if (method.getParameterCount() == 1) {
|
||||||
|
obj1 = method.invoke(scan, 2);
|
||||||
|
obj2 = method.invoke(scanCopy, 2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "getAttribute": {
|
||||||
|
if (method.getParameterCount() == 1) {
|
||||||
|
obj1 = method.invoke(scan, "acl");
|
||||||
|
obj2 = method.invoke(scanCopy, "acl");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "toString": {
|
||||||
|
if (method.getParameterCount() == 1) {
|
||||||
|
obj1 = method.invoke(scan, 25);
|
||||||
|
obj2 = method.invoke(scanCopy, 25);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case "toJSON": {
|
||||||
|
if (method.getParameterCount() == 1) {
|
||||||
|
obj1 = method.invoke(scan, 25);
|
||||||
|
obj2 = method.invoke(scanCopy, 25);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
obj1 = method.invoke(scan);
|
||||||
|
obj2 = method.invoke(scanCopy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (obj1 instanceof Map && obj2 instanceof Map) {
|
||||||
|
obj1 = Collections.unmodifiableMap((Map<?, ?>) obj1);
|
||||||
|
}
|
||||||
|
if (!EqualsBuilder.reflectionEquals(obj1, obj2)) {
|
||||||
|
throw new AssertionError("Method " + method + " does not return equal values");
|
||||||
|
}
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException | IllegalArgumentException e) {
|
||||||
|
throw new AssertionError("Error invoking method " + method, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isGetter(Method method) {
|
||||||
|
if ("hashCode".equals(method.getName()) || "equals".equals(method.getName())
|
||||||
|
|| method.getName().startsWith("set")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return !void.class.equals(method.getReturnType())
|
||||||
|
&& !Scan.class.equals(method.getReturnType());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -19,6 +19,7 @@ package org.apache.hadoop.hbase.regionserver;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import org.apache.hadoop.hbase.KeepDeletedCells;
|
import org.apache.hadoop.hbase.KeepDeletedCells;
|
||||||
|
import org.apache.hadoop.hbase.client.ImmutableScan;
|
||||||
import org.apache.hadoop.hbase.client.Scan;
|
import org.apache.hadoop.hbase.client.Scan;
|
||||||
import org.apache.yetus.audience.InterfaceAudience;
|
import org.apache.yetus.audience.InterfaceAudience;
|
||||||
|
|
||||||
|
@ -42,16 +43,13 @@ public class CustomizedScanInfoBuilder implements ScanOptions {
|
||||||
|
|
||||||
public CustomizedScanInfoBuilder(ScanInfo scanInfo) {
|
public CustomizedScanInfoBuilder(ScanInfo scanInfo) {
|
||||||
this.scanInfo = scanInfo;
|
this.scanInfo = scanInfo;
|
||||||
this.scan = new Scan();
|
this.scan = new ImmutableScan(new Scan());
|
||||||
}
|
}
|
||||||
|
|
||||||
public CustomizedScanInfoBuilder(ScanInfo scanInfo, Scan scan) {
|
public CustomizedScanInfoBuilder(ScanInfo scanInfo, Scan scan) {
|
||||||
this.scanInfo = scanInfo;
|
this.scanInfo = scanInfo;
|
||||||
//copy the scan so no coproc using this ScanOptions can alter the "real" scan
|
//copy the scan so no coproc using this ScanOptions can alter the "real" scan
|
||||||
try {
|
this.scan = new ImmutableScan(scan);
|
||||||
this.scan = new Scan(scan);
|
|
||||||
} catch (IOException e) {
|
|
||||||
throw new AssertionError("Scan should not throw IOException", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -109,11 +107,7 @@ public class CustomizedScanInfoBuilder implements ScanOptions {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Scan getScan() {
|
public Scan getScan() {
|
||||||
try {
|
return scan;
|
||||||
return new Scan(scan);
|
|
||||||
} catch(IOException e) {
|
|
||||||
throw new AssertionError("Scan should not throw IOException anymore", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue