From 6cccdb21dd9a0b45d6eb934c5972707008b65478 Mon Sep 17 00:00:00 2001
From: Michael Zangl <michael.zangl@student.kit.edu>
Date: Mon, 20 Jul 2015 14:17:19 +0200
Subject: [PATCH 2/4] Added a new MapCSS performance test for the rule index.

---
 .../mapcss/MapCSSStyleSourceFilterTest.java        | 146 +++++++++++++++++++++
 1 file changed, 146 insertions(+)
 create mode 100644 test/performance/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSourceFilterTest.java

diff --git a/test/performance/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSourceFilterTest.java b/test/performance/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSourceFilterTest.java
new file mode 100644
index 0000000..8b28279
--- /dev/null
+++ b/test/performance/org/openstreetmap/josm/gui/mappaint/mapcss/MapCSSStyleSourceFilterTest.java
@@ -0,0 +1,146 @@
+// License: GPL. For details, see LICENSE file.
+package org.openstreetmap.josm.gui.mappaint.mapcss;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.openstreetmap.josm.JOSMFixture;
+import org.openstreetmap.josm.PerformanceTestUtils;
+import org.openstreetmap.josm.PerformanceTestUtils.PerformanceTestTimer;
+import org.openstreetmap.josm.data.osm.OsmDataGenerator;
+import org.openstreetmap.josm.data.osm.OsmDataGenerator.KeyValueDataGenerator;
+import org.openstreetmap.josm.gui.mappaint.MultiCascade;
+
+/**
+ * Tests how fast {@link MapCSSStyleSource} finds the right style candidates for one object.
+ * @author Michael Zangl
+ */
+public class MapCSSStyleSourceFilterTest {
+
+    private static final int TEST_RULE_COUNT = 10000;
+
+    private class CssGenerator {
+        StringBuilder sb = new StringBuilder();
+        private KeyValueDataGenerator generator;
+
+        /**
+         * Create a new CSS generator.
+         * @param generator A generator to get the keys from.
+         */
+        public CssGenerator(KeyValueDataGenerator generator) {
+            this.generator = generator;
+        }
+
+        private CssGenerator addKeyValueRules(int count) {
+            for (int i = 0; i < count; i++) {
+                String key = generator.randomKey();
+                String value = generator.randomValue();
+                addRule("node[\"" + key + "\"=\"" + value + "\"]");
+            }
+            return this;
+        }
+
+        private CssGenerator addKeyRegexpRules(int count) {
+            for (int i = 0; i < count; i++) {
+                String key = generator.randomKey();
+                String value = generator.randomValue();
+                value = value.substring(i % value.length());
+                addRule("node[\"" + key + "\"=~/.*" + value + ".*/]");
+            }
+            return this;
+        }
+
+        public CssGenerator addHasKeyRules(int count) {
+            for (int i = 0; i < count; i++) {
+                String key = generator.randomKey();
+                addRule("node[\"" + key + "\"]");
+            }
+            return this;
+        }
+
+        public CssGenerator addIsTrueRules(int count) {
+            for (int i = 0; i < count; i++) {
+                String key = generator.randomKey();
+                // TODO
+                addRule("node[\"" + key + "\"?]");
+            }
+            return this;
+        }
+
+        private void addRule(String selector) {
+            sb.append(selector + " {}\n");
+        }
+
+        public String getCss() {
+            return sb.toString();
+        }
+    }
+
+    private static final int APPLY_CALLS = 1000000;
+
+    /**
+     * Prepare the test.
+     */
+    @BeforeClass
+    public static void createJOSMFixture() {
+        JOSMFixture.createPerformanceTestFixture().init(true);
+    }
+
+    /**
+     * Time how long it takes to evaluate [key=value] rules
+     */
+    @Test
+    public void testKeyValueRules() {
+        KeyValueDataGenerator data = OsmDataGenerator.getKeyValue();
+        data.generateDataSet();
+        CssGenerator css = new CssGenerator(data).addKeyValueRules(TEST_RULE_COUNT);
+        runTest(data, css, "only key=value rules");
+    }
+
+    /**
+     * Time how long it takes to evaluate [key] rules
+     */
+    @Test
+    public void testKeyOnlyRules() {
+        KeyValueDataGenerator data = OsmDataGenerator.getKeyValue();
+        data.generateDataSet();
+        CssGenerator css = new CssGenerator(data).addHasKeyRules(TEST_RULE_COUNT);
+        runTest(data, css, "only has key rules");
+    }
+
+    /**
+     * Time how long it takes to evaluate [key=~...] rules
+     */
+    @Test
+    public void testRegularExpressionRules() {
+        KeyValueDataGenerator data = OsmDataGenerator.getKeyValue();
+        data.generateDataSet();
+        CssGenerator css = new CssGenerator(data).addKeyRegexpRules(TEST_RULE_COUNT);
+        runTest(data, css, "regular expressions");
+    }
+
+    /**
+     * Time how long it takes to evaluate [key?] rules
+     */
+    @Test
+    public void testIsTrueRules() {
+        KeyValueDataGenerator data = OsmDataGenerator.getKeyValue();
+        data.generateDataSet();
+        CssGenerator css = new CssGenerator(data).addIsTrueRules(TEST_RULE_COUNT);
+        runTest(data, css, "is true");
+    }
+
+    private void runTest(KeyValueDataGenerator data, CssGenerator css, String description) {
+        MapCSSStyleSource source = new MapCSSStyleSource(css.getCss());
+        PerformanceTestTimer timer = PerformanceTestUtils.startTimer("MapCSSStyleSource#loadStyleSource(...) for " + description);
+        source.loadStyleSource();
+        timer.done();
+
+        timer = PerformanceTestUtils.startTimer("MapCSSStyleSource#apply(...) for " + description);
+        for (int i = 0; i < APPLY_CALLS; i++) {
+            MultiCascade mc = new MultiCascade();
+            source.apply(mc, data.randomNode(), 1, false);
+        }
+        timer.done();
+    }
+
+}
-- 
1.9.1

