![JAR search and dependency download from the Maven repository](/logo.png)
com.ringcentral.platform.metrics.infoProviders.MaskTreeMetricNamedInfoProvider Maven / Gradle / Ivy
package com.ringcentral.platform.metrics.infoProviders;
import com.ringcentral.platform.metrics.names.MetricName;
import com.ringcentral.platform.metrics.names.MetricNameMask;
import com.ringcentral.platform.metrics.names.MetricNamed;
import com.ringcentral.platform.metrics.predicates.CompositeMetricNamedPredicate;
import com.ringcentral.platform.metrics.predicates.DefaultMetricNamedPredicate;
import com.ringcentral.platform.metrics.predicates.MetricNamedPredicate;
import java.util.*;
import java.util.function.Predicate;
import static com.ringcentral.platform.metrics.names.MetricNameMask.ItemType.FIXED_PART;
import static com.ringcentral.platform.metrics.names.MetricNameMask.anyMetricNameMask;
import static com.ringcentral.platform.metrics.utils.Preconditions.checkState;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static java.util.Objects.requireNonNull;
public class MaskTreeMetricNamedInfoProvider implements PredicativeMetricNamedInfoProvider {
private int infoOrderNumSeq;
private final Node inRoot = new Node<>(null, null);
private final Node exRoot = new Node<>(null, null);
private final List> notMaskInEntries = new ArrayList<>();
private final List> notMaskExEntries = new ArrayList<>();
private final Map>> keyToEntries = new HashMap<>();
@Override
public MaskTreeMetricNamedInfoProvider addInfo(MetricNamedPredicate predicate, I info) {
return addInfo(null, predicate, info);
}
@Override
public MaskTreeMetricNamedInfoProvider addInfo(String key, MetricNamedPredicate predicate, I info) {
List> keyEntries;
if (key != null) {
if (keyToEntries.containsKey(key)) {
throw new IllegalArgumentException("Duplicate key " + key);
}
keyEntries = new ArrayList<>(predicate instanceof CompositeMetricNamedPredicate ? 4 : 1);
} else {
keyEntries = null;
}
MetricNamedPredicate p = requireNonNull(predicate);
if (p instanceof MetricNameMask) {
addMaskEntry(key, keyEntries, (MetricNameMask)p, null, info, nextInfoOrderNum(), true);
} else if (p instanceof DefaultMetricNamedPredicate) {
DefaultMetricNamedPredicate dp = (DefaultMetricNamedPredicate)p;
addMaskEntry(key, keyEntries, dp.nameMask(), dp.additionalPredicate(), info, nextInfoOrderNum(), true);
} else if (p instanceof CompositeMetricNamedPredicate) {
addEntries(key, keyEntries, (CompositeMetricNamedPredicate)p, info);
} else {
addNotMaskEntry(key, keyEntries, p, info, nextInfoOrderNum(), true);
}
if (key != null) {
keyToEntries.put(key, keyEntries);
}
return this;
}
private int nextInfoOrderNum() {
checkState(infoOrderNumSeq < Integer.MAX_VALUE, "Info count limit exceeded");
return ++infoOrderNumSeq;
}
private void addMaskEntry(
String key,
List> keyEntries,
MetricNameMask mask,
MetricNamedPredicate additionalPredicate,
I info,
int infoOrderNum,
boolean inclusion) {
int maskSize = mask.size();
Node node = inclusion ? inRoot : exRoot;
int i = 0;
while (i < maskSize && mask.item(i).type() == FIXED_PART) {
node = node.ensureChild(mask.item(i).fixedPart());
++i;
}
Entry entry;
if (i == maskSize) {
entry = new Entry<>(additionalPredicate, info, infoOrderNum, node, node.nameEntries);
node.nameEntries.add(entry);
} else if (i + 1 == maskSize) {
entry = new Entry<>(additionalPredicate, info, infoOrderNum, node, node.anyNameSuffixEntries);
node.anyNameSuffixEntries.add(entry);
} else {
MetricNameMask submask = mask.submask(i);
int i2 = i;
MetricNamedPredicate p =
additionalPredicate != null ?
n -> submask.matches(n.name(), i2) && additionalPredicate.matches(n) :
n -> submask.matches(n.name(), i2);
entry = new Entry<>(p, info, infoOrderNum, node, node.nameSuffixMaskEntries);
node.nameSuffixMaskEntries.add(entry);
}
if (key != null) {
keyEntries.add(entry);
}
}
private void addEntries(
String key,
List> keyEntries,
CompositeMetricNamedPredicate p,
I info) {
int infoOrderNum = nextInfoOrderNum();
if (p.hasInclusionPredicates()) {
for (MetricNamedPredicate inPredicate : p.inclusionPredicates()) {
if (inPredicate instanceof MetricNameMask) {
addMaskEntry(key, keyEntries, (MetricNameMask)inPredicate, null, info, infoOrderNum, true);
} else if (inPredicate instanceof DefaultMetricNamedPredicate) {
DefaultMetricNamedPredicate dp = (DefaultMetricNamedPredicate)inPredicate;
addMaskEntry(key, keyEntries, dp.nameMask(), dp.additionalPredicate(), info, infoOrderNum, true);
} else {
addNotMaskEntry(key, keyEntries, inPredicate, info, infoOrderNum, true);
}
}
} else {
addMaskEntry(key, keyEntries, anyMetricNameMask(), null, info, infoOrderNum, true);
}
if (p.hasExclusionPredicates()) {
for (MetricNamedPredicate exPredicate : p.exclusionPredicates()) {
if (exPredicate instanceof MetricNameMask) {
addMaskEntry(key, keyEntries, (MetricNameMask)exPredicate, null, info, infoOrderNum, false);
} else if (exPredicate instanceof DefaultMetricNamedPredicate) {
DefaultMetricNamedPredicate dp = (DefaultMetricNamedPredicate)exPredicate;
addMaskEntry(key, keyEntries, dp.nameMask(), dp.additionalPredicate(), info, infoOrderNum, false);
} else {
addNotMaskEntry(key, keyEntries, exPredicate, info, infoOrderNum, false);
}
}
}
}
private void addNotMaskEntry(
String key,
List> keyEntries,
MetricNamedPredicate p,
I info,
int infoOrderNum,
boolean inclusion) {
List> list = inclusion ? notMaskInEntries : notMaskExEntries;
Entry entry = new Entry<>(p, info, infoOrderNum, null, list);
list.add(entry);
if (key != null) {
keyEntries.add(entry);
}
}
@Override
public MaskTreeMetricNamedInfoProvider removeInfo(String key) {
List> entries = keyToEntries.remove(key);
if (entries != null) {
entries.forEach(e -> {
e.containingList.remove(e);
Node node = e.node;
while (node != null && node.parent != null && node.isEmpty()) {
node.parent.children.remove(node.namePart);
node = node.parent;
}
});
}
return this;
}
@Override
public PredicativeMetricNamedInfoProvider removeInfos(Predicate keyPredicate) {
new HashSet<>(keyToEntries.keySet()).stream().filter(keyPredicate).forEach(this::removeInfo);
return this;
}
@Override
public List infosFor(MetricNamed named) {
MetricName name = named.name();
int nameSize = name.size();
ResultBuilder resultBuilder = new ResultBuilder<>();
if (!notMaskInEntries.isEmpty()) {
for (Entry e : notMaskInEntries) {
if (e.predicate.matches(named)) {
resultBuilder.add(e);
}
}
}
Node node = inRoot;
for (int i = 0; node != null && i <= nameSize; ++i) {
if (i == nameSize) {
for (Entry e : node.nameEntries) {
if (!e.hasPredicate() || e.predicate.matches(named)) {
resultBuilder.add(e);
}
}
}
for (Entry e : node.anyNameSuffixEntries) {
if (!e.hasPredicate() || e.predicate.matches(named)) {
resultBuilder.add(e);
}
}
if (i < nameSize) {
for (Entry e : node.nameSuffixMaskEntries) {
if (e.predicate.matches(named)) {
resultBuilder.add(e);
}
}
node = node.child(name.part(i));
} else {
break;
}
}
if (!notMaskExEntries.isEmpty()) {
for (Entry e : notMaskExEntries) {
if (e.predicate.matches(named)) {
resultBuilder.remove(e.infoOrderNum);
}
}
}
node = exRoot;
for (int i = 0; node != null && i <= nameSize; ++i) {
if (i == nameSize) {
for (Entry e : node.nameEntries) {
if (!e.hasPredicate() || e.predicate.matches(named)) {
resultBuilder.remove(e.infoOrderNum);
}
}
}
for (Entry e : node.anyNameSuffixEntries) {
if (!e.hasPredicate() || e.predicate.matches(named)) {
resultBuilder.remove(e.infoOrderNum);
}
}
if (i < nameSize) {
for (Entry e : node.nameSuffixMaskEntries) {
if (e.predicate.matches(named)) {
resultBuilder.remove(e.infoOrderNum);
}
}
node = node.child(name.part(i));
} else {
break;
}
}
return resultBuilder.build();
}
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
private static class Entry {
final MetricNamedPredicate predicate;
final I info;
final Integer infoOrderNum;
final Node node;
final List> containingList;
Entry(
MetricNamedPredicate predicate,
I info,
Integer infoOrderNum,
Node node,
List> containingList) {
this.predicate = predicate;
this.info = info;
this.infoOrderNum = infoOrderNum;
this.node = node;
this.containingList = containingList;
}
boolean hasPredicate() {
return predicate != null;
}
}
private static class ResultBuilder {
private TreeMap infos;
void add(Entry entry) {
if (infos == null) {
infos = new TreeMap<>();
}
infos.put(entry.infoOrderNum, entry.info);
}
void remove(int infoOrderNum) {
if (infos != null) {
infos.remove(infoOrderNum);
}
}
List build() {
if (infos != null) {
return infos.size() == 1 ? singletonList(infos.firstEntry().getValue()) : new ArrayList<>(infos.values());
} else {
return emptyList();
}
}
}
private static class Node {
final List> nameEntries = new ArrayList<>(4);
final List> anyNameSuffixEntries = new ArrayList<>(4);
final List> nameSuffixMaskEntries = new ArrayList<>(4);
final Node parent;
final String namePart;
final Map> children = new HashMap<>();
Node(Node parent, String namePart) {
this.parent = parent;
this.namePart = namePart;
}
Node ensureChild(String childNamePart) {
return children.computeIfAbsent(childNamePart, p -> new Node<>(this, childNamePart));
}
Node child(String childNamePart) {
return children.get(childNamePart);
}
boolean isEmpty() {
return nameEntries.isEmpty()
&& anyNameSuffixEntries.isEmpty()
&& nameSuffixMaskEntries.isEmpty()
&& children.isEmpty();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy