public void addPattern(String pattern) {
        final List<String> tokens = splitByCharacter(pattern);

        PatternToken current = null;
        for (final PatternToken patternToken : roots) {
            if (patternToken.isMatch(tokens.get(0))) {
                current = patternToken;
                break;
            }
        }

        if (current == null) {
            current = new StringToken(tokens.get(0));
            roots.add(current);
        }

        if (tokens.size() == 1) {
            current.setExpression(pattern);
            return;
        }

        for (int i = 1; i < tokens.size(); i++) {
            final String token = tokens.get(i);
            PatternToken newToken;
            if (VarToken.VAR_TOKEN.equals(token)) {
                newToken = new VarToken();
            } else {
                newToken = new StringToken(token);
            }
            final PatternToken found = current.find(newToken);
            if (found == null) {
                current = current.add(newToken);
            } else {
                current = found;
            }
        }
        current.setExpression(pattern);
    }
The pattern is split by /, and each token is a node in the tree. Each node either a literal string or "{var}"
representing a variable.

@param pattern of URIs
oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/config/group/uri/quickmatch/PatternTree.java