private List getMappingsToPurge()

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());
    }