/* * Copyright 2016 NAVER Corp. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.navercorp.pinpoint.web.calltree.span; import java.util.List; import java.util.Stack; /** * @author jaehong.kim */ public class CallTreeFactory { private static final int INTERNAL = 0; private static final int REMOTE = 1; private static final int ASYNC = 2; private static final int END = 3; private final Stack<CallStackMock> callStacks = new Stack<CallStackMock>(); private int nextAsyncId = 0; public CallTree get(List<String> events) { int prevDepth = 0; for (String event : events) { int depth = event.length() - 1; int type = INTERNAL; if (event.startsWith("R")) { type = REMOTE; } else if (event.startsWith("A")) { type = ASYNC; } else if (event.startsWith("E")) { type = END; } if (callStacks.empty() && type == REMOTE) { callStacks.push(new CallStackMock()); continue; } if (prevDepth < depth) { push(type); } else { for (int i = depth; i <= prevDepth; i++) { pop(); } push(type); } prevDepth = depth; } while(callStacks.size() > 1) { pop(); } final CallStackMock callStack = callStacks.pop(); while (!callStack.empty()) { callStack.pop(); } callStacks.clear(); return callStack.close(); } private void push(int type) { if (type == REMOTE) { callStacks.push(new CallStackMock()); CallStackMock callStack = callStacks.peek(); } else if (type == ASYNC) { final int asyncId = nextAsyncId++; CallStackMock callStack = callStacks.peek(); callStack.peek().setNextAsyncId(asyncId); // add async span CallStackMock asyncCallStack = new CallStackMock(true, asyncId); callStacks.push(asyncCallStack); asyncCallStack.push(); } else { CallStackMock callStack = callStacks.peek(); callStack.push(); } } private void pop() { CallStackMock callStack = callStacks.peek(); if (callStack.empty()) { if (callStacks.size() > 1) { callStacks.pop(); callStacks.peek().append(callStack.close()); } } else { callStack.pop(); } } }