Эффективная структура данных для соответствия одному из списка регулярных выражений - PullRequest
0 голосов
/ 01 апреля 2019

У меня есть класс MyRegex

public class MyRegex {
    private Pattern pattern;
    private Map<String, Object> attributes;
    public MyRegex() {
        this.pattern = null;
        this.attributes = new HashMap<String, Object>();
    }
    public MyRegex(String regex) {
        this.pattern = Pattern.compile(regex);
        this.attributes = new HashMap<String, Object>();
    }
    public MyRegex withRegex(String regex) {
        this.pattern = Pattern.compile(regex);
        return this;
    }
    public void putAttribute(String attrName, Object attrValue) {
        attributes.put(attrName, attrValue);
    }
    public Map<String, Object> getAttributes() {
        return Collections.unmodifiableMap(attributes);
    }
    public Pattern getPattern() {
        return pattern;
    }
    public Matcher matcher(CharSequence str) {
        return pattern.matcher(str);
    }
}

И у меня есть этот класс:

public class MyRegexMeta {
    private String metaFileName;

    private List<MyRegex> attrModelList;

    public MyRegexMeta(String metaFileName) {
        this.metaFileName = metaFileName;
        loadConfig();
        startConfigLoader();
    }

    private void startConfigLoader() {
        new Thread(new ConfigLoader()).start();
        log.info("Config loader started");
    }

    private class ConfigLoader implements Runnable {
        public void run() {
            final int sleepSeconds = 7200;
            // load config periodically, so that the it's up to date.
            while (true) {
                try {
                    Thread.sleep(sleepSeconds * 1000);
                } catch (InterruptedException e) {
                    log.error("Failed to make loading thread to sleep. ", e);
                    continue;
                }
                loadConfig();
            }
        }
    }

    private void loadConfig() {
        // Read configuration from a file, and store in a list.
    }

    public void generateAttributes(String name, Map<String, Object> attrs) {
        List<MyRegex> tempModelList = attrModelList;
        Map<String, MyRegex> matched = new HashMap<String, MyRegex>();
        for (MyRegex model : tempModelList) {
            Matcher matcher = model.matcher(name);
            if (matcher.matches()) {
                for (String attrName : model.getAttributes().keySet()) {
                    matched.put(attrName, model);
                }
                attrs.putAll(model.getAttributes());
                continue;
            }
        }
    }
}

Этот код является частью службы, которая работает.Каждая строка моего текстового файла, который я прочитал в loadConfig, имеет регулярное выражение и набор атрибутов.Я вызываю generateAttributes, передающее имя, и Map для хранения атрибутов, которые соответствуют регулярному выражению, которое соответствует моему имени.

Я вызываю generateAttributes несколько раз в секунду, поэтому важно, чтобы он был быстрым.Кроме того, мои имена распределены неравномерно.Скажем, у меня есть 200 строк регулярных выражений в моем attrModelList.Возможно, 20 из этих строк будут соответствовать 70% имен, которые я передаю. Я знаю, что последовательный поиск соответствующего регулярного выражения будет O (n), но я бы хотел, чтобы средний регистр был лучше, чем O (n).

Как повысить эффективность этого кода в среднем случае?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...