Search in sources :

Example 6 with LindenValue

use of com.xiaomi.linden.thrift.common.LindenValue in project linden by XiaoMi.

the class LindenScoreModelStrategyBuilder method build.

public static LindenScoreModelStrategy build(String classHeaderFormat, String pluginPath, LindenScoreModel model, LindenSchema schema) throws Exception {
    if (model.isPlugin()) {
        if (pluginPath == null) {
            throw new Exception("Does not support plugin. Plugin path is null");
        }
        Class<?> clazz;
        if (model.isOverride()) {
            clazz = loadClass(pluginPath, model.getName());
        } else {
            clazz = pluginClassMap.get(model.getName());
            if (clazz != null) {
                return (LindenScoreModelStrategy) clazz.newInstance();
            } else {
                clazz = loadClass(pluginPath, model.getName());
            }
        }
        if (clazz != null) {
            pluginClassMap.put(model.getName(), clazz);
            return (LindenScoreModelStrategy) clazz.newInstance();
        } else {
            throw new Exception("Plugin " + model.getName() + " not found.");
        }
    }
    StringBuilder fingerPrintBuilder = new StringBuilder();
    for (int i = 0; i < model.getParamsSize(); ++i) {
        if (!model.getParams().get(i).isSetValue()) {
            continue;
        }
        fingerPrintBuilder.append(i);
        fingerPrintBuilder.append(model.getParams().get(i).getName());
        LindenValue value = model.getParams().get(i).getValue();
        String paramType = "";
        if (value.isSetStringValue()) {
            paramType = "String";
        } else if (value.isSetLongValue()) {
            paramType = "Long";
        } else if (value.isSetDoubleValue()) {
            paramType = "Double";
        } else if (value.isSetStringValues()) {
            paramType = "StringList";
        } else if (value.isSetLongValues()) {
            paramType = "LongList";
        } else if (value.isSetDoubleValues()) {
            paramType = "DoubleList";
        } else if (value.isSetMapValue()) {
            paramType = "Map";
        }
        fingerPrintBuilder.append(paramType);
    }
    fingerPrintBuilder.append(model.getFunc());
    long hash = fingerPrintBuilder.toString().hashCode();
    String className = "LSM" + Math.abs(hash);
    Class<?> clazz = compiledClassMap.get(className);
    if (clazz != null) {
        return (LindenScoreModelStrategy) clazz.newInstance();
    } else {
        if (failedClassMap.containsKey(className)) {
            throw new Exception("score model " + model.getName() + " compile failed, please check score model code");
        }
        StringWriter classBody = new StringWriter();
        PrintWriter classPrinter = new PrintWriter(classBody);
        String classHeader = String.format(classHeaderFormat, className);
        // header
        classPrinter.println(getImportHeader());
        classPrinter.println(classHeader + "{");
        // model method
        StringBuilder scoreBody = new StringBuilder();
        if (model.isSetParams() && !model.getParams().isEmpty()) {
            String scoreMethodParamCode = buildInputParamCode(model.params);
            scoreBody.append(scoreMethodParamCode);
        }
        scoreBody.append(model.getFunc());
        classPrinter.printf(SCORE_METHOD_FORMAT, scoreBody.toString());
        if (schema != null) {
            boolean hasId = false;
            for (LindenFieldSchema field : schema.getFields()) {
                if (field.getName().equals(schema.getId())) {
                    hasId = true;
                }
                String retType;
                if (field.isMulti()) {
                    switch(field.getType()) {
                        case INTEGER:
                            retType = "int[]";
                            break;
                        case LONG:
                            retType = "long[]";
                            break;
                        case FLOAT:
                            retType = "float[]";
                            break;
                        case DOUBLE:
                            retType = "double[]";
                            break;
                        case STRING:
                        case FACET:
                            retType = "String[]";
                            break;
                        default:
                            continue;
                    }
                } else {
                    switch(field.getType()) {
                        case INTEGER:
                            retType = "Integer";
                            break;
                        case LONG:
                            retType = "Long";
                            break;
                        case DOUBLE:
                            retType = "Double";
                            break;
                        case FLOAT:
                            retType = "Float";
                            break;
                        case STRING:
                        case FACET:
                            retType = "String";
                            break;
                        default:
                            continue;
                    }
                }
                classPrinter.printf("private FieldValues<%s> %s;\n", retType, field.getName());
                classPrinter.printf("public %s %s() throws IOException {\n" + "    if (%s == null) {\n" + "      %s = getFieldValues(\"%s\");\n" + "    }\n" + "    return %s.get();\n" + "  }\n", retType, field.getName(), field.getName(), field.getName(), field.getName(), field.getName());
            }
            // add id field, since id field may not be in schema.getFields()
            if (!hasId) {
                classPrinter.printf("private FieldValues<String> %s;\n", schema.getId());
                classPrinter.printf("public String %s() throws IOException {\n" + "    if (%s == null) {\n" + "      %s = getFieldValues(\"%s\");\n" + "    }\n" + "    return %s.get();\n" + "  }\n", schema.getId(), schema.getId(), schema.getId(), schema.getId(), schema.getId());
            }
            if (isDistanceMethodNeeded(schema)) {
                classPrinter.append(DISTANCE_METHOD);
            }
        }
        classPrinter.println("}");
        try {
            clazz = JavaCompilerHelper.createClass(className, classBody.toString());
        } catch (Exception e) {
            failedClassMap.put(className, e.getMessage());
            throw new Exception(Throwables.getStackTraceAsString(e) + "\n" + classBody.toString());
        }
        compiledClassMap.put(className, clazz);
        return (LindenScoreModelStrategy) clazz.newInstance();
    }
}
Also used : LindenValue(com.xiaomi.linden.thrift.common.LindenValue) LindenFieldSchema(com.xiaomi.linden.thrift.common.LindenFieldSchema) StringWriter(java.io.StringWriter) PrintWriter(java.io.PrintWriter)

Aggregations

LindenValue (com.xiaomi.linden.thrift.common.LindenValue)6 LindenInputParam (com.xiaomi.linden.thrift.common.LindenInputParam)5 LindenScoreModel (com.xiaomi.linden.thrift.common.LindenScoreModel)2 LindenSearchRequest (com.xiaomi.linden.thrift.common.LindenSearchRequest)2 Map (java.util.Map)2 Test (org.junit.Test)2 LindenFieldSchema (com.xiaomi.linden.thrift.common.LindenFieldSchema)1 LindenFlexibleQuery (com.xiaomi.linden.thrift.common.LindenFlexibleQuery)1 LindenSearchField (com.xiaomi.linden.thrift.common.LindenSearchField)1 LindenTerm (com.xiaomi.linden.thrift.common.LindenTerm)1 LindenType (com.xiaomi.linden.thrift.common.LindenType)1 PrintWriter (java.io.PrintWriter)1 StringWriter (java.io.StringWriter)1 AbstractMap (java.util.AbstractMap)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 List (java.util.List)1