1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17import java.util.List;
18import java.util.ArrayList;
19import java.io.Serializable;
20
21/**
22 * An operation with a duration. Could represent a class load or initialization.
23 */
24class Operation implements Serializable {
25
26    private static final long serialVersionUID = 0;
27
28    /**
29     * Type of operation.
30     */
31    enum Type {
32        LOAD, INIT
33    }
34
35    /** Process this operation occurred in. */
36    final Proc process;
37
38    /** Start time for this operation. */
39    final long startTimeNanos;
40
41    /** Index of this operation relative to its process. */
42    final int index;
43
44    /** Type of operation. */
45    final Type type;
46
47    /** End time for this operation. */
48    long endTimeNanos = -1;
49
50    /** The class that this operation loaded or initialized. */
51    final LoadedClass loadedClass;
52
53    /** Other operations that occurred during this one. */
54    final List<Operation> subops = new ArrayList<Operation>();
55
56    /** Constructs a new operation. */
57    Operation(Proc process, LoadedClass loadedClass, long startTimeNanos,
58            int index, Type type) {
59        this.process = process;
60        this.loadedClass = loadedClass;
61        this.startTimeNanos = startTimeNanos;
62        this.index = index;
63        this.type = type;
64    }
65
66    /**
67     * Returns how long this class initialization and all the nested class
68     * initializations took.
69     */
70    private long inclusiveTimeNanos() {
71        if (endTimeNanos == -1) {
72            throw new IllegalStateException("End time hasn't been set yet: "
73                    + loadedClass.name);
74        }
75
76        return endTimeNanos - startTimeNanos;
77    }
78
79    /**
80     * Returns how long this class initialization took.
81     */
82    int exclusiveTimeMicros() {
83        long exclusive = inclusiveTimeNanos();
84
85        for (Operation child : subops) {
86            exclusive -= child.inclusiveTimeNanos();
87        }
88
89        if (exclusive < 0) {
90            throw new AssertionError(loadedClass.name);
91        }
92
93        return nanosToMicros(exclusive);
94    }
95
96    /** Gets the median time that this operation took across all processes. */
97    int medianExclusiveTimeMicros() {
98        switch (type) {
99            case LOAD: return loadedClass.medianLoadTimeMicros();
100            case INIT: return loadedClass.medianInitTimeMicros();
101            default: throw new AssertionError();
102        }
103    }
104
105    /**
106     * Converts nanoseconds to microseconds.
107     *
108     * @throws RuntimeException if overflow occurs
109     */
110    private static int nanosToMicros(long nanos) {
111        long micros = nanos / 1000;
112        int microsInt = (int) micros;
113        if (microsInt != micros) {
114            throw new RuntimeException("Integer overflow: " + nanos);
115        }
116        return microsInt;
117    }
118
119    /**
120     * Primarily for debugger support
121     */
122    @Override
123    public String toString() {
124        StringBuilder sb = new StringBuilder();
125        sb.append(type.toString());
126        sb.append(' ');
127        sb.append(loadedClass.toString());
128        if (subops.size() > 0) {
129            sb.append(" (");
130            sb.append(subops.size());
131            sb.append(" sub ops)");
132        }
133        return sb.toString();
134    }
135
136}
137