/** Get the actions metadata by actions */ public Map<Action, ActionDefinition> getActionMetadataByAction(final List<Action> actions) { final Map<Action, ActionDefinition> actionToMetadata = new HashMap<>(actions.size()); for (final Action action : actions) { final ActionDefinition actionMetadata = actionRegistry.get(action.getName()); actionToMetadata.put(action, actionMetadata); } return actionToMetadata; }
public ActionsProfile profile( final List<ColumnMetadata> columns, final List<Action> actions, final Map<Action, ActionDefinition> actionToMetadata) { final Map<Action, ActionDefinition> metadataByAction = actionToMetadata == null ? getActionMetadataByAction(actions) : actionToMetadata; // Compile actions final Set<String> originalColumns = columns.stream().map(ColumnMetadata::getId).collect(toSet()); final Set<String> valueModifiedColumns = new HashSet<>(); final Set<String> metadataModifiedColumns = new HashSet<>(); int createColumnActions = 0; for (final Action action : actions) { final ActionDefinition actionMetadata = actionRegistry.get(action.getName()); metadataByAction.put(action, actionMetadata); } // Analyze what columns to look at during analysis for (Map.Entry<Action, ActionDefinition> entry : metadataByAction.entrySet()) { final ActionDefinition actionMetadata = entry.getValue(); final Action action = entry.getKey(); Set<ActionDefinition.Behavior> behavior = actionMetadata.getBehavior(); for (ActionDefinition.Behavior currentBehavior : behavior) { switch (currentBehavior) { case VALUES_ALL: // All values are going to be changed, and all original columns are going to be // modified. valueModifiedColumns.addAll(originalColumns); break; case METADATA_CHANGE_TYPE: valueModifiedColumns.add(action.getParameters().get(COLUMN_ID.getKey())); metadataModifiedColumns.add(action.getParameters().get(COLUMN_ID.getKey())); break; case VALUES_COLUMN: valueModifiedColumns.add(action.getParameters().get(COLUMN_ID.getKey())); break; case VALUES_MULTIPLE_COLUMNS: // Add the action's source column valueModifiedColumns.add(action.getParameters().get(COLUMN_ID.getKey())); // ... then add all column parameter (COLUMN_ID is string, not column) final List<Parameter> parameters = actionMetadata.getParameters(); valueModifiedColumns.addAll( parameters .stream() // .filter( parameter -> ParameterType.valueOf(parameter.getType().toUpperCase()) == ParameterType.COLUMN) // .map(parameter -> action.getParameters().get(parameter.getName())) // .collect(Collectors.toList())); break; case METADATA_COPY_COLUMNS: case METADATA_CREATE_COLUMNS: createColumnActions++; break; case METADATA_DELETE_COLUMNS: case METADATA_CHANGE_NAME: // Do nothing: no need to re-analyze where only name was changed. break; default: break; } } } // when values are modified, we need to do a full analysis (schema + invalid + stats) boolean needFullAnalysis = !valueModifiedColumns.isEmpty() || createColumnActions > 0; // when only metadata is modified, we need to re-evaluate the invalids entries boolean needOnlyInvalidAnalysis = !needFullAnalysis && !metadataModifiedColumns.isEmpty(); // only the columns with modified values or new columns need the schema + stats analysis Predicate<ColumnMetadata> filterForFullAnalysis = c -> valueModifiedColumns.contains(c.getId()) || !originalColumns.contains(c.getId()); // only the columns with metadata change or value changes need to re-evaluate invalids Predicate<ColumnMetadata> filterForInvalidAnalysis = filterForFullAnalysis.or(c -> metadataModifiedColumns.contains(c.getId())); Predicate<ColumnMetadata> filterForPatternAnalysis = filterForFullAnalysis.or(c -> metadataModifiedColumns.contains(c.getId())); return new ActionsProfile( needFullAnalysis, needOnlyInvalidAnalysis, filterForFullAnalysis, filterForInvalidAnalysis, filterForPatternAnalysis); }