use of org.tikv.common.key.Key in project client-java by tikv.
the class TiSession method splitRegion.
private List<Metapb.Region> splitRegion(List<ByteString> splitKeys, BackOffer backOffer, int depth) {
List<Metapb.Region> regions = new ArrayList<>();
Map<TiRegion, List<ByteString>> groupKeys = groupKeysByRegion(getRegionManager(), splitKeys, backOffer);
for (Map.Entry<TiRegion, List<ByteString>> entry : groupKeys.entrySet()) {
Pair<TiRegion, TiStore> pair = getRegionManager().getRegionStorePairByKey(entry.getKey().getStartKey());
TiRegion region = pair.first;
TiStore store = pair.second;
List<ByteString> splits = entry.getValue().stream().filter(k -> !k.equals(region.getStartKey()) && !k.equals(region.getEndKey())).collect(Collectors.toList());
if (splits.isEmpty()) {
logger.warn("split key equal to region start key or end key. Region splitting is not needed.");
} else {
logger.info("start to split region id={}, split size={}", region.getId(), splits.size());
List<Metapb.Region> newRegions;
try {
newRegions = getRegionStoreClientBuilder().build(region, store).splitRegion(splits);
// invalidate old region
getRegionManager().invalidateRegion(region);
} catch (final TiKVException e) {
// retry
logger.warn("ReSplitting ranges for splitRegion", e);
getRegionManager().invalidateRegion(region);
backOffer.doBackOff(BackOffFunction.BackOffFuncType.BoRegionMiss, e);
if (depth >= MAX_SPLIT_REGION_STACK_DEPTH) {
logger.warn(String.format("Skip split region because MAX_SPLIT_REGION_STACK_DEPTH(%d) reached!", MAX_SPLIT_REGION_STACK_DEPTH));
newRegions = new ArrayList<>();
} else {
newRegions = splitRegion(splits, backOffer, depth + 1);
}
}
logger.info("region id={}, new region size={}", region.getId(), newRegions.size());
regions.addAll(newRegions);
}
}
logger.info("splitRegion: return region size={}", regions.size());
return regions;
}
use of org.tikv.common.key.Key in project client-java by tikv.
the class TiBatchWriteUtils method getRecordRegions.
public static List<TiRegion> getRecordRegions(TiSession session, TiTableInfo table) {
ArrayList<TiRegion> regionList = new ArrayList<>();
Key key = RowKey.createMin(table.getId());
RowKey endRowKey = RowKey.createBeyondMax(table.getId());
while (key.compareTo(endRowKey) < 0) {
TiRegion region = session.getRegionManager().getRegionByKey(key.toByteString());
regionList.add(region);
key = Key.toRawKey(region.getEndKey());
}
return regionList;
}
use of org.tikv.common.key.Key in project client-java by tikv.
the class TiKVScanAnalyzer method buildTableScanKeyRangePerId.
private Pair<Key, Key> buildTableScanKeyRangePerId(long id, IndexRange ir) {
Key startKey;
Key endKey;
if (ir.hasAccessKey()) {
checkArgument(!ir.hasRange(), "Table scan must have one and only one access condition / point");
Key key = ir.getAccessKey();
checkArgument(key instanceof TypedKey, "Table scan key range must be typed key");
TypedKey typedKey = (TypedKey) key;
startKey = RowKey.toRowKey(id, typedKey);
endKey = startKey.next();
} else if (ir.hasRange()) {
checkArgument(!ir.hasAccessKey(), "Table scan must have one and only one access condition / point");
Range<TypedKey> r = ir.getRange();
if (!r.hasLowerBound()) {
// -INF
startKey = RowKey.createMin(id);
} else {
// Comparison with null should be filtered since it yields unknown always
startKey = RowKey.toRowKey(id, r.lowerEndpoint());
if (r.lowerBoundType().equals(BoundType.OPEN)) {
startKey = startKey.next();
}
}
if (!r.hasUpperBound()) {
// INF
endKey = RowKey.createBeyondMax(id);
} else {
endKey = RowKey.toRowKey(id, r.upperEndpoint());
if (r.upperBoundType().equals(BoundType.CLOSED)) {
endKey = endKey.next();
}
}
} else {
throw new TiClientInternalException("Empty access conditions");
}
return new Pair<>(startKey, endKey);
}
use of org.tikv.common.key.Key in project client-java by tikv.
the class ScanIterator method cacheLoadFails.
// return true if current cache is not loaded or empty
boolean cacheLoadFails() {
if (endOfScan || processingLastBatch) {
return true;
}
if (startKey == null) {
return true;
}
try {
TiRegion region = loadCurrentRegionToCache();
ByteString curRegionEndKey = region.getEndKey();
// See https://github.com/pingcap/tispark/issues/393 for details
if (currentCache == null) {
return true;
}
index = 0;
Key lastKey = Key.EMPTY;
// Session should be single-threaded itself
// so that we don't worry about conf change in the middle
// of a transaction. Otherwise, below code might lose data
int scanLimit = Math.min(limit, conf.getScanBatchSize());
if (currentCache.size() < scanLimit) {
startKey = curRegionEndKey;
lastKey = Key.toRawKey(curRegionEndKey);
} else if (currentCache.size() > scanLimit) {
throw new IndexOutOfBoundsException("current cache size = " + currentCache.size() + ", larger than " + scanLimit);
} else {
// Start new scan from exact next key in current region
lastKey = Key.toRawKey(currentCache.get(currentCache.size() - 1).getKey());
startKey = lastKey.next().toByteString();
}
// if startKey is empty, it indicates +∞
if (hasEndKey && lastKey.compareTo(endKey) >= 0 || startKey.isEmpty()) {
processingLastBatch = true;
startKey = null;
}
} catch (Exception e) {
throw new TiClientInternalException("Error scanning data from region.", e);
}
return false;
}
use of org.tikv.common.key.Key in project client-java by tikv.
the class PredicateUtils method expressionToIndexRanges.
/**
* Build index ranges from access points and access conditions
*
* @param pointPredicates conditions converting to a single point access
* @param rangePredicate conditions converting to a range
* @return Index Range for scan
*/
public static List<IndexRange> expressionToIndexRanges(List<Expression> pointPredicates, Optional<Expression> rangePredicate, TiTableInfo table, TiIndexInfo index) {
requireNonNull(pointPredicates, "pointPredicates is null");
requireNonNull(rangePredicate, "rangePredicate is null");
ImmutableList.Builder<IndexRange> builder = ImmutableList.builder();
IndexRangeSetBuilder indexRangeBuilder = new IndexRangeSetBuilder(table, index);
if (pointPredicates.size() != 0) {
List<Key> pointKeys = expressionToPoints(pointPredicates, table, index);
for (Key key : pointKeys) {
if (rangePredicate.isPresent()) {
Set<Range<TypedKey>> ranges = indexRangeBuilder.buildRange(rangePredicate.get()).asRanges();
for (Range<TypedKey> range : ranges) {
builder.add(new IndexRange(key, range));
}
} else {
// no predicates with point keys leads to empty range encoding
builder.add(new IndexRange(key, null));
}
}
} else {
if (rangePredicate.isPresent()) {
Set<Range<TypedKey>> ranges = indexRangeBuilder.buildRange(rangePredicate.get()).asRanges();
for (Range<TypedKey> range : ranges) {
builder.add(new IndexRange(null, range));
}
} else {
// no filter at all means full range
builder.add(new IndexRange(null, Range.all()));
}
}
return builder.build();
}
Aggregations