-
Notifications
You must be signed in to change notification settings - Fork 362
Expand file tree
/
Copy pathBaseHash.java
More file actions
99 lines (84 loc) · 3.31 KB
/
Copy pathBaseHash.java
File metadata and controls
99 lines (84 loc) · 3.31 KB
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
package datadog.trace.api;
import datadog.trace.util.FNV64Hash;
public final class BaseHash {
private static volatile long baseHash;
private static volatile String baseHashStr;
private static volatile String lastContainerTagsHash;
// 0 means "not yet computed". service/env/primaryTag are fixed for the JVM's lifetime once
// Config is built, so this only needs to be calculated once, lazily, on first read - computing
// it eagerly in a field initializer would risk capturing a premature Config snapshot if this
// class gets loaded (e.g. via DataStreamsTags.EMPTY) before Config settles.
private static volatile long identityHash;
private BaseHash() {}
public static void recalcBaseHash(String containerTagsHash) {
lastContainerTagsHash = containerTagsHash;
recalc();
}
static void recalcBaseHash() {
recalc();
}
private static void recalc() {
updateBaseHash(calc(lastContainerTagsHash));
}
public static void updateBaseHash(long hash) {
baseHash = hash;
baseHashStr = Long.toString(hash);
}
public static long getBaseHash() {
return baseHash;
}
public static String getBaseHashStr() {
return baseHashStr;
}
/**
* DSM topology-identity hash: service + env + primary tag only. Unlike {@link #getBaseHash()}
* (which also folds in process tags and the agent-reported container-tags hash for DBM's
* per-container SQL attribution use case), this is stable across pod restarts / rolling deploys,
* so it's safe to use as the seed for DSM's cardinality-sensitive pathway hash.
*/
public static long getIdentityHash() {
if (identityHash == 0) {
// Deliberately unsynchronized: concurrent callers all recompute from the same Config, so a
// race just means a few redundant, identical writes rather than a correctness issue.
identityHash =
calcIdentity(
Config.get().getServiceName(), Config.get().getEnv(), Config.get().getPrimaryTag());
}
return identityHash;
}
/** Test-only: lets tests set the identity hash without going through {@link Config}. */
public static void updateIdentityHash(long hash) {
identityHash = hash;
}
public static long calc(String containerTagsHash) {
return calc(
Config.get().getServiceName(),
Config.get().getEnv(),
Config.get().getPrimaryTag(),
ProcessTags.getTagsForSerialization(),
containerTagsHash);
}
static long calcIdentity(CharSequence serviceName, CharSequence env, String primaryTag) {
long hash = FNV64Hash.generateHash(serviceName.toString(), FNV64Hash.Version.v1);
hash = FNV64Hash.continueHash(hash, env.toString(), FNV64Hash.Version.v1);
if (primaryTag != null) {
hash = FNV64Hash.continueHash(hash, primaryTag, FNV64Hash.Version.v1);
}
return hash;
}
private static long calc(
CharSequence serviceName,
CharSequence env,
String primaryTag,
CharSequence processTags,
String containerTagsHash) {
long hash = calcIdentity(serviceName, env, primaryTag);
if (processTags != null) {
hash = FNV64Hash.continueHash(hash, processTags.toString(), FNV64Hash.Version.v1);
if (containerTagsHash != null && !containerTagsHash.isEmpty()) {
hash = FNV64Hash.continueHash(hash, containerTagsHash, FNV64Hash.Version.v1);
}
}
return hash;
}
}