Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 21 additions & 5 deletions warp10/src/main/java/io/warp10/continuum/gts/GTSHelper.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2018-2025 SenX S.A.S.
// Copyright 2018-2026 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 Down Expand Up @@ -9402,16 +9402,21 @@ public static void labelsToString(StringBuilder sb, Map<String,String> labels, b
}

public static String buildSelector(GeoTimeSerie gts, boolean forSearch) {
return buildSelector(gts.getMetadata(), forSearch);
return buildSelector(gts.getMetadata(), forSearch, false);
}

public static String buildSelector(Metadata meta, boolean forSearch) {
return buildSelector(meta, forSearch, false);
}

/**
* Build a string representation of Metadata suitable for selection (via FIND/FETCH).
*
* @param metadata Metadata to represent
* @param forSearch Set to true if the result is for searching, in that case for empty values of labels, '~$' will be produced, otherwise '='
* @param searchSyntax Set to true to indicate that the label values may represent exact matches ('= ...') or regexp ('~....') and should be treated accordingly
*/
public static String buildSelector(Metadata metadata, boolean forSearch) {
public static String buildSelector(Metadata metadata, boolean forSearch, boolean hasRegexp) {
StringBuilder sb = new StringBuilder();

String name = metadata.getName();
Expand All @@ -9436,10 +9441,21 @@ public static String buildSelector(Metadata metadata, boolean forSearch) {
}
encodeName(sb, entry.getKey());
if (forSearch && !Constants.ABSENT_LABEL_SUPPORT && "".equals(entry.getValue())) {
// If missing labels are not supported, the match is on an empty content
sb.append("~$");
} else {
sb.append("=");
encodeName(sb, entry.getValue());
// If missing labels are supported, the selector is not a regular expression but
// an empty value which is interpreted as missing labels
if (hasRegexp && entry.getValue().startsWith("~")) {
sb.append(entry.getValue());
} else {
sb.append("=");
if (hasRegexp && entry.getValue().startsWith("=")) {
encodeName(sb, entry.getValue().substring(1));
} else {
encodeName(sb, entry.getValue());
}
}
}
first = false;
}
Expand Down
4 changes: 1 addition & 3 deletions warp10/src/main/java/io/warp10/leveldb/SSTFIND.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2018-2024 SenX S.A.S.
// Copyright 2018-2026 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 Down Expand Up @@ -136,8 +136,6 @@ public Object apply(WarpScriptStack stack) throws WarpScriptException {
metadata.setName(classSelector);
metadata.setLabels(labelSelectors);

String selector = GTSHelper.buildSelector(metadata, true);

//
// Check if we have a GTS list for the given selector
//
Expand Down
40 changes: 20 additions & 20 deletions warp10/src/main/java/io/warp10/script/filter/FilterByMetadata.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2018 SenX S.A.S.
// Copyright 2018-2026 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 Down Expand Up @@ -40,70 +40,70 @@
* Filter GTS by retaining those whose metadata is included in a set
*/
public class FilterByMetadata extends NamedWarpScriptFunction implements WarpScriptFilterFunction {

private final Set<Metadata> metadatas;

public static class Builder extends NamedWarpScriptFunction implements WarpScriptStackFunction {

public Builder(String name) {
super(name);
}

@Override
public Object apply(WarpScriptStack stack) throws WarpScriptException {
Object arg = stack.pop();

if (!(arg instanceof List)) {
throw new WarpScriptException(getName() + " expects a list of GTS on top of the stack.");
}

for (Object o: (List) arg) {
if (!(o instanceof GeoTimeSerie)) {
throw new WarpScriptException(getName() + " expects a list of GTS on top of the stack.");
}
}

stack.push(new FilterByMetadata(getName(), (List<GeoTimeSerie>) arg));
return stack;
}
}

public FilterByMetadata(String name, List<GeoTimeSerie> selector) {
super(name);

this.metadatas = new HashSet<Metadata>();

for (GeoTimeSerie gts: selector) {
this.metadatas.add(gts.getMetadata());
}
}
@Override

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

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

for (List<GeoTimeSerie> serie: series) {
for (GeoTimeSerie gts: serie) {
Metadata meta = gts.getMetadata();

if (this.metadatas.contains(meta)) {
retained.add(gts);
}
}
}
}

return retained;
}

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

sb.append(WarpScriptLib.LIST_START);
sb.append(" ");
for (Metadata metadata: this.metadatas) {
sb.append(StackUtils.toString(GTSHelper.buildSelector(metadata, false)));
sb.append(StackUtils.toString(GTSHelper.buildSelector(metadata, false, false)));
sb.append(" ");
sb.append(WarpScriptLib.PARSESELECTOR);
sb.append(" ");
Expand Down
13 changes: 9 additions & 4 deletions warp10/src/main/java/io/warp10/script/functions/FETCH.java
Original file line number Diff line number Diff line change
Expand Up @@ -355,7 +355,9 @@ public Object apply(WarpScriptStack stack) throws WarpScriptException {
tmeta.setLabels(tokenSelectors);

// Build a selector matching all classes
String tselector = "~.*" + GTSHelper.buildSelector(tmeta, true);
// Consider label values starting with '~' as regular expressions
String tselector = "~.*" + GTSHelper.buildSelector(tmeta, true, true);

MetadataSelectorMatcher matcher = new MetadataSelectorMatcher(tselector);

final List<Metadata> modifiedMetas = new ArrayList<Metadata>(metas.size());
Expand All @@ -364,7 +366,6 @@ public Object apply(WarpScriptStack stack) throws WarpScriptException {

// We clone the Metadata instance so the user cannot alter it
m = new Metadata(m);
modifiedMetas.add(m);

if (null == m.getLabels()) {
m.setLabels(new LinkedHashMap<String,String>());
Expand All @@ -384,10 +385,11 @@ public Object apply(WarpScriptStack stack) throws WarpScriptException {

//
// If the metadata would not get selected by the provided token
// because one of producer/owner/app is missing,
// force the producer/owner/app to be that of the token
//

if (!matches) {
if (!matches && (!m.getLabels().containsKey(Constants.PRODUCER_LABEL) || !m.getLabels().containsKey(Constants.OWNER_LABEL) || !m.getLabels().containsKey(Constants.APPLICATION_LABEL))) {
//
// We will now set producer/owner/application
//
Expand Down Expand Up @@ -426,6 +428,9 @@ public Object apply(WarpScriptStack stack) throws WarpScriptException {
} else {
throw new WarpScriptException(getName() + " provided token is incompatible with '" + PARAM_GTS + "' parameter, expecting a single producer and/or single owner.");
}
modifiedMetas.add(m);
} else if (matches) {
modifiedMetas.add(m);
}

// Recompute IDs
Expand Down Expand Up @@ -535,7 +540,7 @@ public void close() throws Exception {}
throw new WarpScriptException(getName() + " keys and values of label selector must be STRINGs.");
}
}

Map<String, String> labelSelectors = new LinkedHashMap<>((Map<String, String>) o);
labelSelectors.remove(Constants.PRODUCER_LABEL);
labelSelectors.remove(Constants.OWNER_LABEL);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright 2018 SenX S.A.S.
// Copyright 2018-2026 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 Down Expand Up @@ -37,7 +37,7 @@ public Object applyOnElement(Object element) throws WarpScriptException {
} else if (element instanceof GTSEncoder) {
Metadata meta = new Metadata(((GTSEncoder) element).getMetadata());

return GTSHelper.buildSelector(meta, true);
return GTSHelper.buildSelector(meta, true, false);
} else {
throw new WarpScriptException(getName() + " expects a GeoTimeSeries, a GTSEncoder or a list thereof on top of the stack.");
}
Expand Down