Visor: scan cache with filter.
Project: http://git-wip-us.apache.org/repos/asf/ignite/repo Commit: http://git-wip-us.apache.org/repos/asf/ignite/commit/ae23dab0 Tree: http://git-wip-us.apache.org/repos/asf/ignite/tree/ae23dab0 Diff: http://git-wip-us.apache.org/repos/asf/ignite/diff/ae23dab0 Branch: refs/heads/ignite-3443 Commit: ae23dab0af8caaccd3db1dca8e435b57b8844a31 Parents: 4f27a47 Author: Alexey Kuznetsov <[email protected]> Authored: Wed Aug 3 17:10:03 2016 +0700 Committer: Alexey Kuznetsov <[email protected]> Committed: Wed Aug 3 17:10:03 2016 +0700 ---------------------------------------------------------------------- .../internal/visor/query/VisorQueryJob.java | 38 +++++++++--- .../query/VisorQueryScanSubstringFilter.java | 63 ++++++++++++++++++++ .../internal/visor/query/VisorQueryUtils.java | 6 ++ 3 files changed, 99 insertions(+), 8 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ignite/blob/ae23dab0/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryJob.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryJob.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryJob.java index 0f2f82e..153c564 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryJob.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryJob.java @@ -37,9 +37,12 @@ import org.apache.ignite.internal.util.typedef.internal.S; import org.apache.ignite.internal.util.typedef.internal.U; import org.apache.ignite.internal.visor.VisorJob; import org.apache.ignite.internal.visor.util.VisorExceptionWrapper; +import org.apache.ignite.lang.IgniteBiPredicate; import org.apache.ignite.lang.IgniteBiTuple; import static org.apache.ignite.internal.visor.query.VisorQueryUtils.RMV_DELAY; +import static org.apache.ignite.internal.visor.query.VisorQueryUtils.SCAN_CACHE_WITH_FILTER; +import static org.apache.ignite.internal.visor.query.VisorQueryUtils.SCAN_CACHE_WITH_FILTER_CASE_SENSITIVE; import static org.apache.ignite.internal.visor.query.VisorQueryUtils.SCAN_COL_NAMES; import static org.apache.ignite.internal.visor.query.VisorQueryUtils.SCAN_QRY_NAME; import static org.apache.ignite.internal.visor.query.VisorQueryUtils.SCAN_NEAR_CACHE; @@ -81,8 +84,9 @@ public class VisorQueryJob extends VisorJob<VisorQueryArg, IgniteBiTuple<? exten * @param arg Job argument with query parameters. * @return Query cursor. */ - private QueryCursor<Cache.Entry<Object, Object>> scan(IgniteCache<Object, Object> c, VisorQueryArg arg) { - ScanQuery<Object, Object> qry = new ScanQuery<>(null); + private QueryCursor<Cache.Entry<Object, Object>> scan(IgniteCache<Object, Object> c, VisorQueryArg arg, + IgniteBiPredicate<Object, Object> filter) { + ScanQuery<Object, Object> qry = new ScanQuery<>(filter); qry.setPageSize(arg.pageSize()); qry.setLocal(arg.local()); @@ -100,23 +104,41 @@ public class VisorQueryJob extends VisorJob<VisorQueryArg, IgniteBiTuple<? exten } /** {@inheritDoc} */ - @Override protected IgniteBiTuple<? extends VisorExceptionWrapper, VisorQueryResultEx> run(VisorQueryArg arg) { + @Override protected IgniteBiTuple<? extends VisorExceptionWrapper, VisorQueryResultEx> run(final VisorQueryArg arg) { try { UUID nid = ignite.localNode().id(); - boolean near = SCAN_NEAR_CACHE.equalsIgnoreCase(arg.queryTxt()); + String qryTxt = arg.queryTxt(); - boolean scan = arg.queryTxt() == null; + boolean scan = qryTxt == null; + + boolean scanWithFilter = qryTxt != null && qryTxt.startsWith(SCAN_CACHE_WITH_FILTER); + + boolean near = qryTxt != null && qryTxt.startsWith(SCAN_NEAR_CACHE); + + boolean scanAny = scan || scanWithFilter || near; // Generate query ID to store query cursor in node local storage. - String qryId = ((scan || near) ? SCAN_QRY_NAME : SQL_QRY_NAME) + "-" + UUID.randomUUID(); + String qryId = (scanAny ? SCAN_QRY_NAME : SQL_QRY_NAME) + "-" + UUID.randomUUID(); IgniteCache<Object, Object> c = cache(arg.cacheName()); - if (near || scan) { + if (scanAny) { long start = U.currentTimeMillis(); - VisorQueryCursor<Cache.Entry<Object, Object>> cur = new VisorQueryCursor<>(near ? near(c) : scan(c, arg)); + IgniteBiPredicate<Object, Object> filter = null; + + if (scanWithFilter) { + boolean caseSensitive = qryTxt.startsWith(SCAN_CACHE_WITH_FILTER_CASE_SENSITIVE); + + String ptrn = caseSensitive + ? qryTxt.substring(SCAN_CACHE_WITH_FILTER_CASE_SENSITIVE.length()) + : qryTxt.substring(SCAN_CACHE_WITH_FILTER.length()); + + filter = new VisorQueryScanSubstringFilter(caseSensitive, ptrn); + } + + VisorQueryCursor<Cache.Entry<Object, Object>> cur = new VisorQueryCursor<>(near ? near(c) : scan(c, arg, filter)); List<Object[]> rows = fetchScanQueryRows(cur, arg.pageSize()); http://git-wip-us.apache.org/repos/asf/ignite/blob/ae23dab0/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryScanSubstringFilter.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryScanSubstringFilter.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryScanSubstringFilter.java new file mode 100644 index 0000000..43eb6dd --- /dev/null +++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryScanSubstringFilter.java @@ -0,0 +1,63 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.visor.query; + +import org.apache.ignite.lang.IgniteBiPredicate; + +/** + * Filter scan results by specified substring in string presentation of key or value. + */ +public class VisorQueryScanSubstringFilter implements IgniteBiPredicate<Object, Object> { + /** */ + private static final long serialVersionUID = 0L; + + /** Case sensitive flag. */ + private final boolean caseSensitive; + + /** String to search in string presentation of key or value. */ + private final String ptrn; + + /** + * Create filter instance. + * + * @param caseSensitive Case sensitive flag. + * @param ptrn String to search in string presentation of key or value. + */ + public VisorQueryScanSubstringFilter(boolean caseSensitive, String ptrn) { + this.caseSensitive = caseSensitive; + + this.ptrn = caseSensitive ? ptrn : ptrn.toUpperCase(); + } + + /** + * Check that key or value contains specified string. + * + * @param key Key object. + * @param val Value object. + * @return {@code true} when string presentation of key or value contain specified string. + */ + @Override public boolean apply(Object key, Object val) { + String k = key.toString(); + String v = val.toString(); + + if (caseSensitive) + return k.contains(ptrn) || v.contains(ptrn); + + return k.toUpperCase().contains(ptrn) || v.toUpperCase().contains(ptrn); + } +} http://git-wip-us.apache.org/repos/asf/ignite/blob/ae23dab0/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryUtils.java ---------------------------------------------------------------------- diff --git a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryUtils.java b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryUtils.java index 64d2b95..0b8cf83 100644 --- a/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryUtils.java +++ b/modules/core/src/main/java/org/apache/ignite/internal/visor/query/VisorQueryUtils.java @@ -43,6 +43,12 @@ public class VisorQueryUtils { /** Prefix for node local key for SCAN near queries. */ public static final String SCAN_NEAR_CACHE = "VISOR_SCAN_NEAR_CACHE"; + /** Prefix for node local key for SCAN near queries. */ + public static final String SCAN_CACHE_WITH_FILTER = "VISOR_SCAN_CACHE_WITH_FILTER"; + + /** Prefix for node local key for SCAN near queries. */ + public static final String SCAN_CACHE_WITH_FILTER_CASE_SENSITIVE = "VISOR_SCAN_CACHE_WITH_FILTER_CASE_SENSITIVE"; + /** Columns for SCAN queries. */ public static final Collection<VisorQueryField> SCAN_COL_NAMES = Arrays.asList( new VisorQueryField(null, null, "Key Class", ""), new VisorQueryField(null, null, "Key", ""),
