public ProfileAnalyzation analyze(final List<SegmentProfileAnalyzeQuery> queries) throws IOException {
        ProfileAnalyzation analyzation = new ProfileAnalyzation();

        // query sequence range list
        SequenceSearch sequenceSearch = getAllSequenceRange(queries);
        if (sequenceSearch == null) {
            analyzation.setTip("Data not found");
            return analyzation;
        }
        if (sequenceSearch.getTotalSequenceCount() > analyzeSnapshotMaxSize) {
            analyzation.setTip("Out of snapshot analyze limit, " + sequenceSearch.getTotalSequenceCount() + " snapshots found, but analysis first " + analyzeSnapshotMaxSize + " snapshots only.");
        }

        // query snapshots
        List<ProfileStack> stacks = sequenceSearch.getRanges().parallelStream().map(r -> {
            try {
                return getProfileThreadSnapshotQueryDAO().queryRecords(r.getSegmentId(), r.getMinSequence(), r.getMaxSequence());
            } catch (IOException e) {
                LOGGER.warn(e.getMessage(), e);
                return Collections.<ProfileThreadSnapshotRecord>emptyList();
            }
        }).flatMap(Collection::stream).map(ProfileStack::deserialize).distinct().collect(Collectors.toList());

        // analyze
        final List<ProfileStackTree> trees = analyzeByStack(stacks);
        if (trees != null) {
            analyzation.getTrees().addAll(trees);
        }

        return analyzation;
    }
@Test
    public void testAnalyze() throws IOException {
        ProfileStackAnalyzeHolder holder = loadYaml("thread-snapshot.yml", ProfileStackAnalyzeHolder.class);

        for (ProfileStackAnalyze analyze : holder.getList()) {
            analyze.analyzeAndAssert(MAX_ANALYZE_COUNT);
        }
    }