All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.hundsun.lightdb.unisql.golang.Transformer Maven / Gradle / Ivy

package com.hundsun.lightdb.unisql.golang;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.hundsun.lightdb.unisql.model.UnisqlProperties;
import jnr.ffi.Pointer;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.StandardCharsets;
import java.util.concurrent.TimeUnit;

@Slf4j
public class Transformer {

    public static final String PARSE_ERROR = "PARSE ERROR";

    public static final String RESTORE_ERROR = "RESTORE ERROR";

    private static final String ignoreTrans = "/*skipTransform*/";

    private static final Cache sqlCache;

    static {
        final UnisqlProperties properties = UnisqlProperties.getInstance();
        final long maxSize = properties.getCacheMaximumSize();
        final long expireSeconds = properties.getCacheExpireSeconds();
        final boolean debug = properties.isDebug();

        sqlCache = Caffeine.newBuilder()
                .maximumSize(maxSize)
                .expireAfterWrite(expireSeconds, TimeUnit.SECONDS)
                .removalListener((key, value, cause) -> {
                    if (debug) {
                        log.debug("[LTSQL][sqlCache] {} is removed from sqlCache, cause: {}", key, cause);
                    }
                })
                .build();

        // 初始化 gogc 与 gomemlimit 参数
        IGoParser parser = GoParserFactory.getGoParser();

        // 如果程序配置了 GOGC ,则忽略参数配置
        if (properties.isEnvironmentGOGCNotSet()) {
            long gogc = properties.getGOGC();
            try {
                parser.SetGoGc(gogc);
            } catch (Exception ignore) {
                // 不强制要求一定成功,为兼容以前版本的 so
            }
        }

        // 如果程序配置了 GOMEMLIMIT ,则忽略参数配置
        if (properties.isEnvironmentGOMEMLIMITNotSet()) {
            long gomemlimit = properties.getGOMEMLIMIT();
            // gomenlimit 是以字节为单位的,我们约定我们的配置项以 MB 为单位,是为了避免配置过于不直观
            try {
                parser.SetGoMemLimit(gomemlimit * 1024 * 1024);
            } catch (Exception ignore) {
                // 不强制要求一定成功,为兼容以前版本的 so
            }
        }
    }

    public static String parse(String sql, String source, String target) {
        if (sql.startsWith(ignoreTrans)) {
            return sql.substring(ignoreTrans.length());
        }

        return parseUseCache(sql, source, target, true);
    }

    public static String parseUseCache(String sql, String source, String target, boolean useCache) {
        IGoParser parser = GoParserFactory.getGoParser();
        String cacheKey = "";
        if (useCache) {
            cacheKey = source + ":" + target + ":" + sql;
            String cacheSql = sqlCache.getIfPresent(cacheKey);
            if (cacheSql != null) {
                return cacheSql;
            }
        }

        Pointer p4 = parser.Transform(sql, source, target);
        try {
            String utf8 = p4.getString(0, Integer.MAX_VALUE, StandardCharsets.UTF_8);
            if (useCache) {
                sqlCache.put(cacheKey, utf8);
            }
            return utf8;
        } finally {
            parser.FreePointer(p4);
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy