default ResolvedFunction getResolvedFunction(boolean isThreadSafe) { return new ResolvedFunction( getFunctionObject(), isThreadSafe, null, null, null, null ); }
default <T> List<DataMapper<T>> getDataMappers(String spec) { List<ResolvedFunction> resolvedFunctions1 = this.resolveFunctions(spec); return resolvedFunctions1.stream().map( r -> DataMapperFunctionMapper.<T>map(r.getFunctionObject())).collect(Collectors.toList()); }
sb.append(libraryName).append("::"); sb.append(getArgType().getSimpleName()).append("->"); sb.append(getMethod().getDeclaringClass().getName()); sb.append("->").append(getResultClass().getName());
@Override public int compare(ResolvedFunction o1, ResolvedFunction o2) { ValueType iv1 = ValueType.valueOfAssignableClass(o1.getArgType()); ValueType iv2 = ValueType.valueOfAssignableClass(o2.getArgType()); int inputComparison = iv1.compareTo(iv2); if (inputComparison != 0) { return inputComparison; } iv1 = ValueType.valueOfAssignableClass(o1.getResultClass()); iv2 = ValueType.valueOfAssignableClass(o2.getResultClass()); return iv1.compareTo(iv2); } }
inputTypes.peekFirst().add(nodeFunction.getFunctionType().getInputValueType()); boolean isThreadSafe = true; for (ResolvedFunction resolvedFunction : flattenedFuncs) { assembly.andThen(resolvedFunction.getFunctionObject()); if (!resolvedFunction.isThreadSafe()) { isThreadSafe = false;
for (ResolvedFunction resolvedFunction : flattenedFuncs) { try { Object functionObject = resolvedFunction.getFunctionObject(); assembly.andThen(functionObject); if (!resolvedFunction.isThreadSafe()) { isThreadSafe = false;
private Set<Class<?>> getInputs(List<ResolvedFunction> nextFuncs) { Set<Class<?>> inputs = new HashSet<>(); for (ResolvedFunction nextFunc : nextFuncs) { inputs.add(nextFunc.getArgType()); } return inputs; }
private Set<Class<?>> getOutputs(List<ResolvedFunction> prevFuncs) { Set<Class<?>> outputs = new HashSet<>(); for (ResolvedFunction func : prevFuncs) { outputs.add(func.getResultClass()); } return outputs; }
private void removeNonLongFunctions(List<ResolvedFunction> funcs) { List<ResolvedFunction> toRemove = new LinkedList<>(); for (ResolvedFunction func : funcs) { if (func.getFunctionType().getInputValueType() != ValueType.LONG) { toRemove.add(func); } } if (toRemove.size() > 0 && toRemove.size() == funcs.size()) { throw new RuntimeException("removeNonLongFunctions would remove all functions: " + funcs); } funcs.removeAll(toRemove); }
if (!compatibleInputs.contains(nextfunc.getInputClass())) { toremove.add(nextfunc);
private Set<Class<?>> getInputs(List<ResolvedFunction> nextFuncs) { Set<Class<?>> inputs = new HashSet<>(); for (ResolvedFunction nextFunc : nextFuncs) { inputs.add(nextFunc.getArgType()); } return inputs; }
private Set<Class<?>> getOutputs(List<ResolvedFunction> prevFuncs) { Set<Class<?>> outputs = new HashSet<>(); for (ResolvedFunction func : prevFuncs) { outputs.add(func.getResultClass()); } return outputs; }
private void removeNonLongFunctions(List<ResolvedFunction> funcs) { List<ResolvedFunction> toRemove = new LinkedList<>(); for (ResolvedFunction func : funcs) { if (func.getFunctionType().getInputValueType() != ValueType.LONG) { toRemove.add(func); } } if (toRemove.size() > 0 && toRemove.size() == funcs.size()) { throw new RuntimeException("removeNonLongFunctions would remove all functions: " + funcs); } funcs.removeAll(toRemove); }
default ResolvedFunction getResolvedFunction(boolean isThreadSafe) { return new ResolvedFunction(getFunctionObject(), isThreadSafe); }
/** * Provide a way to promote a long function into a data mapper. * * @param spec a binding spec * @return An optional data mapper */ default <T> Optional<DataMapper<T>> getDataMapper(String spec) { List<ResolvedFunction> resolvedFunctions = this.resolveFunctions(spec); switch (resolvedFunctions.size()) { case 0: return Optional.empty(); case 1: return Optional.of(DataMapperFunctionMapper.<T>map(resolvedFunctions.get(0).getFunctionObject())); default: throw new RuntimeException( "Found " + resolvedFunctions.size() + " data mapping functions, expected exactly one for library-level function lookups." + " This may require both an input and an output type qualifier like 'int -> f() -> int'." + " \nFound: [<library name>::] input->class->output [initializer type->parameter type,...]: \n" + resolvedFunctions.stream().map(String::valueOf).collect(Collectors.joining("\n"))); } }
/** * If there are direct type matches between the inner func and the outer func, then remove all * other outer funcs except the ones with direct matches. * * @param prevFuncs The list of candidate inner functions * @param nextFuncs The list of candidate outer functions * @return count of items removed */ private int reduceByDirectTypes(List<ResolvedFunction> prevFuncs, List<ResolvedFunction> nextFuncs) { int progressed = 0; // Rule 1: If there are direct type matches, remove extraneous next funcs Set<Class<?>> outputs = getOutputs(prevFuncs); Set<Class<?>> inputs = getInputs(nextFuncs); Set<Class<?>> directMatches = inputs.stream().filter(outputs::contains).collect(Collectors.toCollection(HashSet::new)); if (directMatches.size() > 0) { List<ResolvedFunction> toremove = new ArrayList<>(); for (ResolvedFunction nextFunc : nextFuncs) { if (!directMatches.contains(nextFunc.getArgType())) { String logmsg = "BY-DIRECT-TYPE removing next func: " + nextFunc + " because its input types are not satisfied by any previous func"; logger.trace(logmsg); toremove.add(nextFunc); progressed++; } } nextFuncs.removeAll(toremove); } return progressed; }
private int reduceByResultType(List<ResolvedFunction> endFuncs, ValueType resultType) { int progressed = 0; LinkedList<ResolvedFunction> tmpList = new LinkedList<>(endFuncs); for (ResolvedFunction endFunc : tmpList) { if (!resultType.getValueClass().isAssignableFrom(endFunc.getResultClass())) { endFuncs.remove(endFunc); logger.trace("removed function '" + endFunc + "' because it does not yield type " + resultType); progressed++; } } if (endFuncs.size() == 0) { throw new RuntimeException("No end funcs were found which yield result type " + resultType); } return progressed; }
default ResolvedFunction getResolvedFunction() { return new ResolvedFunction(getFunctionObject(), getFunctionObject().getClass().getAnnotation(ThreadSafeMapper.class) != null ); }
@SuppressWarnings("unchecked") default <T> DataMapper<T> getDataMapper(String spec, Class<? extends T> clazz) { if (!canParseSpec(spec)) { return null; } Optional<ResolvedFunction> resolvedFunction = resolveFunction(spec); if (!resolvedFunction.isPresent()) { return null; } ResolvedFunction rf = resolvedFunction.get(); DataMapper<Object> dm = DataMapperFunctionMapper.map(rf.getFunctionObject()); return (DataMapper<T>) dm; }
/** * If there are direct type matches between the inner func and the outer func, then remove all * other outer funcs except the ones with direct matches. * * @param prevFuncs The list of candidate inner functions * @param nextFuncs The list of candidate outer functions * @return count of items removed */ private int reduceByDirectTypes(List<ResolvedFunction> prevFuncs, List<ResolvedFunction> nextFuncs) { int progressed = 0; // Rule 1: If there are direct type matches, remove extraneous next funcs Set<Class<?>> outputs = getOutputs(prevFuncs); Set<Class<?>> inputs = getInputs(nextFuncs); Sets.SetView<Class<?>> directMatches = Sets.intersection(inputs, outputs); if (directMatches.size() > 0) { List<ResolvedFunction> toremove = new ArrayList<>(); for (ResolvedFunction nextFunc : nextFuncs) { if (!directMatches.contains(nextFunc.getArgType())) { logger.debug("removing next func: " + nextFunc + " because its input types are not satisfied by an previous func"); toremove.add(nextFunc); progressed++; } } nextFuncs.removeAll(toremove); } return progressed; }