Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: f639e5cc3ce415a618049a31f3d8bc5bdd6877a9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
/*******************************************************************************
 * Copyright (c) 2006, 2017 IBM Corporation and others.
 *
 * This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License 2.0
 * which accompanies this distribution, and is available at
 * https://www.eclipse.org/legal/epl-2.0/
 *
 * SPDX-License-Identifier: EPL-2.0
 *
 * Contributors:
 * IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.team.internal.core.subscribers;

import java.util.*;

import org.eclipse.team.core.diff.IDiff;
import org.eclipse.team.core.diff.IThreeWayDiff;
import org.eclipse.team.core.synchronize.SyncInfo;

public class DiffTreeStatistics {
	/**
	 * {Integer sync kind -> Long number of infos with that sync kind in this sync set}
	 */
	protected Map<Integer, Long> stats = Collections.synchronizedMap(new HashMap<>());

	/**
	 * Count this sync state.
	 * @param state the state
	 */
	public void add(int state) {
		// update statistics
		Long count = stats.get(Integer.valueOf(state));
		if(count == null) {
			count = Long.valueOf(0);
		}
		stats.put(Integer.valueOf(state), Long.valueOf(count.longValue() + 1));
	}

	/**
	 * Remove this sync kind.
	 * @param state the info type to remove
	 */
	public void remove(int state) {
		// update stats
		Integer kind = Integer.valueOf(state);
		Long count = stats.get(kind);
		if(count == null) {
			// error condition, shouldn't be removing if we haven't added yet
			// programmer error calling remove before add.
		} else {
			long newCount = count.intValue() - 1;
			if(newCount > 0) {
				stats.put(kind, Long.valueOf(newCount));
			} else {
				stats.remove(kind);
			}
		}
	}

	/**
	 * Return the count of sync infos for the specified sync kind. A mask can be used to accumulate
	 * counts for specific directions or change types.
	 * To return the number of outgoing changes:
	 * 	long outgoingChanges = stats.countFor(SyncInfo.OUTGOING, SyncInfo.DIRECTION_MASK);
	 *
	 * @param state the sync kind for which to return the count
	 * @param mask the mask applied to the stored sync kind
	 * @return the number of sync info types added for the specific kind
	 */
	public long countFor(int state, int mask) {
		if(mask == 0) {
			Long count = stats.get(Integer.valueOf(state));
			return count == null ? 0 : count.longValue();
		} else {
			Set keySet = stats.keySet();
			long count = 0;
			synchronized (stats) {
				Iterator it = keySet.iterator();
				while (it.hasNext()) {
					Integer key = (Integer) it.next();
					if((key.intValue() & mask) == state) {
						count += stats.get(key).intValue();
					}
				}
			}
			return count;
		}
	}

	/**
	 * Clear the statistics counts. All calls to countFor() will return 0 until new
	 * sync infos are added.
	 */
	public void clear() {
		stats.clear();
	}

	/**
	 * For debugging
	 */
	@Override
	public String toString() {
		StringBuilder out = new StringBuilder();
		Iterator it = stats.keySet().iterator();
		while (it.hasNext()) {
			Integer kind = (Integer) it.next();
			out.append(SyncInfo.kindToString(kind.intValue()) + ": " + stats.get(kind) + "\n"); //$NON-NLS-1$ //$NON-NLS-2$
		}
		return out.toString();
	}

	public void add(IDiff delta) {
		int state = getState(delta);
		add(state);
	}

	public void remove(IDiff delta) {
		int state = getState(delta);
		remove(state);
	}

	private int getState(IDiff delta) {
		int state = delta.getKind();
		if (delta instanceof IThreeWayDiff) {
			IThreeWayDiff twd = (IThreeWayDiff) delta;
			state |= twd.getDirection();
		}
		return state;
	}
}

Back to the top