forked from MapComplete/MapComplete
Add extra optimization on And, add test
This commit is contained in:
parent
2f3886d2e0
commit
819f65e18d
3 changed files with 97 additions and 55 deletions
|
|
@ -1,9 +1,12 @@
|
||||||
import {TagsFilter} from "./TagsFilter";
|
import {TagsFilter} from "./TagsFilter";
|
||||||
import {Or} from "./Or";
|
import {Or} from "./Or";
|
||||||
import {TagUtils} from "./TagUtils";
|
import {TagUtils} from "./TagUtils";
|
||||||
|
import {Tag} from "./Tag";
|
||||||
|
import {RegexTag} from "./RegexTag";
|
||||||
|
|
||||||
export class And extends TagsFilter {
|
export class And extends TagsFilter {
|
||||||
public and: TagsFilter[]
|
public and: TagsFilter[]
|
||||||
|
|
||||||
constructor(and: TagsFilter[]) {
|
constructor(and: TagsFilter[]) {
|
||||||
super();
|
super();
|
||||||
this.and = and
|
this.and = and
|
||||||
|
|
@ -235,6 +238,43 @@ export class And extends TagsFilter {
|
||||||
}
|
}
|
||||||
const optimized = <TagsFilter[]>optimizedRaw;
|
const optimized = <TagsFilter[]>optimizedRaw;
|
||||||
|
|
||||||
|
{
|
||||||
|
// Conflicting keys do return false
|
||||||
|
const properties: object = {}
|
||||||
|
for (const opt of optimized) {
|
||||||
|
if (opt instanceof Tag) {
|
||||||
|
properties[opt.key] = opt.value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const opt of optimized) {
|
||||||
|
if(opt instanceof Tag ){
|
||||||
|
const k = opt.key
|
||||||
|
const v = properties[k]
|
||||||
|
if(v === undefined){
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if(v !== opt.value){
|
||||||
|
// detected an internal conflict
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(opt instanceof RegexTag ){
|
||||||
|
const k = opt.key
|
||||||
|
if(typeof k !== "string"){
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const v = properties[k]
|
||||||
|
if(v === undefined){
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if(v !== opt.value){
|
||||||
|
// detected an internal conflict
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const newAnds: TagsFilter[] = []
|
const newAnds: TagsFilter[] = []
|
||||||
|
|
||||||
let containedOrs: Or[] = []
|
let containedOrs: Or[] = []
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ export class Tag extends TagsFilter {
|
||||||
if (shorten) {
|
if (shorten) {
|
||||||
v = Utils.EllipsesAfter(v, 25);
|
v = Utils.EllipsesAfter(v, 25);
|
||||||
}
|
}
|
||||||
if (v === "" || v === undefined) {
|
if (v === "" || v === undefined && currentProperties !== undefined) {
|
||||||
// This tag will be removed if in the properties, so we indicate this with special rendering
|
// This tag will be removed if in the properties, so we indicate this with special rendering
|
||||||
if (currentProperties !== undefined && (currentProperties[this.key] ?? "") === "") {
|
if (currentProperties !== undefined && (currentProperties[this.key] ?? "") === "") {
|
||||||
// This tag is not present in the current properties, so this tag doesn't change anything
|
// This tag is not present in the current properties, so this tag doesn't change anything
|
||||||
|
|
@ -122,10 +122,6 @@ export class Tag extends TagsFilter {
|
||||||
return [{k: this.key, v: this.value}];
|
return [{k: this.key, v: this.value}];
|
||||||
}
|
}
|
||||||
|
|
||||||
AsJson() {
|
|
||||||
return this.asHumanString(false, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
optimize(): TagsFilter | boolean {
|
optimize(): TagsFilter | boolean {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,12 @@ describe("Tag optimalization", () => {
|
||||||
expect(opt).eq(true)
|
expect(opt).eq(true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it("should return false on conflicting tags", () => {
|
||||||
|
const t = new And([new Tag("key","a"), new Tag("key","b")])
|
||||||
|
const opt = t.optimize()
|
||||||
|
expect(opt).eq(false)
|
||||||
|
})
|
||||||
|
|
||||||
it("with nested ors and common property should be extracted", () => {
|
it("with nested ors and common property should be extracted", () => {
|
||||||
|
|
||||||
// foo&bar & (x=y | a=b) & (x=y | c=d) & foo=bar is equivalent too foo=bar & ((x=y) | (a=b & c=d))
|
// foo&bar & (x=y | a=b) & (x=y | c=d) & foo=bar is equivalent too foo=bar & ((x=y) | (a=b & c=d))
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue