CounterImpl.java
1/*******************************************************************************
2 * Copyright (c) 2009 Mountainminds GmbH & Co. KG and others
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Marc R. Hoffmann - initial API and implementation
10 *
11 * $Id: $
12 *******************************************************************************/
13package org.jacoco.core.analysis;
14
15/**
16 * {@link ICounter} implementations. Implementing a factory pattern allows to
17 * share counter instances.
18 *
19 * @author Marc R. Hoffmann
20 * @version $Revision: $
21 */
22public abstract class CounterImpl extends AbstractCounter {
23
24 /** Max counter value for which singletons are created */
25 private static final int SINGLETON_LIMIT = 10;
26
27 private static final CounterImpl[][] SINGLETONS = new CounterImpl[SINGLETON_LIMIT + 1][];
28
29 static {
30 for (int i = 0; i <= SINGLETON_LIMIT; i++) {
31 SINGLETONS[i] = new CounterImpl[i + 1];
32 for (int j = 0; j <= i; j++) {
33 SINGLETONS[i][j] = new Fix(i, j);
34 }
35 }
36 }
37
38 /** Constant for Counter with 0/0 values. */
39 public static final CounterImpl COUNTER_0_0 = SINGLETONS[0][0];
40
41 /**
42 * Mutable version of the counter.
43 */
44 private static class Var extends CounterImpl {
45 public Var(final int total, final int covered) {
46 super(total, covered);
47 }
48
49 @Override
50 public CounterImpl increment(final ICounter counter) {
51 this.total += counter.getTotalCount();
52 this.covered += counter.getCoveredCount();
53 return this;
54 }
55 }
56
57 /**
58 * Immutable version of the counter.
59 */
60 private static class Fix extends CounterImpl {
61 public Fix(final int total, final int covered) {
62 super(total, covered);
63 }
64
65 @Override
66 public CounterImpl increment(final ICounter counter) {
67 return getInstance(this.total + counter.getTotalCount(),
68 this.covered + counter.getCoveredCount());
69 }
70 }
71
72 /**
73 * Factory method to retrieve a counter with the given number of items.
74 *
75 * @param total
76 * total number of items
77 * @param covered
78 * covered number of items
79 * @return counter instance
80 */
81 public static CounterImpl getInstance(final int total, final int covered) {
82 if (total <= SINGLETON_LIMIT && covered <= total) {
83 return SINGLETONS[total][covered];
84 } else {
85 return new Var(total, covered);
86 }
87 }
88
89 /**
90 * Factory method to retrieve a clone ot the given counter.
91 *
92 * @param counter
93 * counter to copy
94 * @return counter instance
95 */
96 public static CounterImpl getInstance(final ICounter counter) {
97 return getInstance(counter.getTotalCount(), counter.getCoveredCount());
98 }
99
100 /**
101 * Factory method to retrieve a counter with the given number of items.
102 *
103 * @param total
104 * total number of items
105 * @param covered
106 * <code>true</code>, if all items are covered
107 * @return counter instance
108 */
109 public static CounterImpl getInstance(final int total, final boolean covered) {
110 return getInstance(total, covered ? total : 0);
111 }
112
113 /**
114 * Factory method to retrieve a counter for a single item.
115 *
116 * @param covered
117 * <code>true</code>, if the item is covered
118 * @return counter instance
119 */
120 public static CounterImpl getInstance(final boolean covered) {
121 return getInstance(1, covered ? 1 : 0);
122 }
123
124 /**
125 * Creates a new instance with the given figures.
126 *
127 * @param total
128 * total number of items
129 * @param covered
130 * covered number of items
131 */
132 protected CounterImpl(final int total, final int covered) {
133 super(total, covered);
134 }
135
136 /**
137 * Returns a counter with values incremented by the numbers of the given
138 * counter. It is up to the implementation whether this counter instance is
139 * modified or a new instance is returned.
140 *
141 * @param counter
142 * number of additional total and covered items
143 * @return counter instance with incremented values
144 */
145 public abstract CounterImpl increment(final ICounter counter);
146
147}