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
|
/*
* Copyright 2017, OpenCensus Authors
*
* 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 io.opencensus.tags;
import java.util.HashMap;
import java.util.Iterator;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
/**
* A map from {@link TagKey} to {@link TagValue} that can be used to label anything that is
* associated with a specific operation.
*
* <p>For example, {@code TagContext}s can be used to label stats, log messages, or debugging
* information.
*
* @since 0.8
*/
@Immutable
public abstract class TagContext {
/**
* Returns an iterator over the tags in this {@code TagContext}.
*
* @return an iterator over the tags in this {@code TagContext}.
* @since 0.8
*/
// This method is protected to prevent client code from accessing the tags of any TagContext. We
// don't currently support efficient access to tags. However, every TagContext subclass needs to
// provide access to its tags to the stats and tagging implementations by implementing this
// method. If we decide to support access to tags in the future, we can add a public iterator()
// method and implement it for all subclasses by calling getIterator().
//
// The stats and tagging implementations can access any TagContext's tags through
// io.opencensus.tags.InternalUtils.getTags, which calls this method.
protected abstract Iterator<Tag> getIterator();
@Override
public String toString() {
return "TagContext";
}
/**
* Returns true iff the other object is an instance of {@code TagContext} and contains the same
* key-value pairs. Implementations are free to override this method to provide better
* performance.
*/
@Override
public boolean equals(@Nullable Object other) {
if (!(other instanceof TagContext)) {
return false;
}
TagContext otherTags = (TagContext) other;
Iterator<Tag> iter1 = getIterator();
Iterator<Tag> iter2 = otherTags.getIterator();
HashMap<Tag, Integer> tags = new HashMap<Tag, Integer>();
while (iter1 != null && iter1.hasNext()) {
Tag tag = iter1.next();
if (tags.containsKey(tag)) {
tags.put(tag, tags.get(tag) + 1);
} else {
tags.put(tag, 1);
}
}
while (iter2 != null && iter2.hasNext()) {
Tag tag = iter2.next();
if (!tags.containsKey(tag)) {
return false;
}
int count = tags.get(tag);
if (count > 1) {
tags.put(tag, count - 1);
} else {
tags.remove(tag);
}
}
return tags.isEmpty();
}
@Override
public final int hashCode() {
int hashCode = 0;
Iterator<Tag> i = getIterator();
if (i == null) {
return hashCode;
}
while (i.hasNext()) {
Tag tag = i.next();
if (tag != null) {
hashCode += tag.hashCode();
}
}
return hashCode;
}
}
|