in elastic-db-tools/src/main/java/com/microsoft/azure/elasticdb/shard/storeops/recovery/ReplaceMappingsGlobalOperation.java [140:231]
private List<StoreMapping> getMappingsToPurge(IStoreTransactionScope ts) {
// Find all the mappings in GSM belonging to the shard
StoreResults gsmMappingsByShard = ts.executeOperation(StoreOperationRequestBuilder.SP_GET_ALL_SHARD_MAPPINGS_GLOBAL,
StoreOperationRequestBuilder.getAllShardMappingsGlobal(shardMap, shard, null));
if (gsmMappingsByShard.getResult() != StoreResult.Success) {
// Possible errors are:
// StoreResult.ShardMapDoesNotExist
// StoreResult.StoreVersionMismatch
// StoreResult.MissingParametersForStoredProcedure
throw StoreOperationErrorHandler.onRecoveryErrorGlobal(gsmMappingsByShard, shardMap, shard, ShardManagementErrorCategory.Recovery,
this.getOperationName(), StoreOperationRequestBuilder.SP_GET_ALL_SHARD_MAPPINGS_GLOBAL);
}
Map<ShardRange, StoreMapping> intersectingMappings = new HashMap<>();
for (StoreMapping gsmMappingByShard : gsmMappingsByShard.getStoreMappings()) {
ShardKey min = ShardKey.fromRawValue(shardMap.getKeyType(), gsmMappingByShard.getMinValue());
ShardKey max;
switch (shardMap.getMapType()) {
case Range:
max = ShardKey.fromRawValue(shardMap.getKeyType(), gsmMappingByShard.getMaxValue());
break;
default:
assert shardMap.getMapType() == ShardMapType.List;
max = ShardKey.fromRawValue(shardMap.getKeyType(), gsmMappingByShard.getMinValue()).getNextKey();
break;
}
intersectingMappings.put(new ShardRange(min, max), gsmMappingByShard);
}
// We need to discover, also, the range of intersecting mappings, so we can transitively detect
// inconsistencies with other shards.
for (StoreMapping lsmMapping : mappingsToRemove) {
ShardKey min = ShardKey.fromRawValue(shardMap.getKeyType(), lsmMapping.getMinValue());
StoreResults gsmMappingsByRange;
switch (shardMap.getMapType()) {
case Range:
gsmMappingsByRange = ts.executeOperation(StoreOperationRequestBuilder.SP_GET_ALL_SHARD_MAPPINGS_GLOBAL,
StoreOperationRequestBuilder.getAllShardMappingsGlobal(shardMap, null,
new ShardRange(min, ShardKey.fromRawValue(shardMap.getKeyType(), lsmMapping.getMaxValue()))));
break;
default:
assert shardMap.getMapType() == ShardMapType.List;
gsmMappingsByRange = ts.executeOperation(StoreOperationRequestBuilder.SP_FIND_SHARD_MAPPING_BY_KEY_GLOBAL,
StoreOperationRequestBuilder.findShardMappingByKeyGlobal(shardMap, min));
break;
}
if (gsmMappingsByRange.getResult() != StoreResult.Success) {
if (gsmMappingsByRange.getResult() != StoreResult.MappingNotFoundForKey) {
// Possible errors are:
// StoreResult.ShardMapDoesNotExist
// StoreResult.StoreVersionMismatch
// StoreResult.MissingParametersForStoredProcedure
throw StoreOperationErrorHandler.onRecoveryErrorGlobal(gsmMappingsByRange, shardMap, shard, ShardManagementErrorCategory.Recovery,
this.getOperationName(),
shardMap.getMapType() == ShardMapType.Range ? StoreOperationRequestBuilder.SP_GET_ALL_SHARD_MAPPINGS_GLOBAL
: StoreOperationRequestBuilder.SP_FIND_SHARD_MAPPING_BY_KEY_GLOBAL);
}
else {
// No intersections being found is fine. Skip to the next mapping.
assert shardMap.getMapType() == ShardMapType.List;
}
}
else {
for (StoreMapping gsmMappingByRange : gsmMappingsByRange.getStoreMappings()) {
ShardKey minGlobal = ShardKey.fromRawValue(shardMap.getKeyType(), gsmMappingByRange.getMinValue());
ShardKey maxGlobal;
switch (shardMap.getMapType()) {
case Range:
maxGlobal = ShardKey.fromRawValue(shardMap.getKeyType(), gsmMappingByRange.getMaxValue());
break;
default:
assert shardMap.getMapType() == ShardMapType.List;
maxGlobal = ShardKey.fromRawValue(shardMap.getKeyType(), gsmMappingByRange.getMinValue()).getNextKey();
break;
}
intersectingMappings.put(new ShardRange(minGlobal, maxGlobal), gsmMappingByRange);
}
}
}
return new ArrayList<>(intersectingMappings.values());
}