blob: d855dc079571c7083c427cb2da07bdabebf39b8b [file] [log] [blame]
Paul Duffine2363012015-11-30 16:20:41 +00001/*
2 * Copyright (C) 2013 Google Inc.
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 */
16package com.google.caliper.worker;
17
18import com.google.common.base.Joiner;
19import com.google.common.base.Objects;
20import com.google.common.collect.ImmutableList;
21import com.google.common.collect.Interner;
22import com.google.common.collect.Interners;
23
24import java.util.Collection;
25import java.util.List;
26
27/**
28 * Data about a particular allocation performed by a benchmark. This tracks a human readable
29 * description of the allocation (e.g. 'int[23]', 'java.lang.Integer', or 'java.util.ArrayList'),
30 * the total size of the allocation in bytes and the location, which is a stringified stack trace of
31 * the allocation.
32 */
33final class Allocation {
34 // While particular lists of STEs can have a lot of variety within a benchmark there don't tend
35 // to be many individually unique STEs. This can save a lot of memory.
36 // Within a benchmark the code paths should be fairly uniform so it should be safe to just store
37 // these forever.
38 private static final Interner<StackTraceElement> steInterner = Interners.newWeakInterner();
39 private static final Interner<String> descriptionInterner = Interners.newWeakInterner();
40
41 /** Returns the sum of the {@link #size sizes} of the allocations. */
42 static long getTotalSize(Collection<Allocation> allocations) {
43 long totalSize = 0;
44 for (Allocation allocation : allocations) {
45 totalSize += allocation.size;
46 }
47 return totalSize;
48 }
49
50 private final String description;
51 private final long size;
52 private final ImmutableList<StackTraceElement> location;
53
54 Allocation(String description, long size, List<StackTraceElement> location) {
55 this.description = descriptionInterner.intern(description);
56 this.size = size;
57 ImmutableList.Builder<StackTraceElement> locationBuilder = ImmutableList.builder();
58 for (StackTraceElement ste : location) {
59 locationBuilder.add(steInterner.intern(ste));
60 }
61 this.location = locationBuilder.build();
62 }
63
64 @Override public boolean equals(Object obj) {
65 if (obj instanceof Allocation) {
66 Allocation other = (Allocation) obj;
67 return other.description.equals(description)
68 && other.size == size
69 && other.location.equals(location);
70
71 }
72 return false;
73 }
74
75 public String getDescription() {
76 return description;
77 }
78
79 public long getSize() {
80 return size;
81 }
82
83 @Override public int hashCode() {
84 return Objects.hashCode(description, size, location);
85 }
86
87 @Override public String toString() {
88 StringBuilder builder = new StringBuilder();
89 builder.append(description).append(" (").append(size).append(" bytes)\n\tat ");
90 Joiner.on("\n\tat ").appendTo(builder, location);
91 return builder.toString();
92 }
93}