in elastic-db-tools/src/main/java/com/microsoft/azure/elasticdb/shard/recovery/MappingComparisonUtils.java [46:303]
public static ArrayList<MappingComparisonResult> compareRangeMappings(StoreShardMap ssm,
List<StoreMapping> gsmMappings,
List<StoreMapping> lsmMappings) {
// The below ordering was included so that comparison will give proper results.
// Need to verify if this has any adverse effect.
Comparator<StoreMapping> smc = (o1,
o2) -> SignedBytes.lexicographicalComparator().compare(o1.getMinValue(), o2.getMinValue());
gsmMappings.sort(smc);
lsmMappings.sort(smc);
// Detect if these are point mappings and call the ComparePointMappings function below.
ArrayList<MappingComparisonResult> result = new ArrayList<>();
// Identify the type of keys.
ShardKeyType keyType = ssm.getKeyType();
ReferenceObjectHelper<StoreMapping> refGsmMappingCurrent = new ReferenceObjectHelper<>(null);
ReferenceObjectHelper<ShardRange> refGsmRangeCurrent = new ReferenceObjectHelper<>(null);
ReferenceObjectHelper<ShardKey> refGsmMinKeyCurrent = new ReferenceObjectHelper<>(null);
Iterator<StoreMapping> gsmMappingIterator = gsmMappings.iterator();
moveToNextMapping(gsmMappingIterator, keyType, refGsmMappingCurrent, refGsmRangeCurrent, refGsmMinKeyCurrent);
StoreMapping gsmMappingCurrent = refGsmMappingCurrent.argValue;
ShardRange gsmRangeCurrent = refGsmRangeCurrent.argValue;
ShardKey gsmMinKeyCurrent = refGsmMinKeyCurrent.argValue;
ReferenceObjectHelper<StoreMapping> refLsmMappingCurrent = new ReferenceObjectHelper<>(null);
ReferenceObjectHelper<ShardRange> refLsmRangeCurrent = new ReferenceObjectHelper<>(null);
ReferenceObjectHelper<ShardKey> refLsmMinKeyCurrent = new ReferenceObjectHelper<>(null);
Iterator<StoreMapping> lsmMappingIterator = lsmMappings.iterator();
moveToNextMapping(lsmMappingIterator, keyType, refLsmMappingCurrent, refLsmRangeCurrent, refLsmMinKeyCurrent);
StoreMapping lsmMappingCurrent = refLsmMappingCurrent.argValue;
ShardRange lsmRangeCurrent = refLsmRangeCurrent.argValue;
ShardKey lsmMinKeyCurrent = refLsmMinKeyCurrent.argValue;
while (gsmMinKeyCurrent != null) {
// If there is something in LSM, consider the following 6 possibilities.
if (lsmMinKeyCurrent != null) {
if (ShardKey.opLessThanOrEqual(lsmMinKeyCurrent, gsmMinKeyCurrent)) {
// Case 1. LSM starts to the left of or exactly at GSM.
if (ShardKey.opLessThanOrEqual(lsmRangeCurrent.getHigh(), gsmMinKeyCurrent)) {
// Case 1.1: LSM is entirely to the left of Left.
// Add the LSM only entry.
result.add(new MappingComparisonResult(ssm, new ShardRange(lsmMinKeyCurrent, lsmRangeCurrent.getHigh()),
MappingLocation.MappingInShardOnly, null, lsmMappingCurrent));
// LSM range exhausted for current iteration.
ReferenceObjectHelper<StoreMapping> refLsmMappingCurrent2 = new ReferenceObjectHelper<>(lsmMappingCurrent);
ReferenceObjectHelper<ShardRange> refLsmRangeCurrent2 = new ReferenceObjectHelper<>(lsmRangeCurrent);
ReferenceObjectHelper<ShardKey> refLsmMinKeyCurrent2 = new ReferenceObjectHelper<>(lsmMinKeyCurrent);
moveToNextMapping(lsmMappingIterator, keyType, refLsmMappingCurrent2, refLsmRangeCurrent2, refLsmMinKeyCurrent2);
lsmMinKeyCurrent = refLsmMinKeyCurrent2.argValue;
lsmRangeCurrent = refLsmRangeCurrent2.argValue;
lsmMappingCurrent = refLsmMappingCurrent2.argValue;
}
else {
if (ShardKey.opLessThanOrEqual(lsmRangeCurrent.getHigh(), gsmRangeCurrent.getHigh())) {
// Case 1.2: LSM overlaps with GSM,
// with extra values to the left and finishing before GSM.
if (!(lsmMinKeyCurrent.equals(gsmMinKeyCurrent))) {
// Add the LSM only entry.
result.add(new MappingComparisonResult(ssm, new ShardRange(lsmMinKeyCurrent, gsmMinKeyCurrent),
MappingLocation.MappingInShardOnly, null, lsmMappingCurrent));
}
// Add common entry.
result.add(new MappingComparisonResult(ssm, new ShardRange(gsmMinKeyCurrent, lsmRangeCurrent.getHigh()),
MappingLocation.MappingInShardMapAndShard, gsmMappingCurrent, lsmMappingCurrent));
gsmMinKeyCurrent = lsmRangeCurrent.getHigh();
// LSM range exhausted for current iteration.
ReferenceObjectHelper<StoreMapping> refLsmMappingCurrent3 = new ReferenceObjectHelper<>(lsmMappingCurrent);
ReferenceObjectHelper<ShardRange> refLsmRangeCurrent3 = new ReferenceObjectHelper<>(lsmRangeCurrent);
ReferenceObjectHelper<ShardKey> refLsmMinKeyCurrent3 = new ReferenceObjectHelper<>(lsmMinKeyCurrent);
moveToNextMapping(lsmMappingIterator, keyType, refLsmMappingCurrent3, refLsmRangeCurrent3, refLsmMinKeyCurrent3);
lsmMinKeyCurrent = refLsmMinKeyCurrent3.argValue;
lsmRangeCurrent = refLsmRangeCurrent3.argValue;
lsmMappingCurrent = refLsmMappingCurrent3.argValue;
// Detect if GSM range exhausted for current iteration.
if (gsmMinKeyCurrent.equals(gsmRangeCurrent.getHigh())) {
ReferenceObjectHelper<StoreMapping> refGsmMappingCurrent2 = new ReferenceObjectHelper<>(gsmMappingCurrent);
ReferenceObjectHelper<ShardRange> refGsmRangeCurrent2 = new ReferenceObjectHelper<>(gsmRangeCurrent);
ReferenceObjectHelper<ShardKey> refGsmMinKeyCurrent2 = new ReferenceObjectHelper<>(gsmMinKeyCurrent);
moveToNextMapping(gsmMappingIterator, keyType, refGsmMappingCurrent2, refGsmRangeCurrent2, refGsmMinKeyCurrent2);
gsmMinKeyCurrent = refGsmMinKeyCurrent2.argValue;
gsmRangeCurrent = refGsmRangeCurrent2.argValue;
gsmMappingCurrent = refGsmMappingCurrent2.argValue;
}
}
else { // lsmRangeCurrent.getHigh() > gsmRangeCurrent.getHigh()
// Case 1.3: LSM encompasses GSM.
// Add the LSM only entry.
if (!(lsmMinKeyCurrent.equals(gsmMinKeyCurrent))) {
result.add(new MappingComparisonResult(ssm, new ShardRange(lsmMinKeyCurrent, gsmMinKeyCurrent),
MappingLocation.MappingInShardOnly, null, lsmMappingCurrent));
}
// Add common entry.
result.add(new MappingComparisonResult(ssm, new ShardRange(gsmMinKeyCurrent, gsmRangeCurrent.getHigh()),
MappingLocation.MappingInShardMapAndShard, gsmMappingCurrent, lsmMappingCurrent));
lsmMinKeyCurrent = gsmRangeCurrent.getHigh();
// GSM range exhausted for current iteration.
ReferenceObjectHelper<StoreMapping> refGsmMappingCurrent3 = new ReferenceObjectHelper<>(gsmMappingCurrent);
ReferenceObjectHelper<ShardRange> refGsmRangeCurrent3 = new ReferenceObjectHelper<>(gsmRangeCurrent);
ReferenceObjectHelper<ShardKey> refGsmMinKeyCurrent3 = new ReferenceObjectHelper<>(gsmMinKeyCurrent);
moveToNextMapping(gsmMappingIterator, keyType, refGsmMappingCurrent3, refGsmRangeCurrent3, refGsmMinKeyCurrent3);
gsmMinKeyCurrent = refGsmMinKeyCurrent3.argValue;
gsmRangeCurrent = refGsmRangeCurrent3.argValue;
gsmMappingCurrent = refGsmMappingCurrent3.argValue;
}
}
}
else {
// Case 2. LSM starts to the right of GSM.
if (ShardKey.opLessThanOrEqual(lsmRangeCurrent.getHigh(), gsmRangeCurrent.getHigh())) {
// Case 2.1: GSM encompasses LSM.
// Debug.Assert(lsmMinKeyCurrent != gsmMinKeyCurrent,
// "Must have been handled by Case 1.3");
// Add the GSM only entry.
result.add(new MappingComparisonResult(ssm, new ShardRange(gsmMinKeyCurrent, lsmMinKeyCurrent),
MappingLocation.MappingInShardMapOnly, gsmMappingCurrent, null));
gsmMinKeyCurrent = lsmRangeCurrent.getLow();
// Add common entry.
result.add(new MappingComparisonResult(ssm, new ShardRange(gsmMinKeyCurrent, gsmRangeCurrent.getHigh()),
MappingLocation.MappingInShardMapAndShard, gsmMappingCurrent, lsmMappingCurrent));
gsmMinKeyCurrent = lsmRangeCurrent.getHigh();
// LSM range exhausted for current iteration.
ReferenceObjectHelper<StoreMapping> refLsmMappingCurrent4 = new ReferenceObjectHelper<>(lsmMappingCurrent);
ReferenceObjectHelper<ShardRange> refLsmRangeCurrent4 = new ReferenceObjectHelper<>(lsmRangeCurrent);
ReferenceObjectHelper<ShardKey> refLsmMinKeyCurrent4 = new ReferenceObjectHelper<>(lsmMinKeyCurrent);
moveToNextMapping(lsmMappingIterator, keyType, refLsmMappingCurrent4, refLsmRangeCurrent4, refLsmMinKeyCurrent4);
lsmMinKeyCurrent = refLsmMinKeyCurrent4.argValue;
lsmRangeCurrent = refLsmRangeCurrent4.argValue;
lsmMappingCurrent = refLsmMappingCurrent4.argValue;
// Detect if GSM range exhausted for current iteration.
if (gsmMinKeyCurrent.equals(gsmRangeCurrent.getHigh())) {
ReferenceObjectHelper<StoreMapping> refGsmMappingCurrent4 = new ReferenceObjectHelper<>(gsmMappingCurrent);
ReferenceObjectHelper<ShardRange> refGsmRangeCurrent4 = new ReferenceObjectHelper<>(gsmRangeCurrent);
ReferenceObjectHelper<ShardKey> refGsmMinKeyCurrent4 = new ReferenceObjectHelper<>(gsmMinKeyCurrent);
moveToNextMapping(gsmMappingIterator, keyType, refGsmMappingCurrent4, refGsmRangeCurrent4, refGsmMinKeyCurrent4);
gsmMinKeyCurrent = refGsmMinKeyCurrent4.argValue;
gsmRangeCurrent = refGsmRangeCurrent4.argValue;
gsmMappingCurrent = refGsmMappingCurrent4.argValue;
}
}
else {
if (ShardKey.opLessThan(lsmRangeCurrent.getLow(), gsmRangeCurrent.getHigh())) {
// Case 2.2: LSM overlaps with GSM,
// with extra values to the right and finishing after GSM.
// Debug.Assert(lsmMinKeyCurrent != gsmMinKeyCurrent,
// "Must have been handled by Case 1.3");
// Add the GSM only entry.
result.add(new MappingComparisonResult(ssm, new ShardRange(gsmMinKeyCurrent, lsmMinKeyCurrent),
MappingLocation.MappingInShardMapOnly, gsmMappingCurrent, null));
// Add common entry.
result.add(new MappingComparisonResult(ssm, new ShardRange(lsmMinKeyCurrent, gsmRangeCurrent.getHigh()),
MappingLocation.MappingInShardMapAndShard, gsmMappingCurrent, lsmMappingCurrent));
lsmMinKeyCurrent = gsmRangeCurrent.getHigh();
// GSM range exhausted for current iteration.
ReferenceObjectHelper<StoreMapping> refGsmMappingCurrent5 = new ReferenceObjectHelper<>(gsmMappingCurrent);
ReferenceObjectHelper<ShardRange> refGsmRangeCurrent5 = new ReferenceObjectHelper<>(gsmRangeCurrent);
ReferenceObjectHelper<ShardKey> refGsmMinKeyCurrent5 = new ReferenceObjectHelper<>(gsmMinKeyCurrent);
moveToNextMapping(gsmMappingIterator, keyType, refGsmMappingCurrent5, refGsmRangeCurrent5, refGsmMinKeyCurrent5);
gsmMinKeyCurrent = refGsmMinKeyCurrent5.argValue;
gsmRangeCurrent = refGsmRangeCurrent5.argValue;
gsmMappingCurrent = refGsmMappingCurrent5.argValue;
}
else { // lsmRangeCurrent.getLow() >= gsmRangeCurrent.getHigh()
// Case 2.3: LSM is entirely to the right of GSM.
// Add the GSM only entry.
result.add(new MappingComparisonResult(ssm, new ShardRange(gsmMinKeyCurrent, gsmRangeCurrent.getHigh()),
MappingLocation.MappingInShardMapOnly, gsmMappingCurrent, null));
// GSM range exhausted for current iteration.
ReferenceObjectHelper<StoreMapping> refGsmMappingCurrent6 = new ReferenceObjectHelper<>(gsmMappingCurrent);
ReferenceObjectHelper<ShardRange> refGsmRangeCurrent6 = new ReferenceObjectHelper<>(gsmRangeCurrent);
ReferenceObjectHelper<ShardKey> refGsmMinKeyCurrent6 = new ReferenceObjectHelper<>(gsmMinKeyCurrent);
moveToNextMapping(gsmMappingIterator, keyType, refGsmMappingCurrent6, refGsmRangeCurrent6, refGsmMinKeyCurrent6);
gsmMinKeyCurrent = refGsmMinKeyCurrent6.argValue;
gsmRangeCurrent = refGsmRangeCurrent6.argValue;
gsmMappingCurrent = refGsmMappingCurrent6.argValue;
}
}
}
}
else {
// Nothing in LSM, we just keep going over the GSM entries.
// Add the GSM only entry.
result.add(new MappingComparisonResult(ssm, new ShardRange(gsmMinKeyCurrent, gsmRangeCurrent.getHigh()),
MappingLocation.MappingInShardMapOnly, gsmMappingCurrent, null));
// GSM range exhausted for current iteration.
ReferenceObjectHelper<StoreMapping> refGsmMappingCurrent7 = new ReferenceObjectHelper<>(gsmMappingCurrent);
ReferenceObjectHelper<ShardRange> refGsmRangeCurrent7 = new ReferenceObjectHelper<>(gsmRangeCurrent);
ReferenceObjectHelper<ShardKey> refGsmMinKeyCurrent7 = new ReferenceObjectHelper<>(gsmMinKeyCurrent);
moveToNextMapping(gsmMappingIterator, keyType, refGsmMappingCurrent7, refGsmRangeCurrent7, refGsmMinKeyCurrent7);
gsmMinKeyCurrent = refGsmMinKeyCurrent7.argValue;
gsmRangeCurrent = refGsmRangeCurrent7.argValue;
gsmMappingCurrent = refGsmMappingCurrent7.argValue;
}
}
// Go over the partial remainder of LSM entry if any.
if (lsmRangeCurrent != null && ShardKey.opGreaterThan(lsmMinKeyCurrent, lsmRangeCurrent.getLow())) {
// Add the LSM only entry.
result.add(new MappingComparisonResult(ssm, new ShardRange(lsmMinKeyCurrent, lsmRangeCurrent.getHigh()),
MappingLocation.MappingInShardOnly, null, lsmMappingCurrent));
// LSM range exhausted for current iteration.
ReferenceObjectHelper<StoreMapping> refLsmMappingCurrent5 = new ReferenceObjectHelper<>(lsmMappingCurrent);
ReferenceObjectHelper<ShardRange> refLsmRangeCurrent5 = new ReferenceObjectHelper<>(lsmRangeCurrent);
ReferenceObjectHelper<ShardKey> refLsmMinKeyCurrent5 = new ReferenceObjectHelper<>(lsmMinKeyCurrent);
moveToNextMapping(lsmMappingIterator, keyType, refLsmMappingCurrent5, refLsmRangeCurrent5, refLsmMinKeyCurrent5);
lsmMinKeyCurrent = refLsmMinKeyCurrent5.argValue;
lsmRangeCurrent = refLsmRangeCurrent5.argValue;
lsmMappingCurrent = refLsmMappingCurrent5.argValue;
}
// Go over remaining Right entries if any which have no matches on Left.
while (lsmMappingCurrent != null) {
// Add the LSM only entry.
result.add(new MappingComparisonResult(ssm, lsmRangeCurrent, MappingLocation.MappingInShardOnly, null, lsmMappingCurrent));
// LSM range exhausted for current iteration.
ReferenceObjectHelper<StoreMapping> refLsmMappingCurrent6 = new ReferenceObjectHelper<>(lsmMappingCurrent);
ReferenceObjectHelper<ShardRange> refLsmRangeCurrent6 = new ReferenceObjectHelper<>(lsmRangeCurrent);
ReferenceObjectHelper<ShardKey> refLsmMinKeyCurrent6 = new ReferenceObjectHelper<>(lsmMinKeyCurrent);
moveToNextMapping(lsmMappingIterator, keyType, refLsmMappingCurrent6, refLsmRangeCurrent6, refLsmMinKeyCurrent6);
lsmMinKeyCurrent = refLsmMinKeyCurrent6.argValue;
lsmRangeCurrent = refLsmRangeCurrent6.argValue;
lsmMappingCurrent = refLsmMappingCurrent6.argValue;
}
return result;
}