Skip to content

Commit

Permalink
Merge pull request #1358 from hbs/missingLabelsFix
Browse files Browse the repository at this point in the history
Missing labels fix
  • Loading branch information
hbs authored Jun 12, 2024
2 parents 0f0f2e7 + 44f91cb commit f49e648
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8954,7 +8954,7 @@ public static String buildSelector(Metadata metadata, boolean forSearch) {
sb.append(",");
}
encodeName(sb, entry.getKey());
if (forSearch && Constants.ABSENT_LABEL_SUPPORT && "".equals(entry.getValue())) {
if (forSearch && !Constants.ABSENT_LABEL_SUPPORT && "".equals(entry.getValue())) {
sb.append("~$");
} else {
sb.append("=");
Expand Down
85 changes: 51 additions & 34 deletions warp10/src/main/java/io/warp10/script/filter/FilterByLabels.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2018 SenX S.A.S.
// Copyright 2018-2024 SenX S.A.S.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
Expand All @@ -17,6 +17,7 @@
package io.warp10.script.filter;

import io.warp10.continuum.gts.GeoTimeSerie;
import io.warp10.continuum.store.Constants;
import io.warp10.script.NamedWarpScriptFunction;
import io.warp10.script.StackUtils;
import io.warp10.script.WarpScriptFilterFunction;
Expand All @@ -34,24 +35,24 @@
import java.util.regex.Pattern;

public class FilterByLabels extends NamedWarpScriptFunction implements WarpScriptFilterFunction {

private final Map<String,String> selParam;
private final Map<String,Pattern> selectors;

private final boolean checkLabels;
private final boolean checkAttributes;

public static class Builder extends NamedWarpScriptFunction implements WarpScriptStackFunction {

private final boolean checkLabels;
private final boolean checkAttributes;

public Builder(String name, boolean checkLabels, boolean checkAttribtues) {
super(name);
this.checkLabels = checkLabels;
this.checkAttributes = checkAttribtues;
}

@Override
public Object apply(WarpScriptStack stack) throws WarpScriptException {
Object arg = stack.pop();
Expand All @@ -64,64 +65,80 @@ public Object apply(WarpScriptStack stack) throws WarpScriptException {
}

public FilterByLabels(String name, Map<String,String> selectors, boolean checkLabels, boolean checkAttributes) {

super(name);

this.checkLabels = checkLabels;
this.checkAttributes = checkAttributes;

this.selParam = selectors;
this.selectors = new HashMap<String, Pattern>();

for (Entry<String,String> entry: selectors.entrySet()) {
String lname = entry.getKey();
String selector = entry.getValue();
Pattern pattern;

if (selector.startsWith("=")) {

if (Constants.ABSENT_LABEL_SUPPORT && ("".equals(selector) || "=".equals(selector))) {
pattern = null;
} else if (selector.startsWith("=")) {
pattern = Pattern.compile(Pattern.quote(selector.substring(1)));
} else if (selector.startsWith("~")) {
pattern = Pattern.compile(selector.substring(1));
} else {
pattern = Pattern.compile(Pattern.quote(selector));
}

this.selectors.put(lname, pattern);
}
}

@Override
public List<GeoTimeSerie> filter(Map<String,String> commonlabels, List<GeoTimeSerie>... series) throws WarpScriptException {

List<GeoTimeSerie> retained = new ArrayList<GeoTimeSerie>();

Map<String,Matcher> matchers = new HashMap<String,Matcher>();

for (Entry<String,Pattern> entry: this.selectors.entrySet()) {
matchers.put(entry.getKey(), entry.getValue().matcher(""));
if (null != entry.getValue()) {
matchers.put(entry.getKey(), entry.getValue().matcher(""));
} else {
matchers.put(entry.getKey(), null);
}
}

for (List<GeoTimeSerie> serie: series) {
for (GeoTimeSerie gts: serie) {

boolean matched = true;

Map<String,String> labels = gts.getMetadata().getLabels();
Map<String,String> labels = gts.getMetadata().getLabels();
Map<String,String> attributes = gts.getMetadata().getAttributes();

for (Map.Entry<String, Matcher> labelAndMatcher: matchers.entrySet()) {
String label = labelAndMatcher.getKey();
Matcher matcher = labelAndMatcher.getValue();

boolean hasLabel = false;


// If the selector is for a missing label/attribute but the GTS contains the label/attribute, skip it
if (null == matcher && Constants.ABSENT_LABEL_SUPPORT) {
if ((checkLabels && labels.containsKey(label)) || (checkAttributes && attributes.containsKey(label))) {
matched = false;
break;
} else {
continue;
}
}

// Check if labels or attributes contain the given key
if (checkLabels) {
if (labels.containsKey(label)) {
hasLabel = true;
}
}

// If the GTS does not have the named label, check if it has a named attribute
if (!hasLabel && checkAttributes) {
if (!attributes.containsKey(label)) {
Expand All @@ -130,7 +147,7 @@ public List<GeoTimeSerie> filter(Map<String,String> commonlabels, List<GeoTimeSe
} else {
matched = hasLabel;
}

if (!matched) {
break;
}
Expand All @@ -140,24 +157,24 @@ public List<GeoTimeSerie> filter(Map<String,String> commonlabels, List<GeoTimeSe
if (!matcher.reset(labels.get(label)).matches()) {
matched = false;
break;
}
}
} else { // Here, matched && !hasLabel, which can only happen if checkAttributes
if (!matcher.reset(attributes.get(label)).matches()) {
matched = false;
break;
}
}
}
}
}

if (matched) {
retained.add(gts);
}
}
}
}

return retained;
}

@Override
public String toString() {
StringBuilder sb = new StringBuilder();
Expand Down

0 comments on commit f49e648

Please sign in to comment.